use crate::symbols::Symbol; use async_trait::async_trait; use std::error::Error; use std::fs::{metadata, File}; use std::io::copy; use std::marker::PhantomData; use std::path::Path; #[derive(Debug)] pub struct Concat { target: D, sources: S, source_item: PhantomData, } impl Concat { pub fn new(sources: S, target: D) -> Self { Self { target, sources, source_item: PhantomData::default(), } } } #[async_trait(?Send)] impl, D: AsRef, I: AsRef> Symbol for Concat { async fn target_reached(&self) -> Result> { let target = self.target.as_ref(); if !target.exists() { return Ok(false); } let target_date = metadata(target)?.modified()?; for source in self.sources.as_ref() { if metadata(source)?.modified()? > target_date { return Ok(false); } } Ok(true) } async fn execute(&self) -> Result<(), Box> { let mut file = File::create(self.target.as_ref())?; for source in self.sources.as_ref() { copy(&mut File::open(source)?, &mut file)?; } Ok(()) } }