byte_string/
lib.rs

1//! The `byte_string` crate provides two types: `ByteStr` and `ByteString`.
2//! Both types provide a `Debug` implementation
3//! that outputs the slice using the Rust byte string syntax.
4//! `ByteStr` wraps a byte slice (`[u8]`).
5//! `ByteString` wraps a vector of bytes (`Vec<u8>`).
6//!
7//! For example:
8//!
9//! ```
10//! extern crate byte_string;
11//!
12//! use byte_string::ByteStr;
13//!
14//! fn main() {
15//!     let s = b"Hello, world!";
16//!     let bs = ByteStr::new(s);
17//!     assert_eq!(format!("{:?}", bs), "b\"Hello, world!\"");
18//! }
19//! ```
20//!
21//! `ByteStr` is an unsized type, as `[u8]` is.
22//! `ByteStr::new()` returns a `&ByteStr`
23//! and `ByteStr::new_mut()` returns a `&mut ByteStr`.
24//!
25//! `ByteStr` and `ByteString` are meant to be used as an implementation detail.
26//! You should generally avoid exposing a `ByteStr` or a `ByteString`
27//! as part of a struct or enum;
28//! prefer exposing the underlying slice or vector instead.
29//! However, `ByteStr` and `ByteString` implement many traits, including derivable traits,
30//! which makes them suitable for use as a private member of a struct or enum.
31
32#![warn(missing_docs)]
33
34use std::borrow::{Borrow, BorrowMut};
35use std::fmt::{Debug, Error, Formatter};
36use std::iter::FromIterator;
37use std::mem;
38use std::ops::{Deref, DerefMut};
39
40/// Wraps a byte slice and provides a `Debug` implementation
41/// that outputs the slice using the Rust byte string syntax (e.g. `b"abc"`).
42#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
43pub struct ByteStr(pub [u8]);
44
45/// Wraps a vector of bytes and provides a `Debug` implementation
46/// that outputs the slice using the Rust byte string syntax (e.g. `b"abc"`).
47#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub struct ByteString(pub Vec<u8>);
49
50impl ByteStr {
51    /// Converts an immutable byte slice to an immutable `ByteStr` reference.
52    pub fn new(s: &[u8]) -> &ByteStr {
53        unsafe { mem::transmute(s) }
54    }
55
56    /// Converts a mutable byte slice to a mutable `ByteStr` reference.
57    pub fn new_mut(s: &mut [u8]) -> &mut ByteStr {
58        unsafe { mem::transmute(s) }
59    }
60}
61
62impl<'a> From<&'a [u8]> for &'a ByteStr {
63    fn from(s: &[u8]) -> &ByteStr {
64        ByteStr::new(s)
65    }
66}
67
68impl<'a> From<&'a mut [u8]> for &'a mut ByteStr {
69    fn from(s: &mut [u8]) -> &mut ByteStr {
70        ByteStr::new_mut(s)
71    }
72}
73
74impl<'a> From<&'a ByteStr> for &'a [u8] {
75    fn from(s: &ByteStr) -> &[u8] {
76        &s.0
77    }
78}
79
80impl<'a> From<&'a mut ByteStr> for &'a mut [u8] {
81    fn from(s: &mut ByteStr) -> &mut [u8] {
82        &mut s.0
83    }
84}
85
86impl AsRef<[u8]> for ByteStr {
87    fn as_ref(&self) -> &[u8] {
88        &self.0
89    }
90}
91
92impl AsRef<ByteStr> for [u8] {
93    fn as_ref(&self) -> &ByteStr {
94        ByteStr::new(self)
95    }
96}
97
98impl AsMut<[u8]> for ByteStr {
99    fn as_mut(&mut self) -> &mut [u8] {
100        &mut self.0
101    }
102}
103
104impl AsMut<ByteStr> for [u8] {
105    fn as_mut(&mut self) -> &mut ByteStr {
106        ByteStr::new_mut(self)
107    }
108}
109
110impl PartialEq<[u8]> for ByteStr {
111    fn eq(&self, other: &[u8]) -> bool {
112        &self.0 == other
113    }
114}
115
116impl PartialEq<ByteStr> for [u8] {
117    fn eq(&self, other: &ByteStr) -> bool {
118        self == &other.0
119    }
120}
121
122impl Deref for ByteStr {
123    type Target = [u8];
124
125    fn deref(&self) -> &[u8] {
126        &self.0
127    }
128}
129
130impl DerefMut for ByteStr {
131    fn deref_mut(&mut self) -> &mut [u8] {
132        &mut self.0
133    }
134}
135
136impl<'a> Default for &'a ByteStr {
137    fn default() -> &'a ByteStr {
138        ByteStr::new(&[])
139    }
140}
141
142impl<'a> Default for &'a mut ByteStr {
143    fn default() -> &'a mut ByteStr {
144        ByteStr::new_mut(&mut [])
145    }
146}
147
148impl<'a> IntoIterator for &'a ByteStr {
149    type Item = &'a u8;
150    type IntoIter = std::slice::Iter<'a, u8>;
151
152    fn into_iter(self) -> Self::IntoIter {
153        self.0.into_iter()
154    }
155}
156
157impl<'a> IntoIterator for &'a mut ByteStr {
158    type Item = &'a mut u8;
159    type IntoIter = std::slice::IterMut<'a, u8>;
160
161    fn into_iter(self) -> Self::IntoIter {
162        (&mut self.0).into_iter()
163    }
164}
165
166impl Debug for ByteStr {
167    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
168        try!(write!(f, "b\""));
169
170        for &byte in self {
171            for ch in std::ascii::escape_default(byte) {
172                try!(write!(f, "{}", ch as char));
173            }
174        }
175
176        write!(f, "\"")
177    }
178}
179
180impl ByteString {
181    /// Moves a vector of bytes to a new `ByteString`.
182    pub fn new(s: Vec<u8>) -> ByteString {
183        ByteString(s)
184    }
185}
186
187impl From<Vec<u8>> for ByteString {
188    fn from(s: Vec<u8>) -> ByteString {
189        ByteString::new(s)
190    }
191}
192
193impl From<ByteString> for Vec<u8> {
194    fn from(s: ByteString) -> Vec<u8> {
195        s.0
196    }
197}
198
199impl AsRef<Vec<u8>> for ByteString {
200    fn as_ref(&self) -> &Vec<u8> {
201        &self.0
202    }
203}
204
205impl AsRef<[u8]> for ByteString {
206    fn as_ref(&self) -> &[u8] {
207        &self.0
208    }
209}
210
211impl AsMut<Vec<u8>> for ByteString {
212    fn as_mut(&mut self) -> &mut Vec<u8> {
213        &mut self.0
214    }
215}
216
217impl AsMut<[u8]> for ByteString {
218    fn as_mut(&mut self) -> &mut [u8] {
219        &mut self.0
220    }
221}
222
223impl Borrow<ByteStr> for ByteString {
224    fn borrow(&self) -> &ByteStr {
225        ByteStr::new(&self.0)
226    }
227}
228
229impl Borrow<Vec<u8>> for ByteString {
230    fn borrow(&self) -> &Vec<u8> {
231        &self.0
232    }
233}
234
235impl Borrow<[u8]> for ByteString {
236    fn borrow(&self) -> &[u8] {
237        &self.0
238    }
239}
240
241impl BorrowMut<ByteStr> for ByteString {
242    fn borrow_mut(&mut self) -> &mut ByteStr {
243        ByteStr::new_mut(&mut self.0)
244    }
245}
246
247impl BorrowMut<Vec<u8>> for ByteString {
248    fn borrow_mut(&mut self) -> &mut Vec<u8> {
249        &mut self.0
250    }
251}
252
253impl BorrowMut<[u8]> for ByteString {
254    fn borrow_mut(&mut self) -> &mut [u8] {
255        &mut self.0
256    }
257}
258
259impl PartialEq<Vec<u8>> for ByteString {
260    fn eq(&self, other: &Vec<u8>) -> bool {
261        self.0 == *other
262    }
263}
264
265impl PartialEq<[u8]> for ByteString {
266    fn eq(&self, other: &[u8]) -> bool {
267        self.0 == other
268    }
269}
270
271impl PartialEq<ByteString> for Vec<u8> {
272    fn eq(&self, other: &ByteString) -> bool {
273        self == &other.0
274    }
275}
276
277impl PartialEq<ByteString> for [u8] {
278    fn eq(&self, other: &ByteString) -> bool {
279        self == &other.0[..]
280    }
281}
282
283impl Deref for ByteString {
284    type Target = Vec<u8>;
285
286    fn deref(&self) -> &Vec<u8> {
287        &self.0
288    }
289}
290
291impl DerefMut for ByteString {
292    fn deref_mut(&mut self) -> &mut Vec<u8> {
293        &mut self.0
294    }
295}
296
297impl Default for ByteString {
298    fn default() -> ByteString {
299        ByteString::new(vec![])
300    }
301}
302
303impl FromIterator<u8> for ByteString {
304    fn from_iter<I>(iter: I) -> ByteString
305        where I: IntoIterator<Item=u8>
306    {
307        ByteString::new(Vec::from_iter(iter))
308    }
309}
310
311impl<'a> IntoIterator for ByteString {
312    type Item = u8;
313    type IntoIter = std::vec::IntoIter<u8>;
314
315    fn into_iter(self) -> Self::IntoIter {
316        self.0.into_iter()
317    }
318}
319
320impl<'a> IntoIterator for &'a ByteString {
321    type Item = &'a u8;
322    type IntoIter = std::slice::Iter<'a, u8>;
323
324    fn into_iter(self) -> Self::IntoIter {
325        (&self.0).into_iter()
326    }
327}
328
329impl<'a> IntoIterator for &'a mut ByteString {
330    type Item = &'a mut u8;
331    type IntoIter = std::slice::IterMut<'a, u8>;
332
333    fn into_iter(self) -> Self::IntoIter {
334        (&mut self.0).into_iter()
335    }
336}
337
338impl Debug for ByteString {
339    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
340        // Delegate to ByteStr's implementation
341        Debug::fmt(Borrow::<ByteStr>::borrow(self), f)
342    }
343}
344
345#[cfg(test)]
346mod tests {
347    use super::*;
348
349    const EMPTY: &'static str = "b\"\"";
350    const ALL_BYTES: &'static str = concat!("b\"",
351        "\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f",
352        "\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f",
353        " !\\\"#$%&\\\'()*+,-./",
354        "0123456789:;<=>?",
355        "@ABCDEFGHIJKLMNO",
356        "PQRSTUVWXYZ[\\\\]^_",
357        "`abcdefghijklmno",
358        "pqrstuvwxyz{|}~\\x7f",
359        "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f",
360        "\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f",
361        "\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf",
362        "\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf",
363        "\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf",
364        "\\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf",
365        "\\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef",
366        "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff",
367        "\"");
368
369    #[test]
370    fn debug_bytestr_empty() {
371        let bytes = [];
372        let bs = ByteStr::new(&bytes);
373        let result = format!("{:?}", bs);
374        assert_eq!(result, EMPTY);
375    }
376
377    #[test]
378    fn debug_bytestr() {
379        let bytes = [
380            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
381            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
382            0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
383            0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
384            0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
385            0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
386            0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
387            0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
388            0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
389            0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
390            0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
391            0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
392            0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
393            0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
394            0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
395            0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
396        ];
397        let bs = ByteStr::new(&bytes);
398        let result = format!("{:?}", bs);
399        assert_eq!(result, ALL_BYTES);
400    }
401
402    #[test]
403    fn debug_bytestring_empty() {
404        let bytes = vec![];
405        let bs = ByteString::new(bytes);
406        let result = format!("{:?}", bs);
407        assert_eq!(result, EMPTY);
408    }
409
410    #[test]
411    fn debug_bytestring() {
412        let bytes = vec![
413            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
414            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
415            0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
416            0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
417            0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
418            0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
419            0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
420            0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
421            0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
422            0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
423            0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
424            0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
425            0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
426            0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
427            0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
428            0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
429        ];
430        let bs = ByteString::new(bytes);
431        let result = format!("{:?}", bs);
432        assert_eq!(result, ALL_BYTES);
433    }
434}