ligen_parser/parser/universal/attributes/attribute/
mod.rs1use intermediary_attribute::IntermediaryAttribute;
4use ligen_ir::macro_attributes::{Named, Group};
5use syn::__private::ToTokens;
6use crate::prelude::*;
7use crate::universal::parser::PathParser;
8use ligen_ir::{Attribute, Literal};
9use crate::parser::{Parser, ParserConfig};
10use crate::parser::universal::identifier::IdentifierParser;
11use crate::parser::universal::attributes::AttributesParser;
12use crate::parser::universal::literal::LiteralParser;
13
14pub(crate) mod intermediary_attribute;
15
16#[derive(Default)]
17pub struct AttributeParser<T: LiteralParser> {
18 literal_parser: T
19}
20
21impl<T: LiteralParser> Parser<syn::ItemMacro> for AttributeParser<T> {
22 type Output = Attribute;
23 fn parse(&self, call: syn::ItemMacro, config: &ParserConfig) -> Result<Self::Output> {
24 let identifier = call
25 .mac
26 .path
27 .segments
28 .last()
29 .ok_or(Error::Message("Failed to get identifier from syn::ItemMacro".to_string()))?
30 .ident
31 .clone();
32 let identifier = IdentifierParser::new().parse(identifier, config)?;
33 let attributes = AttributesParser::<T>::default().parse(call.mac.tokens.to_string().as_str(), config)?;
34 let group = Group::new(identifier, attributes).into();
35 Ok(group)
36 }
37}
38
39impl<T: LiteralParser> Parser<syn::MetaList> for AttributeParser<T> {
40 type Output = Attribute;
41 fn parse(&self, meta_list: syn::MetaList, config: &ParserConfig) -> Result<Self::Output> {
42 let path = PathParser::default().parse(meta_list.path.clone(), config)?;
43 let inner = meta_list.tokens.into_iter().map(|token| token.to_string()).collect::<Vec<_>>().join("");
44 let attributes = AttributesParser::<T>::default().parse(inner.as_str(), config)?;
45 let group = Group::new(path, attributes);
46 Ok(group.into())
47 }
48}
49
50impl<T: LiteralParser> Parser<syn::Lit> for AttributeParser<T> {
51 type Output = Attribute;
52 fn parse(&self, lit: syn::Lit, config: &ParserConfig) -> Result<Self::Output> {
53 self.literal_parser.parse(lit.to_token_stream().to_string(), config).map(Attribute::Literal)
54 }
55}
56
57impl<T: LiteralParser> Parser<syn::ExprCall> for AttributeParser<T> {
58 type Output = Attribute;
59 fn parse(&self, expr_call: syn::ExprCall, config: &ParserConfig) -> Result<Self::Output> {
60 let identifier = expr_call
61 .func
62 .to_token_stream()
63 .to_string();
64 let identifier = IdentifierParser::new().parse(identifier, config)?;
65 let attributes = AttributesParser::<T>::default().parse(expr_call.args, config)?;
66 let group = Group::new(identifier, attributes);
67 Ok(group.into())
68 }
69}
70
71impl<T: LiteralParser> Parser<syn::ExprAssign> for AttributeParser<T> {
72 type Output = Attribute;
73 fn parse(&self, expr_assign: syn::ExprAssign, config: &ParserConfig) -> Result<Self::Output> {
74 let identifier = expr_assign
75 .left
76 .to_token_stream()
77 .to_string();
78 let identifier = IdentifierParser::new().parse(identifier, config)?;
79 let literal = self.literal_parser.parse(expr_assign.right.to_token_stream().to_string(), config)?;
80 let group = Named::new(identifier, literal);
81 Ok(group.into())
82 }
83}
84
85impl<T: LiteralParser> Parser<syn::Expr> for AttributeParser<T> {
86 type Output = Attribute;
87 fn parse(&self, expr: syn::Expr, config: &ParserConfig) -> Result<Self::Output> {
88 match expr {
89 syn::Expr::Path(expr) => self.parse(expr, config),
90 syn::Expr::Lit(expr) => self.literal_parser.parse(expr.to_token_stream().to_string(), config).map(Attribute::Literal),
91 syn::Expr::Call(expr) => self.parse(expr, config),
92 syn::Expr::Assign(expr) => self.parse(expr, config),
93 _ => Ok(Attribute::Literal(Literal::Unknown(expr.to_token_stream().into_iter().map(|token| token.to_string()).collect::<Vec<_>>().join("")))),
94 }
95 }
96}
97
98impl<T: LiteralParser> Parser<syn::ExprPath> for AttributeParser<T> {
99 type Output = Attribute;
100 fn parse(&self, input: syn::ExprPath, config: &ParserConfig) -> Result<Self::Output> {
101 self.parse(input.path, config)
102 }
103}
104
105impl<T: LiteralParser> Parser<syn::Path> for AttributeParser<T> {
106 type Output = Attribute;
107 fn parse(&self, path: syn::Path, config: &ParserConfig) -> Result<Self::Output> {
108 let path = PathParser::default().parse(path, config)?;
109 let attribute = Group::from(path).into();
110 Ok(attribute)
111 }
112}
113
114
115impl<T: LiteralParser> Parser<syn::MetaNameValue> for AttributeParser<T> {
116 type Output = Attribute;
117 fn parse(&self, meta_name_value: syn::MetaNameValue, config: &ParserConfig) -> Result<Self::Output> {
118 let path = PathParser::default().parse(meta_name_value.path, config)?;
119 let literal = self.literal_parser.parse(meta_name_value.value.to_token_stream().to_string(), config)?;
120 let attribute = Named::new(path, literal).into();
121 Ok(attribute)
122 }
123}
124
125impl<T: LiteralParser> Parser<syn::Meta> for AttributeParser<T> {
126 type Output = Attribute;
127 fn parse(&self, meta: syn::Meta, config: &ParserConfig) -> Result<Self::Output> {
128 match meta {
129 syn::Meta::Path(path) => self.parse(path, config),
130 syn::Meta::List(list) => self.parse(list, config),
131 syn::Meta::NameValue(name_value) => self.parse(name_value, config),
132 }
133 }
134}
135
136impl<T: LiteralParser> Parser<syn::Attribute> for AttributeParser<T> {
137 type Output = Attribute;
138 fn parse(&self, attribute: syn::Attribute, config: &ParserConfig) -> Result<Self::Output> {
139 self.parse(attribute.meta, config)
140 }
141}
142
143impl<T: LiteralParser> Parser<String> for AttributeParser<T> {
144 type Output = Attribute;
145 fn parse(&self, input: String, config: &ParserConfig) -> Result<Self::Output> {
146 self.parse(input.as_str(), config)
147 }
148}
149
150impl<T: LiteralParser> Parser<IntermediaryAttribute> for AttributeParser<T> {
151 type Output = Attribute;
152 fn parse(&self, input: IntermediaryAttribute, config: &ParserConfig) -> Result<Self::Output> {
153 match input {
154 IntermediaryAttribute::Meta(meta) => self.parse(meta, config),
155 IntermediaryAttribute::Lit(lit) => self.parse(lit, config),
156 IntermediaryAttribute::Expr(expr) => self.parse(expr, config),
157 IntermediaryAttribute::Unknown(unknown) => Ok(Attribute::Literal(Literal::Unknown(unknown))),
158 }
159 }
160}
161
162impl<T: LiteralParser> Parser<&str> for AttributeParser<T> {
163 type Output = Attribute;
164 fn parse(&self, input: &str, config: &ParserConfig) -> Result<Self::Output> {
165 let attribute = syn::parse_str::<IntermediaryAttribute>(input)
166 .map_err(|e| Error::Message(format!("Failed to parse attribute: {:?} - {}", e, input)))?;
167 self.parse(attribute, config)
168 }
169}