blob: bb5a025e6a6c4df2a1dd950b346665a7041ee75b [file] [log] [blame]
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -07001use std::fmt;
2use std::ops::Deref;
3use std::str;
4
5use bytes::Bytes;
6
7use clear::Clear;
8
9/// Thin wrapper around `Bytes` which guarantees that bytes are valid UTF-8 string.
10#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
11pub struct Chars(Bytes);
12
13impl Chars {
14 /// New empty object.
15 pub fn new() -> Chars {
16 Chars(Bytes::new())
17 }
18
19 /// Try convert from `Bytes`
20 pub fn from_bytes(bytes: Bytes) -> Result<Chars, str::Utf8Error> {
21 str::from_utf8(&bytes)?;
22
23 Ok(Chars(bytes))
24 }
25
26 /// Len in bytes.
27 pub fn len(&self) -> usize {
28 self.0.len()
29 }
30
31 /// Self-explanatory
32 pub fn is_empty(&self) -> bool {
33 self.0.is_empty()
34 }
35}
36
37impl<'a> From<&'a str> for Chars {
38 fn from(src: &'a str) -> Chars {
39 Chars(Bytes::copy_from_slice(src.as_bytes()))
40 }
41}
42
43impl From<String> for Chars {
44 fn from(src: String) -> Chars {
45 Chars(Bytes::from(src))
46 }
47}
48
49impl Default for Chars {
50 fn default() -> Self {
51 Chars::new()
52 }
53}
54
55impl Deref for Chars {
56 type Target = str;
57
58 fn deref(&self) -> &str {
59 unsafe { str::from_utf8_unchecked(&self.0) }
60 }
61}
62
63impl Clear for Chars {
64 fn clear(&mut self) {
65 self.0.clear();
66 }
67}
68
69impl fmt::Display for Chars {
70 #[inline]
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 fmt::Display::fmt(&**self, f)
73 }
74}
75
76impl fmt::Debug for Chars {
77 #[inline]
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79 fmt::Debug::fmt(&**self, f)
80 }
81}
82
83#[cfg(test)]
84mod test {
85 use super::Chars;
86
87 #[test]
88 fn test_display_and_debug() {
89 let s = "test";
90 let string: String = s.into();
91 let chars: Chars = s.into();
92
93 assert_eq!(format!("{}", string), format!("{}", chars));
94 assert_eq!(format!("{:?}", string), format!("{:?}", chars));
95 }
96}