prefix_file_tree/scheme/
mod.rs

1use std::borrow::Cow;
2use std::cmp::Ordering;
3use std::ffi::{OsStr, OsString};
4
5#[cfg(feature = "data-encoding")]
6pub mod encoding;
7pub mod hex;
8
9#[derive(Clone, Copy, Debug, Eq, PartialEq, thiserror::Error)]
10pub enum Error {
11    #[error("Expected UTF-8")]
12    NonUtf8,
13    #[error("Invalid byte")]
14    InvalidByte(u8),
15    #[error("Invalid length")]
16    InvalidLength(usize),
17}
18
19#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
20pub enum Case {
21    #[default]
22    Lower,
23    Upper,
24    Any,
25}
26
27pub trait Scheme {
28    type Name;
29    type NameRef<'a>;
30
31    #[must_use]
32    fn fixed_length() -> Option<usize> {
33        None
34    }
35
36    fn name_to_string<'a>(&self, name: Self::NameRef<'a>) -> Cow<'a, str>;
37    fn name_from_file_stem(&self, file_stem: &OsStr) -> Result<Self::Name, Error>;
38
39    fn cmp_prefix_part(&self, a: &OsStr, b: &OsStr) -> Result<Ordering, Error> {
40        Ok(a.cmp(b))
41    }
42}
43
44#[derive(Clone, Copy, Debug, Eq, PartialEq)]
45pub struct Identity;
46
47impl Scheme for Identity {
48    type Name = OsString;
49    type NameRef<'a> = &'a OsStr;
50
51    fn name_to_string<'a>(&self, name: Self::NameRef<'a>) -> Cow<'a, str> {
52        name.to_string_lossy()
53    }
54
55    fn name_from_file_stem(&self, file_stem: &OsStr) -> Result<Self::Name, Error> {
56        Ok(file_stem.to_os_string())
57    }
58}
59
60#[derive(Clone, Copy, Debug, Eq, PartialEq)]
61pub struct Utf8;
62
63impl Scheme for Utf8 {
64    type Name = String;
65    type NameRef<'a> = &'a str;
66
67    fn name_to_string<'a>(&self, name: Self::NameRef<'a>) -> Cow<'a, str> {
68        name.into()
69    }
70
71    fn name_from_file_stem(&self, file_stem: &OsStr) -> Result<Self::Name, Error> {
72        file_stem
73            .to_str()
74            .map(std::string::ToString::to_string)
75            .ok_or(Error::NonUtf8)
76    }
77}