use std::collections::BTreeMap;
use crate::{
ElementId, LabelId, PropertyKeyId, PropertyValue, RelationId, RelationTypeId,
error::DbError,
typed::{Key, Readable, ValueType},
};
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Properties {
values: BTreeMap<PropertyKeyId, PropertyValue>,
}
impl Properties {
pub(crate) fn from_pairs(
pairs: impl IntoIterator<Item = (PropertyKeyId, PropertyValue)>,
) -> Self {
Self {
values: pairs.into_iter().collect(),
}
}
#[must_use]
pub fn get<T: ValueType, V: Readable<T>>(&self, key: Key<T>) -> Option<V> {
self.values.get(&key.id()).and_then(V::read)
}
pub fn require<T: ValueType, V: Readable<T>>(&self, key: Key<T>) -> Result<V, DbError> {
self.get(key)
.ok_or_else(|| DbError::MissingProperty { key: key.id() })
}
#[must_use]
pub fn value(&self, key: PropertyKeyId) -> Option<&PropertyValue> {
self.values.get(&key)
}
#[must_use]
pub fn len(&self) -> usize {
self.values.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = (PropertyKeyId, &PropertyValue)> {
self.values.iter().map(|(key, value)| (*key, value))
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Element {
pub id: ElementId,
pub labels: Vec<LabelId>,
properties: Properties,
}
impl Element {
pub(crate) const fn new(id: ElementId, labels: Vec<LabelId>, properties: Properties) -> Self {
Self {
id,
labels,
properties,
}
}
#[must_use]
pub fn has(&self, label: LabelId) -> bool {
self.labels.binary_search(&label).is_ok()
}
#[must_use]
pub const fn properties(&self) -> &Properties {
&self.properties
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Relation {
pub id: RelationId,
pub relation_type: Option<RelationTypeId>,
pub labels: Vec<LabelId>,
properties: Properties,
}
impl Relation {
pub(crate) const fn new(
id: RelationId,
relation_type: Option<RelationTypeId>,
labels: Vec<LabelId>,
properties: Properties,
) -> Self {
Self {
id,
relation_type,
labels,
properties,
}
}
#[must_use]
pub fn has(&self, label: LabelId) -> bool {
self.labels.binary_search(&label).is_ok()
}
#[must_use]
pub const fn properties(&self) -> &Properties {
&self.properties
}
}