Skip to main content

nom_kconfig/attribute/
macro.rs

1use crate::attribute::{parse_function_call, FunctionCall};
2use crate::util::ws;
3use crate::KconfigInput;
4use nom::branch::alt;
5use nom::bytes::complete::tag;
6use nom::character::complete::{alphanumeric1, one_of};
7use nom::combinator::{map, recognize};
8use nom::multi::many1;
9use nom::sequence::delimited;
10use nom::{IResult, Parser};
11#[cfg(feature = "deserialize")]
12use serde::Deserialize;
13#[cfg(feature = "serialize")]
14use serde::Serialize;
15#[cfg(feature = "display")]
16use std::fmt::Display;
17
18#[derive(Debug, PartialEq, Clone)]
19#[cfg_attr(feature = "hash", derive(Hash))]
20#[cfg_attr(feature = "serialize", derive(Serialize))]
21#[cfg_attr(feature = "deserialize", derive(Deserialize))]
22#[cfg_attr(feature = "serialize", serde(rename = "CompareOperand"))]
23pub enum Macro {
24    FunctionCall(FunctionCall),
25    DoubleQuoted(Box<Macro>),
26    Variable(String),
27}
28
29#[cfg(feature = "display")]
30impl Display for Macro {
31    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
32        match self {
33            Macro::FunctionCall(func) => write!(f, "{}", func),
34            Macro::Variable(v) => write!(f, "$({})", v),
35            Macro::DoubleQuoted(d) => write!(f, "\"{})\"", d),
36        }
37    }
38}
39
40pub fn parse_macro(input: KconfigInput) -> IResult<KconfigInput, Macro> {
41    alt((
42        map(parse_function_call, Macro::FunctionCall),
43        map(parse_macro_variable, Macro::Variable),
44        map(delimited(tag("\""), parse_macro, tag("\"")), |e| {
45            Macro::DoubleQuoted(Box::new(e))
46        }),
47    ))
48    .parse(input)
49}
50
51pub fn parse_macro_variable(input: KconfigInput) -> IResult<KconfigInput, String> {
52    map(
53        delimited(
54            tag("$("),
55            recognize(ws(many1(alt((alphanumeric1, recognize(one_of("_-"))))))),
56            tag(")"),
57        ),
58        |d: KconfigInput| d.fragment().to_string(),
59    )
60    .parse(input)
61}