Skip to main content

nom_kconfig/attribute/
default.rs

1use nom::{bytes::complete::tag, combinator::map, IResult, Parser};
2#[cfg(feature = "deserialize")]
3use serde::Deserialize;
4#[cfg(feature = "serialize")]
5use serde::Serialize;
6#[cfg(feature = "display")]
7use std::fmt::Display;
8
9use crate::{util::ws, KconfigInput};
10
11use super::{parse_expression, parse_if_attribute, Expression};
12
13/// A config option can have any number of default values.
14/// If multiple default values are visible, only the first defined one is active.
15/// Default values are not limited to the menu entry where they are defined.
16/// This means the default can be defined somewhere else or be overridden by an earlier definition.
17/// The default value is only assigned to the config symbol if no other value was set by the user.
18///
19/// see ["default value"](https://www.kernel.org/doc/html/next/kbuild/kconfig-language.html#menu-attributes) for more information.
20#[derive(Debug, Clone, PartialEq)]
21#[cfg_attr(feature = "hash", derive(Hash))]
22#[cfg_attr(feature = "serialize", derive(Serialize))]
23#[cfg_attr(feature = "deserialize", derive(Deserialize))]
24pub struct DefaultAttribute {
25    pub expression: Expression,
26    #[cfg_attr(
27        any(feature = "serialize", feature = "deserialize"),
28        serde(skip_serializing_if = "Option::is_none")
29    )]
30    pub r#if: Option<Expression>,
31}
32
33#[cfg(feature = "display")]
34impl Display for DefaultAttribute {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        match &self.r#if {
37            Some(i) => write!(f, "{} if {}", self.expression, i),
38            None => write!(f, "{}", self.expression),
39        }
40    }
41}
42
43/// Parses a `default` attribute.
44///
45/// # Example
46/// ```
47/// use nom_kconfig::{
48///     assert_parsing_eq,
49///     attribute::{
50///         parse_default, DefaultAttribute,
51///         Expression, AndExpression, Atom, OrExpression, Term
52///     },
53///     symbol::Symbol,
54///     symbol::ConstantSymbol
55/// };
56///
57/// assert_parsing_eq!(
58///     parse_default, "default 0x1",
59///     Ok((
60///         "",
61///         DefaultAttribute {
62///             expression: Expression::Term(AndExpression::Term(Term::Atom(
63///                 Atom::Symbol(Symbol::Constant(ConstantSymbol::Hex("0x1".to_string())))
64///             ))),
65///             r#if: None
66///         }
67///     ))
68/// )
69/// ```
70pub fn parse_default(input: KconfigInput) -> IResult<KconfigInput, DefaultAttribute> {
71    map(
72        (ws(tag("default")), ws(parse_expression), parse_if_attribute),
73        |(_, e, i)| DefaultAttribute {
74            expression: e,
75            r#if: i,
76        },
77    )
78    .parse(input)
79}