nom_config_in/entry/
choice.rs1use nom::{
2 branch::alt,
3 bytes::complete::tag,
4 character::complete::{alphanumeric1, one_of},
5 combinator::{map, recognize},
6 multi::many1,
7 sequence::{delimited, pair, tuple},
8 IResult,
9};
10use serde::Serialize;
11
12use crate::{symbol::parse_constant_symbol, util::ws, ConfigInInput};
13
14use super::comment::parse_prompt_option;
15
16fn parse_choice_option_label(input: ConfigInInput) -> IResult<ConfigInInput, String> {
17 map(
18 recognize(many1(alt((alphanumeric1, recognize(one_of(",._()-/$+")))))),
19 |c: ConfigInInput| c.to_string(),
20 )(input)
21}
22
23fn parse_choice_option(input: ConfigInInput) -> IResult<ConfigInInput, ChoiceOption> {
24 map(
25 tuple((ws(parse_choice_option_label), ws(parse_constant_symbol))),
26 |(l, r)| ChoiceOption {
27 left: l,
28 right: r.to_string(),
29 },
30 )(input)
31}
32
33pub fn parse_choice(input: ConfigInInput) -> IResult<ConfigInInput, Choice> {
34 let (input, prompt) = tuple((ws(tag("choice")), ws(parse_prompt_option)))(input)?;
35 let (input, ok) = alt((
36 pair(
37 delimited(ws(tag("\"")), many1(ws(parse_choice_option)), ws(tag("\""))),
38 ws(parse_constant_symbol),
39 ),
40 delimited(
41 ws(tag("\"")),
42 pair(many1(ws(parse_choice_option)), ws(parse_constant_symbol)),
43 ws(tag("\"")),
44 ),
45 ))(input)?;
46 Ok((
47 input,
48 Choice {
49 prompt: prompt.1.to_string(),
50 entries: ok.0,
51 default: ok.1.to_string(),
52 },
53 ))
54}
55
56#[derive(Debug, Clone, Default, Serialize, PartialEq)]
57pub struct Choice {
58 pub prompt: String,
59 pub entries: Vec<ChoiceOption>,
60 pub default: String,
61}
62
63#[derive(Debug, Clone, Default, Serialize, PartialEq)]
64pub struct ChoiceOption {
65 pub left: String,
66 pub right: String,
67}