You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
967 B
50 lines
967 B
use core::fmt;
|
|
use std::fmt::Display;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use super::Path;
|
|
|
|
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
|
|
pub struct Hash(String);
|
|
|
|
impl From<Path> for Hash {
|
|
fn from(path: Path) -> Self {
|
|
path.hash
|
|
}
|
|
}
|
|
|
|
impl Display for Hash {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.write_str(self.0.as_ref())
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for Hash {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
Display::fmt(self, f)
|
|
}
|
|
}
|
|
|
|
impl Hash {
|
|
pub fn parse<S: AsRef<str>>(str: S) -> Result<Self, (usize, char)> {
|
|
let str = str.as_ref();
|
|
let match_closure = |acc, c|
|
|
match acc {
|
|
Ok(i) => match c {
|
|
'a'..='z' | '0'..='9' => Ok(i + 1),
|
|
_ => Err((i, c)),
|
|
}
|
|
Err(x) => Err(x)
|
|
};
|
|
|
|
match str.chars().fold(Ok(0usize), match_closure) {
|
|
Ok(_) => Ok(Hash(str.into())),
|
|
Err(err) => Err(err),
|
|
}
|
|
}
|
|
|
|
pub fn to_string(self) -> String {
|
|
self.0
|
|
}
|
|
}
|
|
|