use std::{
env::Args,
fs::{self, File},
io::{self, LineWriter, Seek, SeekFrom, Write},
path::{Path, PathBuf},
str::FromStr,
};
use crate::orwritekey::{self, KeywordReader};
pub enum Argommand {
Init,
Link,
}
#[derive(Debug)]
pub enum ArgoErr {
Duh,
}
impl FromStr for Argommand {
type Err = ArgoErr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == "init" {
Ok(Argommand::Init)
} else {
Err(ArgoErr::Duh)
}
}
}
pub struct ArgBoy(Args);
impl ArgBoy {
pub fn new() -> Self {
let args = std::env::args();
ArgBoy(args)
}
pub fn errand(&mut self) -> Argommand {
dbg!(self.0.next());
match self.0.next() {
Some(ref s) => s.parse().expect("now only has `init`"),
None => Argommand::Link,
}
}
}
#[derive(Debug)]
pub struct RepoBoy {
pub src: PathBuf,
pub models: PathBuf,
pub sections: PathBuf,
pub materials: PathBuf,
}
impl RepoBoy {
pub fn new() -> Self {
let paf = |s: &str| PathBuf::from(s);
let src = paf("src");
let models = paf("src/models");
let sections = paf("src/sections");
let materials = paf("src/materials");
RepoBoy {
src,
models,
sections,
materials,
}
}
pub fn init(self) -> io::Result<()> {
let cre = |paf: PathBuf| {
if !paf.exists() {
fs::create_dir(paf)
} else {
Ok(())
}
};
File::create("dry.toml")?;
cre(self.src)?;
cre(self.models)?;
cre(self.materials)?;
cre(self.sections)
}
pub fn main_key_compo(&self, ddar: &DirWalker) -> io::Result<()> {
let file = File::create("main.k")?;
let mut ln_wtr = LineWriter::new(file);
ln_wtr.write_all(b"*INCLUDE\n").expect("write *INCLUDE");
let mut mats_k_p = ddar.key_paf_vec(self.materials.clone());
let mut secs_k_p = ddar.key_paf_vec(self.sections.clone());
let itr_secs = secs_k_p.iter_mut().filter_map(|c| c.as_os_str().to_str());
let itr_mats = mats_k_p.iter_mut().filter_map(|c| c.as_os_str().to_str());
let itr = itr_secs.chain(itr_mats);
'k: for i in itr {
if !KeyPath(i).is_k() {
continue 'k;
};
ln_wtr.write_all(i.as_bytes()).expect("writing to main.k");
ln_wtr.write_all(b"\n").expect(r"writing `\n`");
}
ln_wtr
.write_all(b"*INCLUDE_AUTO_OFFSET\n")
.expect("write *INCLUDE");
let mut modls_k_p = ddar.key_paf_vec(self.models.clone());
let itr_modls = modls_k_p.iter_mut().filter_map(|c| c.as_os_str().to_str());
'k: for i in itr_modls {
if !KeyPath(i).is_k() {
continue 'k;
};
ln_wtr.write_all(i.as_bytes()).expect("writing to main.k");
ln_wtr.write_all(b"\n").expect(r"writing `\n`");
}
ln_wtr.write_all(b"*END\n").expect("write *END");
Ok(())
}
}
pub struct KeyPath<T: AsRef<Path>>(pub T);
impl<T: AsRef<Path>> KeyPath<T> {
pub fn is_k(&self) -> bool {
let sufx = self.0.as_ref().extension();
match sufx {
Some(ref k) => *k == "k",
None => false,
}
}
}
type WalkDir = Box<dyn Fn(PathBuf) -> std::fs::ReadDir>;
pub struct DirWalker {
iter: WalkDir,
}
impl DirWalker {
pub fn new() -> Self {
let iter = Box::new(|p| fs::read_dir(p).expect("dir should exists"));
DirWalker { iter }
}
pub fn key_paf_vec(&self, p: PathBuf) -> Vec<PathBuf> {
let a = &self.iter;
let b = a(p);
b.filter_map(|c| c.ok()).map(|e| e.path()).collect()
}
}