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