1use super::*;
2
3fn kvp_kserd_to_kserd<'a, E: CxErr<'a>>(
5 force_inline: bool,
6) -> impl Fn(&'a str) -> IResult<&'a str, (Kserd<'a>, Kserd<'a>), E> {
7 move |input: &'a str| {
8 let value_parser = if force_inline {
9 kserd_inline
10 } else {
11 kserd_concise
12 };
13
14 context(
15 "kserd-kserd key-value pair",
16 separated_pair(
17 alt((kserd_concise, kserd_inline)),
18 ignore_inline_whitespace(char(':')),
19 ignore_inline_whitespace(value_parser),
20 ),
21 )(input)
22 }
23}
24
25fn inline_map_kserds<'a, E: CxErr<'a>>(
27 i: &'a str,
28) -> IResult<&'a str, Vec<(Kserd<'a>, Kserd<'a>)>, E> {
29 context(
30 "comma separated kserd-kserd pair",
31 separated_list0(
32 ignore_inline_whitespace(char(',')),
33 ignore_inline_whitespace(kvp_kserd_to_kserd(true)),
34 ),
35 )(i)
36}
37
38fn concise_map_kserds<'a, E: CxErr<'a>>(
40 i: &'a str,
41) -> IResult<&'a str, Vec<(Kserd<'a>, Kserd<'a>)>, E> {
42 context(
43 "newline separated (concise) kserd-kserd pair",
44 preceded(
45 multiline_whitespace,
46 terminated(
47 separated_list0(multiline_whitespace, kvp_kserd_to_kserd(false)),
48 multiline_whitespace,
49 ),
50 ),
51 )(i)
52}
53
54pub(super) fn delimited<'a, E: CxErr<'a>>(
58 force_inline: bool,
59) -> impl Fn(&'a str) -> IResult<&'a str, Kserd<'a>, E> {
60 move |i: &'a str| {
61 let (i, ident) = opt(ident(false))(i)?;
62
63 let (i, _) = ignore_inline_whitespace(char('{'))(i)?; let concise = recognise_concise(i) && !force_inline;
67
68 let parser = if concise {
69 concise_map_kserds
70 } else {
71 inline_map_kserds
72 };
73
74 let ctx = if concise { "concise map" } else { "inline map" };
75
76 let (i, value) = context(ctx, terminated(parser, ignore_inline_whitespace(char('}'))))(i)?;
77
78 let value = Value::Map(value.into_iter().collect());
79
80 Ok((i, kserd_ctor(ident, value)))
81 }
82}