Source code

Revision control

Copy as Markdown

Other Tools

use snapbox::prelude::*;
use snapbox::str;
use crate::ascii::dec_uint;
use crate::ascii::digit0;
use crate::combinator::dispatch;
use crate::combinator::empty;
use crate::combinator::fail;
use crate::combinator::seq;
use crate::prelude::*;
use crate::token::any;
#[test]
fn dispatch_basics() {
fn escape_seq_char<'i>(input: &mut &'i str) -> TestResult<&'i str, char> {
dispatch! {any;
'b' => empty.value('\u{8}'),
'f' => empty.value('\u{c}'),
'n' => empty.value('\n'),
'r' => empty.value('\r'),
't' => empty.value('\t'),
'\\' => empty.value('\\'),
'"' => empty.value('"'),
_ => fail::<_, char, _>,
}
.parse_next(input)
}
assert_parse!(
escape_seq_char.parse_peek("b123"),
str![[r#"
Ok(
(
"123",
'\u{8}',
),
)
"#]]
.raw()
);
assert_parse!(
escape_seq_char.parse_peek("error"),
str![[r#"
Err(
Backtrack(
InputError {
input: "rror",
},
),
)
"#]]
.raw()
);
assert_parse!(
escape_seq_char.parse_peek(""),
str![[r#"
Err(
Backtrack(
InputError {
input: "",
},
),
)
"#]]
.raw()
);
}
#[test]
fn seq_struct_basics() {
#[derive(Debug, PartialEq)]
struct Point {
x: u32,
y: u32,
}
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
seq! {
Point {
x: dec_uint,
_: ',',
y: dec_uint,
}
}
.parse_next(input)
}
assert_parse!(
parser.parse_peek("123,4 remaining"),
str![[r#"
Ok(
(
" remaining",
Point {
x: 123,
y: 4,
},
),
)
"#]]
.raw()
);
assert_parse!(
parser.parse_peek("123, remaining"),
str![[r#"
Err(
Backtrack(
InputError {
input: " remaining",
},
),
)
"#]]
.raw()
);
assert_parse!(
parser.parse_peek(""),
str![[r#"
Err(
Backtrack(
InputError {
input: "",
},
),
)
"#]]
.raw()
);
}
#[test]
fn seq_struct_default_init() {
#[derive(Debug, PartialEq, Default)]
struct Point {
x: u32,
y: u32,
z: u32,
}
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
seq! {
Point {
x: dec_uint,
_: ',',
y: dec_uint,
..Default::default()
}
}
.parse_next(input)
}
assert_parse!(
parser.parse_peek("123,4 remaining"),
str![[r#"
Ok(
(
" remaining",
Point {
x: 123,
y: 4,
z: 0,
},
),
)
"#]]
.raw()
);
assert_parse!(
parser.parse_peek("123, remaining"),
str![[r#"
Err(
Backtrack(
InputError {
input: " remaining",
},
),
)
"#]]
.raw()
);
assert_parse!(
parser.parse_peek(""),
str![[r#"
Err(
Backtrack(
InputError {
input: "",
},
),
)
"#]]
.raw()
);
}
#[test]
fn seq_struct_trailing_comma_elided() {
#![allow(dead_code)]
#[derive(Debug, PartialEq)]
struct Point {
x: u32,
y: u32,
}
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
seq! {
Point {
x: dec_uint,
_: ',',
y: dec_uint,
_: empty,
}
}
.parse_next(input)
}
}
#[test]
fn seq_struct_no_trailing_comma() {
#![allow(dead_code)]
#[derive(Debug, PartialEq)]
struct Point {
x: u32,
y: u32,
}
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
seq! {
Point {
x: dec_uint,
_: ',',
y: dec_uint
}
}
.parse_next(input)
}
}
#[test]
fn seq_struct_no_trailing_comma_elided() {
#![allow(dead_code)]
#[derive(Debug, PartialEq)]
struct Point {
x: u32,
y: u32,
}
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
seq! {
Point {
x: dec_uint,
_: ',',
y: dec_uint,
_: empty
}
}
.parse_next(input)
}
}
#[test]
fn seq_enum_struct_variant() {
#[derive(Debug, PartialEq, Eq)]
enum Expr {
Add { lhs: u32, rhs: u32 },
Mul(u32, u32),
}
fn add<'i>(input: &mut &'i [u8]) -> TestResult<&'i [u8], Expr> {
seq! {Expr::Add {
lhs: dec_uint::<_, u32, _>,
_: b" + ",
rhs: dec_uint::<_, u32, _>,
}}
.parse_next(input)
}
fn mul<'i>(input: &mut &'i [u8]) -> TestResult<&'i [u8], Expr> {
seq!(Expr::Mul(
dec_uint::<_, u32, _>,
_: b" * ",
dec_uint::<_, u32, _>,
))
.parse_next(input)
}
assert_parse!(
add.parse_peek(&b"1 + 2"[..]),
str![[r#"
Ok(
(
[],
Add {
lhs: 1,
rhs: 2,
},
),
)
"#]]
.raw()
);
assert_parse!(
mul.parse_peek(&b"3 * 4"[..]),
str![[r#"
Ok(
(
[],
Mul(
3,
4,
),
),
)
"#]]
.raw()
);
}
#[test]
fn seq_struct_borrow() {
#![allow(dead_code)]
#[derive(Debug, PartialEq)]
struct Point {
x: u32,
y: u32,
}
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
let mut dec_uint = digit0.parse_to();
seq! {
Point {
x: dec_uint,
_: ',',
y: dec_uint,
_: empty
}
}
.parse_next(input)
}
}
#[test]
fn seq_tuple_struct_basics() {
#[derive(Debug, PartialEq)]
struct Point(u32, u32);
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
seq! {
Point(
dec_uint,
_: ',',
dec_uint,
)
}
.parse_next(input)
}
assert_parse!(
parser.parse_peek("123,4 remaining"),
str![[r#"
Ok(
(
" remaining",
Point(
123,
4,
),
),
)
"#]]
.raw()
);
assert_parse!(
parser.parse_peek("123, remaining"),
str![[r#"
Err(
Backtrack(
InputError {
input: " remaining",
},
),
)
"#]]
.raw()
);
assert_parse!(
parser.parse_peek(""),
str![[r#"
Err(
Backtrack(
InputError {
input: "",
},
),
)
"#]]
.raw()
);
}
#[test]
fn seq_tuple_struct_trailing_comma_elided() {
#![allow(dead_code)]
#[derive(Debug, PartialEq)]
struct Point(u32, u32);
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
seq! {
Point(
dec_uint,
_: ',',
dec_uint,
_: empty,
)
}
.parse_next(input)
}
}
#[test]
fn seq_tuple_struct_no_trailing_comma() {
#![allow(dead_code)]
#[derive(Debug, PartialEq)]
struct Point(u32, u32);
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
seq! {
Point(
dec_uint,
_: ',',
dec_uint
)
}
.parse_next(input)
}
}
#[test]
fn seq_tuple_struct_no_trailing_comma_elided() {
#![allow(dead_code)]
#[derive(Debug, PartialEq)]
struct Point(u32, u32);
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
seq! {
Point(
dec_uint,
_: ',',
dec_uint,
_: empty
)
}
.parse_next(input)
}
}
#[test]
fn seq_tuple_basics() {
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, (u32, u32)> {
seq! {
(
dec_uint,
_: ',',
dec_uint,
)
}
.parse_next(input)
}
assert_parse!(
parser.parse_peek("123,4 remaining"),
str![[r#"
Ok(
(
" remaining",
(
123,
4,
),
),
)
"#]]
.raw()
);
assert_parse!(
parser.parse_peek("123, remaining"),
str![[r#"
Err(
Backtrack(
InputError {
input: " remaining",
},
),
)
"#]]
.raw()
);
assert_parse!(
parser.parse_peek(""),
str![[r#"
Err(
Backtrack(
InputError {
input: "",
},
),
)
"#]]
.raw()
);
}
#[test]
fn seq_tuple_trailing_comma_elided() {
#![allow(dead_code)]
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, (u32, u32)> {
seq! {
(
dec_uint,
_: ',',
dec_uint,
_: empty,
)
}
.parse_next(input)
}
}
#[test]
fn seq_tuple_no_trailing_comma() {
#![allow(dead_code)]
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, (u32, u32)> {
seq! {
(
dec_uint,
_: ',',
dec_uint
)
}
.parse_next(input)
}
}
#[test]
fn seq_tuple_no_trailing_comma_elided() {
#![allow(dead_code)]
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, (u32, u32)> {
seq! {
(
dec_uint,
_: ',',
dec_uint,
_: empty
)
}
.parse_next(input)
}
}
#[test]
fn seq_tuple_no_parens() {
#![allow(dead_code)]
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, (u32, u32)> {
seq! (
dec_uint,
_: ',',
dec_uint,
)
.parse_next(input)
}
}
#[test]
fn seq_tuple_borrow() {
#![allow(dead_code)]
#[derive(Debug, PartialEq)]
struct Point(u32, u32);
fn parser<'i>(input: &mut &'i str) -> TestResult<&'i str, Point> {
let mut dec_uint = digit0.parse_to();
seq! {
Point(
dec_uint,
_: ',',
dec_uint,
_: empty
)
}
.parse_next(input)
}
}