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

ambee/giterated-api

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

Update to new structure

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨b49b7cd

⁨src/request.rs⁩ - ⁨2389⁩ bytes
Raw
1 use anyhow::Error;
2 use futures_util::{SinkExt, StreamExt};
3 use giterated_models::{
4 messages::error::ConnectionError,
5 model::{
6 authenticated::{Authenticated, AuthenticationSourceProvider},
7 instance::Instance,
8 },
9 };
10 use serde::{de::DeserializeOwned, Serialize};
11 use tokio_tungstenite::tungstenite::Message;
12
13 use crate::DaemonConnectionPool;
14
15 pub fn request_local<'a, T: Serialize + DeserializeOwned>(
16 request: &'a T,
17 ) -> PreparedRequest<'a, T> {
18 PreparedRequest {
19 request: Authenticated::new_empty(request),
20 instance: None,
21 }
22 }
23
24 pub fn request<'a, T: Serialize + DeserializeOwned>(
25 instance: &'a Instance,
26 request: &'a T,
27 ) -> PreparedRequest<'a, T> {
28 PreparedRequest {
29 request: Authenticated::new_empty(request),
30 instance: Some(instance),
31 }
32 }
33
34 pub struct PreparedRequest<'a, T: Serialize + DeserializeOwned> {
35 instance: Option<&'a Instance>,
36 request: Authenticated<&'a T>,
37 }
38
39 impl<'a, T: Serialize + DeserializeOwned> PreparedRequest<'a, T> {
40 pub fn authenticate(
41 mut self,
42 source: &impl ToOwned<Owned = impl AuthenticationSourceProvider>,
43 ) -> Self {
44 self.request.append_authentication(source.to_owned());
45
46 self
47 }
48
49 pub async fn execute_expect<R: DeserializeOwned>(
50 self,
51 pool: &DaemonConnectionPool,
52 ) -> Result<R, Error> {
53 let mut socket = pool.0.get().await.unwrap();
54
55 let payload = serde_json::to_vec(&self.request).unwrap();
56
57 socket.send(Message::Binary(payload)).await?;
58
59 while let Some(message) = socket.next().await {
60 let payload = match message? {
61 Message::Binary(payload) => payload,
62 _ => {
63 continue;
64 }
65 };
66
67 let as_target = serde_json::from_slice::<R>(&payload).map_err(|e| Error::from(e));
68
69 if as_target.is_err() {
70 // Maybe we got an error payload?
71 if let Ok(error_payload) = serde_json::from_slice::<ConnectionError>(&payload) {
72 return Err(error_payload.into());
73 }
74 } else {
75 // We did not get an error payload, forward the deserialization error from the
76 // expected type
77 return as_target;
78 }
79 }
80
81 panic!()
82 }
83 }
84