prefix_file_tree/scheme/
mod.rs1use 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}