use std::{io::Error as IoError, path::PathBuf, pin::Pin}; use bytes::Bytes; use futures::{Stream, stream::BoxStream}; use crate::{ address::Addressable, storage_fs::FileSystem, }; #[derive(thiserror::Error, Debug)] pub enum Error { #[error("Unspecified Storage Error")] Unspecified, #[error("Storage IO: {0}")] Io(#[from] IoError), #[error("Object Not Found")] NotFound, } pub struct InnerStream { stream: BoxStream<'static, Result>, } impl InnerStream { pub fn new(stream: BoxStream<'static, Result>) -> Self { InnerStream { stream } } } impl Stream for InnerStream { type Item = Result; fn poll_next( self: Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { Pin::new(&mut self.get_mut().stream).poll_next(cx) } } /// The storage trait needs to be implemented for accessing objects from the /// platform. This API is based on registry/storage/driver/storagedriver.go in /// the distribution codebase. pub trait StorageIface: Sync + Send { /// List a single directory of objects // async fn list(&self, addr: &Address) -> Result, Error>; // async fn stat(&self, addr: &Address) -> Result, Error>; // async fn read_bytes(&self, addr: &Address) -> Result>, Error>; /// Check if an object exists at the given address fn exists(&self, path: &A) -> impl Future> + Send where A: Addressable + Send + Sync; /// Write bytes to the address, truncating any existing object fn write_all( &self, path: &A, bytes: &[u8], ) -> impl Future> + Send where A: Addressable + Send + Sync; /// write bytes to a file that has already been created fn write(&self, path: &A, bytes: &[u8]) -> impl Future> + Send where A: Addressable + Send + Sync; fn mv(&self, src: &A, dst: &B) -> impl Future> + Send where A: Addressable + Send + Sync, B: Addressable + Send + Sync; // fn mv (&self, )std::future::Future + Send fn read(&self, src: &A) -> impl Future> + Send where A: Addressable + Send + Sync; fn read_bytes(&self, src: &A) -> impl Future> + Send where A: Addressable + Send + Sync; fn delete(&self, src: &A) -> impl Future> + Send where A: Addressable + Send + Sync; } #[derive(Debug, Clone)] pub enum Storage { FileSystem { base: PathBuf }, } impl Storage { pub fn init(&self) -> Result<(), Error> { match self { Storage::FileSystem { base } => FileSystem { base: base.clone() }.init(), } } pub fn inner(&self) -> impl StorageIface { match self { Storage::FileSystem { base } => FileSystem { base: base.clone() }, } } }