surrealdb_derive/
lib.rs

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