use corium_core::{AttrId, EntityId, IndexOrder, Keyword, Value};
use corium_db::{Db, key_prefix};
#[derive(Clone, Copy, Debug)]
pub struct Entity<'a> {
db: &'a Db,
id: EntityId,
}
impl<'a> Entity<'a> {
#[must_use]
pub const fn new(db: &'a Db, id: EntityId) -> Self {
Self { db, id }
}
#[must_use]
pub const fn id(&self) -> EntityId {
self.id
}
#[must_use]
pub const fn db(&self) -> &'a Db {
self.db
}
#[must_use]
pub fn get(&self, attr: AttrId) -> Vec<Value> {
self.db.values(self.id, attr)
}
#[must_use]
pub fn get_kw(&self, keyword: &Keyword) -> Vec<Value> {
self.db
.idents()
.entid(keyword)
.map(|attr| self.get(attr))
.unwrap_or_default()
}
#[must_use]
pub fn keys(&self) -> Vec<AttrId> {
let prefix = key_prefix(IndexOrder::Eavt, Some(self.id), None, None);
let mut attrs: Vec<AttrId> = self
.db
.datoms_prefix(IndexOrder::Eavt, &prefix)
.map(|datom| datom.a)
.collect();
attrs.dedup();
attrs
}
#[must_use]
pub fn refs(&self, attr: AttrId) -> Vec<Entity<'a>> {
self.get(attr)
.into_iter()
.filter_map(|value| match value {
Value::Ref(child) => Some(Entity::new(self.db, child)),
_ => None,
})
.collect()
}
#[must_use]
pub fn reverse(&self, attr: AttrId) -> Vec<Entity<'a>> {
let value = Value::Ref(self.id);
let prefix = key_prefix(IndexOrder::Vaet, None, Some(attr), Some(&value));
self.db
.datoms_prefix(IndexOrder::Vaet, &prefix)
.map(|datom| Entity::new(self.db, datom.e))
.collect()
}
}