surrealdb_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{DeriveInput, parse_macro_input};
4
5#[proc_macro_derive(Store)]
6pub fn store(input: TokenStream) -> TokenStream {
7	// Parse the token stream
8	let input = parse_macro_input!(input as DeriveInput);
9	// Fetch the struct name
10	let name = &input.ident;
11	// Add derived implementations
12	let output = quote! {
13
14		impl TryFrom<#name> for Vec<u8> {
15			type Error = crate::err::Error;
16			fn try_from(v: #name) -> Result<Self, Self::Error> {
17				Self::try_from(&v)
18			}
19		}
20
21		impl TryFrom<Vec<u8>> for #name {
22			type Error = crate::err::Error;
23			fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {
24				Self::try_from(&v)
25			}
26		}
27
28		impl TryFrom<&#name> for Vec<u8> {
29			type Error = crate::err::Error;
30			fn try_from(v: &#name) -> Result<Self, Self::Error> {
31				let mut out:Vec<u8> = vec![];
32				revision::Revisioned::serialize_revisioned(v, &mut out)?;
33				Ok(out)
34			}
35		}
36
37		impl TryFrom<&Vec<u8>> for #name {
38			type Error = crate::err::Error;
39			fn try_from(v: &Vec<u8>) -> Result<Self, Self::Error> {
40				Ok(revision::Revisioned::deserialize_revisioned(&mut v.as_slice())?)
41			}
42		}
43
44	};
45	//
46	output.into()
47}
48
49#[proc_macro_derive(Key)]
50pub fn key(input: TokenStream) -> TokenStream {
51	// Parse the token stream
52	let input = parse_macro_input!(input as DeriveInput);
53	// Fetch the struct name
54	let name = &input.ident;
55	// Compute the generics
56	let generics = input.generics;
57	let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
58	assert!(generics.lifetimes().count() <= 1);
59	let (lifetime, from_owned) = if let Some(lifetime_def) = generics.lifetimes().next() {
60		let lifetime = &lifetime_def.lifetime;
61		(quote! {#lifetime}, quote! {})
62	} else {
63		(
64			quote! {},
65			quote! {
66				impl #impl_generics From<Vec<u8>> for #name #ty_generics #where_clause {
67					fn from(v: Vec<u8>) -> Self {
68						Self::decode(&v).unwrap()
69					}
70				}
71			},
72		)
73	};
74
75	// Generate the output
76	let output = quote! {
77
78		impl #impl_generics From<#name #ty_generics> for Vec<u8> #where_clause {
79			fn from(v: #name #ty_generics) -> Vec<u8> {
80				v.encode().unwrap_or_default()
81			}
82		}
83
84		impl #impl_generics From<&#name #ty_generics> for Vec<u8> #where_clause {
85			fn from(v: &#name #ty_generics) -> Vec<u8> {
86				v.encode().unwrap_or_default()
87			}
88		}
89
90		#from_owned
91
92		impl #impl_generics From<&#lifetime Vec<u8>> for #name #ty_generics #where_clause {
93			fn from(v: &#lifetime Vec<u8>) -> Self {
94				Self::decode(v).unwrap()
95			}
96		}
97
98		impl #impl_generics #name #ty_generics #where_clause {
99
100			pub fn encode(&self) -> Result<Vec<u8>, crate::err::Error> {
101				let v = storekey::serialize(self);
102				Ok(v?)
103			}
104
105			pub fn decode(v: &#lifetime[u8]) -> Result<Self, crate::err::Error> {
106				let v = storekey::deserialize(v);
107				Ok(v?)
108			}
109
110		}
111
112	};
113
114	output.into()
115}