mirror of
https://github.com/trussed-dev/serde-indexed.git
synced 2026-06-20 04:16:32 -07:00
Implement serialize_with
This commit is contained in:
committed by
sosthene-nitrokey
parent
431df81340
commit
1ba7e85dfc
+1
-1
@@ -23,6 +23,6 @@ heapless = { version = "0.7.16", default-features = false, features = ["serde"]
|
||||
hex-literal = "0.4.1"
|
||||
serde = { version = "1" }
|
||||
serde-byte-array = "0.1.2"
|
||||
serde_bytes = { version = "0.11.12", default-features = false }
|
||||
serde_bytes = { version = "0.11.12" }
|
||||
serde_cbor = { version = "0.11.0" }
|
||||
serde_test = "1.0.176"
|
||||
|
||||
+28
-2
@@ -44,16 +44,42 @@ fn serialize_fields(fields: &[parse::Field], offset: usize) -> Vec<proc_macro2::
|
||||
.filter_map(|field| {
|
||||
let index = field.index + offset;
|
||||
let member = &field.member;
|
||||
let serialize_member = match &field.serialize_with {
|
||||
None => quote!(&self.#member),
|
||||
Some(f) => {
|
||||
let ty = &field.ty;
|
||||
quote!({
|
||||
struct __SerializeWith<'__lifetime> {
|
||||
value: &'__lifetime #ty,
|
||||
}
|
||||
|
||||
impl<'__lifetime> serde::Serialize for __SerializeWith<'__lifetime> {
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__s: __S,
|
||||
) -> ::core::result::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: serde::Serializer,
|
||||
{
|
||||
#f(self.value, __s)
|
||||
}
|
||||
}
|
||||
|
||||
&__SerializeWith { value: &self.#member }
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
// println!("field {:?} index {:?}", &field.label, field.index);
|
||||
match &field.skip_serializing_if {
|
||||
Skip::If(path) => Some(quote! {
|
||||
if !#path(&self.#member) {
|
||||
map.serialize_entry(&#index, &self.#member)?;
|
||||
map.serialize_entry(&#index, #serialize_member)?;
|
||||
}
|
||||
}),
|
||||
Skip::Always => None,
|
||||
Skip::Never => Some(quote! {
|
||||
map.serialize_entry(&#index, &self.#member)?;
|
||||
map.serialize_entry(&#index, #serialize_member)?;
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -38,6 +38,7 @@ pub struct Field {
|
||||
pub skip_serializing_if: Skip,
|
||||
pub serialize_with: Option<syn::ExprPath>,
|
||||
pub deserialize_with: Option<syn::ExprPath>,
|
||||
pub ty: syn::Type,
|
||||
}
|
||||
|
||||
fn parse_meta(attrs: &mut StructAttrs, meta: ParseNestedMeta) -> Result<()> {
|
||||
@@ -190,6 +191,7 @@ fn fields_from_ast(
|
||||
},
|
||||
index: current_index,
|
||||
// TODO: make this... more concise? handle errors? the thing with the spans?
|
||||
ty: field.ty.clone(),
|
||||
skip_serializing_if,
|
||||
serialize_with,
|
||||
deserialize_with,
|
||||
|
||||
@@ -418,6 +418,7 @@ mod generics {
|
||||
use heapless::String;
|
||||
use serde_byte_array::ByteArray;
|
||||
use serde_bytes::Bytes;
|
||||
use serde_test::assert_ser_tokens;
|
||||
|
||||
#[derive(PartialEq, Debug, SerializeIndexed, DeserializeIndexed)]
|
||||
#[serde_indexed(offset = 1)]
|
||||
@@ -522,4 +523,25 @@ mod generics {
|
||||
|
||||
assert_eq!(deserialized, example);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_with() {
|
||||
#[derive(serde_indexed::SerializeIndexed)]
|
||||
struct SerializeWith {
|
||||
#[serde(serialize_with = "serde_bytes::serialize")]
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
let value = SerializeWith { data: vec![0; 128] };
|
||||
|
||||
assert_ser_tokens(
|
||||
&value,
|
||||
&[
|
||||
Token::Map { len: Some(1) },
|
||||
Token::U64(0),
|
||||
Token::Bytes(&[0; 128]),
|
||||
Token::MapEnd,
|
||||
],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user