bitwarden_uuid_macro/
lib.rs1#![doc = include_str!("../README.md")]
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{
6 parse::{Parse, ParseStream},
7 parse_macro_input, Ident, Visibility,
8};
9
10#[allow(missing_docs)]
11#[proc_macro]
12pub fn uuid(input: TokenStream) -> TokenStream {
13 let input = parse_macro_input!(input as IdTypeInput);
15 let ident = input.ident;
16 let vis = input.vis;
17 let name_str = ident.to_string();
18
19 let tsify_type = format!("Tagged<Uuid, \"{}\">", name_str);
20 let doc_string = format!(" NewType wrapper for `{}`", name_str);
21
22 let expanded = quote! {
23 #[doc = #doc_string]
24 #[cfg_attr(feature = "wasm", derive(::tsify_next::Tsify), tsify(into_wasm_abi, from_wasm_abi))]
25 #[derive(
26 ::serde::Serialize, ::serde::Deserialize,
27 ::std::cmp::PartialEq, ::std::cmp::Eq,
28 ::std::clone::Clone, ::std::marker::Copy, ::std::fmt::Debug
29 )]
30 #[repr(transparent)]
31 #vis struct #ident
32 (
33 #[cfg_attr(feature = "wasm", tsify(type = #tsify_type))]
34 ::uuid::Uuid
35 );
36
37 #[cfg(feature = "uniffi")]
38 uniffi::custom_newtype!(#ident, uuid::Uuid);
39
40 impl #ident {
41 #[allow(missing_docs)]
42 pub fn new(value: uuid::Uuid) -> Self {
43 Self(value)
44 }
45 }
46
47 impl ::std::str::FromStr for #ident {
48 type Err = uuid::Error;
49
50 fn from_str(s: &str) -> Result<Self, Self::Err> {
51 uuid::Uuid::from_str(s).map(Self)
52 }
53 }
54
55 impl From<#ident> for ::uuid::Uuid {
56 fn from(value: #ident) -> Self {
57 value.0
58 }
59 }
60 };
61
62 TokenStream::from(expanded)
63}
64
65struct IdTypeInput {
67 vis: Visibility,
68 ident: Ident,
69}
70
71impl Parse for IdTypeInput {
72 fn parse(input: ParseStream) -> syn::Result<Self> {
73 let vis: Visibility = input.parse()?;
74 let ident: Ident = input.parse()?;
75 Ok(IdTypeInput { vis, ident })
76 }
77}