JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Base protocol refactor complete

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨079d544

⁨giterated-models/src/operation/mod.rs⁩ - ⁨7879⁩ bytes
Raw
1 use std::{
2 any::type_name,
3 convert::Infallible,
4 fmt::{Debug, Display},
5 marker::PhantomData,
6 str::FromStr,
7 };
8
9 use anyhow::Error;
10 use serde::{de::DeserializeOwned, Deserialize, Serialize};
11 use serde_json::Value;
12
13 use crate::{
14 error::{GetValueError, OperationError},
15 model::{instance::Instance, settings::Setting, MessageTarget},
16 values::{GetSetting, GetSettingError, SetSetting, SetSettingError},
17 };
18
19 pub mod instance;
20 pub mod repository;
21 pub mod user;
22
23 pub trait GiteratedObject: Send + Display + FromStr {
24 fn object_name() -> &'static str;
25
26 fn from_object_str(object_str: &str) -> Result<Self, Error>;
27 }
28
29 pub trait GiteratedOperation<O: GiteratedObject>: Send + Serialize + DeserializeOwned {
30 type Success: Serialize + DeserializeOwned + Send;
31 type Failure: Serialize + DeserializeOwned + Send;
32
33 fn operation_name() -> &'static str {
34 type_name::<Self>()
35 }
36 }
37
38 pub trait GiteratedObjectValue: Serialize + DeserializeOwned {
39 type Object: GiteratedObject;
40
41 fn value_name() -> &'static str;
42 }
43
44 #[derive(Debug, Clone)]
45 pub struct Object<'b, O: GiteratedObject, B: ObjectBackend + 'b + Send + Sync + Clone> {
46 inner: O,
47 backend: B,
48 _marker: PhantomData<&'b ()>,
49 }
50
51 #[async_trait::async_trait]
52 pub trait ObjectBackend: Send + Sync + Sized + Clone {
53 async fn object_operation<O: GiteratedObject + Debug, D: GiteratedOperation<O> + Debug>(
54 &self,
55 object: O,
56 operation: D,
57 ) -> Result<D::Success, OperationError<D::Failure>>;
58
59 async fn get_object<O: GiteratedObject + Debug>(
60 &self,
61 object_str: &str,
62 ) -> Result<Object<O, Self>, OperationError<ObjectRequestError>>;
63 }
64
65 impl<'b, B: ObjectBackend + Send + Sync + Clone, O: GiteratedObject> Object<'b, O, B> {
66 pub unsafe fn new_unchecked(object: O, backend: B) -> Object<'b, O, B> {
67 Object {
68 inner: object,
69 backend,
70 _marker: PhantomData,
71 }
72 }
73 }
74
75 // impl<'b, O: GiteratedObject, B: ObjectBackend> Object<'b, O, B> {
76 // pub unsafe fn new_unchecked(value: O, backend: Arc<B>) -> Object<'b, O, B> {
77 // todo!()
78 // }
79 // }
80
81 impl<'b, O: GiteratedObject + Clone + Debug, B: ObjectBackend + Debug + Send + Sync + Clone>
82 Object<'b, O, B>
83 {
84 // pub async fn get<V: GiteratedObjectValue<Object = O> + Send>(
85 // &self,
86 // ) -> Result<V, OperationError<ObjectRequestError>> {
87 // let operation: GetValue<V> = GetValue {
88 // value_name: V::value_name().to_string(),
89 // _marker: PhantomData,
90 // };
91
92 // let _message: GiteratedMessage<O, _> = GiteratedMessage {
93 // object: self.inner.clone(),
94 // operation: operation.operation_name().to_string(),
95 // payload: operation,
96 // };
97
98 // todo!()
99 // }
100
101 // pub fn request<R: GiteratedOperation<O> + Debug>(
102 // &mut self,
103 // request: R,
104 // ) -> Result<R::Success, R::Failure> {
105 // self.backend.object_operation(self.inner.clone(), request);
106
107 // todo!()
108 // }
109 }
110
111 #[derive(Serialize, Deserialize, Debug, Clone)]
112 pub struct GetValue<V: GiteratedObjectValue> {
113 pub value_name: String,
114 _marker: PhantomData<V>,
115 }
116
117 impl<O: GiteratedObject + Send, V: GiteratedObjectValue<Object = O> + Send> GiteratedOperation<O>
118 for GetValue<V>
119 {
120 fn operation_name() -> &'static str {
121 "get_value"
122 }
123 type Success = V;
124 type Failure = GetValueError;
125 }
126
127 #[derive(Serialize)]
128 #[serde(bound(deserialize = "O: GiteratedObject, V: GiteratedOperation<O>"))]
129 pub struct GiteratedMessage<O: GiteratedObject, V: GiteratedOperation<O>> {
130 #[serde(with = "string")]
131 pub object: O,
132 pub operation: String,
133 pub payload: V,
134 }
135
136 mod string {
137 use std::fmt::Display;
138 use std::str::FromStr;
139
140 use serde::{de, Deserialize, Deserializer, Serializer};
141
142 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
143 where
144 T: Display,
145 S: Serializer,
146 {
147 serializer.collect_str(value)
148 }
149
150 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
151 where
152 T: FromStr,
153 T::Err: Display,
154 D: Deserializer<'de>,
155 {
156 String::deserialize(deserializer)?
157 .parse()
158 .map_err(de::Error::custom)
159 }
160 }
161
162 impl GiteratedMessage<AnyObject, AnyOperation> {
163 pub fn try_into<O: GiteratedObject, V: GiteratedOperation<O>>(
164 &self,
165 ) -> Result<GiteratedMessage<O, V>, ()> {
166 let object = O::from_object_str(&self.object.0).map_err(|_| ())?;
167 let payload = serde_json::from_value::<V>(self.payload.0.clone()).map_err(|_| ())?;
168
169 Ok(GiteratedMessage {
170 object,
171 operation: self.operation.clone(),
172 payload,
173 })
174 }
175 }
176
177 impl<O: GiteratedObject, V: GiteratedOperation<O>> MessageTarget for GiteratedMessage<O, V> {}
178
179 impl<V: GiteratedOperation<O> + Debug, O: GiteratedObject + Debug> Debug
180 for GiteratedMessage<O, V>
181 {
182 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
183 f.debug_struct("GiteratedMessage")
184 .field("object", &self.object)
185 .field("operation", &self.operation)
186 .field("payload", &self.payload)
187 .finish()
188 }
189 }
190
191 #[derive(Debug, Serialize, Deserialize)]
192 pub struct ObjectRequest(pub String);
193
194 #[derive(Serialize, Deserialize)]
195 pub struct ObjectResponse(pub Vec<u8>);
196
197 impl GiteratedOperation<Instance> for ObjectRequest {
198 type Success = ObjectResponse;
199
200 type Failure = ObjectRequestError;
201 }
202
203 #[derive(Debug, thiserror::Error, Serialize, Deserialize)]
204 pub enum ObjectRequestError {
205 #[error("error decoding the object")]
206 Deserialization(String),
207 }
208
209 #[derive(Clone, Debug, Serialize, Deserialize)]
210 #[repr(transparent)]
211 pub struct AnyObject(pub String);
212
213 impl GiteratedObject for AnyObject {
214 fn object_name() -> &'static str {
215 "any"
216 }
217
218 fn from_object_str(object_str: &str) -> Result<Self, Error> {
219 Ok(Self(object_str.to_string()))
220 }
221 }
222
223 impl Display for AnyObject {
224 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
225 f.write_str(&self.0)
226 }
227 }
228
229 impl FromStr for AnyObject {
230 type Err = Infallible;
231
232 fn from_str(s: &str) -> Result<Self, Self::Err> {
233 Ok(Self(s.to_owned()))
234 }
235 }
236
237 #[derive(Clone, Debug, Serialize, Deserialize)]
238 #[serde(transparent)]
239 #[repr(transparent)]
240 pub struct AnyOperation(pub Value);
241
242 impl<O: GiteratedObject> GiteratedOperation<O> for AnyOperation {
243 type Success = Vec<u8>;
244
245 type Failure = Vec<u8>;
246 }
247
248 impl<'b, O: GiteratedObject + Clone + Debug, B: ObjectBackend> Object<'b, O, B> {
249 pub async fn get<V: GiteratedObjectValue<Object = O> + Send + Debug>(
250 &mut self,
251 ) -> Result<V, OperationError<GetValueError>> {
252 self.request(GetValue {
253 value_name: V::value_name().to_string(),
254 _marker: PhantomData,
255 })
256 .await
257 }
258
259 pub async fn get_setting<S: Setting + Send + Clone + Debug>(
260 &mut self,
261 ) -> Result<S, OperationError<GetSettingError>> {
262 self.request(GetSetting {
263 setting_name: S::name().to_string(),
264 _marker: PhantomData,
265 })
266 .await
267 }
268
269 pub async fn set_setting<S: Setting + Send + Clone + Debug>(
270 &mut self,
271 setting: S,
272 ) -> Result<(), OperationError<SetSettingError>> {
273 self.request(SetSetting {
274 setting_name: S::name().to_string(),
275 value: setting,
276 })
277 .await
278 }
279
280 pub async fn request<R: GiteratedOperation<O> + Debug>(
281 &mut self,
282 request: R,
283 ) -> Result<R::Success, OperationError<R::Failure>> {
284 self.backend
285 .object_operation(self.inner.clone(), request)
286 .await
287 }
288 }
289