tc_state/object/public/
mod.rs1use tc_transact::public::generic::COPY;
2use tc_transact::public::helpers::AttributeHandler;
3use tc_transact::public::{GetHandler, Handler, PostHandler, Route};
4use tc_transact::{Gateway, Transaction};
5use tcgeneric::PathSegment;
6
7use crate::object::{InstanceClass, InstanceExt, Object, ObjectType};
8use crate::{CacheBlock, State};
9
10mod instance;
11pub mod method;
12
13impl<Txn> Route<State<Txn>> for ObjectType {
14 fn route<'a>(
15 &'a self,
16 _path: &'a [PathSegment],
17 ) -> Option<Box<dyn Handler<'a, State<Txn>> + 'a>> {
18 None
19 }
20}
21
22struct ClassHandler<'a> {
23 class: &'a InstanceClass,
24}
25
26impl<'a, Txn> Handler<'a, State<Txn>> for ClassHandler<'a>
27where
28 Txn: Transaction<CacheBlock> + Gateway<State<Txn>>,
29{
30 fn get<'b>(self: Box<Self>) -> Option<GetHandler<'a, 'b, Txn, State<Txn>>>
31 where
32 'b: 'a,
33 {
34 Some(Box::new(|_txn, key| {
35 Box::pin(async move {
36 let parent = State::from(key);
37 let instance = InstanceExt::new(parent, self.class.clone());
38 Ok(State::Object(instance.into()))
39 })
40 }))
41 }
42
43 fn post<'b>(self: Box<Self>) -> Option<PostHandler<'a, 'b, Txn, State<Txn>>>
44 where
45 'b: 'a,
46 {
47 Some(Box::new(|_txn, members| {
48 Box::pin(async move {
49 let instance =
50 InstanceExt::anonymous(State::default(), self.class.clone(), members);
51
52 Ok(State::Object(instance.into()))
53 })
54 }))
55 }
56}
57
58impl<Txn> Route<State<Txn>> for InstanceClass
59where
60 Txn: Transaction<CacheBlock> + Gateway<State<Txn>>,
61{
62 fn route<'a>(
63 &'a self,
64 path: &'a [PathSegment],
65 ) -> Option<Box<dyn Handler<'a, State<Txn>> + 'a>> {
66 if path == ©[..] {
67 return Some(Box::new(AttributeHandler::from(Object::Class(
68 self.clone(),
69 ))));
70 }
71
72 if path.is_empty() {
73 Some(Box::new(ClassHandler { class: self }))
74 } else if let Some(attribute) = self.proto().get(&path[0]) {
75 attribute.route(&path[1..])
76 } else {
77 None
78 }
79 }
80}
81
82impl<Txn> Route<State<Txn>> for Object<Txn>
83where
84 Txn: Transaction<CacheBlock> + Gateway<State<Txn>>,
85{
86 fn route<'a>(
87 &'a self,
88 path: &'a [PathSegment],
89 ) -> Option<Box<dyn Handler<'a, State<Txn>> + 'a>> {
90 match self {
91 Self::Class(class) => class.route(path),
92 Self::Instance(instance) => instance.route(path),
93 }
94 }
95}