tc_scalar/
public.rs

1use std::ops::Bound;
2
3use safecast::TryCastFrom;
4
5use tc_error::*;
6use tc_transact::public::generic::COPY;
7use tc_transact::public::helpers::{AttributeHandler, EchoHandler};
8use tc_transact::public::value;
9use tc_transact::public::{
10    ClosureInstance, DeleteHandler, GetHandler, Handler, PostHandler, PutHandler, Route,
11    StateInstance,
12};
13use tc_transact::Gateway;
14use tc_value::{Number, TCString, Value};
15use tcgeneric::{Id, Map, PathSegment, TCPathBuf, Tuple};
16
17use crate::{ClusterRef, Refer, Scalar, ScalarType};
18
19impl<State> Route<State> for ScalarType
20where
21    State: StateInstance,
22{
23    fn route<'a>(&'a self, _path: &'a [PathSegment]) -> Option<Box<dyn Handler<'a, State> + 'a>> {
24        None
25    }
26}
27
28struct ClusterHandler {
29    path: TCPathBuf,
30}
31
32impl ClusterHandler {
33    fn new(cluster: &ClusterRef, path: &[PathSegment]) -> Self {
34        let mut cluster_path = cluster.path().clone();
35        cluster_path.extend(path.into_iter().cloned());
36        Self { path: cluster_path }
37    }
38}
39
40impl<'a, State> Handler<'a, State> for ClusterHandler
41where
42    State: StateInstance,
43{
44    fn get<'b>(self: Box<Self>) -> Option<GetHandler<'a, 'b, State::Txn, State>>
45    where
46        'b: 'a,
47    {
48        Some(Box::new(|txn, key| Box::pin(txn.get(self.path, key))))
49    }
50
51    fn put<'b>(self: Box<Self>) -> Option<PutHandler<'a, 'b, State::Txn, State>>
52    where
53        'b: 'a,
54    {
55        Some(Box::new(|txn, key, value| {
56            Box::pin(txn.put(self.path, key, value))
57        }))
58    }
59
60    fn post<'b>(self: Box<Self>) -> Option<PostHandler<'a, 'b, State::Txn, State>>
61    where
62        'b: 'a,
63    {
64        Some(Box::new(|txn, params| {
65            Box::pin(txn.post(self.path, params))
66        }))
67    }
68
69    fn delete<'b>(self: Box<Self>) -> Option<DeleteHandler<'a, 'b, State::Txn>>
70    where
71        'b: 'a,
72    {
73        Some(Box::new(|txn, key| Box::pin(txn.delete(self.path, key))))
74    }
75}
76
77impl<State> Route<State> for ClusterRef
78where
79    State: StateInstance,
80{
81    fn route<'a>(&'a self, path: &'a [PathSegment]) -> Option<Box<dyn Handler<'a, State> + 'a>> {
82        Some(Box::new(ClusterHandler::new(self, path)))
83    }
84}
85
86impl<State> Route<State> for Scalar
87where
88    State: StateInstance
89        + Refer<State>
90        + From<Scalar>
91        + From<Tuple<Scalar>>
92        + From<Map<Scalar>>
93        + From<Value>
94        + From<Tuple<Value>>
95        + From<Number>,
96    Box<dyn ClosureInstance<State>>: TryCastFrom<State>,
97    Id: TryCastFrom<State>,
98    Map<State>: TryFrom<State, Error = TCError> + TryCastFrom<State>,
99    Number: TryCastFrom<State>,
100    TCString: TryCastFrom<State>,
101    Tuple<State>: TryCastFrom<State>,
102    Value: TryCastFrom<State>,
103{
104    fn route<'a>(&'a self, path: &'a [PathSegment]) -> Option<Box<dyn Handler<'a, State> + 'a>> {
105        if path == &COPY[..] {
106            return Some(Box::new(AttributeHandler::from(self.clone())));
107        }
108
109        match self {
110            Self::Cluster(cluster) => cluster.route(path),
111            Self::Map(map) => map.route(path),
112            Self::Op(op_def) if path.is_empty() => Some(Box::new(op_def.clone())),
113            Self::Range((start, end)) => {
114                if path.is_empty() {
115                    None
116                } else {
117                    match path[0].as_str() {
118                        "start" => match start {
119                            Bound::Included(value) => value.route(&path[1..]),
120                            Bound::Excluded(value) => value.route(&path[1..]),
121                            Bound::Unbounded => Value::None.route(&path[1..]),
122                        },
123                        "end" => match end {
124                            Bound::Included(value) => value.route(&path[1..]),
125                            Bound::Excluded(value) => value.route(&path[1..]),
126                            Bound::Unbounded => Value::None.route(&path[1..]),
127                        },
128                        _ => None,
129                    }
130                }
131            }
132            Self::Ref(_) => None,
133            Self::Value(value) => value.route(path),
134            Self::Tuple(tuple) => tuple.route(path),
135            _ => None,
136        }
137    }
138}
139
140pub struct Static;
141
142impl<State> Route<State> for Static
143where
144    State: StateInstance,
145{
146    fn route<'a>(&'a self, path: &'a [PathSegment]) -> Option<Box<dyn Handler<'a, State> + 'a>> {
147        if path.is_empty() {
148            Some(Box::new(EchoHandler))
149        } else if path[0] == value::PREFIX {
150            value::Static.route(&path[1..])
151        } else {
152            None
153        }
154    }
155}