moxy-derive 0.0.4

derive macros for moxy crate
Documentation
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)
    }
}