bat/src/syntax_mapping/ignored_suffixes.rs

110 lines
3.2 KiB
Rust

use std::ffi::OsStr;
use std::fmt::Debug;
use std::path::Path;
use crate::error::*;
#[derive(Debug, Clone)]
pub struct IgnoredSuffixes<'a> {
values: Vec<&'a str>,
}
impl Default for IgnoredSuffixes<'_> {
fn default() -> Self {
Self {
values: vec![
// Editor etc backups
"~",
".bak",
".old",
".orig",
// Debian and derivatives apt/dpkg/ucf backups
".dpkg-dist",
".dpkg-new",
".dpkg-old",
".dpkg-tmp",
".ucf-dist",
".ucf-new",
".ucf-old",
// Red Hat and derivatives rpm backups
".rpmnew",
".rpmorig",
".rpmsave",
// Build system input/template files
".in",
],
}
}
}
impl<'a> IgnoredSuffixes<'a> {
pub fn add_suffix(&mut self, suffix: &'a str) {
self.values.push(suffix)
}
pub fn strip_suffix(&self, file_name: &'a str) -> Option<&'a str> {
for suffix in self.values.iter() {
if let Some(stripped_file_name) = file_name.strip_suffix(suffix) {
return Some(stripped_file_name);
}
}
None
}
/// If we find an ignored suffix on the file name, e.g. '~', we strip it and
/// then try again without it.
pub fn try_with_stripped_suffix<T, F>(&self, file_name: &'a OsStr, func: F) -> Result<Option<T>>
where
F: Fn(&'a OsStr) -> Result<Option<T>>,
{
if let Some(file_str) = Path::new(file_name).to_str() {
if let Some(stripped_file_name) = self.strip_suffix(file_str) {
return func(OsStr::new(stripped_file_name));
}
}
Ok(None)
}
}
#[test]
fn internal_suffixes() {
let ignored_suffixes = IgnoredSuffixes::default();
let file_names = ignored_suffixes
.values
.iter()
.map(|suffix| format!("test.json{suffix}"));
for file_name_str in file_names {
let file_name = OsStr::new(&file_name_str);
let expected_stripped_file_name = OsStr::new("test.json");
let stripped_file_name = ignored_suffixes
.try_with_stripped_suffix(file_name, |stripped_file_name| Ok(Some(stripped_file_name)));
assert_eq!(
expected_stripped_file_name,
stripped_file_name.unwrap().unwrap()
);
}
}
#[test]
fn external_suffixes() {
let mut ignored_suffixes = IgnoredSuffixes::default();
ignored_suffixes.add_suffix(".development");
ignored_suffixes.add_suffix(".production");
let file_names = ignored_suffixes
.values
.iter()
.map(|suffix| format!("test.json{suffix}"));
for file_name_str in file_names {
let file_name = OsStr::new(&file_name_str);
let expected_stripped_file_name = OsStr::new("test.json");
let stripped_file_name = ignored_suffixes
.try_with_stripped_suffix(file_name, |stripped_file_name| Ok(Some(stripped_file_name)));
assert_eq!(
expected_stripped_file_name,
stripped_file_name.unwrap().unwrap()
);
}
}