ligen_parser/parser/universal/attributes/
mod.rs

1pub mod attribute;
2
3use crate::prelude::*;
4use crate::parser::{Parser, ParserConfig};
5use attribute::intermediary_attribute::IntermediaryAttribute;
6use ligen_ir::{Attribute, Attributes, Literal};
7use attribute::AttributeParser;
8use crate::parser::universal::literal::LiteralParser;
9
10#[derive(Default)]
11pub struct AttributesParser<L: LiteralParser> {
12    attribute_parser: AttributeParser<L>,
13}
14
15impl<L: LiteralParser> AttributesParser<L> {
16    pub fn new(attribute_parser: AttributeParser<L>) -> Self {
17        Self { attribute_parser }
18    }
19}
20
21impl<L: LiteralParser> Parser<String> for AttributesParser<L> {
22    type Output = Attributes;
23    fn parse(&self, input: String, config: &ParserConfig) -> Result<Self::Output> {
24        self.parse(input.as_str(), config)
25    }
26}
27
28impl<L: LiteralParser> Parser<&str> for AttributesParser<L>
29{
30    type Output = Attributes;
31    fn parse(&self, input: &str, config: &ParserConfig) -> Result<Self::Output> {
32        let attributes = syn::parse_str::<syn2::punctuated::Punctuated<IntermediaryAttribute, syn::token::Comma>>(input)
33            .map_err(|e| Error::Message(format!("Failed to parse attributes: {}. Input: {}", e, input)))
34            .and_then(|input| self.parse(input.0, config));
35        if let Ok(attributes) = attributes {
36            Ok(attributes)
37        } else {
38            Ok(Attributes::from(Attribute::from(Literal::from(input))))
39        }
40    }
41}
42
43impl<L: LiteralParser> Parser<Vec<syn::Attribute>> for AttributesParser<L> {
44    type Output = Attributes;
45    fn parse(&self, in_attributes: Vec<syn::Attribute>, config: &ParserConfig) -> Result<Self::Output> {
46        let mut attributes = Vec::new();
47        for attribute in in_attributes {
48            attributes.push(self.attribute_parser.parse(attribute, config)?);
49        }
50        Ok(Self::Output { attributes })
51    }
52}
53
54impl<L: LiteralParser> Parser<syn::punctuated::Punctuated<IntermediaryAttribute, syn::token::Comma>> for AttributesParser<L>
55{
56    type Output = Attributes;
57    fn parse(&self, input: syn::punctuated::Punctuated<IntermediaryAttribute, syn::token::Comma>, config: &ParserConfig) -> Result<Self::Output> {
58        let mut attributes = Vec::new();
59        for attribute in input {
60            attributes.push(self.attribute_parser.parse(attribute, config)?);
61        }
62        Ok(Self::Output { attributes })
63    }
64}
65
66impl<L: LiteralParser> Parser<syn::punctuated::Punctuated<syn::Expr, syn::token::Comma>> for AttributesParser<L>
67{
68    type Output = Attributes;
69    fn parse(&self, input: syn::punctuated::Punctuated<syn::Expr, syn::token::Comma>, config: &ParserConfig) -> Result<Self::Output> {
70        let attributes = input
71            .into_iter()
72            .map(|input| self.attribute_parser.parse(input, config).expect("Failed to parse nested meta."))
73            .collect();
74        Ok(Self::Output { attributes })
75    }
76}
77
78impl<L: LiteralParser> Parser<syn::punctuated::Punctuated<syn::Meta, syn::token::Comma>> for AttributesParser<L> {
79    type Output = Attributes;
80    fn parse(&self, input: syn::punctuated::Punctuated<syn::Meta, syn::token::Comma>, config: &ParserConfig) -> Result<Self::Output> {
81        let attributes = input
82            .into_iter()
83            .map(|nested_meta| self.attribute_parser.parse(nested_meta, config).expect("Failed to parse nested meta."))
84            .collect();
85        Ok(Self::Output { attributes })
86    }
87}