diff --git a/linera-base/src/identifiers.rs b/linera-base/src/identifiers.rs index 3767b7ac6ff..912b4b5aded 100644 --- a/linera-base/src/identifiers.rs +++ b/linera-base/src/identifiers.rs @@ -13,7 +13,7 @@ use std::{ use anyhow::{anyhow, Context}; use async_graphql::SimpleObject; use linera_witty::{WitLoad, WitStore, WitType}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::{ bcs_scalar, @@ -201,21 +201,7 @@ impl From<&BlobContent> for BlobType { } /// A content-addressed blob ID i.e. the hash of the `BlobContent`. -#[derive( - Eq, - PartialEq, - Ord, - PartialOrd, - Clone, - Copy, - Hash, - Debug, - Serialize, - Deserialize, - WitType, - WitStore, - WitLoad, -)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, WitType, WitStore, WitLoad)] #[cfg_attr(with_testing, derive(test_strategy::Arbitrary, Default))] pub struct BlobId { /// The hash of the blob. @@ -263,6 +249,45 @@ impl FromStr for BlobId { } } +#[derive(Serialize, Deserialize)] +#[serde(rename = "BlobId")] +struct BlobIdHelper { + hash: CryptoHash, + blob_type: BlobType, +} + +impl Serialize for BlobId { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if serializer.is_human_readable() { + serializer.serialize_str(&self.to_string()) + } else { + let helper = BlobIdHelper { + hash: self.hash, + blob_type: self.blob_type, + }; + helper.serialize(serializer) + } + } +} + +impl<'a> Deserialize<'a> for BlobId { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'a>, + { + if deserializer.is_human_readable() { + let s = String::deserialize(deserializer)?; + Self::from_str(&s).map_err(serde::de::Error::custom) + } else { + let helper = BlobIdHelper::deserialize(deserializer)?; + Ok(BlobId::new(helper.hash, helper.blob_type)) + } + } +} + /// The index of a message in a chain. #[derive( Eq, diff --git a/linera-client/src/util.rs b/linera-client/src/util.rs index ce7ac4508b6..e3a4e4d173a 100644 --- a/linera-client/src/util.rs +++ b/linera-client/src/util.rs @@ -66,38 +66,3 @@ macro_rules! impl_from_infallible { pub(crate) use impl_from_dynamic; pub(crate) use impl_from_infallible; - -pub mod serde_btreemap_keys_as_strings { - use std::{collections::BTreeMap, fmt::Display, str::FromStr}; - - use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; - - pub fn serialize(map: &BTreeMap, serializer: S) -> Result - where - K: Display, - V: Serialize, - S: Serializer, - { - let string_map: BTreeMap = - map.iter().map(|(k, v)| (k.to_string(), v)).collect(); - string_map.serialize(serializer) - } - - pub fn deserialize<'de, K, V, D>(deserializer: D) -> Result, D::Error> - where - K: FromStr + Ord, - ::Err: Display, - V: Deserialize<'de>, - D: Deserializer<'de>, - { - let string_map: BTreeMap = BTreeMap::deserialize(deserializer)?; - string_map - .into_iter() - .map(|(k, v)| { - k.parse() - .map(|key| (key, v)) - .map_err(serde::de::Error::custom) - }) - .collect() - } -} diff --git a/linera-client/src/wallet.rs b/linera-client/src/wallet.rs index 3588511980a..79a0f0fddda 100644 --- a/linera-client/src/wallet.rs +++ b/linera-client/src/wallet.rs @@ -18,7 +18,7 @@ use linera_storage::Storage; use rand::Rng as _; use serde::{Deserialize, Serialize}; -use crate::{config::GenesisConfig, error, util::serde_btreemap_keys_as_strings, Error}; +use crate::{config::GenesisConfig, error, Error}; #[derive(Serialize, Deserialize)] pub struct Wallet { @@ -210,7 +210,6 @@ pub struct UserChain { pub timestamp: Timestamp, pub next_block_height: BlockHeight, pub pending_block: Option, - #[serde(with = "serde_btreemap_keys_as_strings")] pub pending_blobs: BTreeMap, }