use crate::symbols::Symbol; use async_trait::async_trait; use std::error::Error; use std::fs::File as FsFile; use std::io::{Read, Write}; use std::path::Path; #[derive(Debug)] pub struct File { path: D, content: C, } impl File { pub const fn new(path: D, content: C) -> Self { Self { path, content } } } #[async_trait(?Send)] impl, C: AsRef> Symbol for File { async fn target_reached(&self) -> Result> { if !self.path.as_ref().exists() { return Ok(false); } let file = FsFile::open(self.path.as_ref())?; // Check if content is the same let mut file_content = file.bytes(); let mut target_content = self.content.as_ref().bytes(); loop { match (file_content.next(), target_content.next()) { (None, None) => return Ok(true), (Some(Ok(a)), Some(b)) if a == b => {} (Some(Err(e)), _) => return Err(Box::new(e)), (_, _) => return Ok(false), } } } async fn execute(&self) -> Result<(), Box> { let mut file = FsFile::create(self.path.as_ref())?; file.write_all(self.content.as_ref().as_bytes())?; Ok(()) } }