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

ambee/giterated

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

Progress on refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨c9f076f

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