ncalendar

Reimplementation of the BSD calendar(1) program in Rust

git clone https://git.8pit.net/ncalendar.git

 1use nom::{
 2    branch::alt,
 3    bytes::complete::tag,
 4    character::complete::{char, line_ending, one_of},
 5    combinator::{map_res, recognize},
 6    error::{FromExternalError, ParseError},
 7    multi::{many0, many1},
 8    sequence::delimited,
 9    IResult,
10};
11
12// Bind the given parser to the given value (map_res short).
13pub fn bind<'a, F: 'a, T: Copy, O, E: ParseError<&'a str> + FromExternalError<&'a str, ()>>(
14    inner: F,
15    val: T,
16) -> impl FnMut(&'a str) -> IResult<&'a str, T, E>
17where
18    F: FnMut(&'a str) -> IResult<&'a str, O, E>,
19{
20    map_res(inner, move |_| -> Result<T, ()> { Ok(val) })
21}
22
23// Parse on of the given strings and return the given value.
24pub fn str<'a, T: Copy, E: ParseError<&'a str> + FromExternalError<&'a str, ()> + 'a>(
25    name: &'a str,
26    other: &'a str,
27    val: T,
28) -> impl FnMut(&'a str) -> IResult<&'a str, T, E> {
29    bind(alt((tag(name), tag(other))), val)
30}
31
32pub fn digits(input: &str) -> IResult<&str, u32> {
33    map_res(recognize(many1(one_of("0123456789"))), |input: &str| {
34        u32::from_str_radix(input, 10)
35    })(input)
36}
37
38pub fn ws<'a, F: 'a, O, E: ParseError<&'a str>>(
39    inner: F,
40) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>
41where
42    F: Fn(&'a str) -> IResult<&'a str, O, E>,
43{
44    delimited(many0(char(' ')), inner, many0(char(' ')))
45}
46
47pub fn empty_lines<'a, F: 'a, O, E: ParseError<&'a str> + 'a>(
48    inner: F,
49) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>
50where
51    F: Fn(&'a str) -> IResult<&'a str, O, E>,
52{
53    delimited(many0(ws(line_ending)), inner, many0(ws(line_ending)))
54}