ligen_python_parser/macro_attributes/attributes/
mod.rs1pub 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(); 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}