exocore_store/
entity.rs

1use exocore_protos::{
2    prost::Message,
3    store::{Entity, Trait},
4    NamedMessage,
5};
6
7pub type EntityId = String;
8pub type EntityIdRef<'s> = &'s str;
9pub type TraitId = String;
10pub type TraitIdRef<'s> = &'s str;
11
12pub struct TraitInstance<'e, M: NamedMessage + Message + Default> {
13    pub instance: M,
14    pub trt: &'e Trait,
15}
16
17pub trait EntityExt {
18    fn trait_with_id<M: NamedMessage + Message + Default>(
19        &self,
20        id: &str,
21    ) -> Option<TraitInstance<M>>;
22
23    fn traits_of_type<M: NamedMessage + Message + Default>(&self) -> Vec<TraitInstance<M>>;
24
25    fn trait_of_type<M: NamedMessage + Message + Default>(&self) -> Option<TraitInstance<M>>;
26}
27
28impl EntityExt for Entity {
29    fn trait_with_id<M: NamedMessage + Message + Default>(
30        &self,
31        id: &str,
32    ) -> Option<TraitInstance<M>> {
33        let msg_any_url = M::protobuf_any_url();
34
35        self.traits
36            .iter()
37            .filter(|t| t.id == id)
38            .flat_map(|t| {
39                let msg = t.message.as_ref()?;
40                if msg.type_url == msg_any_url {
41                    let instance = M::decode(msg.value.as_slice()).ok()?;
42                    Some(TraitInstance { instance, trt: t })
43                } else {
44                    None
45                }
46            })
47            .next()
48    }
49
50    fn traits_of_type<M: NamedMessage + Message + Default>(&self) -> Vec<TraitInstance<M>> {
51        let msg_any_url = M::protobuf_any_url();
52
53        self.traits
54            .iter()
55            .flat_map(|t| {
56                let msg = t.message.as_ref()?;
57                if msg.type_url == msg_any_url {
58                    let instance = M::decode(msg.value.as_slice()).ok()?;
59                    Some(TraitInstance { instance, trt: t })
60                } else {
61                    None
62                }
63            })
64            .collect()
65    }
66
67    fn trait_of_type<M: NamedMessage + Message + Default>(&self) -> Option<TraitInstance<M>> {
68        let msg_any_url = M::protobuf_any_url();
69
70        self.traits
71            .iter()
72            .flat_map(|t| {
73                let msg = t.message.as_ref()?;
74                if msg.type_url == msg_any_url {
75                    let instance = M::decode(msg.value.as_slice()).ok()?;
76                    Some(TraitInstance { instance, trt: t })
77                } else {
78                    None
79                }
80            })
81            .next()
82    }
83}