1use corium_core::{AttrId, EntityId, IndexOrder, Keyword, Value};
4use corium_db::{Db, key_prefix};
5
6#[derive(Clone, Copy, Debug)]
9pub struct Entity<'a> {
10 db: &'a Db,
11 id: EntityId,
12}
13
14impl<'a> Entity<'a> {
15 #[must_use]
17 pub const fn new(db: &'a Db, id: EntityId) -> Self {
18 Self { db, id }
19 }
20
21 #[must_use]
23 pub const fn id(&self) -> EntityId {
24 self.id
25 }
26
27 #[must_use]
29 pub const fn db(&self) -> &'a Db {
30 self.db
31 }
32
33 #[must_use]
35 pub fn get(&self, attr: AttrId) -> Vec<Value> {
36 self.db.values(self.id, attr)
37 }
38
39 #[must_use]
41 pub fn get_kw(&self, keyword: &Keyword) -> Vec<Value> {
42 self.db
43 .idents()
44 .entid(keyword)
45 .map(|attr| self.get(attr))
46 .unwrap_or_default()
47 }
48
49 #[must_use]
51 pub fn keys(&self) -> Vec<AttrId> {
52 let prefix = key_prefix(IndexOrder::Eavt, Some(self.id), None, None);
53 let mut attrs: Vec<AttrId> = self
54 .db
55 .datoms_prefix(IndexOrder::Eavt, &prefix)
56 .map(|datom| datom.a)
57 .collect();
58 attrs.dedup();
59 attrs
60 }
61
62 #[must_use]
64 pub fn refs(&self, attr: AttrId) -> Vec<Entity<'a>> {
65 self.get(attr)
66 .into_iter()
67 .filter_map(|value| match value {
68 Value::Ref(child) => Some(Entity::new(self.db, child)),
69 _ => None,
70 })
71 .collect()
72 }
73
74 #[must_use]
76 pub fn reverse(&self, attr: AttrId) -> Vec<Entity<'a>> {
77 let value = Value::Ref(self.id);
78 let prefix = key_prefix(IndexOrder::Vaet, None, Some(attr), Some(&value));
79 self.db
80 .datoms_prefix(IndexOrder::Vaet, &prefix)
81 .map(|datom| Entity::new(self.db, datom.e))
82 .collect()
83 }
84}