flutter_rust_bridge_codegen 2.12.0

Flutter/Dart <-> Rust binding generator, feature-rich, but seamless and simple
Documentation
use std::fs;
use std::path::{Path, PathBuf};

pub(crate) fn temp_change_file(
    path: PathBuf,
    modifier: impl FnOnce(Option<String>) -> String,
) -> anyhow::Result<TempChangeFile> {
    let content_original = if path.exists() {
        Some(fs::read_to_string(&path)?)
    } else {
        None
    };

    let ans = TempChangeFile {
        path: path.clone(),
        content_original: content_original.clone(),
    };
    fs::write(&path, modifier(content_original))?;
    Ok(ans)
}

pub(crate) struct TempChangeFile {
    path: PathBuf,
    content_original: Option<String>,
}

impl Drop for TempChangeFile {
    fn drop(&mut self) {
        if let Some(content_original) = &self.content_original {
            fs::write(&self.path, content_original)
        } else {
            fs::remove_file(&self.path)
        }
        .unwrap()
    }
}

pub fn create_dir_all_and_write<P: AsRef<Path>, C: AsRef<[u8]>>(
    path: P,
    contents: C,
) -> anyhow::Result<()> {
    fn inner(path: &Path, contents: &[u8]) -> anyhow::Result<()> {
        if let Some(dir) = path.parent() {
            fs::create_dir_all(dir)?;
        }
        Ok(fs::write(path, contents)?)
    }
    inner(path.as_ref(), contents.as_ref())
}

#[cfg(test)]
mod tests {
    use crate::utils::file_utils::temp_change_file;
    use std::fs;

    #[test]
    fn test_temp_change_file_when_file_already_exists() -> anyhow::Result<()> {
        let dir = tempfile::tempdir()?;
        let path = dir.path().join("hello.txt");

        fs::write(&path, "a")?;

        assert_eq!(fs::read_to_string(&path)?, "a");

        let change = temp_change_file(path.to_owned(), |text| {
            assert_eq!(text, Some("a".to_owned()));
            text.unwrap_or_default() + "b"
        })?;

        assert_eq!(fs::read_to_string(&path)?, "ab");

        drop(change);

        assert_eq!(fs::read_to_string(&path)?, "a");

        drop(dir);
        Ok(())
    }

    #[test]
    fn test_temp_change_file_when_file_not_exist() -> anyhow::Result<()> {
        let dir = tempfile::tempdir()?;
        let path = dir.path().join("hello.txt");

        assert!(!path.exists());

        let change = temp_change_file(path.to_owned(), |text| {
            assert_eq!(text, None);
            text.unwrap_or_default() + "b"
        })?;

        assert_eq!(fs::read_to_string(&path)?, "b");

        drop(change);

        assert!(!path.exists());

        drop(dir);
        Ok(())
    }
}