atomic-ops 0.1.1

Performs atomic operations in the filesystem
Documentation
use std::{
    path::{Path, PathBuf},
    sync::Arc,
};

use serde::{Deserialize, Serialize};
use serde_flow::encoder::{bincode, FlowEncoder};

use crate::{
    error::{OpsError, OpsResult},
    operation::LoaderFn,
    process::{constants::DELETE_FILE_ID, Process},
};

#[derive(Serialize, Deserialize, Default)]
pub struct Op {
    from: PathBuf,

    #[serde(skip)]
    bytes: Vec<u8>,
}

impl Op {
    #[must_use]
    pub fn new(from: &Path) -> Self {
        let mut object = Self {
            from: from.to_path_buf(),
            bytes: Vec::new(),
        };
        object.bytes = bincode::Encoder::serialize(&object).unwrap();
        object
    }

    pub fn from_bytes(bytes: &[u8]) -> OpsResult<Self> {
        let mut decoded: Op =
            bincode::Encoder::deserialize(bytes).map_err(|_| OpsError::SerializeFailed)?;
        decoded.bytes = bytes.to_vec();
        Ok(decoded)
    }
}

pub fn load(bytes: &[u8]) -> OpsResult<Box<dyn Process>> {
    let value = Op::from_bytes(bytes)?;
    Ok(Box::new(value))
}

pub fn loader() -> (u8, LoaderFn) {
    (DELETE_FILE_ID, Arc::new(load))
}

impl Process for Op {
    #[inline]
    fn prepare(&self) -> OpsResult<()> {
        Ok(())
    }

    #[inline]
    fn run(&self) -> OpsResult<()> {
        Ok(())
    }

    #[inline]
    fn clean(&self) -> OpsResult<()> {
        std::fs::remove_file(self.from.as_path())?;
        Ok(())
    }

    #[inline]
    fn revert_prepare(&self) -> OpsResult<()> {
        Ok(())
    }

    #[inline]
    fn revert_run(&self) -> OpsResult<()> {
        Ok(())
    }

    fn id() -> u8 {
        DELETE_FILE_ID
    }

    fn as_bytes(&self) -> &[u8] {
        &self.bytes
    }
}

#[cfg(test)]
pub mod tests {

    #[test]
    fn remove_file() {}
}