use std::fmt::Debug; use anyhow::Error; use futures_util::{SinkExt, StreamExt}; use giterated_models::{ messages::{error::ConnectionError, MessageTarget}, model::{ authenticated::{Authenticated, AuthenticationSourceProvider}, instance::Instance, }, }; use serde::{de::DeserializeOwned, Serialize}; use tokio_tungstenite::tungstenite::Message; use crate::DaemonConnectionPool; pub fn request_local( request: T, ) -> PreparedRequest { PreparedRequest { request: Authenticated::new_empty(request), instance: None, } } pub fn request( instance: Instance, request: T, ) -> PreparedRequest { PreparedRequest { request: Authenticated::new_empty(request), instance: Some(instance), } } pub struct PreparedRequest { instance: Option, request: Authenticated, } impl PreparedRequest { pub fn authenticate(mut self, source: P) -> Self { self.request.append_authentication(source); self } pub async fn execute_expect( self, pool: &DaemonConnectionPool, ) -> Result { let mut socket = pool.0.get().await.unwrap(); let payload = serde_json::to_vec(&self.request.into_payload()).unwrap(); socket.send(Message::Binary(payload)).await?; while let Some(message) = socket.next().await { let payload = match message? { Message::Binary(payload) => payload, _ => { continue; } }; let as_target = serde_json::from_slice::(&payload).map_err(|e| Error::from(e)); if as_target.is_err() { // Maybe we got an error payload? if let Ok(error_payload) = serde_json::from_slice::(&payload) { return Err(error_payload.into()); } } else { // We did not get an error payload, forward the deserialization error from the // expected type return as_target; } } panic!() } }