use crate::{Error, Result, utils::define_name_type_impls};
use serde::Serialize;
use zvariant::{OwnedValue, Str, Type, Value};
#[derive(
Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue,
)]
pub struct MemberName<'name>(Str<'name>);
#[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)]
pub struct OwnedMemberName(#[serde(borrow)] MemberName<'static>);
define_name_type_impls! {
name: MemberName,
owned: OwnedMemberName,
validate: validate,
}
fn validate(name: &str) -> Result<()> {
validate_bytes(name.as_bytes()).map_err(|_| {
Error::InvalidName(
"Invalid member name. See \
https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member",
)
})
}
pub(crate) fn validate_bytes(bytes: &[u8]) -> std::result::Result<(), ()> {
use winnow::{
Parser,
stream::AsChar,
token::{one_of, take_while},
};
let first_element_char = one_of((AsChar::is_alpha, b'_'));
let subsequent_element_chars = take_while::<_, _, ()>(0.., (AsChar::is_alphanum, b'_'));
let mut member_name = (first_element_char, subsequent_element_chars);
member_name.parse(bytes).map_err(|_| ()).and_then(|_| {
if bytes.len() > 255 {
return Err(());
}
Ok(())
})
}