ligen_python_parser/macro_attributes/attributes/
mod.rs

1pub mod attribute;
2
3use crate::identifier::IdentifierParser;
4use crate::literal::LiteralParser;
5use crate::path::PathParser;
6use crate::prelude::*;
7use ligen::parser::ParserConfig;
8use ligen::ir::{Attributes, Attribute, macro_attributes::{Group, Named}};
9use rustpython_parser::ast::{Expr, Keyword, Ranged};
10
11#[derive(Default)]
12pub struct AttributesParser {
13    path_parser: PathParser,
14    identifier_parser: IdentifierParser,
15    literal_parser: LiteralParser,
16}
17
18impl Parser<WithSource<&Vec<Expr>>> for AttributesParser {
19    type Output = Attributes;
20    fn parse(&self, input: WithSource<&Vec<Expr>>, config: &ParserConfig) -> Result<Self::Output> {
21        let mut attributes = Attributes::default();
22        for expr in input.ast {
23            let attribute = self.parse(input.sub(expr), config)?;
24            attributes.push(attribute);
25        }
26        Ok(attributes)
27    }
28}
29
30impl Parser<WithSource<&Vec<Keyword>>> for AttributesParser {
31    type Output = Attributes;
32    fn parse(&self, input: WithSource<&Vec<Keyword>>, config: &ParserConfig) -> Result<Self::Output> {
33        let mut attributes = Attributes::default();
34        for keyword in input.ast {
35            let attribute = self.parse(input.sub(keyword), config)?;
36            attributes.push(attribute);
37        }
38        Ok(attributes)
39    }
40} 
41
42impl Parser<WithSource<&Keyword>> for AttributesParser {
43    type Output = Attribute;
44    fn parse(&self, input: WithSource<&Keyword>, config: &ParserConfig) -> Result<Self::Output> {
45        let name = input
46            .ast
47            .arg
48            .as_ref()
49            .map(|arg| arg.to_string())
50            .ok_or_else(|| Error::Message(format!("Failed to parse attribute name: {:?} @ \"{}\"", input.ast.arg, &input.source[input.ast.range.start().to_usize()..input.ast.range.end().to_usize()])))?;
51        let identifier = self.identifier_parser.parse(name, config)?;
52        let literal = self.literal_parser.parse(&input.ast.value, config)?;
53        Ok(Named::new(identifier, literal).into())
54    }
55}
56
57impl Parser<WithSource<&Expr>> for AttributesParser {
58    type Output = Attribute;
59    fn parse(&self, input: WithSource<&Expr>, config: &ParserConfig) -> Result<Self::Output> {
60        match input.ast {
61            Expr::Call(expr) => {
62                let path = self.path_parser.parse(&*expr.func, config)?;
63                let mut attributes = self.parse(input.sub(&expr.args), config).unwrap_or_default(); // TODO: We might want to check for errors here.
64                let keywords = self.parse(input.sub(&expr.keywords), config)?;
65                attributes.attributes.extend(keywords.attributes);
66                Ok(Group::new(path, attributes).into())
67            },
68            Expr::Name(expr) => {
69                let path = self.path_parser.parse(expr, config)?;
70                let attributes = Attributes::default();
71                Ok(Group::new(path, attributes).into())
72            },
73            Expr::Attribute(expr) => {
74                let name = expr.attr.to_string();
75                let identifier = self.identifier_parser.parse(name, config)?;
76                let attributes = Attributes::default();
77                Ok(Group::new(identifier, attributes).into())
78            }
79            _ => Err(Error::Message(format!("Invalid attribute {:?}", &input.source[input.ast.start().to_usize()..input.ast.end().to_usize()])))
80        }
81    }
82}