1 use std::fmt; 2 use std::ops::Deref; 3 use std::str; 4 5 use bytes::Bytes; 6 7 use 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)] 11 pub struct Chars(Bytes); 12 13 impl Chars { 14 /// New empty object. new() -> Chars15 pub fn new() -> Chars { 16 Chars(Bytes::new()) 17 } 18 19 /// Try convert from `Bytes` from_bytes(bytes: Bytes) -> Result<Chars, str::Utf8Error>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. len(&self) -> usize27 pub fn len(&self) -> usize { 28 self.0.len() 29 } 30 31 /// Self-explanatory is_empty(&self) -> bool32 pub fn is_empty(&self) -> bool { 33 self.0.is_empty() 34 } 35 } 36 37 impl<'a> From<&'a str> for Chars { from(src: &'a str) -> Chars38 fn from(src: &'a str) -> Chars { 39 Chars(Bytes::copy_from_slice(src.as_bytes())) 40 } 41 } 42 43 impl From<String> for Chars { from(src: String) -> Chars44 fn from(src: String) -> Chars { 45 Chars(Bytes::from(src)) 46 } 47 } 48 49 impl Default for Chars { default() -> Self50 fn default() -> Self { 51 Chars::new() 52 } 53 } 54 55 impl Deref for Chars { 56 type Target = str; 57 deref(&self) -> &str58 fn deref(&self) -> &str { 59 unsafe { str::from_utf8_unchecked(&self.0) } 60 } 61 } 62 63 impl Clear for Chars { clear(&mut self)64 fn clear(&mut self) { 65 self.0.clear(); 66 } 67 } 68 69 impl fmt::Display for Chars { 70 #[inline] fmt(&self, f: &mut fmt::Formatter) -> fmt::Result71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 72 fmt::Display::fmt(&**self, f) 73 } 74 } 75 76 impl fmt::Debug for Chars { 77 #[inline] fmt(&self, f: &mut fmt::Formatter) -> fmt::Result78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 79 fmt::Debug::fmt(&**self, f) 80 } 81 } 82 83 #[cfg(test)] 84 mod test { 85 use super::Chars; 86 87 #[test] test_display_and_debug()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 } 97