leyline-http 0.1.1

HTTP client that mimics browsers on the wire
Documentation
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Duration;

use crate::core::Result;
use crate::util::autosave::{Autosave, SaveJob, SaveTarget, Schedule};

use super::Jar;

pub struct JarAutosave {
    path: Arc<Path>,
    autosave: Autosave,
}

struct JarTarget {
    jar: Jar,
    path: Arc<Path>,
    saved: Option<u64>,
}

impl Jar {
    pub fn autosave(&self, path: impl Into<PathBuf>, interval: Duration) -> JarAutosave {
        let path: Arc<Path> = Arc::from(path.into());
        let target = JarTarget {
            jar: self.clone(),
            path: Arc::clone(&path),
            saved: None,
        };
        let schedule = Schedule {
            interval,
            periodic: None,
            label: "cookie jar",
        };
        JarAutosave {
            path,
            autosave: Autosave::spawn(target, self.changes(), schedule),
        }
    }
}

impl JarAutosave {
    pub async fn flush(&self) -> Result<()> {
        self.autosave.flush().await
    }

    pub async fn shutdown(self) -> Result<()> {
        self.autosave.shutdown().await
    }
}

impl std::fmt::Debug for JarAutosave {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("JarAutosave")
            .field("path", &self.path)
            .finish_non_exhaustive()
    }
}

impl SaveTarget for JarTarget {
    fn prepare(&mut self) -> Option<SaveJob> {
        let generation = *self.jar.changes.borrow();
        if self.saved == Some(generation) {
            return None;
        }
        let jar = self.jar.clone();
        let path = Arc::clone(&self.path);
        Some(SaveJob {
            generation,
            write: Box::new(move || jar.save_to(&*path)),
        })
    }

    fn saved(&mut self, generation: u64) {
        self.saved = Some(generation);
    }
}