use log::*;
use serde_yaml::Value;
use std::{fs, path::PathBuf};
use crate::{
common::PRNumber, doc_filename::DocFileName, error, schema::Schema, utils::get_project_root,
};
#[derive(Debug)]
pub struct DocFile {
pub file: PathBuf,
pub content: Value,
pub schema: Schema,
}
impl DocFile {
pub fn new(schema: Schema, file: PathBuf) -> Self {
let content = Self::load(schema.clone(), &file).unwrap();
Self { file, content, schema }
}
pub fn load_from_number(schema: Schema, n: PRNumber) -> Self {
let filename = DocFileName::from(n);
let file = PathBuf::from(filename);
let content = Self::load(schema.clone(), &file).unwrap();
Self { file, content, schema }
}
pub fn load(schema: Schema, file: &PathBuf) -> crate::error::Result<Value> {
schema.load(file)
}
pub fn generate(file: PathBuf) -> error::Result<String> {
let template_file = if file.is_absolute() {
file
} else {
let repo_root = get_project_root().expect("We need to work in a repo");
repo_root.join(file)
};
Ok(fs::read_to_string(template_file)?)
}
pub fn find(
schema: Schema,
dir: &PathBuf,
valid_only: bool,
) -> crate::error::Result<impl Iterator<Item = PathBuf>> {
trace!("valid_only: {valid_only}");
let res = std::fs::read_dir(dir)?
.filter_map(|res| res.ok())
.map(|dir_entry| dir_entry.path())
.filter_map(|path| {
if path.extension().map_or(false, |ext| ext == "prdoc") {
Some(path)
} else {
None
}
})
.filter_map(move |path| {
if valid_only {
let is_valid = DocFileName::is_valid(&path);
trace!(
"{}: filename {}",
path.display(),
if is_valid { " VALID " } else { "INVALID" }
);
if is_valid {
Some(path)
} else {
None
}
} else {
Some(path)
}
})
.filter_map(move |path| {
let schema_valid = schema.check_file(&path);
trace!(
"{}: schema {}",
path.display(),
if schema_valid { " VALID " } else { "INVALID" }
);
if valid_only {
if schema_valid {
Some(path)
} else {
None
}
} else {
Some(path)
}
});
Ok(res)
}
}