use quote::quote;
use super::{DisplayOptions, DisplayOutput, Segment, SegmentKind, access};
pub struct JsonStyleSyntax {
pub pretty: bool,
}
impl JsonStyleSyntax {
pub fn render(&self, opts: &DisplayOptions) -> syn::Result<DisplayOutput> {
let mut out = DisplayOutput::new();
let serialize = if self.pretty {
quote! { ::serde_json::to_string_pretty(&__val) }
} else {
quote! { ::serde_json::to_string(&__val) }
};
if opts.is_named {
let inserts = opts
.fields
.iter()
.map(|f| {
let a = access(f, opts.use_self);
let dname = f.display_name()?;
Ok(quote! {
__map.insert(
#dname.into(),
::serde_json::to_value(&#a).unwrap_or(::serde_json::Value::Null),
);
})
})
.collect::<syn::Result<Vec<_>>>()?;
out.push(Segment::placeholder(
SegmentKind::Value,
quote! {
{
let mut __map = ::serde_json::Map::new();
#(#inserts)*
let __val = ::serde_json::Value::Object(__map);
#serialize.unwrap_or_default()
}
},
));
} else {
let pushes: Vec<_> = opts
.fields
.iter()
.map(|f| {
let a = access(f, opts.use_self);
quote! {
__arr.push(
::serde_json::to_value(&#a).unwrap_or(::serde_json::Value::Null),
);
}
})
.collect();
out.push(Segment::placeholder(
SegmentKind::Value,
quote! {
{
let mut __arr = ::std::vec::Vec::new();
#(#pushes)*
let __val = ::serde_json::Value::Array(__arr);
#serialize.unwrap_or_default()
}
},
));
}
Ok(out)
}
}