utf8_rune/
byte_type.rs

1use std::fmt::{Debug, Formatter};
2
3use crate::internal::unwrap_indent;
4
5#[derive(Clone, Copy, PartialEq, Eq)]
6pub enum ByteType {
7    None,
8    Ascii(u8),
9    One(u8),
10    Two(u8),
11    Three(u8),
12    FourOrMore(u8),
13    Continuation(u8),
14}
15
16impl ByteType {
17    pub fn new(byte: u8) -> ByteType {
18        if byte < 127 {
19            ByteType::Ascii(byte)
20        } else {
21            match byte.leading_ones() {
22                0 => ByteType::One(byte),
23                1 => ByteType::Continuation(byte),
24                2 => ByteType::Two(byte),
25                3 => ByteType::Three(byte),
26                _ => ByteType::FourOrMore(byte),
27            }
28        }
29    }
30
31    pub fn name(&self) -> &'static str {
32        match self {
33            ByteType::None => "None",
34            ByteType::Ascii(_) => "Ascii",
35            ByteType::One(_) => "One",
36            ByteType::Two(_) => "Two",
37            ByteType::Three(_) => "Three",
38            ByteType::FourOrMore(_) => "FourOrMore",
39            ByteType::Continuation(_) => "Continuation",
40        }
41    }
42
43    pub fn byte(&self) -> u8 {
44        match self {
45            ByteType::None => u8::default(),
46            ByteType::Ascii(byte) => *byte,
47            ByteType::One(byte) => *byte,
48            ByteType::Two(byte) => *byte,
49            ByteType::Three(byte) => *byte,
50            ByteType::FourOrMore(byte) => *byte,
51            ByteType::Continuation(byte) => *byte,
52        }
53    }
54
55    pub fn len(&self) -> usize {
56        match self {
57            ByteType::Continuation(_) | ByteType::Ascii(_) => 1,
58            _ => (self.byte().leading_ones()) as usize,
59        }
60    }
61
62    pub fn is_ascii(&self) -> bool {
63        match self {
64            ByteType::Ascii(_) => true,
65            _ => false,
66        }
67    }
68
69    pub fn is_continuation(&self) -> bool {
70        match self {
71            ByteType::Continuation(_) => true,
72            _ => false,
73        }
74    }
75
76    pub fn has_rune_delta(&self) -> bool {
77        match self {
78            ByteType::None => false,
79            ByteType::Ascii(_) => false,
80            ByteType::Continuation(_) => false,
81            _ => true,
82        }
83    }
84
85    fn as_debug(&self, indent: Option<usize>) -> String {
86        let indent = unwrap_indent(indent);
87        format!(
88            "{}::{}{{\n{}\n}})",
89            "ByteType",
90            self.name(),
91            [
92                format!(
93                    "byte: 0x{:02x},{}",
94                    self.byte(),
95                    if let Ok(c) = std::str::from_utf8(&[self.byte()]) {
96                        format!(" // \"{c}\"")
97                    } else {
98                        String::new()
99                    }
100                ),
101                format!("len: {},", self.len()),
102            ]
103            .iter()
104            .map(|c| {
105                let padding = " ".repeat(indent);
106                format!("{padding}{c}")
107            })
108            .collect::<Vec<String>>()
109            .join("\n")
110        )
111    }
112}
113impl From<u8> for ByteType {
114    fn from(byte: u8) -> ByteType {
115        ByteType::new(byte)
116    }
117}
118impl From<&u8> for ByteType {
119    fn from(byte: &u8) -> ByteType {
120        ByteType::new(*byte)
121    }
122}
123impl From<u16> for ByteType {
124    fn from(bytes: u16) -> ByteType {
125        ByteType::from(bytes.to_le_bytes()[0])
126    }
127}
128impl From<u32> for ByteType {
129    fn from(bytes: u32) -> ByteType {
130        ByteType::from(bytes.to_le_bytes()[0])
131    }
132}
133impl From<u64> for ByteType {
134    fn from(bytes: u64) -> ByteType {
135        ByteType::from(bytes.to_le_bytes()[0])
136    }
137}
138impl From<usize> for ByteType {
139    fn from(bytes: usize) -> ByteType {
140        ByteType::from(bytes.to_le_bytes()[0])
141    }
142}
143
144impl Debug for ByteType {
145    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
146        write!(f, "{}", self.as_debug(None))
147    }
148}