use nom::{
branch::alt,
bytes::complete::tag,
character::complete::digit0,
combinator::{map, map_res},
multi::separated_list1,
sequence::tuple,
IResult,
};
#[derive(Debug, Clone)]
pub enum Types {
Asterik,
Digit(u8),
AllXSteps(u8),
List(Vec<Self>),
Range { min: u8, max: u8 },
}
impl Types {
pub fn parser(input: &str) -> IResult<&str, Self> {
alt((
Self::parser_all_x_minute,
Self::parser_range,
Self::parser_digit_as_list,
Self::parser_digit,
Self::parser_asterik,
))(input)
}
pub fn parser_asterik(input: &str) -> IResult<&str, Self> {
map(tag("*"), |_| Types::Asterik)(input)
}
pub fn parser_digit(input: &str) -> IResult<&str, Self> {
map(map_res(digit0, |s: &str| s.parse::<u8>()), |parsed| {
Types::Digit(parsed)
})(input)
}
pub fn parser_all_x_minute(input: &str) -> IResult<&str, Self> {
map(
tuple((
tag("*"),
tag("/"),
map_res(digit0, |s: &str| s.parse::<u8>()),
)),
|(_, _, number)| Self::AllXSteps(number),
)(input)
}
pub fn parser_range(input: &str) -> IResult<&str, Self> {
map(
tuple((
map_res(digit0, |s: &str| s.parse::<u8>()),
tag("-"),
map_res(digit0, |s: &str| s.parse::<u8>()),
)),
|(min, _, max)| Self::Range { min, max },
)(input)
}
pub fn parser_digit_as_list(input: &str) -> IResult<&str, Self> {
map(
separated_list1(
tag(","),
alt((
Self::parser_digit,
Self::parser_all_x_minute,
Self::parser_range,
)),
),
Self::List,
)(input)
}
}