我有一个带有UUID(16个字节(、1个字节类型字段和4个字节的二进制数据包,其中包含一个浮点值。
如何使用nom进行解析并得到元组(Uuid,u8,f32(?
use nom::{
combinator::map_res, number::complete::le_f32, number::complete::le_u128,
number::complete::le_u8, sequence::tuple, IResult,
};
use uuid;
fn detect(data: &[u8]) -> IResult<&[u8], (uuid::Uuid, u8, f32)> {
???
/* my attempt so far:
map_res(tuple((le_u128, le_u8, le_f32)), |tup| {
Ok((uuid::Uuid::from_u128(tup.0), tup.1, tup.2))
})(data)
*/
}
fn main() {
let pdu = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 200, 65,
];
let result = detect(&pdu);
println!("{:?}", result);
}
[dependencies]
nom = "5"
uuid = "0.8"
在nom 5中,您可以只使用经典的rust方式,例如自述:
use nom::combinator;
use nom::number::complete as number;
fn detect(data: &[u8]) -> nom::IResult<&[u8], (uuid::Uuid, u8, f32)> {
let (data, uuid) = combinator::map(number::le_u128, uuid::Uuid::from_u128)(data)?;
let (data, type_field) = number::le_u8(data)?;
let (data, value) = number::le_f32(data)?;
Ok((data, (uuid, type_field, value)))
}
fn main() {
let pdu = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 200, 65,
];
let result = detect(&pdu);
println!("{:?}", result);
}
我刚刚修复了您的尝试。您可以实现一个更有用的错误。
use nom::{
combinator::map_res, number::complete::le_f32, number::complete::le_u128,
number::complete::le_u8, sequence::tuple, IResult,
};
use std::fmt::{Display, Formatter};
use uuid;
#[derive(Debug)]
struct Error;
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Error")
}
}
impl std::error::Error for Error {}
fn detect(data: &[u8]) -> IResult<&[u8], (uuid::Uuid, u8, f32)> {
map_res(
tuple((le_u128, le_u8, le_f32)),
|tup: (u128, u8, f32)| -> Result<(uuid::Uuid, u8, f32), Error> {
Ok((uuid::Uuid::from_u128(tup.0), tup.1, tup.2))
},
)(data)
}
fn main() {
let pdu = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 200, 65,
];
let result = detect(&pdu);
println!("{:?}", result);
}