use async_trait::async_trait;
use bytes::Bytes;
use conjure_error::Error;
use futures_core::Stream;
use http::{Request, Response};
use std::io::Write;
use std::pin::Pin;
pub trait Service<C> {
fn new(client: C) -> Self;
}
pub trait AsyncService<C> {
fn new(client: C) -> Self;
}
#[derive(Clone)]
pub struct Endpoint {
service: &'static str,
version: Option<&'static str>,
name: &'static str,
path: &'static str,
}
impl Endpoint {
#[inline]
pub fn new(
service: &'static str,
version: Option<&'static str>,
name: &'static str,
path: &'static str,
) -> Self {
Endpoint {
service,
version,
name,
path,
}
}
#[inline]
pub fn service(&self) -> &'static str {
self.service
}
#[inline]
pub fn version(&self) -> Option<&'static str> {
self.version
}
#[inline]
pub fn name(&self) -> &'static str {
self.name
}
#[inline]
pub fn path(&self) -> &'static str {
self.path
}
}
pub enum Body<'a, W> {
Empty,
Fixed(Bytes),
Streaming(&'a mut dyn WriteBody<W>),
}
pub enum AsyncBody<'a, W> {
Empty,
Fixed(Bytes),
Streaming(Pin<&'a mut (dyn AsyncWriteBody<W> + Send)>),
}
pub trait Client {
type BodyWriter;
type ResponseBody: Iterator<Item = Result<Bytes, Error>>;
fn send(
&self,
req: Request<Body<'_, Self::BodyWriter>>,
) -> Result<Response<Self::ResponseBody>, Error>;
}
#[async_trait]
pub trait AsyncClient {
type BodyWriter;
type ResponseBody: Stream<Item = Result<Bytes, Error>>;
async fn send(
&self,
req: Request<AsyncBody<'_, Self::BodyWriter>>,
) -> Result<Response<Self::ResponseBody>, Error>;
}
pub trait WriteBody<W> {
fn write_body(&mut self, w: &mut W) -> Result<(), Error>;
fn reset(&mut self) -> bool;
}
impl<W> WriteBody<W> for &[u8]
where
W: Write,
{
fn write_body(&mut self, w: &mut W) -> Result<(), Error> {
w.write_all(self).map_err(Error::internal_safe)
}
fn reset(&mut self) -> bool {
true
}
}
#[async_trait]
pub trait AsyncWriteBody<W> {
async fn write_body(self: Pin<&mut Self>, w: Pin<&mut W>) -> Result<(), Error>;
async fn reset(self: Pin<&mut Self>) -> bool
where
W: 'async_trait;
}