Почему nom ожидает &str, когда я передаю CompleteStr?
Парсер работает как положено, пока я не захочу разобрать h:
цифра, которая всегда является последней цифрой в строке, и компилятор дает мне
^ expected &str, found struct `nom::types::CompleteStr`
Я предполагаю, что это потому, что парсер смотрит в будущее. Как мне это остановить или как я могу показать, что это сделано?
#[macro_use]
extern crate nom;
use nom::digit;
use nom::types::CompleteStr;
use std::str::FromStr;
#[derive(Debug, PartialEq)]
pub struct Order {
pub l: u64,
pub w: u64,
pub h: u64,
}
named!(order_parser<CompleteStr, Order>,
do_parse!(
l: map_res!(digit, u64::from_str) >>
tag!("x") >>
w: map_res!(digit, u64::from_str) >>
tag!("x") >>
h: map_res!(digit, u64::from_str) >>
(Order {l: l, w: w, h: h })
)
);
pub fn wrap_order(order: &str) -> Result<(CompleteStr, Order), nom::Err<&str>> {
order_parser(order)
}
#[test]
fn test_order_parser() {
assert_eq!(
wrap_order(CompleteStr("2x3x4")),
Ok((CompleteStr(""), Order { l: 2, w: 3, h: 4 }))
);
}
1 ответ
Решение
Ошибка не в последнем анализаторе цифр, а в каждом из них (Rust 1.30.0 печатает ошибку три раза). Это потому что u64::from_str
работает на &str
не CompleteStr
,
Вы можете исправить ваши парсеры для использования u64::from_str
правильно так:
do_parse!(
l: map_res!(digit, |CompleteStr(s)| u64::from_str(s)) >>
tag!("x") >>
w: map_res!(digit, |CompleteStr(s)| u64::from_str(s)) >>
tag!("x") >>
h: map_res!(digit, |CompleteStr(s)| u64::from_str(s)) >>
(Order { l: l, w: w, h: h })
)
Есть также некоторая несвязанная ошибка со следующей функцией, которую можно исправить, используя соответствующие типы в сигнатуре:
pub fn wrap_order(order: &str) -> Result<(CompleteStr, Order), nom::Err<CompleteStr>> {
order_parser(CompleteStr(order))
}