1 | use crate::parser::errors::ParserError; |
2 | use std::str::FromStr; |
3 | use tinystr::TinyStr4; |
4 | |
5 | #[derive (Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord, Copy)] |
6 | pub struct Script(TinyStr4); |
7 | |
8 | impl Script { |
9 | pub fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { |
10 | let slen: usize = v.len(); |
11 | |
12 | let s: TinyAsciiStr<4> = TinyStr4::from_bytes(v).map_err(|_| ParserError::InvalidSubtag)?; |
13 | if slen != 4 || !s.is_ascii_alphabetic() { |
14 | return Err(ParserError::InvalidSubtag); |
15 | } |
16 | Ok(Self(s.to_ascii_titlecase())) |
17 | } |
18 | |
19 | pub fn as_str(&self) -> &str { |
20 | self.0.as_str() |
21 | } |
22 | |
23 | /// # Safety |
24 | /// |
25 | /// This function accepts any u64 that is exected to be a valid |
26 | /// `TinyStr4` and a valid `Script` subtag. |
27 | pub const unsafe fn from_raw_unchecked(v: u32) -> Self { |
28 | Self(TinyStr4::from_bytes_unchecked(v.to_le_bytes())) |
29 | } |
30 | } |
31 | |
32 | impl From<Script> for u32 { |
33 | fn from(input: Script) -> Self { |
34 | u32::from_le_bytes(*input.0.all_bytes()) |
35 | } |
36 | } |
37 | |
38 | impl<'l> From<&'l Script> for &'l str { |
39 | fn from(input: &'l Script) -> Self { |
40 | input.0.as_str() |
41 | } |
42 | } |
43 | |
44 | impl FromStr for Script { |
45 | type Err = ParserError; |
46 | |
47 | fn from_str(source: &str) -> Result<Self, Self::Err> { |
48 | Self::from_bytes(source.as_bytes()) |
49 | } |
50 | } |
51 | |
52 | impl std::fmt::Display for Script { |
53 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
54 | f.write_str(&self.0) |
55 | } |
56 | } |
57 | |
58 | impl PartialEq<&str> for Script { |
59 | fn eq(&self, other: &&str) -> bool { |
60 | self.as_str() == *other |
61 | } |
62 | } |
63 | |