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
use {TryRead, TryWrite, Error, Result, check_len};
use core::str;
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Str {
Len(usize),
Delimiter(u8),
DelimiterUntil(u8, usize),
}
impl Default for Str {
#[inline]
fn default() -> Self {
Str::Delimiter(NULL)
}
}
pub const NULL: u8 = 0;
pub const SPACE: u8 = 0x20;
pub const RET: u8 = 0x0a;
pub const TAB: u8 = 0x09;
impl<'a> TryRead<'a, Str> for &'a str {
#[inline]
fn try_read(bytes: &'a [u8], ctx: Str) -> Result<(Self, usize)> {
let (bytes, size) = match ctx {
Str::Len(len) => {
let len = check_len(bytes, len)?;
(&bytes[..len], len)
}
Str::Delimiter(delimiter) => {
let position = bytes
.iter()
.position(|c| *c == delimiter)
.ok_or(Error::Incomplete)?;
(&bytes[..position], position + 1)
}
Str::DelimiterUntil(delimiter, len) => {
let position = bytes.iter().take(len).position(|c| *c == delimiter);
match position {
Some(position) => (&bytes[..position], position + 1),
None => {
let len = check_len(bytes, len)?;
(&bytes[..len], len)
}
}
}
};
str::from_utf8(bytes)
.map(|str| (str, size))
.map_err(|_| Error::BadInput { err: "UTF8 Error" })
}
}
impl<'a> TryWrite for &'a str {
#[inline]
fn try_write(self, bytes: &mut [u8], _ctx: ()) -> Result<usize> {
let str_bytes = self.as_bytes();
check_len(bytes, str_bytes.len())?;
bytes[..str_bytes.len()].clone_from_slice(str_bytes);
Ok(str_bytes.len())
}
}