use rustolio_utils::{
bytes::encoding::{decode_from_bytes, encode_to_bytes},
http::{self, Outgoing, StatusCode},
prelude::*,
};
use crate::ServerFnError;
pub async fn fetch_rpc_call<T, R, E>(
uri: &'static str,
msg: T,
before_fetch: fn(http::request::Builder<Outgoing>) -> http::request::Builder<Outgoing>,
) -> Result<R, ServerFnError<E>>
where
T: Encode,
R: Decode,
E: Decode,
{
let body =
encode_to_bytes(&msg).map_err(|e| ServerFnError::SerializationError(e.to_string()))?;
let req = http::Request::post(uri).bytes(&body);
let req = before_fetch(req);
let res = req
.fetch()
.await
.map_err(|e| ServerFnError::NetworkError(e.to_string()))?;
if !res.is_success() {
let status = res.status();
let text = res
.text()
.await
.map_err(|e| ServerFnError::DeserializationError(e.to_string()))?
.into_body();
return Err(ServerFnError::HttpError(status, text));
}
let body = res
.bytes()
.await
.map_err(|e| ServerFnError::NetworkError(e.to_string()))?
.into_body();
decode_from_bytes::<Result<_, _>>(body)
.map_err(|e| ServerFnError::DeserializationError(e.to_string()))
.flatten()
}