use crate::{Str, Type, names::utils::define_name_type_impls};
use serde::Serialize;
#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, PartialOrd, Ord)]
pub struct UniqueName<'name>(pub(crate) Str<'name>);
#[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, PartialOrd, Ord)]
pub struct OwnedUniqueName(#[serde(borrow)] UniqueName<'static>);
define_name_type_impls! {
name: UniqueName,
owned: OwnedUniqueName,
validate: validate_unique_name,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{OwnedVariant, Variant};
#[test]
fn value_conversion_rejects_empty_name() {
let value = Variant::from("");
UniqueName::try_from(value).unwrap_err();
OwnedUniqueName::try_from(Variant::from("")).unwrap_err();
OwnedUniqueName::try_from(OwnedVariant::from(crate::Str::from(""))).unwrap_err();
}
#[test]
fn optional_value_conversion_maps_empty_name_to_none() {
use crate::Optional;
let opt = Optional::<UniqueName<'_>>::try_from(Variant::from("")).unwrap();
assert_eq!(Option::from(opt), None::<UniqueName<'_>>);
let opt = Optional::<UniqueName<'_>>::try_from(Variant::from(":1.23")).unwrap();
assert_eq!(opt.as_ref().unwrap().as_str(), ":1.23");
Optional::<UniqueName<'_>>::try_from(Variant::from("not a unique name")).unwrap_err();
}
#[test]
fn optional_owned_value_conversion_maps_empty_name_to_none() {
use crate::Optional;
let owned = OwnedVariant::from(crate::Str::from(""));
let opt = Optional::<OwnedUniqueName>::try_from(owned).unwrap();
assert!(Option::<OwnedUniqueName>::from(opt).is_none());
let owned = OwnedVariant::from(crate::Str::from(":1.23"));
let opt = Optional::<OwnedUniqueName>::try_from(owned).unwrap();
assert_eq!(
Option::<OwnedUniqueName>::from(opt).unwrap().as_str(),
":1.23"
);
}
#[test]
fn optional_name_wire_round_trip() {
use crate::{
Optional,
wire::{LE, serialized::Context, to_bytes},
};
let ctxt = Context::new(LE, 0);
let encoded = to_bytes(ctxt, &Optional::<UniqueName<'_>>::default()).unwrap();
let opt: Optional<UniqueName<'_>> = encoded.deserialize().unwrap().0;
assert!(Option::<UniqueName<'_>>::from(opt).is_none());
let name = UniqueName::try_from(":1.23").unwrap();
let encoded = to_bytes(ctxt, &Optional::from(Some(name.clone()))).unwrap();
let opt: Optional<UniqueName<'_>> = encoded.deserialize().unwrap().0;
assert_eq!(Option::from(opt), Some(name));
let encoded = to_bytes(ctxt, &"not a unique name").unwrap();
encoded
.deserialize::<Optional<UniqueName<'_>>>()
.unwrap_err();
}
#[test]
fn optional_owned_name_is_deserialize_owned() {
use crate::{
Optional,
names::OwnedBusName,
wire::{LE, serialized::Context, to_bytes},
};
use serde::de::DeserializeOwned;
fn assert_deserialize_owned<T: DeserializeOwned>() {}
assert_deserialize_owned::<Optional<OwnedUniqueName>>();
assert_deserialize_owned::<Optional<OwnedBusName>>();
let ctxt = Context::new(LE, 0);
let encoded = to_bytes(ctxt, &Optional::<OwnedUniqueName>::default()).unwrap();
let opt: Optional<OwnedUniqueName> = encoded.deserialize().unwrap().0;
assert!(Option::<OwnedUniqueName>::from(opt).is_none());
let name = OwnedUniqueName::try_from(":1.42").unwrap();
let encoded = to_bytes(ctxt, &Optional::from(Some(name.clone()))).unwrap();
let opt: Optional<OwnedUniqueName> = encoded.deserialize().unwrap().0;
assert_eq!(Option::<OwnedUniqueName>::from(opt), Some(name));
}
#[test]
fn value_conversion_round_trips_valid_name() {
let name = UniqueName::try_from(":1.23").unwrap();
let value = Variant::from(name.clone());
let parsed = UniqueName::try_from(value).unwrap();
assert_eq!(parsed, name);
let owned = OwnedVariant::try_from(name.clone()).unwrap();
assert_eq!(UniqueName::try_from(owned).unwrap(), name);
let owned_name = OwnedUniqueName::from(name.clone());
let value: Variant<'static> = Variant::from(owned_name.clone());
assert_eq!(OwnedUniqueName::try_from(value).unwrap(), owned_name);
let owned = OwnedVariant::try_from(owned_name.clone()).unwrap();
assert_eq!(OwnedUniqueName::try_from(owned).unwrap(), owned_name);
}
}