nom_kconfig/entry/
choice.rs1use nom::{
2 branch::alt,
3 bytes::complete::tag,
4 combinator::map,
5 multi::many0,
6 sequence::{delimited, pair},
7 IResult, Parser,
8};
9
10#[cfg(feature = "coreboot")]
11use nom::{
12 character::complete::{alphanumeric1, one_of},
13 combinator::recognize,
14 multi::many1,
15};
16#[cfg(feature = "deserialize")]
17use serde::Deserialize;
18#[cfg(feature = "serialize")]
19use serde::Serialize;
20
21use crate::{
22 attribute::{optional::parse_optional, parse_attribute, r#type::parse_type, Attribute},
23 util::ws,
24 Entry, KconfigInput,
25};
26
27use super::parse_entry;
28
29#[derive(Debug, Clone, Default, PartialEq)]
35#[cfg_attr(feature = "hash", derive(Hash))]
36#[cfg_attr(feature = "serialize", derive(Serialize))]
37#[cfg_attr(feature = "deserialize", derive(Deserialize))]
38pub struct Choice {
39 #[cfg(feature = "coreboot")]
41 pub name: Option<String>,
42 pub options: Vec<Attribute>,
43 pub entries: Vec<Entry>,
44}
45
46fn parse_choice_attributes(input: KconfigInput) -> IResult<KconfigInput, Vec<Attribute>> {
47 ws(many0(alt((
48 parse_attribute,
49 parse_type,
50 map(ws(parse_optional), |_| Attribute::Optional),
51 ))))
52 .parse(input)
53}
54
55#[cfg(feature = "coreboot")]
56pub fn parse_choice_for_coreboot(input: KconfigInput) -> IResult<KconfigInput, Choice> {
57 map(
58 delimited(
59 tag("choice"),
60 (
61 map(
62 recognize(ws(many1(alt((alphanumeric1, recognize(one_of("._"))))))),
63 |c: KconfigInput| c.trim().to_string(),
64 ),
65 parse_choice_attributes,
66 many0(ws(parse_entry)),
67 ),
68 ws(tag("endchoice")),
69 ),
70 |(name, options, entries)| Choice {
71 options,
72 entries,
73 name: Some(name),
74 },
75 )
76 .parse(input)
77}
78
79fn parse_choice_simple(input: KconfigInput) -> IResult<KconfigInput, Choice> {
80 map(
81 delimited(
82 tag("choice"),
83 pair(parse_choice_attributes, many0(ws(parse_entry))),
84 ws(tag("endchoice")),
85 ),
86 |(options, entries)| {
87 #[cfg(feature = "coreboot")]
88 return Choice {
89 options,
90 entries,
91 name: None,
92 };
93 #[cfg(not(feature = "coreboot"))]
94 return Choice { options, entries };
95 },
96 )
97 .parse(input)
98}
99
100pub fn parse_choice(input: KconfigInput) -> IResult<KconfigInput, Choice> {
101 alt((
102 parse_choice_simple,
103 #[cfg(feature = "coreboot")]
104 parse_choice_for_coreboot,
105 ))
106 .parse(input)
107}