ocilot 0.1.0

cli and library for interacting with OCI registries
Documentation
use std::pin::Pin;

use async_compression::tokio::bufread::{
    BzDecoder, GzipDecoder, LzmaDecoder, XzDecoder, ZstdDecoder,
};
use tokio::io::AsyncRead;
use tokio::io::BufReader;

use crate::{
    layer::Reader,
    models::{Compression, MediaType},
};

pub struct Decompress {
    inner: Pin<Box<dyn AsyncRead>>,
}

unsafe impl Send for Decompress {}
unsafe impl Sync for Decompress {}

impl Decompress {
    pub fn new(media: &MediaType, reader: Reader) -> Self {
        Self {
            inner: match media {
                MediaType::DockerImageRootfs(compression) => match compression {
                    Compression::Gzip | Compression::None => {
                        Box::pin(GzipDecoder::new(BufReader::new(reader)))
                    }
                    Compression::Bzip2 => Box::pin(BzDecoder::new(BufReader::new(reader))),
                    Compression::Lz4 => Box::pin(LzmaDecoder::new(BufReader::new(reader))),
                    Compression::Xz => Box::pin(XzDecoder::new(BufReader::new(reader))),
                    Compression::Zstd => Box::pin(ZstdDecoder::new(BufReader::new(reader))),
                },
                MediaType::Layer(compression) => match compression {
                    Compression::Gzip => Box::pin(GzipDecoder::new(BufReader::new(reader))),
                    Compression::Bzip2 => Box::pin(BzDecoder::new(BufReader::new(reader))),
                    Compression::Lz4 => Box::pin(LzmaDecoder::new(BufReader::new(reader))),
                    Compression::Xz => Box::pin(XzDecoder::new(BufReader::new(reader))),
                    Compression::Zstd => Box::pin(ZstdDecoder::new(BufReader::new(reader))),
                    Compression::None => Box::pin(BufReader::new(reader)),
                },
                _ => Box::pin(BufReader::new(reader)),
            },
        }
    }
}

impl AsyncRead for Decompress {
    fn poll_read(
        self: Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
        buf: &mut tokio::io::ReadBuf<'_>,
    ) -> std::task::Poll<std::io::Result<()>> {
        let this = self.get_mut();
        this.inner.as_mut().poll_read(cx, buf)
    }
}