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