derive_attribute_utils/
syn_2.rs1
2use std::{str::FromStr, fmt::Display};
3
4use proc_macro2::{Span, Ident};
5use syn_v2::{Attribute, Meta, MetaNameValue, Expr, ExprLit, Lit, punctuated::Punctuated, token::Eq, Token, spanned::Spanned, Path, ExprArray, PathSegment};
6
7use crate::{shared::{SynVersion, GetSpan}};
8
9pub struct Syn2;
11
12impl SynVersion for Syn2 {
13 type Attribute = Attribute;
14
15 type ArgMeta = Meta;
16
17 fn deserialize_key(meta: &Self::ArgMeta) -> Option<String> {
18 meta.path().get_ident().map(|id| id.to_string())
19 }
20 fn deserialize_attr_key(meta: &Self::Attribute) -> Option<String> {
21 meta.path().get_ident().map(|id| id.to_string())
22 }
23
24 fn deserialize_integer<T>(meta: &Self::ArgMeta) -> Option<T>
25 where
26 T: FromStr,
27 T::Err: Display
28 {
29 match meta {
30 Meta::NameValue(MetaNameValue { value: Expr::Lit(ExprLit { lit: Lit::Int(literal), .. }), .. }) => {
31 literal.base10_parse().map_or(None, Some)
32 },
33 _ => None
34 }
35 }
36
37 fn deserialize_float<T>(meta: &Self::ArgMeta) -> Option<T> where T: FromStr, T::Err: Display {
38 match meta {
39 Meta::NameValue(MetaNameValue { value: Expr::Lit(ExprLit { lit: Lit::Float(literal), .. }), .. }) => {
40 literal.base10_parse().map_or(None, Some)
41 },
42 _ => None
43 }
44 }
45
46 fn deserialize_string(meta: &Self::ArgMeta) -> Option<String> {
47 match meta {
48 Meta::NameValue(MetaNameValue { value: Expr::Lit(ExprLit { lit: Lit::Str(literal), .. } ), .. }) => Some(literal.value()),
49 _ => None
50 }
51 }
52 fn deserialize_bool(meta: &Self::ArgMeta) -> Option<bool> {
53 match meta {
54 Meta::Path(_) => Some(true),
55 Meta::NameValue(MetaNameValue { value: Expr::Lit( ExprLit { lit: Lit::Bool(literal), .. } ), .. }) => Some(literal.value()),
56 _ => None
57 }
58 }
59
60 fn deserialize_list_args(meta: &Self::ArgMeta) -> Option<Vec<Self::ArgMeta>> {
61 match meta {
62 Meta::List(list) => {
63 let x = list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated);
64 match x {
65 Ok(x) => Some(x.into_iter().collect()),
66 Err(_) => None
67 }
68 },
69 _ => None
70 }
71 }
72 fn deserialize_attr_args(attr: &Self::Attribute) -> Option<Vec<Self::ArgMeta>> {
73 let maybe_args = attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated);
74 match maybe_args {
75 Ok(args) => Some(args.into_iter().collect()),
76 Err(_) => None
77 }
78 }
79
80 fn deserialize_array(meta: &Self::ArgMeta) -> Option<Vec<Self::ArgMeta>> {
81 match meta {
82 Meta::NameValue(MetaNameValue { value: Expr::Array(ExprArray { elems, .. }), .. }) => {
83 let list =
84 elems
85 .into_iter()
86 .map(|e|
87 Meta::NameValue(
88 MetaNameValue {
89 path:
90 Path {
91 leading_colon: None,
92 segments:
93 vec![PathSegment {
94 ident: Ident::new("_", e.span()),
95 arguments: syn_v2::PathArguments::None
96 }]
97 .into_iter().collect()
98 },
99 eq_token: Eq { spans: [meta.span()] },
100 value: e.clone()
101 }
102 )
103 ).collect();
104 Some(list)
105 }
106 _ => None
107 }
108 }
109
110 type Error = syn_v2::Error;
111 fn convert_error(error: crate::shared::Error) -> Self::Error {
112 syn_v2::Error::new(error.location, error.msg)
113 }
114}
115
116impl GetSpan for Attribute {
117 fn get_span(&self) -> Span { self.path().span() }
118}
119
120impl GetSpan for Meta {
121 fn get_span(&self) -> Span { self.path().span() }
122}
123