nom_kconfig/entry/
choice.rs

1use nom::{
2    branch::alt,
3    bytes::complete::tag,
4    combinator::map,
5    multi::many0,
6    sequence::{delimited, pair},
7    IResult, Parser,
8};
9#[cfg(feature = "deserialize")]
10use serde::Deserialize;
11#[cfg(feature = "serialize")]
12use serde::Serialize;
13
14use crate::{
15    attribute::{optional::parse_optional, parse_attribute, r#type::parse_type, Attribute},
16    util::ws,
17    Entry, KconfigInput,
18};
19
20use super::parse_entry;
21
22/// This defines a choice group and accepts any of the above attributes as options. A choice can only be of type bool or tristate. If no type is specified for a choice, its type will be determined by the type of the first choice element in the group or remain unknown if none of the choice elements have a type specified, as well.
23///
24/// While a boolean choice only allows a single config entry to be selected, a tristate choice also allows any number of config entries to be set to 'm'. This can be used if multiple drivers for a single hardware exists and only a single driver can be compiled/loaded into the kernel, but all drivers can be compiled as modules.
25///
26/// A choice accepts another option "optional", which allows to set the choice to 'n' and no entry needs to be selected. If no [symbol](crate::symbol::Symbol) is associated with a choice, then you can not have multiple definitions of that choice. If a [symbol](crate::symbol::Symbol) is associated to the choice, then you may define the same choice (i.e. with the same entries) in another place.
27#[derive(Debug, Clone, Default, PartialEq)]
28#[cfg_attr(feature = "hash", derive(Hash))]
29#[cfg_attr(feature = "serialize", derive(Serialize))]
30#[cfg_attr(feature = "deserialize", derive(Deserialize))]
31pub struct Choice {
32    pub options: Vec<Attribute>,
33    pub entries: Vec<Entry>,
34}
35
36fn parse_choice_attributes(input: KconfigInput) -> IResult<KconfigInput, Vec<Attribute>> {
37    ws(many0(alt((
38        parse_attribute,
39        parse_type,
40        map(ws(parse_optional), |_| Attribute::Optional),
41    ))))
42    .parse(input)
43}
44
45pub fn parse_choice(input: KconfigInput) -> IResult<KconfigInput, Choice> {
46    map(
47        delimited(
48            tag("choice"),
49            pair(parse_choice_attributes, many0(ws(parse_entry))),
50            ws(tag("endchoice")),
51        ),
52        |(options, entries)| Choice { options, entries },
53    )
54    .parse(input)
55}