dioxus_core_macro/
utils.rs1use quote::ToTokens;
2use syn::parse::{Parse, ParseStream};
3use syn::spanned::Spanned;
4use syn::{parse_quote, Expr, Lit, Meta, Token, Type};
5
6pub fn lit_to_string(lit: Lit) -> Option<String> {
12 match lit {
13 Lit::Str(l) => Some(l.value()),
14 Lit::ByteStr(l) => String::from_utf8(l.value()).ok(),
15 Lit::Byte(l) => Some(String::from(l.value() as char)),
16 Lit::Char(l) => Some(l.value().to_string()),
17 Lit::Int(l) => Some(l.base10_digits().to_string()),
18 Lit::Float(l) => Some(l.base10_digits().to_string()),
19 Lit::Bool(l) => Some(l.value().to_string()),
20 Lit::Verbatim(_) => None,
21 _ => None,
22 }
23}
24
25pub fn format_type_string(ty: &Type) -> String {
26 let ty_unformatted = ty.into_token_stream().to_string();
27 let ty_unformatted = ty_unformatted.trim();
28
29 let ty_formatted = ty_unformatted.replace(' ', "");
31
32 ty_formatted.to_string()
33}
34
35#[derive(Default)]
39pub struct DeprecatedAttribute {
40 pub since: Option<String>,
41 pub note: Option<String>,
42}
43
44impl DeprecatedAttribute {
45 pub fn from_meta(meta: &Meta) -> syn::Result<Self> {
47 if meta.path() != &parse_quote!(deprecated) {
48 return Err(syn::Error::new(
49 meta.span(),
50 "attribute path is not `deprecated`",
51 ));
52 }
53
54 match &meta {
55 Meta::Path(_) => Ok(Self::default()),
56 Meta::NameValue(name_value) => {
57 let Expr::Lit(expr_lit) = &name_value.value else {
58 return Err(syn::Error::new(
59 name_value.span(),
60 "literal in `deprecated` value must be a string",
61 ));
62 };
63
64 Ok(Self {
65 since: None,
66 note: lit_to_string(expr_lit.lit.clone()).map(|s| s.trim().to_string()),
67 })
68 }
69 Meta::List(list) => {
70 let parsed = list.parse_args::<DeprecatedAttributeArgsParser>()?;
71
72 Ok(Self {
73 since: parsed.since.map(|s| s.trim().to_string()),
74 note: parsed.note.map(|s| s.trim().to_string()),
75 })
76 }
77 }
78 }
79}
80
81mod kw {
82 use syn::custom_keyword;
83 custom_keyword!(since);
84 custom_keyword!(note);
85}
86
87struct DeprecatedAttributeArgsParser {
88 since: Option<String>,
89 note: Option<String>,
90}
91
92impl Parse for DeprecatedAttributeArgsParser {
93 fn parse(input: ParseStream) -> syn::Result<Self> {
94 let mut since: Option<String> = None;
95 let mut note: Option<String> = None;
96
97 if input.peek(kw::since) {
98 input.parse::<kw::since>()?;
99 input.parse::<Token![=]>()?;
100
101 since = lit_to_string(input.parse()?);
102 }
103
104 if input.peek(Token![,]) && input.peek2(kw::note) {
105 input.parse::<Token![,]>()?;
106 input.parse::<kw::note>()?;
107 input.parse::<Token![=]>()?;
108
109 note = lit_to_string(input.parse()?);
110 }
111
112 Ok(Self { since, note })
113 }
114}