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}