1use std::{cmp, fmt, hash, ops, str};
28use bytes::{BufMut, Bytes, BytesMut};
29use ::master::scan::{BadSymbol, CharSource, Scan, Scanner, ScanError, Symbol,
30 SymbolError, SyntaxError};
31use super::compose::Compose;
32use super::parse::{ParseAll, ParseAllError, Parse, Parser, ShortBuf};
33
34
35#[derive(Clone)]
47pub struct CharStr {
48 inner: Bytes
50}
51
52
53impl CharStr {
56 pub fn empty() -> Self {
58 CharStr { inner: Bytes::from_static(b"") }
59 }
60
61 unsafe fn from_bytes_unchecked(bytes: Bytes) -> Self {
65 CharStr { inner: bytes }
66 }
67
68 pub fn from_bytes(bytes: Bytes) -> Result<Self, CharStrError> {
73 if bytes.len() > 255 { Err(CharStrError) }
74 else { Ok(unsafe { Self::from_bytes_unchecked(bytes) })}
75 }
76
77 pub fn from_slice(slice: &[u8]) -> Result<Self, CharStrError> {
85 if slice.len() > 255 { Err(CharStrError) }
86 else { Ok(unsafe { Self::from_bytes_unchecked(slice.into()) })}
87 }
88
89 pub fn into_bytes(self) -> Bytes {
91 self.inner
92 }
93
94 pub fn as_bytes(&self) -> &Bytes {
96 &self.inner
97 }
98
99 pub fn as_slice(&self) -> &[u8] {
101 self.inner.as_ref()
102 }
103
104 pub fn try_into_mut(self) -> Result<CharStrMut, Self> {
113 self.inner.try_mut()
114 .map(|b| unsafe { CharStrMut::from_bytes_unchecked(b) })
115 .map_err(|b| unsafe { CharStr::from_bytes_unchecked(b) })
116 }
117
118 pub fn into_mut(self) -> CharStrMut {
124 unsafe { CharStrMut::from_bytes_unchecked(self.inner.into()) }
125 }
126
127 pub fn scan_hex<C: CharSource>(
129 scanner: &mut Scanner<C>
130 ) -> Result<Self, ScanError> {
131 scanner.scan_hex_word(|b| unsafe {
132 Ok(CharStr::from_bytes_unchecked(b))
133 })
134 }
135
136 pub fn display_hex(&self, f: &mut fmt::Formatter) -> fmt::Result {
138 for ch in self {
139 write!(f, "{:02X}", ch)?;
140 }
141 Ok(())
142 }
143}
144
145
146impl str::FromStr for CharStr {
149 type Err = FromStrError;
150
151 fn from_str(s: &str) -> Result<Self, Self::Err> {
152 let mut res = CharStrMut::with_capacity(s.len());
154 let mut chars = s.chars();
155 while let Some(symbol) = Symbol::from_chars(&mut chars)? {
156 res.push(symbol.into_byte()?)?
157 }
158 Ok(res.freeze())
159 }
160}
161
162
163
164impl Parse for CharStr {
167 type Err = ShortBuf;
168
169 fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
170 let len = parser.parse_u8()? as usize;
171 parser.parse_bytes(len).map(|bytes| {
172 unsafe { Self::from_bytes_unchecked(bytes) }
173 })
174 }
175
176 fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
177 let len = parser.parse_u8()? as usize;
178 parser.advance(len)
179 }
180}
181
182impl ParseAll for CharStr {
183 type Err = ParseAllError;
184
185 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
186 let char_len = parser.parse_u8()? as usize;
187 ParseAllError::check(char_len + 1, len)?;
188 parser.parse_bytes(char_len).map_err(Into::into).map(|bytes| {
189 unsafe { Self::from_bytes_unchecked(bytes) }
190 })
191 }
192}
193
194impl Compose for CharStr {
195 fn compose_len(&self) -> usize {
196 self.len() + 1
197 }
198
199 fn compose<B: BufMut>(&self, buf: &mut B) {
200 buf.put_u8(self.len() as u8);
201 buf.put_slice(self.as_ref());
202 }
203}
204
205
206impl Scan for CharStr {
209 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
210 -> Result<Self, ScanError> {
211 scanner.scan_byte_phrase(|res| {
212 if res.len() > 255 {
213 Err(SyntaxError::LongCharStr)
214 }
215 else {
216 Ok(unsafe { CharStr::from_bytes_unchecked(res) })
217 }
218 })
219 }
220}
221
222impl fmt::Display for CharStr {
223 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
224 for ch in &self.inner {
225 fmt::Display::fmt(&Symbol::from_byte(ch), f)?
226 }
227 Ok(())
228 }
229}
230
231
232impl ops::Deref for CharStr {
235 type Target = Bytes;
236
237 fn deref(&self) -> &Self::Target {
238 &self.inner
239 }
240}
241
242impl AsRef<Bytes> for CharStr {
243 fn as_ref(&self) -> &Bytes {
244 &self.inner
245 }
246}
247
248impl AsRef<[u8]> for CharStr {
249 fn as_ref(&self) -> &[u8] {
250 &self.inner
251 }
252}
253
254
255impl IntoIterator for CharStr {
258 type Item = u8;
259 type IntoIter = ::bytes::buf::Iter<::std::io::Cursor<Bytes>>;
260
261 fn into_iter(self) -> Self::IntoIter {
262 self.inner.into_iter()
263 }
264}
265
266impl<'a> IntoIterator for &'a CharStr {
267 type Item = u8;
268 type IntoIter = ::bytes::buf::Iter<::std::io::Cursor<&'a Bytes>>;
269
270 fn into_iter(self) -> Self::IntoIter {
271 (&self.inner).into_iter()
272 }
273}
274
275
276impl<T: AsRef<[u8]>> PartialEq<T> for CharStr {
279 fn eq(&self, other: &T) -> bool {
280 self.as_slice().eq_ignore_ascii_case(other.as_ref())
281 }
282}
283
284impl Eq for CharStr { }
285
286
287impl<T: AsRef<[u8]>> PartialOrd<T> for CharStr {
290 fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
291 self.iter().map(u8::to_ascii_lowercase)
292 .partial_cmp(other.as_ref().iter()
293 .map(u8::to_ascii_lowercase))
294 }
295}
296
297impl Ord for CharStr {
298 fn cmp(&self, other: &Self) -> cmp::Ordering {
299 self.iter().map(u8::to_ascii_lowercase)
300 .cmp(other.iter().map(u8::to_ascii_lowercase))
301 }
302}
303
304
305impl hash::Hash for CharStr {
308 fn hash<H: hash::Hasher>(&self, state: &mut H) {
309 self.iter().map(u8::to_ascii_lowercase)
310 .for_each(|ch| ch.hash(state))
311 }
312}
313
314
315impl fmt::Debug for CharStr {
318 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
319 try!("CharStr(\"".fmt(f));
320 try!(fmt::Display::fmt(self, f));
321 "\")".fmt(f)
322 }
323}
324
325
326#[derive(Default)]
335pub struct CharStrMut {
336 bytes: BytesMut,
337}
338
339
340impl CharStrMut {
341 unsafe fn from_bytes_unchecked(bytes: BytesMut) -> Self {
346 CharStrMut { bytes }
347 }
348
349 pub fn from_bytes(bytes: BytesMut) -> Result<Self, CharStrError> {
353 if bytes.len() > 255 {
354 Err(CharStrError)
355 }
356 else {
357 Ok(unsafe { Self::from_bytes_unchecked(bytes) })
358 }
359 }
360
361 pub fn with_capacity(capacity: usize) -> Self {
366 unsafe {
367 CharStrMut::from_bytes_unchecked(BytesMut::with_capacity(capacity))
368 }
369 }
370
371 pub fn new() -> Self {
373 Self::default()
374 }
375
376 pub fn len(&self) -> usize {
378 self.bytes.len()
379 }
380
381 pub fn is_empty(&self) -> bool {
383 self.bytes.is_empty()
384 }
385
386 pub fn capacity(&self) -> usize {
388 self.bytes.capacity()
389 }
390
391 pub fn freeze(self) -> CharStr {
393 unsafe { CharStr::from_bytes_unchecked(self.bytes.freeze()) }
394 }
395}
396
397impl CharStrMut {
400 pub fn reserve(&mut self, additional: usize) {
405 self.bytes.reserve(additional)
406 }
407
408 pub fn push(&mut self, ch: u8) -> Result<(), PushError> {
413 self.extend_from_slice(&[ch])
414 }
415
416 pub fn extend_from_slice(&mut self, extend: &[u8])
421 -> Result<(), PushError> {
422 if self.bytes.len() + extend.len() > 255 {
423 Err(PushError)
424 }
425 else {
426 self.bytes.extend_from_slice(extend);
427 Ok(())
428 }
429 }
430}
431
432
433impl ops::Deref for CharStrMut {
436 type Target = [u8];
437
438 fn deref(&self) -> &[u8] {
439 self.bytes.as_ref()
440 }
441}
442
443impl ops::DerefMut for CharStrMut {
444 fn deref_mut(&mut self) -> &mut [u8] {
445 self.bytes.as_mut()
446 }
447}
448
449
450impl AsRef<[u8]> for CharStrMut {
453 fn as_ref(&self) -> &[u8] {
454 self.bytes.as_ref()
455 }
456}
457
458impl AsMut<[u8]> for CharStrMut {
459 fn as_mut(&mut self) -> &mut [u8] {
460 self.bytes.as_mut()
461 }
462}
463
464
465#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
471#[fail(display="illegal character string")]
472pub struct CharStrError;
473
474
475#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
479pub enum FromStrError {
480 #[fail(display="unexpected end of input")]
484 ShortInput,
485
486 #[fail(display="character string with more than 255 octets")]
488 LongString,
489
490 #[fail(display="illegal escape sequence")]
496 BadEscape,
497
498 #[fail(display="illegal character '{}'", _0)]
502 BadSymbol(Symbol),
503}
504
505
506impl From<SymbolError> for FromStrError {
509 fn from(err: SymbolError) -> FromStrError {
510 match err {
511 SymbolError::BadEscape => FromStrError::BadEscape,
512 SymbolError::ShortInput => FromStrError::ShortInput,
513 }
514 }
515}
516
517impl From<BadSymbol> for FromStrError {
518 fn from(err: BadSymbol) -> FromStrError {
519 FromStrError::BadSymbol(err.0)
520 }
521}
522
523impl From<PushError> for FromStrError {
524 fn from(_: PushError) -> FromStrError {
525 FromStrError::LongString
526 }
527}
528
529
530#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
539#[fail(display="adding bytes would exceed the size limit")]
540pub struct PushError;
541
542
543#[cfg(test)]
546mod test {
547 use super::*;
548 use ::master::scan::Symbol;
549
550 #[test]
551 fn from_slice() {
552 assert_eq!(CharStr::from_slice(b"01234").unwrap().as_slice(),
553 b"01234");
554 assert_eq!(CharStr::from_slice(b"").unwrap().as_slice(), b"");
555 assert!(CharStr::from_slice(&vec![0; 255]).is_ok());
556 assert!(CharStr::from_slice(&vec![0; 256]).is_err());
557 }
558
559 #[test]
560 fn from_bytes() {
561 assert_eq!(CharStr::from_bytes(Bytes::from_static(b"01234"))
562 .unwrap() .as_slice(),
563 b"01234");
564 assert_eq!(CharStr::from_bytes(Bytes::from_static(b""))
565 .unwrap().as_slice(),
566 b"");
567 assert!(CharStr::from_bytes(vec![0; 255].into()).is_ok());
568 assert!(CharStr::from_bytes(vec![0; 256].into()).is_err());
569 }
570
571 #[test]
572 fn from_str() {
573 use std::str::FromStr;
574
575 assert_eq!(CharStr::from_str("foo").unwrap().as_slice(),
576 b"foo");
577 assert_eq!(CharStr::from_str("f\\oo").unwrap().as_slice(),
578 b"foo");
579 assert_eq!(CharStr::from_str("foo\\112").unwrap().as_slice(),
580 b"foo\x70");
581 assert_eq!(CharStr::from_str("\"foo\\\"2\"").unwrap().as_slice(),
582 b"\"foo\"2\"");
583 assert_eq!(CharStr::from_str("06 dii").unwrap().as_slice(),
584 b"06 dii");
585 assert_eq!(CharStr::from_str("0\\"), Err(FromStrError::ShortInput));
586 assert_eq!(CharStr::from_str("0\\2"), Err(FromStrError::ShortInput));
587 assert_eq!(CharStr::from_str("0\\2a"),
588 Err(FromStrError::BadEscape));
589 assert_eq!(CharStr::from_str("ö"),
590 Err(FromStrError::BadSymbol(Symbol::Char('ö'))));
591 assert_eq!(CharStr::from_str("\x06"),
592 Err(FromStrError::BadSymbol(Symbol::Char('\x06'))));
593 }
594
595 #[test]
596 fn parse() {
597 use ::bits::parse::{Parse, Parser, ShortBuf};
598
599 let mut parser = Parser::from_static(b"12\x03foo\x02bartail");
600 parser.advance(2).unwrap();
601 let foo = CharStr::parse(&mut parser).unwrap();
602 let bar = CharStr::parse(&mut parser).unwrap();
603 assert_eq!(foo.as_slice(), b"foo");
604 assert_eq!(bar.as_slice(), b"ba");
605 assert_eq!(parser.peek_all(), b"rtail");
606
607 assert_eq!(CharStr::parse(&mut Parser::from_static(b"\x04foo")),
608 Err(ShortBuf))
609 }
610
611 #[test]
612 fn parse_all() {
613 use ::bits::parse::{ParseAll, ParseAllError, Parser};
614
615 let mut parser = Parser::from_static(b"12\x03foo12");
616 parser.advance(2).unwrap();
617 assert_eq!(CharStr::parse_all(&mut parser.clone(), 5),
618 Err(ParseAllError::TrailingData));
619 assert_eq!(CharStr::parse_all(&mut parser.clone(), 2),
620 Err(ParseAllError::ShortField));
621 let foo = CharStr::parse_all(&mut parser, 4).unwrap();
622 let bar = u8::parse_all(&mut parser, 1).unwrap();
623 assert_eq!(foo.as_slice(), b"foo");
624 assert_eq!(bar, b'1');
625 assert_eq!(parser.peek_all(), b"2");
626
627 assert_eq!(CharStr::parse_all(&mut Parser::from_static(b"\x04foo"), 5),
628 Err(ParseAllError::ShortBuf));
629 }
630
631 #[test]
632 fn compose() {
633 use bytes::BytesMut;
634 use bits::compose::Compose;
635
636 let mut buf = BytesMut::with_capacity(10);
637 let val = CharStr::from_bytes(Bytes::from_static(b"foo")).unwrap();
638 assert_eq!(val.compose_len(), 4);
639 val.compose(&mut buf);
640 assert_eq!(buf, &b"\x03foo"[..]);
641
642 let mut buf = BytesMut::with_capacity(10);
643 let val = CharStr::from_bytes(Bytes::from_static(b"")).unwrap();
644 assert_eq!(val.compose_len(), 1);
645 val.compose(&mut buf);
646 assert_eq!(buf, &b"\x00"[..]);
647 }
648
649 fn are_eq(l: &[u8], r: &[u8]) -> bool {
650 CharStr::from_slice(l).unwrap() == CharStr::from_slice(r).unwrap()
651 }
652
653 #[test]
654 fn eq() {
655 assert!(are_eq(b"abc", b"abc"));
656 assert!(!are_eq(b"abc", b"def"));
657 assert!(!are_eq(b"abc", b"ab"));
658 assert!(!are_eq(b"abc", b"abcd"));
659 assert!(are_eq(b"ABC", b"abc"));
660 assert!(!are_eq(b"ABC", b"def"));
661 assert!(!are_eq(b"ABC", b"ab"));
662 assert!(!are_eq(b"ABC", b"abcd"));
663 assert!(are_eq(b"", b""));
664 assert!(!are_eq(b"", b"A"));
665 }
666
667 fn is_ord(l: &[u8], r: &[u8], order: cmp::Ordering) {
668 assert_eq!(CharStr::from_slice(l)
669 .unwrap().cmp(&CharStr::from_slice(r).unwrap()),
670 order)
671 }
672
673 #[test]
674 fn ord() {
675 use std::cmp::Ordering::*;
676
677 is_ord(b"abc", b"ABC", Equal);
678 is_ord(b"abc", b"a", Greater);
679 is_ord(b"abc", b"A", Greater);
680 is_ord(b"a", b"BC", Less);
681 }
682
683 #[test]
684 fn push() {
685 let mut o = CharStrMut::new();
686 o.push(b'f').unwrap();
687 o.push(b'o').unwrap();
688 o.push(b'o').unwrap();
689 assert_eq!(o.freeze().as_slice(), b"foo");
690
691 let mut o = CharStrMut::from_bytes(vec![0; 254].into()).unwrap();
692 o.push(b'f').unwrap();
693 assert_eq!(o.len(), 255);
694 assert!(o.push(b'f').is_err());
695 }
696
697 #[test]
698 fn extend_from_slice() {
699 let mut o = CharStrMut::from_bytes(vec![b'f', b'o', b'o'].into())
700 .unwrap();
701 o.extend_from_slice(b"bar").unwrap();
702 assert_eq!(o.as_ref(), b"foobar");
703 assert!(o.extend_from_slice(&[0u8; 250][..]).is_err());
704 o.extend_from_slice(&[0u8; 249][..]).unwrap();
705 assert_eq!(o.len(), 255);
706 }
707}
708