1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::error::Error;
use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Token68(pub(crate) String);
impl Token68 {
#[inline]
pub fn new(s: &str) -> Result<Token68, InvalidToken68> {
let trimmed = s.trim_right_matches('=');
if trimmed.is_empty() {
return Err(InvalidToken68(()));
}
let ok = trimmed.as_bytes().iter().all(|b| match b {
b'0'...b'9' | b'a'...b'z' | b'A'...b'Z' | b'-' | b'.' | b'_' | b'~' | b'+' | b'/' => {
true
}
_ => false,
});
if ok {
Ok(Token68(s.to_string()))
} else {
Err(InvalidToken68(()))
}
}
#[inline]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for Token68 {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(self.as_str())
}
}
impl FromStr for Token68 {
type Err = InvalidToken68;
#[inline]
fn from_str(s: &str) -> Result<Token68, InvalidToken68> {
Token68::new(s)
}
}
#[derive(Debug)]
pub struct InvalidToken68(());
impl fmt::Display for InvalidToken68 {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("invalid base68")
}
}
impl Error for InvalidToken68 {
fn description(&self) -> &str {
"invalid base68"
}
}