From c2d0cde3d4a21faf4dd60ae61ee31d6a1252752e Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Mon, 30 Jun 2025 11:46:38 +0300 Subject: [PATCH 1/4] serde serialize & deserialize for ManagedBuffer & ManagedVec --- Cargo.lock | 2 + framework/base/Cargo.toml | 14 +++- .../src/types/managed/basic/managed_buffer.rs | 33 +++++++++ .../src/types/managed/wrapped/managed_vec.rs | 71 ++++++++++++++++++- 4 files changed, 117 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e27de7e9ee..3d41da9a69 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -3072,6 +3072,8 @@ dependencies = [ "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "serde", + "serde_json", "unwrap-infallible", ] diff --git a/framework/base/Cargo.toml b/framework/base/Cargo.toml index 9cdd1acc87..88dd32ee47 100644 --- a/framework/base/Cargo.toml +++ b/framework/base/Cargo.toml @@ -4,7 +4,10 @@ version = "0.58.0" edition = "2021" rust-version = "1.83" -authors = ["Andrei Marinica ", "MultiversX "] +authors = [ + "Andrei Marinica ", + "MultiversX ", +] license = "GPL-3.0-only" readme = "README.md" repository = "https://github.com/multiversx/mx-sdk-rs" @@ -12,7 +15,12 @@ homepage = "https://multiversx.com/" documentation = "https://docs.multiversx.com/" description = "MultiversX smart contract API" keywords = ["multiversx", "wasm", "webassembly", "blockchain", "contract"] -categories = ["no-std", "wasm", "cryptography::cryptocurrencies", "development-tools"] +categories = [ + "no-std", + "wasm", + "cryptography::cryptocurrencies", + "development-tools", +] [package.metadata.docs.rs] all-features = true @@ -26,6 +34,8 @@ esdt-token-payment-legacy-decode = [] [dependencies] hex-literal = "1.0" bitflags = "2.9" +serde = { version = "1.0", default-features = false, features = ["derive"] } +serde_json = { version = "1.0", default-features = false, features = ["alloc"] } num-traits = { version = "=0.2.19", default-features = false } unwrap-infallible = "0.1.5" generic-array = "1.2.0" diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index 8ed21b959e..7775650fd9 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -18,6 +18,11 @@ use crate::{ StaticBufferRef, }, }; +use core::fmt; +use serde::{ + de::{self, Deserializer, Visitor}, + ser::Serializer, +}; /// A byte buffer managed by an external API. #[repr(transparent)] @@ -569,3 +574,31 @@ impl core::fmt::Display for ManagedBuffer { s.fmt(f) } } + +impl serde::Serialize for ManagedBuffer { + fn serialize(&self, serializer: S) -> Result { + let bytes = self.to_boxed_bytes(); + serializer.serialize_bytes(bytes.as_slice()) + } +} + +struct ManagedBufferVisitor(core::marker::PhantomData); + +impl<'de, M: ManagedTypeApi> Visitor<'de> for ManagedBufferVisitor { + type Value = ManagedBuffer; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("a UTF-8 string") + } + + fn visit_bytes(self, v: &[u8]) -> Result { + let buf = ManagedBuffer::new_from_bytes(v); + Ok(buf) + } +} + +impl<'de, M: ManagedTypeApi> serde::Deserialize<'de> for ManagedBuffer { + fn deserialize>(deserializer: D) -> Result { + deserializer.deserialize_bytes(ManagedBufferVisitor(core::marker::PhantomData)) + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 5692a5f090..ff64af9934 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -16,11 +16,16 @@ use alloc::{format, vec::Vec}; use core::{ borrow::Borrow, cmp::Ordering, - fmt::Debug, + fmt::{self, Debug}, iter::FromIterator, marker::PhantomData, mem::{transmute_copy, ManuallyDrop, MaybeUninit}, }; +use serde::{ + de::{SeqAccess, Visitor}, + ser::SerializeSeq, + Deserialize, Deserializer, Serialize, Serializer, +}; pub(crate) const INDEX_OUT_OF_RANGE_MSG: &[u8] = b"ManagedVec index out of range"; @@ -811,3 +816,67 @@ where } } } +struct ManagedVecVisitor { + _phantom: PhantomData<(M, T)>, +} + +impl<'de, M, T> Visitor<'de> for ManagedVecVisitor +where + M: ManagedTypeApi, + T: ManagedVecItem + Deserialize<'de>, +{ + type Value = ManagedVec; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "a sequence that can be deserialized into ManagedVec") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let mut vec = ManagedVec::::new(); + + while let Some(item) = seq.next_element::()? { + vec.push(item); + } + + Ok(vec) + } +} + +impl Serialize for ManagedVec +where + M: ManagedTypeApi, + T: ManagedVecItem + Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let len = self.len(); + let mut seq = serializer.serialize_seq(Some(len))?; + + for i in 0..len { + let item_ref = self.get(i); + seq.serialize_element(item_ref.borrow())?; + } + + seq.end() + } +} + +impl<'de, M, T> Deserialize<'de> for ManagedVec +where + M: ManagedTypeApi, + T: ManagedVecItem + Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_seq(ManagedVecVisitor { + _phantom: PhantomData, + }) + } +} From 4f097a3b448a2dfe2b06754a877d83f4d0e9d41b Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Wed, 2 Jul 2025 10:31:17 +0300 Subject: [PATCH 2/4] managed_serde::to_managed_buffer - not working --- Cargo.lock | 2 + .../feature-tests/basic-features/Cargo.toml | 9 ++++ .../basic-features/src/basic_features_main.rs | 2 + .../basic-features/src/serde_features.rs | 36 +++++++++++++ framework/base/src/types/managed.rs | 2 + .../src/types/managed/managed_serde/mod.rs | 1 + .../managed_serde/to_managed_buffer.rs | 54 +++++++++++++++++++ 7 files changed, 106 insertions(+) create mode 100644 contracts/feature-tests/basic-features/src/serde_features.rs create mode 100644 framework/base/src/types/managed/managed_serde/mod.rs create mode 100644 framework/base/src/types/managed/managed_serde/to_managed_buffer.rs diff --git a/Cargo.lock b/Cargo.lock index 3d41da9a69..d26ff0e63d 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,6 +248,8 @@ dependencies = [ "multiversx-sc", "multiversx-sc-modules", "multiversx-sc-scenario", + "serde", + "serde_json", ] [[package]] diff --git a/contracts/feature-tests/basic-features/Cargo.toml b/contracts/feature-tests/basic-features/Cargo.toml index bd93259768..8e9410d60b 100644 --- a/contracts/feature-tests/basic-features/Cargo.toml +++ b/contracts/feature-tests/basic-features/Cargo.toml @@ -12,6 +12,15 @@ path = "src/basic_features_main.rs" version = "0.58.0" path = "../../../framework/base" +[dependencies.serde] +version = "1.0" +default-features = false +features = ["derive"] + +[dependencies.serde_json] +version = "1.0" +default-features = false + [dev-dependencies.multiversx-sc-scenario] version = "0.58.0" features = ["wasmer-experimental"] diff --git a/contracts/feature-tests/basic-features/src/basic_features_main.rs b/contracts/feature-tests/basic-features/src/basic_features_main.rs index 5a0ef5c466..b730b44f9f 100644 --- a/contracts/feature-tests/basic-features/src/basic_features_main.rs +++ b/contracts/feature-tests/basic-features/src/basic_features_main.rs @@ -20,6 +20,7 @@ pub mod managed_buffer_features; pub mod managed_decimal_features; pub mod managed_vec_features; pub mod non_zero_features; +pub mod serde_features; pub mod small_num_overflow_test_ops; pub mod special_roles_from_system_account; pub mod storage_direct_load; @@ -61,6 +62,7 @@ pub trait BasicFeatures: + managed_address_features::ManagedAddressFeatures + managed_buffer_features::ManagedBufferFeatures + managed_vec_features::ManagedVecFeatures + + serde_features::SerdeFeatures + storage_raw_api_features::StorageRawApiFeatures + storage_direct_load::StorageLoadFeatures + storage_direct_store::StorageStoreFeatures diff --git a/contracts/feature-tests/basic-features/src/serde_features.rs b/contracts/feature-tests/basic-features/src/serde_features.rs new file mode 100644 index 0000000000..4aefa85dd4 --- /dev/null +++ b/contracts/feature-tests/basic-features/src/serde_features.rs @@ -0,0 +1,36 @@ +use serde::{Deserialize, Serialize}; + +multiversx_sc::imports!(); + +multiversx_sc::derive_imports!(); + +#[type_abi] +#[derive( + NestedEncode, + NestedDecode, + TopEncode, + TopDecode, + PartialEq, + Eq, + Debug, + Clone, + Serialize, + Deserialize, +)] +pub struct StructManaged { + pub m_buffer: ManagedBuffer, + pub m_vec_of_m_buffers: ManagedVec>, +} + +#[multiversx_sc::module] +pub trait SerdeFeatures { + #[endpoint] + fn managed_serialize(&self, json: ManagedBuffer) -> StructManaged { + todo!(); + } + + #[endpoint] + fn managed_deserialize(&self, m_struct: StructManaged) -> ManagedBuffer { + todo!(); + } +} diff --git a/framework/base/src/types/managed.rs b/framework/base/src/types/managed.rs index 3107f1ee3e..7687446527 100644 --- a/framework/base/src/types/managed.rs +++ b/framework/base/src/types/managed.rs @@ -1,11 +1,13 @@ mod basic; mod codec_util; +mod managed_serde; mod managed_type_trait; mod multi_value; mod wrapped; pub use basic::*; pub use codec_util::*; +pub use managed_serde::*; pub use managed_type_trait::ManagedType; pub use multi_value::*; pub use wrapped::*; diff --git a/framework/base/src/types/managed/managed_serde/mod.rs b/framework/base/src/types/managed/managed_serde/mod.rs new file mode 100644 index 0000000000..57d231bf28 --- /dev/null +++ b/framework/base/src/types/managed/managed_serde/mod.rs @@ -0,0 +1 @@ +mod to_managed_buffer; diff --git a/framework/base/src/types/managed/managed_serde/to_managed_buffer.rs b/framework/base/src/types/managed/managed_serde/to_managed_buffer.rs new file mode 100644 index 0000000000..7883d4be8e --- /dev/null +++ b/framework/base/src/types/managed/managed_serde/to_managed_buffer.rs @@ -0,0 +1,54 @@ +use core::fmt; +use serde::Serialize; + +use crate::{api::ManagedTypeApi, types::ManagedBuffer}; + +#[derive(Debug)] +pub enum ToManagedBufferError { + Serde(serde_json::Error), +} + +impl fmt::Display for ToManagedBufferError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ToManagedBufferError::Serde(e) => write!(f, "Serialization error: {}", e), + } + } +} + +impl From for ToManagedBufferError { + fn from(e: serde_json::Error) -> Self { + ToManagedBufferError::Serde(e) + } +} + +struct ManagedBufferWriter<'a, M: ManagedTypeApi> { + buffer: &'a mut ManagedBuffer, +} + +impl<'a, M: ManagedTypeApi> std::io::Write for ManagedBufferWriter<'a, M> { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.buffer.append_bytes(buf); + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + +pub fn to_managed_buffer(value: &T) -> Result, ToManagedBufferError> +where + M: ManagedTypeApi, + T: ?Sized + Serialize, +{ + let mut buffer = ManagedBuffer::::new(); + { + let mut writer = ManagedBufferWriter { + buffer: &mut buffer, + }; + let mut serializer = serde_json::Serializer::new(&mut writer); + value.serialize(&mut serializer)?; + } + Ok(buffer) +} From 4be4e3cde966057bc7e52174bb51be3f12cf55f9 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Tue, 12 Aug 2025 12:21:50 +0300 Subject: [PATCH 3/4] partial implementation --- Cargo.lock | 21 +++++++- framework/base/Cargo.toml | 7 ++- .../managed_serde/from_managed_buffer.rs | 10 ++++ .../managed/managed_serde/from_managed_vec.rs | 9 ++++ .../src/types/managed/managed_serde/mod.rs | 5 +- .../managed_serde/to_managed_buffer.rs | 53 +++---------------- .../managed/managed_serde/to_managed_vec.rs | 22 ++++++++ 7 files changed, 77 insertions(+), 50 deletions(-) create mode 100644 framework/base/src/types/managed/managed_serde/from_managed_buffer.rs create mode 100644 framework/base/src/types/managed/managed_serde/from_managed_vec.rs create mode 100644 framework/base/src/types/managed/managed_serde/to_managed_vec.rs diff --git a/Cargo.lock b/Cargo.lock index e6c3c67d78..8bc8cfc50a 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -657,6 +657,15 @@ dependencies = [ "cc", ] +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.12", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -3111,8 +3120,8 @@ dependencies = [ "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "postcard", "serde", - "serde_json", "unwrap-infallible", ] @@ -3837,6 +3846,16 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "postcard" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c1de96e20f51df24ca73cafcc4690e044854d803259db27a00a461cb3b9d17a" +dependencies = [ + "cobs", + "serde", +] + [[package]] name = "ppv-lite86" version = "0.2.21" diff --git a/framework/base/Cargo.toml b/framework/base/Cargo.toml index ad7193ffb1..370e4d21a5 100644 --- a/framework/base/Cargo.toml +++ b/framework/base/Cargo.toml @@ -34,10 +34,13 @@ esdt-token-payment-legacy-decode = [] barnard = [] [dependencies] +serde = { version = "1.0", default-features = false, features = [ + "derive", + "alloc", +] } +postcard = { version = "1.0", default-features = false } hex-literal = "1.0" bitflags = "2.9" -serde = { version = "1.0", default-features = false, features = ["derive"] } -serde_json = { version = "1.0", default-features = false, features = ["alloc"] } num-traits = { version = "=0.2.19", default-features = false } unwrap-infallible = "0.1.5" generic-array = "1.2.0" diff --git a/framework/base/src/types/managed/managed_serde/from_managed_buffer.rs b/framework/base/src/types/managed/managed_serde/from_managed_buffer.rs new file mode 100644 index 0000000000..bb9c4f26f6 --- /dev/null +++ b/framework/base/src/types/managed/managed_serde/from_managed_buffer.rs @@ -0,0 +1,10 @@ +use postcard::from_bytes; +use serde::de::DeserializeOwned; + +use crate::{api::ManagedTypeApi, types::ManagedBuffer}; + +pub fn from_managed_buffer( + mb: &ManagedBuffer, +) -> Result { + mb.with_buffer_contents(|slice| from_bytes(slice)) +} diff --git a/framework/base/src/types/managed/managed_serde/from_managed_vec.rs b/framework/base/src/types/managed/managed_serde/from_managed_vec.rs new file mode 100644 index 0000000000..e00c60bc6d --- /dev/null +++ b/framework/base/src/types/managed/managed_serde/from_managed_vec.rs @@ -0,0 +1,9 @@ +use crate::{api::ManagedTypeApi, types::ManagedVec}; +use postcard::from_bytes; +use serde::de::DeserializeOwned; + +pub fn from_managed_vec( + mv: &ManagedVec, +) -> Result { + mv.with_self_as_slice(|mv_slice| from_bytes(mv_slice)) +} diff --git a/framework/base/src/types/managed/managed_serde/mod.rs b/framework/base/src/types/managed/managed_serde/mod.rs index 57d231bf28..53d1df28f0 100644 --- a/framework/base/src/types/managed/managed_serde/mod.rs +++ b/framework/base/src/types/managed/managed_serde/mod.rs @@ -1 +1,4 @@ -mod to_managed_buffer; +pub mod from_managed_buffer; +pub mod from_managed_vec; +pub mod to_managed_buffer; +pub mod to_managed_vec; diff --git a/framework/base/src/types/managed/managed_serde/to_managed_buffer.rs b/framework/base/src/types/managed/managed_serde/to_managed_buffer.rs index 7883d4be8e..637051b1bb 100644 --- a/framework/base/src/types/managed/managed_serde/to_managed_buffer.rs +++ b/framework/base/src/types/managed/managed_serde/to_managed_buffer.rs @@ -1,54 +1,15 @@ -use core::fmt; use serde::Serialize; -use crate::{api::ManagedTypeApi, types::ManagedBuffer}; - -#[derive(Debug)] -pub enum ToManagedBufferError { - Serde(serde_json::Error), -} - -impl fmt::Display for ToManagedBufferError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ToManagedBufferError::Serde(e) => write!(f, "Serialization error: {}", e), - } - } -} - -impl From for ToManagedBufferError { - fn from(e: serde_json::Error) -> Self { - ToManagedBufferError::Serde(e) - } -} +use crate::{ + api::ManagedTypeApi, + types::{to_managed_vec::to_managed_vec, ManagedBuffer}, +}; struct ManagedBufferWriter<'a, M: ManagedTypeApi> { buffer: &'a mut ManagedBuffer, } -impl<'a, M: ManagedTypeApi> std::io::Write for ManagedBufferWriter<'a, M> { - fn write(&mut self, buf: &[u8]) -> std::io::Result { - self.buffer.append_bytes(buf); - Ok(buf.len()) - } - - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } -} - -pub fn to_managed_buffer(value: &T) -> Result, ToManagedBufferError> -where - M: ManagedTypeApi, - T: ?Sized + Serialize, -{ - let mut buffer = ManagedBuffer::::new(); - { - let mut writer = ManagedBufferWriter { - buffer: &mut buffer, - }; - let mut serializer = serde_json::Serializer::new(&mut writer); - value.serialize(&mut serializer)?; - } - Ok(buffer) +pub fn to_managed_buffer(obj: &T) -> ManagedBuffer { + let mv = to_managed_vec(obj); + mv.buffer } diff --git a/framework/base/src/types/managed/managed_serde/to_managed_vec.rs b/framework/base/src/types/managed/managed_serde/to_managed_vec.rs new file mode 100644 index 0000000000..6e32e29144 --- /dev/null +++ b/framework/base/src/types/managed/managed_serde/to_managed_vec.rs @@ -0,0 +1,22 @@ +use crate::types::ManagedVec; +use postcard::to_slice; +use serde::Serialize; + +use crate::api::ManagedTypeApi; + +pub fn to_managed_vec(obj: &T) -> ManagedVec { + let mut buffer: ManagedVec = ManagedVec::new(); + + const MAX: usize = 1024; + let mut temp = [0u8; MAX]; + + let len = to_slice(obj, &mut temp) + .expect("serialization failed") + .len(); + + for byte in &temp[..len] { + buffer.push(*byte); + } + + buffer +} From 793423656d5a3ec8577f01ca91c717eacf3d71b6 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Tue, 12 Aug 2025 13:02:48 +0300 Subject: [PATCH 4/4] cleanup --- .../src/types/managed/basic/managed_buffer.rs | 33 --------- .../src/types/managed/wrapped/managed_vec.rs | 71 +------------------ 2 files changed, 1 insertion(+), 103 deletions(-) diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index de83c88936..27622034be 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -18,11 +18,6 @@ use crate::{ StaticBufferRef, }, }; -use core::fmt; -use serde::{ - de::{self, Deserializer, Visitor}, - ser::Serializer, -}; /// A byte buffer managed by an external API. #[repr(transparent)] @@ -580,31 +575,3 @@ impl core::fmt::Display for ManagedBuffer { s.fmt(f) } } - -impl serde::Serialize for ManagedBuffer { - fn serialize(&self, serializer: S) -> Result { - let bytes = self.to_boxed_bytes(); - serializer.serialize_bytes(bytes.as_slice()) - } -} - -struct ManagedBufferVisitor(core::marker::PhantomData); - -impl<'de, M: ManagedTypeApi> Visitor<'de> for ManagedBufferVisitor { - type Value = ManagedBuffer; - - fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("a UTF-8 string") - } - - fn visit_bytes(self, v: &[u8]) -> Result { - let buf = ManagedBuffer::new_from_bytes(v); - Ok(buf) - } -} - -impl<'de, M: ManagedTypeApi> serde::Deserialize<'de> for ManagedBuffer { - fn deserialize>(deserializer: D) -> Result { - deserializer.deserialize_bytes(ManagedBufferVisitor(core::marker::PhantomData)) - } -} diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 3d8490a238..6c4cbba559 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -16,16 +16,11 @@ use alloc::{format, vec::Vec}; use core::{ borrow::Borrow, cmp::Ordering, - fmt::{self, Debug}, + fmt::Debug, iter::FromIterator, marker::PhantomData, mem::{transmute_copy, ManuallyDrop, MaybeUninit}, }; -use serde::{ - de::{SeqAccess, Visitor}, - ser::SerializeSeq, - Deserialize, Deserializer, Serialize, Serializer, -}; pub(crate) const INDEX_OUT_OF_RANGE_MSG: &[u8] = b"ManagedVec index out of range"; @@ -828,67 +823,3 @@ where } } } -struct ManagedVecVisitor { - _phantom: PhantomData<(M, T)>, -} - -impl<'de, M, T> Visitor<'de> for ManagedVecVisitor -where - M: ManagedTypeApi, - T: ManagedVecItem + Deserialize<'de>, -{ - type Value = ManagedVec; - - fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "a sequence that can be deserialized into ManagedVec") - } - - fn visit_seq(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - let mut vec = ManagedVec::::new(); - - while let Some(item) = seq.next_element::()? { - vec.push(item); - } - - Ok(vec) - } -} - -impl Serialize for ManagedVec -where - M: ManagedTypeApi, - T: ManagedVecItem + Serialize, -{ - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let len = self.len(); - let mut seq = serializer.serialize_seq(Some(len))?; - - for i in 0..len { - let item_ref = self.get(i); - seq.serialize_element(item_ref.borrow())?; - } - - seq.end() - } -} - -impl<'de, M, T> Deserialize<'de> for ManagedVec -where - M: ManagedTypeApi, - T: ManagedVecItem + Deserialize<'de>, -{ - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_seq(ManagedVecVisitor { - _phantom: PhantomData, - }) - } -}