use std::fs::read; use std::path::{Path, PathBuf}; /// Name of tag file. pub const CACHEDIR_TAG: &str = "CACHEDIR.TAG"; /// Prefix of contents of tag file. pub const TAG: &str = "Signature: 8a477f597d28d172789f06886806bc55"; /// Is a given file a cache directory tag? pub fn is_cachedir_tag(filename: &Path) -> Result { // Is the filename OK? if let Some(basename) = filename.file_name() { if basename != CACHEDIR_TAG { return Ok(false); } } // Does the file exist? It's OK if it doesn't, but we don't want // to try to read it if it doesn't. if !filename.exists() { return Ok(false); } // Does the file start with the right prefix? let data = read(filename).map_err(|e| CacheDirError::Read(filename.into(), e))?; if data.len() >= TAG.len() { Ok(&data[..TAG.len()] == TAG.as_bytes()) } else { Ok(false) } } #[derive(Debug, thiserror::Error)] pub enum CacheDirError { #[error("failed to read file {0}")] Read(PathBuf, #[source] std::io::Error), #[error("failed to write file {0}")] Write(PathBuf, #[source] std::io::Error), #[error("failed to delete file {0}")] Remove(PathBuf, #[source] std::io::Error), #[error(transparent)] WalkDir(#[from] walkdir::Error), }