nom_kconfig/attribute/
mod.rs

1//! Module defining the different attributes.
2//! A entry can have a number of attributes: [https://www.kernel.org/doc/html/next/kbuild/kconfig-language.html#menu-attributes](https://www.kernel.org/doc/html/next/kbuild/kconfig-language.html#menu-attributes)
3
4pub mod default;
5pub mod depends_on;
6pub mod expression;
7pub mod function;
8pub mod help;
9pub mod imply;
10pub mod modules;
11pub mod option;
12pub mod optional;
13pub mod prompt;
14pub mod range;
15pub mod requires;
16pub mod select;
17pub mod transitional;
18pub mod r#type;
19pub mod visible;
20
21use nom::{branch::alt, combinator::map, multi::many0, IResult, Parser};
22#[cfg(feature = "deserialize")]
23use serde::Deserialize;
24#[cfg(feature = "serialize")]
25use serde::Serialize;
26
27use crate::{attribute::transitional::parse_transitional, util::ws, KconfigInput};
28
29use self::r#type::ConfigType;
30pub use self::{
31    default::{parse_default, DefaultAttribute},
32    depends_on::parse_depends_on,
33    expression::Expression,
34    help::parse_help,
35    imply::{parse_imply, Imply},
36    modules::parse_modules,
37    option::{parse_option, OptionValues},
38    prompt::{parse_prompt, Prompt},
39    range::{parse_range, Range},
40    requires::parse_requires,
41    select::{parse_select, Select},
42    visible::parse_visible,
43};
44
45pub use self::expression::{
46    parse_expression, parse_if_attribute, AndExpression, Atom, CompareExpression, CompareOperator,
47    OrExpression, Term,
48};
49pub use self::function::{parse_function_call, ExpressionToken, FunctionCall, Parameter};
50pub use self::optional::parse_optional;
51pub use self::prompt::parse_prompt_value;
52
53/// Official documentation regarding the different attributes: [https://www.kernel.org/doc/html/next/kbuild/kconfig-language.html#menu-attributes](https://www.kernel.org/doc/html/next/kbuild/kconfig-language.html#menu-attributes)
54#[derive(Debug, Clone, PartialEq)]
55#[cfg_attr(feature = "hash", derive(Hash))]
56#[cfg_attr(feature = "serialize", derive(Serialize))]
57#[cfg_attr(feature = "deserialize", derive(Deserialize))]
58pub enum Attribute {
59    Help(String),
60    Prompt(Prompt),
61    Modules,
62    Select(Select),
63    DependsOn(Expression),
64    Optional,
65    Range(Range),
66    Visible(Option<Expression>),
67    Default(DefaultAttribute),
68    Imply(Imply),
69    Requires(Expression),
70    Type(ConfigType),
71    Option(OptionValues),
72    Transitional,
73}
74
75pub fn parse_attributes(input: KconfigInput) -> IResult<KconfigInput, Vec<Attribute>> {
76    ws(many0(parse_attribute)).parse(input)
77}
78
79pub fn parse_attribute(input: KconfigInput) -> IResult<KconfigInput, Attribute> {
80    alt((
81        map(ws(parse_prompt), Attribute::Prompt),
82        map(ws(parse_help), Attribute::Help),
83        ws(parse_depends_on),
84        map(ws(parse_select), Attribute::Select),
85        map(ws(parse_default), Attribute::Default),
86        map(ws(parse_requires), Attribute::Requires),
87        map(ws(parse_modules), |_| Attribute::Modules),
88        map(ws(parse_range), Attribute::Range),
89        map(ws(parse_imply), Attribute::Imply),
90        map(ws(parse_visible), Attribute::Visible),
91        map(ws(parse_option), Attribute::Option),
92        map(ws(parse_optional), |_| Attribute::Optional),
93        map(ws(parse_transitional), |_| Attribute::Transitional),
94    ))
95    .parse(input)
96}
97
98#[cfg(feature = "display")]
99use std::fmt::Display;
100#[cfg(feature = "display")]
101impl Display for Attribute {
102    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103        match self {
104            Attribute::Help(s) => write!(f, "help\n  {}", s),
105            Attribute::Prompt(p) => write!(f, "prompt {p}"),
106            Attribute::Modules => write!(f, "modules"),
107            Attribute::Select(s) => write!(f, "select {s}"),
108            Attribute::DependsOn(d) => write!(f, "depends on {d}"),
109            Attribute::Optional => write!(f, "optional"),
110            Attribute::Range(r) => write!(f, "range {r}"),
111            Attribute::Visible(v) => match v {
112                Some(e) => write!(f, "visible if {e}"),
113                None => write!(f, "visible"),
114            },
115            Attribute::Default(d) => write!(f, "default {d}"),
116            Attribute::Imply(i) => write!(f, "imply {i}"),
117            Attribute::Requires(r) => write!(f, "requires {r}"),
118            Attribute::Type(t) => write!(f, "{t}"),
119            Attribute::Option(o) => write!(f, "option {o}"),
120            Attribute::Transitional => write!(f, "transitional"),
121        }
122    }
123}
124
125#[cfg(test)]
126mod default_test;
127#[cfg(test)]
128mod depends_on_test;
129#[cfg(test)]
130mod expression_test;
131#[cfg(test)]
132mod function_test;
133#[cfg(test)]
134mod help_test;
135#[cfg(test)]
136mod imply_test;
137#[cfg(test)]
138mod mod_test;
139#[cfg(test)]
140mod modules_test;
141#[cfg(test)]
142mod option_test;
143#[cfg(test)]
144mod optional_test;
145#[cfg(test)]
146mod prompt_test;
147#[cfg(test)]
148mod range_test;
149#[cfg(test)]
150mod requires_test;
151#[cfg(test)]
152mod select_test;
153#[cfg(test)]
154mod transitional_test;
155#[cfg(test)]
156mod type_test;
157#[cfg(test)]
158mod visible_test;