liquid_derive/
value_view.rs

1use proc_macro2::TokenStream;
2use quote::quote;
3use syn::DeriveInput;
4
5pub(crate) fn derive(input: &DeriveInput) -> TokenStream {
6    let DeriveInput {
7        ident,
8        data,
9        generics,
10        ..
11    } = input;
12
13    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
14
15    let fields = match crate::object_view::get_fields(data) {
16        Ok(fields) => fields,
17        Err(err) => return err.to_compile_error(),
18    };
19
20    quote! {
21        impl #impl_generics ::liquid::ValueView for #ident #ty_generics #where_clause {
22            fn as_debug(&self) -> &dyn ::std::fmt::Debug {
23                self
24            }
25
26            fn render(&self) -> ::liquid::model::DisplayCow<'_> {
27                ::liquid::model::DisplayCow::Owned(Box::new(::liquid::model::ObjectRender::new(self)))
28            }
29            fn source(&self) -> ::liquid::model::DisplayCow<'_> {
30                ::liquid::model::DisplayCow::Owned(Box::new(::liquid::model::ObjectSource::new(self)))
31            }
32            fn type_name(&self) -> &'static str {
33                "object"
34            }
35            fn query_state(&self, state: ::liquid::model::State) -> bool {
36                match state {
37                    ::liquid::model::State::Truthy => true,
38                    ::liquid::model::State::DefaultValue |
39                    ::liquid::model::State::Empty |
40                    ::liquid::model::State::Blank => self.size() == 0,
41                }
42            }
43
44            fn to_kstr(&self) -> ::liquid::model::KStringCow<'_> {
45                let s = ::liquid::model::ObjectRender::new(self).to_string();
46                ::liquid::model::KStringCow::from_string(s)
47            }
48            fn to_value(&self) -> ::liquid::model::Value {
49                let mut object = ::liquid::model::Object::new();
50                #(
51                    object.insert(stringify!(#fields).into(), ::liquid::model::ValueView::to_value(&self.#fields));
52                )*
53                ::liquid::model::Value::Object(object)
54            }
55
56            fn as_object(&self) -> Option<&dyn ::liquid::ObjectView> {
57                Some(self)
58            }
59        }
60    }
61}
62
63pub(crate) fn core_derive(input: &DeriveInput) -> TokenStream {
64    let DeriveInput {
65        ident,
66        data,
67        generics,
68        ..
69    } = input;
70
71    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
72
73    let fields = match crate::object_view::get_fields(data) {
74        Ok(fields) => fields,
75        Err(err) => return err.to_compile_error(),
76    };
77
78    quote! {
79        impl #impl_generics ::liquid_core::ValueView for #ident #ty_generics #where_clause {
80            fn as_debug(&self) -> &dyn ::std::fmt::Debug {
81                self
82            }
83
84            fn render(&self) -> ::liquid_core::model::DisplayCow<'_> {
85                ::liquid_core::model::DisplayCow::Owned(Box::new(::liquid_core::model::ObjectRender::new(self)))
86            }
87            fn source(&self) -> ::liquid_core::model::DisplayCow<'_> {
88                ::liquid_core::model::DisplayCow::Owned(Box::new(::liquid_core::model::ObjectSource::new(self)))
89            }
90            fn type_name(&self) -> &'static str {
91                "object"
92            }
93            fn query_state(&self, state: ::liquid_core::model::State) -> bool {
94                match state {
95                    ::liquid_core::model::State::Truthy => true,
96                    ::liquid_core::model::State::DefaultValue |
97                    ::liquid_core::model::State::Empty |
98                    ::liquid_core::model::State::Blank => self.size() == 0,
99                }
100            }
101
102            fn to_kstr(&self) -> ::liquid_core::model::KStringCow<'_> {
103                let s = ::liquid_core::model::ObjectRender::new(self).to_string();
104                ::liquid_core::model::KStringCow::from_string(s)
105            }
106            fn to_value(&self) -> ::liquid_core::model::Value {
107                let mut object = ::liquid_core::model::Object::new();
108                #(
109                    object.insert(stringify!(#fields).into(), ::liquid_core::model::ValueView::to_value(&self.#fields));
110                )*
111                ::liquid_core::model::Value::Object(object)
112            }
113
114            fn as_object(&self) -> Option<&dyn ::liquid_core::ObjectView> {
115                Some(self)
116            }
117        }
118    }
119}