gapirs-common 0.0.1

Common library for gapirs
Documentation
pub mod resumable;
pub use download::*;
pub use upload::*;
pub(crate) mod multipart {
    use super::{MediaUpload, MediaUploadStream};
    use serde::{Deserialize, Serialize};
    #[derive(Debug)]
    pub struct MultipartBody {
        pub(crate) boundary: String,
        pub json_body: String,
        pub media_body: MediaUpload<dyn MediaUploadStream>,
        pub(crate) state: MultipartState,
    }
    impl MultipartBody {
        pub fn new(
            media_body: MediaUpload<dyn MediaUploadStream>,
            body: impl Into<String>,
        ) -> Self {
            Self {
                boundary: "BOUNDARY".to_string(),
                json_body: body.into(),
                media_body,
                state: MultipartState::NotStarted,
            }
        }
    }

    #[derive(Debug, Clone)]
    pub(crate) enum MultipartState {
        NotStarted,
        Polling,
        Done,
    }
    impl MultipartBody {
        pub(crate) fn get_body_before_media(&self) -> String {
            let json_str = self.json_body.to_string();
            let media = &self.media_body;

            let body_string = format!(
                "--{}\r\n\
        Content-Type: application/json; charset=UTF-8\r\n\
        Content-Length: {}\r\n\
        \r\n\
        {}\r\n\
        \r\n\
        --{}\r\n\
        Content-Type: {}\r\n\
        Content-Length: {}\r\n\
        \r\n",
                self.boundary,
                json_str.len(),
                json_str,
                self.boundary,
                media.mime_type,
                media.length
            );
            body_string
        }
        pub(crate) fn get_body_after_media(&self) -> String {
            format!("\r\n--{}--\r\n", self.boundary,)
        }
    }
}
mod upload {
    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, Default)]
    pub enum MediaUploadProtocol {
        #[default]
        None,
        Simple,
        Resumable,
    }

    use crate::media::resumable::LimitedStream;
    use bytes::{Buf, Bytes};
    use core::fmt::Debug;
    use futures_core::Stream;
    use futures_util::lock::Mutex;
    use futures_util::{AsyncRead, AsyncSeek};
    use serde::{Deserialize, Serialize};
    use std::error::Error;
    use std::pin::Pin;
    #[derive(derive_more::Debug)]
    pub struct MediaUpload<T: MediaUploadStream + ?Sized> {
        pub(crate) mime_type: String,
        #[debug(skip)]
        pub(crate) body: Pin<Box<T>>,
        pub(crate) length: u64,
    }
    impl<T> MediaUpload<T>
    where
        T: MediaUploadStream + ?Sized,
    {
        pub fn new(mime_type: impl Into<String>, body: Pin<Box<T>>, length: u64) -> Self {
            Self {
                mime_type: mime_type.into(),
                body,
                length,
            }
        }
    }
    #[derive(derive_more::Debug)]
    pub struct AsyncMediaUpload<T: AsyncMediaUploadStream + ?Sized> {
        pub(crate) mime_type: String,
        #[debug(skip)]
        pub(crate) body: LimitedStream<T>,
        pub(crate) length: u64,
    }
    impl<T> AsyncMediaUpload<T>
    where
        T: AsyncMediaUploadStream + ?Sized,
    {
        pub fn new(mime_type: impl Into<String>, body: LimitedStream<T>, length: u64) -> Self {
            Self {
                mime_type: mime_type.into(),
                body,
                length,
            }
        }
    }
    pub trait MediaUploadStream:
        Stream<Item = Result<Bytes, Box<dyn Error + Send + Sync>>> + Send + Sync + 'static
    {
    }
    impl<T> MediaUploadStream for T where
        T: Stream<Item = Result<Bytes, Box<dyn Error + Send + Sync>>> + Send + Sync + 'static
    {
    }

    pub trait AsyncMediaUploadStream:
        AsyncRead + AsyncSeek + Debug + Send + Sync + 'static
    {
    }
    impl<T> AsyncMediaUploadStream for T where T: AsyncRead + Debug + AsyncSeek + Send + Sync + 'static {}
}
mod download {
    use core::fmt::Debug;
    use http_body_util::BodyDataStream;
    use hyper::body::Incoming;
    use hyper::HeaderMap;
    use std::io::Write;

    #[derive(Debug)]
    pub struct MediaDownload<T: MediaDownloadStream + ?Sized> {
        pub(crate) stream: Box<T>,
    }

    impl<T: MediaDownloadStream + ?Sized> MediaDownload<T> {
        pub(crate) fn get_range(&self) -> Option<String> {
            // todo!("somehow get some sort of range string")
            None
        }
    }

    impl<T: MediaDownloadStream + ?Sized> MediaDownload<T> {
        pub fn new(stream: Box<T>) -> Self {
            Self { stream }
        }
    }

    pub trait MediaDownloadStream: Write + Debug + Send + Sync {}
    impl<T> MediaDownloadStream for T where T: Write + Debug + Send + Sync {}

    pub struct MediaDownloadResponseStream {
        pub stream: BodyDataStream<Incoming>,
        pub headers: HeaderMap,
    }
}