guilded_http 0.1.0-dev.13

Guilded API HTTP Client for the Guilded-rs ecosystem of crates.
Documentation
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::task::{Context, Poll};

use guilded_model::id::{marker::ServerMarker, Id};
use hyper::body::{self, Bytes};
use hyper::{Body, Response as HyperResponse};

use crate::response::error::{DeserializationError, DeserializationErrorType};

pub mod error;
pub mod future;

pub struct Response<T> {
    server_id: Option<Id<ServerMarker>>,
    inner: HyperResponse<Body>,
    phantom: PhantomData<T>,
}

impl<T> Response<T> {
    pub(crate) const fn new(inner: HyperResponse<Body>) -> Self {
        Self {
            server_id: None,
            inner,
            phantom: PhantomData,
        }
    }

    pub fn bytes(self) -> BytesFuture {
        let body = self.inner.into_body();

        let future = async move {
            body::to_bytes(body)
                .await
                .map_err(|source| DeserializationError {
                    source: Some(Box::new(source)),
                    r#type: DeserializationErrorType::Chunking,
                })
        };

        BytesFuture {
            future: Box::pin(future),
        }
    }
}

pub struct BytesFuture {
    future:
        Pin<Box<dyn Future<Output = Result<Bytes, DeserializationError>> + Send + Sync + 'static>>,
}

impl Future for BytesFuture {
    type Output = Result<Vec<u8>, DeserializationError>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        if let Poll::Ready(result) = Pin::new(&mut self.future).poll(cx) {
            Poll::Ready(result.map(|b| b.into_iter().collect()))
        } else {
            Poll::Pending
        }
    }
}