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 = "named-choice")]
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
21#[cfg(feature = "named-choice")]
22use crate::attribute::string::parse_string;
23use crate::{
24 attribute::{optional::parse_optional, parse_attribute, r#type::parse_type, Attribute},
25 util::ws,
26 Entry, KconfigInput,
27};
28
29use super::parse_entry;
30
31#[derive(Debug, Clone, Default, PartialEq)]
37#[cfg_attr(feature = "hash", derive(Hash))]
38#[cfg_attr(feature = "serialize", derive(Serialize))]
39#[cfg_attr(feature = "deserialize", derive(Deserialize))]
40pub struct Choice {
41 #[cfg(feature = "named-choice")]
43 pub name: Option<String>,
44 pub options: Vec<Attribute>,
45 pub entries: Vec<Entry>,
46}
47
48fn parse_choice_attributes(input: KconfigInput) -> IResult<KconfigInput, Vec<Attribute>> {
49 ws(many0(alt((
50 parse_attribute,
51 parse_type,
52 map(ws(parse_optional), |_| Attribute::Optional),
53 ))))
54 .parse(input)
55}
56
57fn parse_choice_simple(input: KconfigInput) -> IResult<KconfigInput, Choice> {
58 map(
59 delimited(
60 tag("choice"),
61 pair(parse_choice_attributes, many0(ws(parse_entry))),
62 ws(tag("endchoice")),
63 ),
64 |(options, entries)| {
65 #[cfg(feature = "named-choice")]
66 return Choice {
67 options,
68 entries,
69 name: None,
70 };
71 #[cfg(not(feature = "named-choice"))]
72 return Choice { options, entries };
73 },
74 )
75 .parse(input)
76}
77
78pub fn parse_choice(input: KconfigInput) -> IResult<KconfigInput, Choice> {
79 alt((
80 parse_choice_simple,
81 #[cfg(feature = "named-choice")]
82 parse_named_choice,
83 ))
84 .parse(input)
85}
86
87#[cfg(feature = "named-choice")]
88pub fn parse_named_choice(input: KconfigInput) -> IResult<KconfigInput, Choice> {
89 map(
90 delimited(
91 tag("choice"),
92 (
93 ws(parse_choice_name),
94 parse_choice_attributes,
95 many0(ws(parse_entry)),
96 ),
97 ws(tag("endchoice")),
98 ),
99 |(name, options, entries)| Choice {
100 options,
101 entries,
102 name: Some(name),
103 },
104 )
105 .parse(input)
106}
107
108#[cfg(feature = "named-choice")]
109pub fn parse_choice_name(input: KconfigInput) -> IResult<KconfigInput, String> {
110 alt((
111 map(
112 recognize(ws(many1(alt((alphanumeric1, recognize(one_of("._"))))))),
113 |c: KconfigInput| c.trim().to_string(),
114 ),
115 parse_string,
116 ))
117 .parse(input)
118}