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 == ©[..] {
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}