remozipsy 0.2.0

Remote Zip Sync - sync remote zip to local fs
Documentation
use core::{fmt::Debug, future::Future};
use futures_lite::stream::Stream;
use std::ops::RangeInclusive;

use bytes::Bytes;

use crate::model::{FileInfo, RemoteFileInfo};

mod local_directory;
mod remote_file_info;
mod sync;

pub use local_directory::calculate_local_unix_path;
pub use remote_file_info::{RemoteFetchError, fetch_remote_file_info};
pub use sync::Statemachine;

// TODO: evaluate removing Clone here, so we can advantage of `mut` in
// evaluate phase

/// This trait is used to access the local file system.
/// You can implement it according to your needs or use
/// the [`crate::tokio::TokioLocalStorage`] struct.
/// Note: try to avoid parallel modifications to the Filesystem during
/// execution time of the statemachine.
pub trait FileSystem {
    type Error: Debug + Send;
    type StorePrepare: Send;

    /// Returns all files existing locally and thus might already be in sync, or
    /// out-of-sync with the remote files.
    fn all_files(&mut self) -> impl Future<Output = Result<Vec<FileInfo>, Self::Error>> + Send;

    /// This function is always called before any data is actually stored. You
    /// can assume it to be called exactly once per storage, UNLESS an error
    /// occurs in the meantime. It's useful for opening a file in the
    /// meantime, or for doing some checks early.
    fn prepare_store_file(
        &self,
        info: FileInfo,
    ) -> impl Future<Output = Result<Self::StorePrepare, Self::Error>> + Send;

    /// Write a file to the FileSystem.
    fn store_file(
        &self,
        prepared: Self::StorePrepare,
        data: Bytes,
    ) -> impl Future<Output = Result<(), Self::Error>> + Send;

    /// Remove a file from the FileSystem.
    fn delete_file(&self, info: FileInfo) -> impl Future<Output = Result<(), Self::Error>> + Send;
}

/// This trait is used to access the remote zip file.
/// You can implement it according to your needs or use
/// the [`crate::reqwest::ReqwestRemoteZip`] struct.
/// Note: the zip MUST NOT change during execution time of the statemachine.
pub trait RemoteZip {
    type Error: Debug + Send;

    fn fetch_remote_file_info(&self) -> impl Future<Output = Result<Vec<RemoteFileInfo>, Self::Error>> + Send;
    fn fetch_bytes_stream(
        &self,
        range: RangeInclusive<usize>,
    ) -> impl Future<Output = Result<impl Stream<Item = Result<Bytes, Self::Error>> + Send, Self::Error>> + Send;
}