use super::{
DomainError, EntityId, EntityKind, GraphGeneration, GraphRevision, MAX_GRAPH_INPUT_BYTES,
};
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct GraphName<'a>(&'a str);
impl<'a> GraphName<'a> {
pub const fn new(value: &'a str) -> Result<Self, DomainError> {
if value.len() > MAX_GRAPH_INPUT_BYTES {
Err(DomainError::InputTooLarge)
} else {
Ok(Self(value))
}
}
pub fn from_utf8(value: &'a [u8]) -> Result<Self, DomainError> {
if value.len() > MAX_GRAPH_INPUT_BYTES {
return Err(DomainError::InputTooLarge);
}
Self::new(std::str::from_utf8(value).map_err(|_| DomainError::InvalidUtf8)?)
}
#[must_use]
pub const fn as_str(self) -> &'a str {
self.0
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ApplicationKey<'a> {
kind: EntityKind,
namespace: GraphName<'a>,
key: GraphName<'a>,
}
impl<'a> ApplicationKey<'a> {
pub fn new(kind: EntityKind, namespace: &'a str, key: &'a str) -> Result<Self, DomainError> {
if namespace
.len()
.checked_add(key.len())
.is_none_or(|bytes| bytes > MAX_GRAPH_INPUT_BYTES)
{
return Err(DomainError::InputTooLarge);
}
Ok(Self {
kind,
namespace: GraphName::new(namespace)?,
key: GraphName::new(key)?,
})
}
#[must_use]
pub const fn kind(self) -> EntityKind {
self.kind
}
#[must_use]
pub const fn namespace(self) -> GraphName<'a> {
self.namespace
}
#[must_use]
pub const fn key(self) -> GraphName<'a> {
self.key
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct EntityMetadata<'a> {
id: EntityId,
key: Option<ApplicationKey<'a>>,
revision: GraphRevision,
last_change_generation: GraphGeneration,
}
impl<'a> EntityMetadata<'a> {
pub fn new(
id: EntityId,
key: Option<ApplicationKey<'a>>,
revision: GraphRevision,
last_change_generation: GraphGeneration,
) -> Result<Self, DomainError> {
if key.is_some_and(|key| key.kind() != id.kind()) {
return Err(DomainError::EntityKindMismatch);
}
Ok(Self {
id,
key,
revision,
last_change_generation,
})
}
#[must_use]
pub const fn id(self) -> EntityId {
self.id
}
#[must_use]
pub const fn key(self) -> Option<ApplicationKey<'a>> {
self.key
}
#[must_use]
pub const fn revision(self) -> GraphRevision {
self.revision
}
#[must_use]
pub const fn last_change_generation(self) -> GraphGeneration {
self.last_change_generation
}
}