use std::{fs::File, io::prelude::*, path::PathBuf};
use crate::parser::ContentResults;
const DEFAULT_FILE_NAME: &str = "rdocs";
pub enum Content {
Only(Output),
All(Output, Format),
}
pub enum Output {
Path(PathBuf),
Stdout,
}
#[derive(clap::ValueEnum, Clone)]
pub enum Format {
Json,
Yaml,
}
impl Format {
#[must_use]
pub const fn get_extension(&self) -> &'static str {
match self {
Self::Json => "json",
Self::Yaml => "yaml",
}
}
}
impl Output {
#[must_use]
pub fn new(path: Option<PathBuf>) -> Self {
path.map_or(Self::Stdout, Self::Path)
}
}
impl Content {
pub fn export(&self, results: Vec<ContentResults>) -> Result<(), Box<dyn std::error::Error>> {
match self {
Self::Only(output) => {
for result in results {
match output {
Output::Path(path) => {
let file_path = path.join(result.metadata.id);
if let Some(parent) = file_path.parent() {
std::fs::create_dir_all(parent)?;
}
let mut file = File::create(file_path)?;
file.write_all(result.data.as_bytes())?;
}
Output::Stdout => println!("{}", result.data),
}
}
}
Self::All(output, format) => {
let content = match format {
Format::Json => serde_json::to_string_pretty(&results)?,
Format::Yaml => serde_yaml::to_string(&results)?,
};
match output {
Output::Path(path) => {
let file_path = if path.extension().is_some() {
path.clone()
} else {
let mut file_path = path.join(DEFAULT_FILE_NAME);
file_path.set_extension(format.get_extension());
file_path
};
if let Some(parent) = file_path.parent() {
std::fs::create_dir_all(parent)?;
}
let mut file = File::create(file_path)?;
file.write_all(content.as_bytes())?;
}
Output::Stdout => println!("{content}"),
}
}
}
Ok(())
}
}