Ghee/src/xattr.rs

127 lines
3.3 KiB
Rust
Raw Normal View History

2023-08-04 23:28:38 +02:00
use nom::{
branch::alt,
bytes::complete::{tag, take_while, take_while1},
character::complete::char,
character::is_alphabetic,
error::ParseError,
sequence::{pair, separated_pair, terminated},
IResult,
};
#[derive(Clone, Debug, PartialEq)]
2023-08-04 23:28:38 +02:00
pub struct Xattr {
pub namespace: Vec<u8>,
pub attr: Vec<u8>,
}
/// Parse the `namespace.attr` (or just bare `attr`) xattr names, filling in the `user` namespace
/// when none is provided.
// pub fn parse_xattr<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], Xattr, E> {
// pair(
// alt((tag(""), terminated(take_while(is_alphabetic), tag(".")))),
// take_while(is_alphabetic),
// )(i)
// .map(|(i, (namespace, attr))| {
// (
// i,
// Xattr {
// namespace: if namespace.is_empty() {
// b"user.".into_iter().copied().collect()
// } else {
// namespace.iter().copied().collect()
// },
// attr: attr.iter().copied().collect(),
// },
// )
// })
// }
fn parse_xattr_complete(i: &[u8]) -> IResult<&[u8], Xattr> {
separated_pair(
take_while1(is_alphabetic),
char('.'),
take_while1(is_alphabetic),
)(i)
.map(|(i, (namespace, attr))| {
(
i,
Xattr {
namespace: namespace.iter().copied().collect(),
attr: attr.iter().copied().collect(),
},
)
})
}
fn parse_xattr_bare(i: &[u8]) -> IResult<&[u8], Xattr> {
take_while1(is_alphabetic)(i).map(|(i, attr)| {
(
i,
Xattr {
namespace: b"user".to_vec(),
attr: attr.iter().copied().collect(),
},
)
})
}
// pub fn parse_xattr(i: &[u8]) -> IResult<&[u8], Xattr> {
// pair(
// alt((tag(""), terminated(take_while(is_alphabetic), tag(".")))),
// take_while1(is_alphabetic),
// )(i)
// .map(|(i, (namespace, attr))| {
// (
// i,
// Xattr {
// namespace: if namespace.is_empty() {
// b"user".into_iter().copied().collect()
// } else {
// namespace.iter().copied().collect()
// },
// attr: attr.iter().copied().collect(),
// },
// )
// })
// }
pub fn parse_xattr(i: &[u8]) -> IResult<&[u8], Xattr> {
alt((parse_xattr_complete, parse_xattr_bare))(i)
}
#[test]
fn test_parse_xattr() {
assert!(parse_xattr(b"").is_err());
assert_eq!(
parse_xattr(b"abc"),
Ok((
b"".as_slice(),
Xattr {
namespace: b"user".to_vec(),
attr: b"abc".to_vec()
}
))
);
assert_eq!(
parse_xattr(b"system.abc"),
Ok((
b"".as_slice(),
Xattr {
namespace: b"system".to_vec(),
attr: b"abc".to_vec()
}
))
);
assert_eq!(
parse_xattr(b"blah.blah.blah"),
Ok((
b".blah".as_slice(),
Xattr {
namespace: b"blah".to_vec(),
attr: b"blah".to_vec()
}
))
);
}