1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// This file is licensed under the terms of Apache-2.0 License.

pub use nom::{
	branch::alt,
	bytes::complete::{
		is_not,
		tag,
		take,
		take_till,
		take_until,
		take_while,
	},
	character::complete::{
		alpha1,
		alphanumeric1,
		char,
		digit1,
		multispace0,
		multispace1,
		space1,
	},
	combinator::{
		cut,
		map,
		opt,
		recognize,
		success,
		value,
		verify,
	},
	error::{
		context,
		ParseError,
	},
	multi::{
		fold_many0,
		fold_many1,
		many0,
		many1,
		separated_list0,
		separated_list1,
	},
	sequence::{
		delimited,
		pair,
		preceded,
		separated_pair,
		terminated,
	},
};

pub type IResult<I, O, E = nom::error::VerboseError<I>> = Result<(I, O), nom::Err<E>>;

pub fn wrap_space0<'a, F: 'a, O>(inner: F) -> impl FnMut(&'a str) -> IResult<&'a str, O>
where
	F: FnMut(&'a str) -> IResult<&'a str, O>,
{
	delimited(multispace0, inner, multispace0)
}

pub fn list0<'a, O, F>(inner: F, sep: char) -> impl FnMut(&'a str) -> IResult<&'a str, Vec<O>>
where
	F: FnMut(&'a str) -> IResult<&'a str, O>,
{
	map(
		pair(
			// Items.
			separated_list0(wrap_space0(char(sep)), inner),
			// Optional trailing separator.
			opt(char(sep)),
		),
		|(xs, ..)| xs,
	)
}

pub fn list1<'a, O, F>(inner: F, sep: char) -> impl FnMut(&'a str) -> IResult<&'a str, Vec<O>>
where
	F: FnMut(&'a str) -> IResult<&'a str, O>,
{
	map(
		pair(
			// Items.
			separated_list1(wrap_space0(char(sep)), inner),
			// Optional trailing separator.
			opt(char(sep)),
		),
		|(xs, ..)| xs,
	)
}