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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use std::{
borrow::Borrow,
fmt::{Display, Formatter},
str,
};
use encoding::{all::ISO_8859_1, Encoding};
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SubCharacter {
Symbol(String),
Blank,
}
struct SplitWith<'a, 'b> {
haystack: Option<&'a [u8]>,
when: &'b [u8],
}
impl<'a, 'b> Iterator for SplitWith<'a, 'b> {
type Item = &'a [u8];
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
match self.haystack {
Some(haystack) => {
for i in 0usize..haystack.len() {
if (&haystack[i..]).starts_with(self.when) {
let res = &haystack[..i];
self.haystack = Some(&haystack[(self.when.len() + i)..]);
return Some(res);
}
}
let res = Some(haystack);
self.haystack = None;
res
}
None => None,
}
}
}
fn split<'a, 'b>(haystack: &'a [u8], when: &'b [u8]) -> SplitWith<'a, 'b> {
SplitWith {
haystack: Some(haystack),
when,
}
}
impl SubCharacter {
pub fn split(raw: &[u8], blank_character: &[u8]) -> Result<Vec<SubCharacter>, String> {
let mut res = Vec::new();
for (i, string) in split(raw, blank_character).enumerate() {
if i != 0 {
res.push(SubCharacter::Blank);
}
if !string.is_empty() {
let string = ISO_8859_1
.decode(string, encoding::DecoderTrap::Strict)
.map_err(|e| e.to_string())?
.to_string();
for g in string.graphemes(false) {
res.push(SubCharacter::Symbol(g.to_string()));
}
}
}
Ok(res)
}
pub fn width(&self) -> usize {
match self {
SubCharacter::Blank => 1,
SubCharacter::Symbol(ref sym) => UnicodeWidthStr::width(sym.as_str()),
}
}
pub fn is_blank(&self) -> bool {
match self {
SubCharacter::Blank => true,
_ => false,
}
}
}
impl Borrow<str> for SubCharacter {
fn borrow<'a>(&'a self) -> &'a str {
match self {
SubCharacter::Symbol(ref res) => res,
SubCharacter::Blank => " ",
}
}
}
impl Display for SubCharacter {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
match self {
SubCharacter::Blank => write!(fmt, " "),
SubCharacter::Symbol(c) => write!(fmt, "{}", c),
}
}
}
impl From<&char> for SubCharacter {
#[inline]
fn from(c: &char) -> Self {
SubCharacter::Symbol(c.to_string())
}
}
impl From<char> for SubCharacter {
#[inline]
fn from(c: char) -> Self {
From::from(&c)
}
}