sea_query_derive/iden/
attr.rs1use std::convert::{TryFrom, TryInto};
2
3use syn::spanned::Spanned;
4use syn::{Attribute, Error, Expr, ExprLit, Ident, Lit, LitStr, Meta};
5
6use super::{error::ErrorMsg, path::IdenPath};
7
8#[derive(PartialEq, Eq)]
9pub(crate) enum IdenAttr {
10 Rename(String),
11 Method(Ident),
12 Flatten,
13}
14
15impl IdenAttr {
16 fn extract_method(meta: Meta) -> syn::Result<Self> {
17 match meta {
18 Meta::NameValue(nv) => match nv.value {
19 Expr::Lit(ExprLit { lit, .. }) => match lit {
20 Lit::Str(name) => {
21 Ok(Self::Method(Ident::new(name.value().as_str(), name.span())))
22 }
23 _ => Err(Error::new_spanned(nv.eq_token, ErrorMsg::WrongLiteral)),
24 },
25 _ => Err(Error::new_spanned(nv, ErrorMsg::WrongLiteral)),
26 },
27 a => Err(Error::new_spanned(
28 a,
29 ErrorMsg::WrongNamedValueFormat(IdenPath::Method, IdenPath::Method),
30 )),
31 }
32 }
33
34 fn extract_iden(meta: Meta) -> syn::Result<Self> {
35 match &meta {
36 Meta::NameValue(nv) => match &nv.value {
37 Expr::Lit(ExprLit { lit, .. }) => match lit {
38 Lit::Str(lit) => Ok(IdenAttr::Rename(lit.value())),
39 _ => Err(Error::new_spanned(&nv.value, ErrorMsg::WrongLiteral)),
40 },
41 _ => Err(Error::new_spanned(nv, ErrorMsg::WrongLiteral)),
42 },
43 Meta::List(list) if list.path.is_ident("iden") => {
44 let mut iden_attr: Option<Self> = None;
45 list.parse_nested_meta(|nested| {
46 if nested.path.is_ident(&IdenPath::Flatten) {
47 iden_attr = Some(IdenAttr::Flatten);
48 Ok(())
49 } else if nested.path.is_ident(&IdenPath::Rename) {
50 let value = nested.value()?;
51 let value: LitStr = value.parse()?;
52 iden_attr = Some(IdenAttr::Rename(value.value()));
53 Ok(())
54 } else if nested.path.is_ident(&IdenPath::Method) {
55 let value = nested.value()?;
56 let value: LitStr = value.parse()?;
57 iden_attr = Some(IdenAttr::Method(Ident::new(&value.value(), meta.span())));
58 Ok(())
59 } else {
60 Err(Error::new_spanned(
61 &meta,
62 ErrorMsg::UnsupportedKeyword(nested.path.get_ident().unwrap().clone()),
63 ))
64 }
65 })?;
66 iden_attr.ok_or(Error::new_spanned(meta, ErrorMsg::WrongListFormat))
67 }
68 a => Err(Error::new_spanned(a, ErrorMsg::WrongAttributeFormat)),
69 }
70 }
71}
72
73impl TryFrom<&Attribute> for IdenAttr {
74 type Error = Error;
75
76 fn try_from(value: &Attribute) -> Result<Self, Self::Error> {
77 value.meta.clone().try_into()
78 }
79}
80
81impl TryFrom<Meta> for IdenAttr {
82 type Error = Error;
83
84 fn try_from(value: Meta) -> Result<Self, Self::Error> {
85 let path = value.path();
86 if path.is_ident(&IdenPath::Method) {
87 Self::extract_method(value)
88 } else if path.is_ident(&IdenPath::Iden) {
89 Self::extract_iden(value)
90 } else {
91 todo!()
92 }
93 }
94}