scyllax_macros_core/
json.rs

1use proc_macro2::TokenStream;
2use quote::quote;
3use syn::ItemStruct;
4
5pub fn expand_attr(_args: TokenStream, input: TokenStream) -> TokenStream {
6    quote! {
7        #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, scyllax::prelude::JsonData)]
8        #input
9    }
10}
11
12pub fn expand(input: TokenStream) -> TokenStream {
13    let input: ItemStruct = match syn::parse2(input.clone()) {
14        Ok(it) => it,
15        Err(e) => return e.to_compile_error(),
16    };
17    let ident = &input.ident;
18
19    let expanded = quote! {
20        impl scylla::frame::value::Value for #ident {
21            fn serialize(
22                &self,
23                buf: &mut Vec<u8>
24            ) -> Result<(), scylla::frame::value::ValueTooBig> {
25                let data = serde_json::to_string(self).unwrap();
26                <String as scylla::frame::value::Value>::serialize(&data, buf)
27            }
28        }
29
30        impl scylla::cql_to_rust::FromCqlVal<
31            scylla::frame::response::result::CqlValue
32        > for #ident {
33            fn from_cql(
34                cql_val: scylla::frame::response::result::CqlValue
35            ) -> Result<Self, scylla::cql_to_rust::FromCqlValError> {
36                let data = <String as scylla::cql_to_rust::FromCqlVal<
37                    scylla::frame::response::result::CqlValue>
38                >::from_cql(cql_val)?;
39
40                serde_json::from_str(&data)
41                    .ok()
42                    .ok_or(scylla::cql_to_rust::FromCqlValError::BadCqlType)
43            }
44        }
45
46        impl scylla::serialize::value::SerializeCql for #ident {
47            fn serialize<'b>(
48                &self,
49                typ: &scylla::frame::response::result::ColumnType,
50                writer: scylla::serialize::CellWriter<'b>,
51            ) -> Result<
52                scylla::serialize::writers::WrittenCellProof<'b>,
53                scylla::serialize::SerializationError,
54            > {
55                let data = serde_json::to_string(&self).unwrap();
56                <String as scylla::serialize::value::SerializeCql>::serialize(&data, typ, writer)
57            }
58        }
59    };
60
61    expanded
62}