Как правильно вернуть простую пользовательскую ошибку с помощью функции errorkind?
Простой обработчик ошибок добавлен в nom
Первый компилируется без ошибок, второй выдает ошибки
use nom::*;
use std::str;
// This works
named!(
field<&str>,
map!(
complete!(add_return_error!(
ErrorKind::Custom(1),
preceded!(
tag!("."),
recognize!(many1!(
alt!(alphanumeric => { |_| true } | char!('_') => {|_| true})
))
)
)),
|v| str::from_utf8(v).unwrap()
)
);
// This doesn't compile
named!(
entity<&str>,
add_return_error!(
ErrorKind::Custom(2),
map!(
recognize!(many1!(
alt!(alphanumeric => { |_| true } | char!('_') => {|_| true})
)),
|v| str::from_utf8(v).unwrap()
)
)
);
Ошибка
cargo build
Compiling pdl_parser v0.1.0 (file:///H:/parser)
error[E0282]: type annotations needed
--> src\pdl_parser.rs:72:1
|
72 | / named!(
73 | | entity<&str>,
74 | | add_return_error!(
75 | | ErrorKind::Custom(2),
... |
82 | | )
83 | | );
| |__^ cannot infer type for `E`
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
Почему первый работает, а второй нет? И что я могу сделать, чтобы это исправить? Я попытался изменить подпись второго на entity<&[u8],&str,ErrorKind>
а затем i32
а также u32
но безуспешно
1 ответ
Решение проблемы cannot infer type for E
ошибка состоит в том, чтобы выделить этапы синтаксического анализа, чтобы компилятор не запутался.
Переписать синтаксический анализатор как
named!(
entity_name<Vec<u8>>,
many1!(alt!(alphanumeric => { |x : &[u8]| x[0] } | char!('_') => {|_| b'_'}))
);
named!(
entity<&[u8],&str,i32>,
add_return_error!(
ErrorKind::Custom(2),
map!(recognize!(entity_name),|v| str::from_utf8(v).unwrap())
)
);
И соответствующий тест
#[test]
fn parse_pdl_error_test() {
assert_eq!(entity(b"_error_stack").to_result(), Ok("_error_stack"));
assert_eq!(entity(b"[];']").to_result(), Err(ErrorKind::Custom(2)));
}