1#![cfg(feature = "bytes")]
2
3use std::borrow::Borrow;
4use std::fmt;
5use std::ops::Deref;
6use std::str;
7
8use bytes::Bytes;
9
10#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
13pub struct Chars(Bytes);
14
15impl Chars {
16 pub const fn new() -> Chars {
18 Chars(Bytes::new())
19 }
20
21 pub fn clear(&mut self) {
23 self.0.clear();
24 }
25
26 pub fn from_bytes(bytes: Bytes) -> Result<Chars, str::Utf8Error> {
28 str::from_utf8(&bytes)?;
29
30 Ok(Chars(bytes))
31 }
32
33 pub fn len(&self) -> usize {
35 self.0.len()
36 }
37
38 pub fn is_empty(&self) -> bool {
40 self.0.is_empty()
41 }
42}
43
44impl<'a> From<&'a str> for Chars {
45 fn from(src: &'a str) -> Chars {
46 Chars(Bytes::copy_from_slice(src.as_bytes()))
47 }
48}
49
50impl From<String> for Chars {
51 fn from(src: String) -> Chars {
52 Chars(Bytes::from(src))
53 }
54}
55
56impl Into<String> for Chars {
57 fn into(self) -> String {
58 unsafe { String::from_utf8_unchecked(self.0.as_ref().to_owned()) }
60 }
61}
62
63impl Default for Chars {
64 fn default() -> Self {
65 Chars::new()
66 }
67}
68
69impl Deref for Chars {
70 type Target = str;
71
72 fn deref(&self) -> &str {
73 unsafe { str::from_utf8_unchecked(&self.0) }
75 }
76}
77
78impl Borrow<str> for Chars {
79 fn borrow(&self) -> &str {
80 &*self
81 }
82}
83
84impl fmt::Display for Chars {
85 #[inline]
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 fmt::Display::fmt(&**self, f)
88 }
89}
90
91impl fmt::Debug for Chars {
92 #[inline]
93 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94 fmt::Debug::fmt(&**self, f)
95 }
96}
97
98#[cfg(test)]
99mod test {
100 use super::Chars;
101
102 #[test]
103 #[cfg_attr(miri, ignore)] fn test_display_and_debug() {
105 let s = "test";
106 let string: String = s.into();
107 let chars: Chars = s.into();
108
109 assert_eq!(format!("{}", string), format!("{}", chars));
110 assert_eq!(format!("{:?}", string), format!("{:?}", chars));
111 }
112}