tc_state/object/public/
mod.rs

1use 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 == &COPY[..] {
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}