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
use std::str;
use std::io::{self, Write};
use nom::{self, IResult, Needed};
use {Format, C0, C1, CSI, SGR};
#[derive(Eq, PartialEq, Clone, Debug)]
pub enum Control<'a> {
C0(C0::T),
C1(C1::T<'a>),
None(&'a str),
}
impl<'a> From<C0::T> for Control<'a> {
fn from(value: C0::T) -> Control<'a> {
Control::C0(value)
}
}
impl<'a> From<C1::T<'a>> for Control<'a> {
fn from(value: C1::T<'a>) -> Control<'a> {
Control::C1(value)
}
}
impl<'a> From<CSI::T> for Control<'a> {
fn from(value: CSI::T) -> Control<'a> {
Control::C1(C1::ControlSequence(value))
}
}
impl<'a> From<SGR::T> for Control<'a> {
fn from(value: SGR::T) -> Control<'a> {
Control::C1(C1::ControlSequence(CSI::SelectGraphicalRendition(vec![value])))
}
}
impl<'a> From<Vec<SGR::T>> for Control<'a> {
fn from(value: Vec<SGR::T>) -> Control<'a> {
Control::C1(C1::ControlSequence(CSI::SelectGraphicalRendition(value)))
}
}
impl<'a> Format for Control<'a> {
fn fmt<W: Write>(&self, mut f: W, wide: bool) -> io::Result<()> {
match self {
&Control::None(ref value) =>
f.write_all(value.as_bytes()),
&Control::C0(ref value) =>
value.fmt(f, wide),
&Control::C1(ref value) =>
value.fmt(f, wide),
}
}
}
named!(pub parse<Control>,
alt!(control | string));
fn string(i: &[u8]) -> IResult<&[u8], Control> {
const WIDTH: [u8; 256] = [
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
let mut length = WIDTH[i[0] as usize] as usize;
if i.len() < length {
return IResult::Incomplete(Needed::Size(length - i.len()));
}
let mut rest = &i[length..];
while !rest.is_empty() && control(rest).is_err() {
let w = WIDTH[rest[0] as usize] as usize;
if rest.len() < w {
return IResult::Incomplete(Needed::Size(w - rest.len()));
}
length += w;
rest = &rest[w..];
}
if let Ok(string) = str::from_utf8(&i[..length]) {
IResult::Done(&i[length..], Control::None(string))
}
else {
IResult::Error(nom::Err::Code(nom::ErrorKind::Custom(9001)))
}
}
named!(control<Control>,
alt!(
map!(C1::parse, |c| Control::C1(c)) |
map!(C0::parse, |c| Control::C0(c))));