use std::marker::PhantomData; use anyhow::Context; use arrpc::core::{ClientContract, MakeClient, Result, Service, ServiceContract, UniversalClient}; use async_trait::async_trait; use serde::{de::DeserializeOwned, Serialize}; use serde_json::Value; pub struct Request { input: Value, } impl arrpc::core::Request for Request { type Response = Response; fn proc(&self) -> Result

{ serde_json::from_value(self.input.to_owned()).context("deserializing proc") } fn respond(self, value: V) -> Result { Ok(Response( serde_json::to_value(value).context("serializing response")?, )) } } pub struct Response(Value); #[derive(Default)] pub struct LocalContract(PhantomData); #[async_trait] impl ServiceContract for LocalContract where S: Service + Send + Sync, { type R = Request; async fn eval(&self, _: &Self::R) -> Result<()> { Ok(()) } } #[async_trait] impl MakeClient for LocalContract where S: Service + Send + Sync, { type Args = LocalService; type Client = LocalContractClient; fn make_client(args: A) -> UniversalClient where Self::Args: From, { let local_svc: LocalService = args.into(); UniversalClient(LocalContractClient(local_svc.0)) } } pub struct LocalContractClient(S); #[async_trait] impl ClientContract for LocalContractClient where S: Service + Send + Sync, { async fn send(&self, req: R) -> Result where R: Serialize + Send + Sync, V: DeserializeOwned + Send + Sync, { let request = Request { input: serde_json::to_value(req).context("serializing request to Value")?, }; let response = self.0.accept(request).await?; serde_json::from_value(response.0).context("deserializing from value") } } pub struct LocalService(S); impl From for LocalService { fn from(value: S) -> Self { LocalService(value) } }