diff --git a/changelog/new.txt b/changelog/new.txt index c050bdb..120fcb3 100644 --- a/changelog/new.txt +++ b/changelog/new.txt @@ -4,6 +4,7 @@ Breaking changes: Bugs fixed: - backup crashed when there was a non-unicode link target. The crash has been fixed. However, non-unicode link targets are still unsupported. +- Extended attributes which were saved with value null couldn't be handled. This has been fixed. New features: - copy: Added --init option to initialize uninitialized target repos diff --git a/src/backend/node.rs b/src/backend/node.rs index 785af1c..e814c8c 100644 --- a/src/backend/node.rs +++ b/src/backend/node.rs @@ -11,10 +11,11 @@ use anyhow::Result; use anyhow::{anyhow, bail}; use chrono::{DateTime, Local}; use derive_more::{Constructor, IsVariant}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use serde_aux::prelude::*; -use serde_with::base64::Base64; -use serde_with::serde_as; +use serde_with::base64::{Base64, Standard}; +use serde_with::formats::Padded; +use serde_with::{DeserializeAs, SerializeAs}; use crate::id::Id; @@ -73,11 +74,23 @@ pub struct Metadata { pub extended_attributes: Vec, } -#[serde_as] +// Deserialize a Base64-encoded value into Vec. +// Handles '"value" = null' by first deserializing into a Option. +fn deserialize_value<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let value: Option> = Base64::::deserialize_as(deserializer)?; + Ok(value.unwrap_or_default()) +} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ExtendedAttribute { pub name: String, - #[serde_as(as = "Base64")] + #[serde( + serialize_with = "Base64::::serialize_as", + deserialize_with = "deserialize_value" + )] pub value: Vec, }