use crate::ChildPath;
use crate::files;
use std::cmp::{Ord, Ordering};
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum SourceFileMetadata {
Dir,
RawFile,
RenderableFile { extension: &'static str },
}
impl SourceFileMetadata {
fn kind_idx(&self) -> usize {
match self {
Self::Dir => 1,
Self::RenderableFile { .. } => 2,
Self::RawFile => 3,
}
}
}
impl Ord for SourceFileMetadata {
fn cmp(&self, other: &Self) -> Ordering {
self.kind_idx().cmp(&other.kind_idx())
}
}
impl PartialOrd for SourceFileMetadata {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SourceFile {
pub childpath: ChildPath,
pub layer_order: usize,
pub metadata: SourceFileMetadata,
}
impl Ord for SourceFile {
fn cmp(&self, other: &Self) -> Ordering {
let l = self.layer_order.cmp(&other.layer_order);
if l == Ordering::Equal {
self.metadata.cmp(&other.metadata)
} else {
l
}
}
}
impl PartialOrd for SourceFile {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl SourceFile {
pub fn childpath(&self) -> &ChildPath {
&self.childpath
}
}
impl From<(ChildPath, usize)> for SourceFile {
fn from((childpath, layer_order): (ChildPath, usize)) -> Self {
let path = PathBuf::from(&childpath);
if path.is_dir() {
SourceFile {
childpath,
layer_order,
metadata: SourceFileMetadata::Dir,
}
} else if files::is_ffizer_handlebars(&path) {
SourceFile {
childpath,
layer_order,
metadata: SourceFileMetadata::RenderableFile {
extension: files::FILEEXT_HANDLEBARS,
},
}
} else {
SourceFile {
childpath,
layer_order,
metadata: SourceFileMetadata::RawFile,
}
}
}
}
pub(crate) fn optimize_sourcefiles(sources: &mut Vec<SourceFile>) {
sources.sort();
if let Some(pos) = sources
.iter()
.position(|x| !matches!(x.metadata, SourceFileMetadata::RenderableFile { .. }))
{
sources.truncate(pos + 1);
}
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_cmp_sourcefile() {
let mut input = vec![
SourceFile::from((ChildPath::new("./tests/test_1/template", "file_2.txt"), 0)),
SourceFile::from((
ChildPath::new("./tests/test_1/template", "file_2.txt.ffizer.hbs"),
0,
)),
];
let expected = vec![
SourceFile::from((
ChildPath::new("./tests/test_1/template", "file_2.txt.ffizer.hbs"),
0,
)),
SourceFile::from((ChildPath::new("./tests/test_1/template", "file_2.txt"), 0)),
];
optimize_sourcefiles(&mut input);
assert_eq!(&expected, &input);
}
}