Updated dependencies, nix shell, justfile

- Updated all dependencies
- Updated Rust edition to 2024
- Nix shell from flake
- Added justfile
- Mirgrate all changes to various packages
This commit is contained in:
2025-03-07 18:21:23 +01:00
parent 80f4af9087
commit 2f1eb4df3a
14 changed files with 391 additions and 251 deletions

View File

@ -1,23 +1,22 @@
use {
nom::{
bytes::complete::take_while_m_n,
character::complete::{char, multispace0},
combinator::eof,
sequence::{delimited, terminated},
IResult, InputIter, InputLength, InputTake, Slice,
},
std::ops::RangeFrom,
};
// TODO generic input
use nom::IResult;
use nom::bytes::complete::take_while_m_n;
use nom::character::complete::char;
use nom::character::complete::multispace0;
use nom::combinator::eof;
use nom::error::ParseError;
use nom::sequence::delimited;
use nom::sequence::terminated;
use nom::{Input, Parser};
/// Trim leading and trailing whitespace from the input Parser
/// - Parameters
/// - `inner`: The parser to trim
/// - Returns: A parser that trims leading and trailing whitespace from the input and then runs the value from the inner parser
pub fn trim<'a, Parser, R>(inner: Parser) -> impl FnMut(&'a str) -> IResult<&'a str, R>
pub fn trim<I, O, F, E: ParseError<I>>(inner: F) -> impl Parser<I, Output = O, Error = E>
where
Parser: FnMut(&'a str) -> IResult<&'a str, R>,
I: Input,
F: Parser<I, Output = O, Error = E>,
<I as Input>::Item: nom::AsChar,
{
delimited(multispace0, inner, multispace0)
}
@ -27,9 +26,11 @@ where
/// - Parameters
/// - `inner`: The parser to run inside the parentheses
/// - Returns: A parser that parses a parenthesized expression
pub fn parenthesized<'a, Parser, R>(inner: Parser) -> impl FnMut(&'a str) -> IResult<&'a str, R>
pub fn parenthesized<I, O, F, E: ParseError<I>>(inner: F) -> impl Parser<I, Output = O, Error = E>
where
Parser: FnMut(&'a str) -> IResult<&'a str, R>,
I: Input,
F: Parser<I, Output = O, Error = E>,
<I as Input>::Item: nom::AsChar,
{
delimited(char('('), inner, char(')'))
}
@ -39,10 +40,10 @@ where
/// - `n`: The length of the string to take
/// - `predicate`: The predicate to call to validate the input
/// - Returns: A parser that takes `n` characters from the input
pub fn take_where<F, Input>(n: usize, predicate: F) -> impl Fn(Input) -> IResult<Input, Input>
pub fn take_where<F, I>(n: usize, predicate: F) -> impl FnMut(I) -> IResult<I, I>
where
Input: InputTake + InputIter + InputLength + Slice<RangeFrom<usize>>,
F: Fn(<Input as InputIter>::Item) -> bool + Copy,
I: Input,
F: Fn(<I as Input>::Item) -> bool,
{
take_while_m_n(n, n, predicate)
}
@ -54,40 +55,43 @@ where
/// - Returns: A parser that runs the inner parser and then the end of the input
/// # Example
/// ```
/// use nom::bytes::complete::{tag};
/// use lib::nom::combinators::exhausted;
/// use nom::bytes::complete::{tag};
/// use nom::Parser;
///
/// let input = "test";
/// let (remaining, result) = exhausted(tag("test"))(input).unwrap();
/// let (remaining, result) = exhausted(tag::<&str, &str, nom::error::Error<&str>>("test")).parse(input).unwrap();
/// assert_eq!(remaining, "");
/// assert_eq!(result, "test");
/// ```
/// - Fails if the input is not exhausted
/// ```
/// use nom::bytes::complete::{tag};
/// use lib::nom::combinators::exhausted;
/// use nom::bytes::complete::{tag};
/// use nom::Parser;
///
/// let input = "test";
/// assert!(exhausted(tag("tes"))(input).is_err());
/// assert!(exhausted(tag::<&str, &str, nom::error::Error<&str>>("tes")).parse(input).is_err());
/// ```
pub fn exhausted<'a, Parser, R>(inner: Parser) -> impl FnMut(&'a str) -> IResult<&'a str, R>
pub fn exhausted<F, I, O, E: ParseError<I>>(inner: F) -> impl Parser<I, Output = O, Error = E>
where
Parser: FnMut(&'a str) -> IResult<&'a str, R>,
I: Input,
F: Parser<I, Output = O, Error = E>,
{
terminated(inner, eof)
}
#[cfg(test)]
mod tests {
use nom::{bytes::complete::take_while, sequence::tuple};
use super::*;
use nom::bytes::complete::take_while;
#[test]
fn test_trim_both_sides() {
let input = " test ";
let (remaining, result) =
trim(take_where(4, |c: char| c.is_ascii_alphabetic()))(input).unwrap();
let (remaining, result) = trim(take_where(4, |c: char| c.is_ascii_alphabetic()))
.parse(input)
.unwrap();
assert_eq!(remaining, "");
assert_eq!(result, "test");
}
@ -95,8 +99,9 @@ mod tests {
#[test]
fn test_trim_leading() {
let input = " test";
let (remaining, result) =
trim(take_where(4, |c: char| c.is_ascii_alphabetic()))(input).unwrap();
let (remaining, result) = trim(take_where(4, |c: char| c.is_ascii_alphabetic()))
.parse(input)
.unwrap();
assert_eq!(remaining, "");
assert_eq!(result, "test");
}
@ -104,8 +109,9 @@ mod tests {
#[test]
fn test_trim_trailing() {
let input = "test ";
let (remaining, result) =
trim(take_where(4, |c: char| c.is_ascii_alphabetic()))(input).unwrap();
let (remaining, result) = trim(take_where(4, |c: char| c.is_ascii_alphabetic()))
.parse(input)
.unwrap();
assert_eq!(remaining, "");
assert_eq!(result, "test");
}
@ -113,8 +119,9 @@ mod tests {
#[test]
fn test_trim_no_trim() {
let input = "test";
let (remaining, result) =
trim(take_where(4, |c: char| c.is_ascii_alphabetic()))(input).unwrap();
let (remaining, result) = trim(take_where(4, |c: char| c.is_ascii_alphabetic()))
.parse(input)
.unwrap();
assert_eq!(remaining, "");
assert_eq!(result, "test");
}
@ -122,8 +129,9 @@ mod tests {
#[test]
fn test_parenthesized() {
let input = "(test)";
let (remaining, result) =
parenthesized(take_where(4, |c: char| c.is_ascii_alphabetic()))(input).unwrap();
let (remaining, result) = parenthesized(take_where(4, |c: char| c.is_ascii_alphabetic()))
.parse(input)
.unwrap();
assert_eq!(remaining, "");
assert_eq!(result, "test");
}
@ -131,7 +139,11 @@ mod tests {
#[test]
fn test_parenthesized_parse_until_end() {
let input = "(test)";
assert!(parenthesized(take_while(|_| true))(input).is_err());
assert!(
parenthesized::<&str, &str, _, nom::error::Error<&str>>(take_while(|_| true))
.parse(input)
.is_err()
);
}
#[test]
@ -152,7 +164,7 @@ mod tests {
fn test_take_where_too_much() {
let input = "testing";
assert_eq!(
take_where(4, |c: char| c.is_ascii_alphabetic())(input),
take_where(4, |c: char| c.is_ascii_alphabetic()).parse(input),
Ok(("ing", "test"))
);
}
@ -160,14 +172,19 @@ mod tests {
#[test]
fn test_take_where_predicate_false() {
let input = "test";
assert!(take_where(4, |c: char| c.is_ascii_digit())(input).is_err());
assert!(
take_where(4, |c: char| c.is_ascii_digit())
.parse(input)
.is_err()
);
}
#[test]
fn test_exhausted() {
let input = "test";
let (remaining, result) =
exhausted(take_where(4, |c: char| c.is_ascii_alphabetic()))(input).unwrap();
let (remaining, result) = exhausted(take_where(4, |c: char| c.is_ascii_alphabetic()))
.parse(input)
.unwrap();
assert_eq!(remaining, "");
assert_eq!(result, "test");
}
@ -175,16 +192,21 @@ mod tests {
#[test]
fn test_exhausted_not_exhausted() {
let input = "test ";
assert!(exhausted(take_where(4, |c: char| c.is_ascii_alphabetic()))(input).is_err());
assert!(
exhausted(take_where(4, |c: char| c.is_ascii_alphabetic()))
.parse(input)
.is_err()
);
}
#[test]
fn test_exhausted_tuple() {
let input = "test";
let (remaining, result) = exhausted(tuple((
let (remaining, result) = exhausted((
take_where(3, |c: char| c.is_ascii_alphabetic()),
take_while(|c: char| c.is_ascii_alphabetic()),
)))(input)
))
.parse(input)
.unwrap();
assert_eq!(remaining, "");
assert_eq!(result, ("tes", "t"));