1 //! Traits input types have to implement to work with nom combinators
2 use crate::error::{ErrorKind, ParseError};
3 use crate::internal::{Err, IResult, Needed};
4 use crate::lib::std::iter::{Copied, Enumerate};
5 use crate::lib::std::ops::{Range, RangeFrom, RangeFull, RangeTo};
6 use crate::lib::std::slice::Iter;
7 use crate::lib::std::str::from_utf8;
8 use crate::lib::std::str::CharIndices;
9 use crate::lib::std::str::Chars;
10 use crate::lib::std::str::FromStr;
11
12 #[cfg(feature = "alloc")]
13 use crate::lib::std::string::String;
14 #[cfg(feature = "alloc")]
15 use crate::lib::std::vec::Vec;
16
17 /// Abstract method to calculate the input length
18 pub trait InputLength {
19 /// Calculates the input length, as indicated by its name,
20 /// and the name of the trait itself
input_len(&self) -> usize21 fn input_len(&self) -> usize;
22 }
23
24 impl<'a, T> InputLength for &'a [T] {
25 #[inline]
input_len(&self) -> usize26 fn input_len(&self) -> usize {
27 self.len()
28 }
29 }
30
31 impl<'a> InputLength for &'a str {
32 #[inline]
input_len(&self) -> usize33 fn input_len(&self) -> usize {
34 self.len()
35 }
36 }
37
38 impl<'a> InputLength for (&'a [u8], usize) {
39 #[inline]
input_len(&self) -> usize40 fn input_len(&self) -> usize {
41 //println!("bit input length for ({:?}, {}):", self.0, self.1);
42 //println!("-> {}", self.0.len() * 8 - self.1);
43 self.0.len() * 8 - self.1
44 }
45 }
46
47 /// Useful functions to calculate the offset between slices and show a hexdump of a slice
48 pub trait Offset {
49 /// Offset between the first byte of self and the first byte of the argument
offset(&self, second: &Self) -> usize50 fn offset(&self, second: &Self) -> usize;
51 }
52
53 impl Offset for [u8] {
offset(&self, second: &Self) -> usize54 fn offset(&self, second: &Self) -> usize {
55 let fst = self.as_ptr();
56 let snd = second.as_ptr();
57
58 snd as usize - fst as usize
59 }
60 }
61
62 impl<'a> Offset for &'a [u8] {
offset(&self, second: &Self) -> usize63 fn offset(&self, second: &Self) -> usize {
64 let fst = self.as_ptr();
65 let snd = second.as_ptr();
66
67 snd as usize - fst as usize
68 }
69 }
70
71 impl Offset for str {
offset(&self, second: &Self) -> usize72 fn offset(&self, second: &Self) -> usize {
73 let fst = self.as_ptr();
74 let snd = second.as_ptr();
75
76 snd as usize - fst as usize
77 }
78 }
79
80 impl<'a> Offset for &'a str {
offset(&self, second: &Self) -> usize81 fn offset(&self, second: &Self) -> usize {
82 let fst = self.as_ptr();
83 let snd = second.as_ptr();
84
85 snd as usize - fst as usize
86 }
87 }
88
89 /// Helper trait for types that can be viewed as a byte slice
90 pub trait AsBytes {
91 /// Casts the input type to a byte slice
as_bytes(&self) -> &[u8]92 fn as_bytes(&self) -> &[u8];
93 }
94
95 impl<'a> AsBytes for &'a str {
96 #[inline(always)]
as_bytes(&self) -> &[u8]97 fn as_bytes(&self) -> &[u8] {
98 (*self).as_bytes()
99 }
100 }
101
102 impl AsBytes for str {
103 #[inline(always)]
as_bytes(&self) -> &[u8]104 fn as_bytes(&self) -> &[u8] {
105 self.as_ref()
106 }
107 }
108
109 impl<'a> AsBytes for &'a [u8] {
110 #[inline(always)]
as_bytes(&self) -> &[u8]111 fn as_bytes(&self) -> &[u8] {
112 *self
113 }
114 }
115
116 impl AsBytes for [u8] {
117 #[inline(always)]
as_bytes(&self) -> &[u8]118 fn as_bytes(&self) -> &[u8] {
119 self
120 }
121 }
122
123 macro_rules! as_bytes_array_impls {
124 ($($N:expr)+) => {
125 $(
126 impl<'a> AsBytes for &'a [u8; $N] {
127 #[inline(always)]
128 fn as_bytes(&self) -> &[u8] {
129 *self
130 }
131 }
132
133 impl AsBytes for [u8; $N] {
134 #[inline(always)]
135 fn as_bytes(&self) -> &[u8] {
136 self
137 }
138 }
139 )+
140 };
141 }
142
143 as_bytes_array_impls! {
144 0 1 2 3 4 5 6 7 8 9
145 10 11 12 13 14 15 16 17 18 19
146 20 21 22 23 24 25 26 27 28 29
147 30 31 32
148 }
149
150 /// Transforms common types to a char for basic token parsing
151 pub trait AsChar {
152 /// makes a char from self
as_char(self) -> char153 fn as_char(self) -> char;
154
155 /// Tests that self is an alphabetic character
156 ///
157 /// Warning: for `&str` it recognizes alphabetic
158 /// characters outside of the 52 ASCII letters
is_alpha(self) -> bool159 fn is_alpha(self) -> bool;
160
161 /// Tests that self is an alphabetic character
162 /// or a decimal digit
is_alphanum(self) -> bool163 fn is_alphanum(self) -> bool;
164 /// Tests that self is a decimal digit
is_dec_digit(self) -> bool165 fn is_dec_digit(self) -> bool;
166 /// Tests that self is an hex digit
is_hex_digit(self) -> bool167 fn is_hex_digit(self) -> bool;
168 /// Tests that self is an octal digit
is_oct_digit(self) -> bool169 fn is_oct_digit(self) -> bool;
170 /// Gets the len in bytes for self
len(self) -> usize171 fn len(self) -> usize;
172 }
173
174 impl AsChar for u8 {
175 #[inline]
as_char(self) -> char176 fn as_char(self) -> char {
177 self as char
178 }
179 #[inline]
is_alpha(self) -> bool180 fn is_alpha(self) -> bool {
181 (self >= 0x41 && self <= 0x5A) || (self >= 0x61 && self <= 0x7A)
182 }
183 #[inline]
is_alphanum(self) -> bool184 fn is_alphanum(self) -> bool {
185 self.is_alpha() || self.is_dec_digit()
186 }
187 #[inline]
is_dec_digit(self) -> bool188 fn is_dec_digit(self) -> bool {
189 self >= 0x30 && self <= 0x39
190 }
191 #[inline]
is_hex_digit(self) -> bool192 fn is_hex_digit(self) -> bool {
193 (self >= 0x30 && self <= 0x39)
194 || (self >= 0x41 && self <= 0x46)
195 || (self >= 0x61 && self <= 0x66)
196 }
197 #[inline]
is_oct_digit(self) -> bool198 fn is_oct_digit(self) -> bool {
199 self >= 0x30 && self <= 0x37
200 }
201 #[inline]
len(self) -> usize202 fn len(self) -> usize {
203 1
204 }
205 }
206 impl<'a> AsChar for &'a u8 {
207 #[inline]
as_char(self) -> char208 fn as_char(self) -> char {
209 *self as char
210 }
211 #[inline]
is_alpha(self) -> bool212 fn is_alpha(self) -> bool {
213 (*self >= 0x41 && *self <= 0x5A) || (*self >= 0x61 && *self <= 0x7A)
214 }
215 #[inline]
is_alphanum(self) -> bool216 fn is_alphanum(self) -> bool {
217 self.is_alpha() || self.is_dec_digit()
218 }
219 #[inline]
is_dec_digit(self) -> bool220 fn is_dec_digit(self) -> bool {
221 *self >= 0x30 && *self <= 0x39
222 }
223 #[inline]
is_hex_digit(self) -> bool224 fn is_hex_digit(self) -> bool {
225 (*self >= 0x30 && *self <= 0x39)
226 || (*self >= 0x41 && *self <= 0x46)
227 || (*self >= 0x61 && *self <= 0x66)
228 }
229 #[inline]
is_oct_digit(self) -> bool230 fn is_oct_digit(self) -> bool {
231 *self >= 0x30 && *self <= 0x37
232 }
233 #[inline]
len(self) -> usize234 fn len(self) -> usize {
235 1
236 }
237 }
238
239 impl AsChar for char {
240 #[inline]
as_char(self) -> char241 fn as_char(self) -> char {
242 self
243 }
244 #[inline]
is_alpha(self) -> bool245 fn is_alpha(self) -> bool {
246 self.is_ascii_alphabetic()
247 }
248 #[inline]
is_alphanum(self) -> bool249 fn is_alphanum(self) -> bool {
250 self.is_alpha() || self.is_dec_digit()
251 }
252 #[inline]
is_dec_digit(self) -> bool253 fn is_dec_digit(self) -> bool {
254 self.is_ascii_digit()
255 }
256 #[inline]
is_hex_digit(self) -> bool257 fn is_hex_digit(self) -> bool {
258 self.is_ascii_hexdigit()
259 }
260 #[inline]
is_oct_digit(self) -> bool261 fn is_oct_digit(self) -> bool {
262 self.is_digit(8)
263 }
264 #[inline]
len(self) -> usize265 fn len(self) -> usize {
266 self.len_utf8()
267 }
268 }
269
270 impl<'a> AsChar for &'a char {
271 #[inline]
as_char(self) -> char272 fn as_char(self) -> char {
273 *self
274 }
275 #[inline]
is_alpha(self) -> bool276 fn is_alpha(self) -> bool {
277 self.is_ascii_alphabetic()
278 }
279 #[inline]
is_alphanum(self) -> bool280 fn is_alphanum(self) -> bool {
281 self.is_alpha() || self.is_dec_digit()
282 }
283 #[inline]
is_dec_digit(self) -> bool284 fn is_dec_digit(self) -> bool {
285 self.is_ascii_digit()
286 }
287 #[inline]
is_hex_digit(self) -> bool288 fn is_hex_digit(self) -> bool {
289 self.is_ascii_hexdigit()
290 }
291 #[inline]
is_oct_digit(self) -> bool292 fn is_oct_digit(self) -> bool {
293 self.is_digit(8)
294 }
295 #[inline]
len(self) -> usize296 fn len(self) -> usize {
297 self.len_utf8()
298 }
299 }
300
301 /// Abstracts common iteration operations on the input type
302 pub trait InputIter {
303 /// The current input type is a sequence of that `Item` type.
304 ///
305 /// Example: `u8` for `&[u8]` or `char` for `&str`
306 type Item;
307 /// An iterator over the input type, producing the item and its position
308 /// for use with [Slice]. If we're iterating over `&str`, the position
309 /// corresponds to the byte index of the character
310 type Iter: Iterator<Item = (usize, Self::Item)>;
311
312 /// An iterator over the input type, producing the item
313 type IterElem: Iterator<Item = Self::Item>;
314
315 /// Returns an iterator over the elements and their byte offsets
iter_indices(&self) -> Self::Iter316 fn iter_indices(&self) -> Self::Iter;
317 /// Returns an iterator over the elements
iter_elements(&self) -> Self::IterElem318 fn iter_elements(&self) -> Self::IterElem;
319 /// Finds the byte position of the element
position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::Item) -> bool320 fn position<P>(&self, predicate: P) -> Option<usize>
321 where
322 P: Fn(Self::Item) -> bool;
323 /// Get the byte offset from the element's position in the stream
slice_index(&self, count: usize) -> Result<usize, Needed>324 fn slice_index(&self, count: usize) -> Result<usize, Needed>;
325 }
326
327 /// Abstracts slicing operations
328 pub trait InputTake: Sized {
329 /// Returns a slice of `count` bytes. panics if count > length
take(&self, count: usize) -> Self330 fn take(&self, count: usize) -> Self;
331 /// Split the stream at the `count` byte offset. panics if count > length
take_split(&self, count: usize) -> (Self, Self)332 fn take_split(&self, count: usize) -> (Self, Self);
333 }
334
335 impl<'a> InputIter for &'a [u8] {
336 type Item = u8;
337 type Iter = Enumerate<Self::IterElem>;
338 type IterElem = Copied<Iter<'a, u8>>;
339
340 #[inline]
iter_indices(&self) -> Self::Iter341 fn iter_indices(&self) -> Self::Iter {
342 self.iter_elements().enumerate()
343 }
344 #[inline]
iter_elements(&self) -> Self::IterElem345 fn iter_elements(&self) -> Self::IterElem {
346 self.iter().copied()
347 }
348 #[inline]
position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::Item) -> bool,349 fn position<P>(&self, predicate: P) -> Option<usize>
350 where
351 P: Fn(Self::Item) -> bool,
352 {
353 self.iter().position(|b| predicate(*b))
354 }
355 #[inline]
slice_index(&self, count: usize) -> Result<usize, Needed>356 fn slice_index(&self, count: usize) -> Result<usize, Needed> {
357 if self.len() >= count {
358 Ok(count)
359 } else {
360 Err(Needed::new(count - self.len()))
361 }
362 }
363 }
364
365 impl<'a> InputTake for &'a [u8] {
366 #[inline]
take(&self, count: usize) -> Self367 fn take(&self, count: usize) -> Self {
368 &self[0..count]
369 }
370 #[inline]
take_split(&self, count: usize) -> (Self, Self)371 fn take_split(&self, count: usize) -> (Self, Self) {
372 let (prefix, suffix) = self.split_at(count);
373 (suffix, prefix)
374 }
375 }
376
377 impl<'a> InputIter for &'a str {
378 type Item = char;
379 type Iter = CharIndices<'a>;
380 type IterElem = Chars<'a>;
381 #[inline]
iter_indices(&self) -> Self::Iter382 fn iter_indices(&self) -> Self::Iter {
383 self.char_indices()
384 }
385 #[inline]
iter_elements(&self) -> Self::IterElem386 fn iter_elements(&self) -> Self::IterElem {
387 self.chars()
388 }
position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::Item) -> bool,389 fn position<P>(&self, predicate: P) -> Option<usize>
390 where
391 P: Fn(Self::Item) -> bool,
392 {
393 for (o, c) in self.char_indices() {
394 if predicate(c) {
395 return Some(o);
396 }
397 }
398 None
399 }
400 #[inline]
slice_index(&self, count: usize) -> Result<usize, Needed>401 fn slice_index(&self, count: usize) -> Result<usize, Needed> {
402 let mut cnt = 0;
403 for (index, _) in self.char_indices() {
404 if cnt == count {
405 return Ok(index);
406 }
407 cnt += 1;
408 }
409 if cnt == count {
410 return Ok(self.len());
411 }
412 Err(Needed::Unknown)
413 }
414 }
415
416 impl<'a> InputTake for &'a str {
417 #[inline]
take(&self, count: usize) -> Self418 fn take(&self, count: usize) -> Self {
419 &self[..count]
420 }
421
422 // return byte index
423 #[inline]
take_split(&self, count: usize) -> (Self, Self)424 fn take_split(&self, count: usize) -> (Self, Self) {
425 let (prefix, suffix) = self.split_at(count);
426 (suffix, prefix)
427 }
428 }
429
430 /// Dummy trait used for default implementations (currently only used for `InputTakeAtPosition` and `Compare`).
431 ///
432 /// When implementing a custom input type, it is possible to use directly the
433 /// default implementation: If the input type implements `InputLength`, `InputIter`,
434 /// `InputTake` and `Clone`, you can implement `UnspecializedInput` and get
435 /// a default version of `InputTakeAtPosition` and `Compare`.
436 ///
437 /// For performance reasons, you might want to write a custom implementation of
438 /// `InputTakeAtPosition` (like the one for `&[u8]`).
439 pub trait UnspecializedInput {}
440
441 /// Methods to take as much input as possible until the provided function returns true for the current element.
442 ///
443 /// A large part of nom's basic parsers are built using this trait.
444 pub trait InputTakeAtPosition: Sized {
445 /// The current input type is a sequence of that `Item` type.
446 ///
447 /// Example: `u8` for `&[u8]` or `char` for `&str`
448 type Item;
449
450 /// Looks for the first element of the input type for which the condition returns true,
451 /// and returns the input up to this position.
452 ///
453 /// *streaming version*: If no element is found matching the condition, this will return `Incomplete`
split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool454 fn split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
455 where
456 P: Fn(Self::Item) -> bool;
457
458 /// Looks for the first element of the input type for which the condition returns true
459 /// and returns the input up to this position.
460 ///
461 /// Fails if the produced slice is empty.
462 ///
463 /// *streaming version*: If no element is found matching the condition, this will return `Incomplete`
split_at_position1<P, E: ParseError<Self>>( &self, predicate: P, e: ErrorKind, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool464 fn split_at_position1<P, E: ParseError<Self>>(
465 &self,
466 predicate: P,
467 e: ErrorKind,
468 ) -> IResult<Self, Self, E>
469 where
470 P: Fn(Self::Item) -> bool;
471
472 /// Looks for the first element of the input type for which the condition returns true,
473 /// and returns the input up to this position.
474 ///
475 /// *complete version*: If no element is found matching the condition, this will return the whole input
split_at_position_complete<P, E: ParseError<Self>>( &self, predicate: P, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool476 fn split_at_position_complete<P, E: ParseError<Self>>(
477 &self,
478 predicate: P,
479 ) -> IResult<Self, Self, E>
480 where
481 P: Fn(Self::Item) -> bool;
482
483 /// Looks for the first element of the input type for which the condition returns true
484 /// and returns the input up to this position.
485 ///
486 /// Fails if the produced slice is empty.
487 ///
488 /// *complete version*: If no element is found matching the condition, this will return the whole input
split_at_position1_complete<P, E: ParseError<Self>>( &self, predicate: P, e: ErrorKind, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool489 fn split_at_position1_complete<P, E: ParseError<Self>>(
490 &self,
491 predicate: P,
492 e: ErrorKind,
493 ) -> IResult<Self, Self, E>
494 where
495 P: Fn(Self::Item) -> bool;
496 }
497
498 impl<T: InputLength + InputIter + InputTake + Clone + UnspecializedInput> InputTakeAtPosition
499 for T
500 {
501 type Item = <T as InputIter>::Item;
502
split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,503 fn split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
504 where
505 P: Fn(Self::Item) -> bool,
506 {
507 match self.position(predicate) {
508 Some(n) => Ok(self.take_split(n)),
509 None => Err(Err::Incomplete(Needed::new(1))),
510 }
511 }
512
split_at_position1<P, E: ParseError<Self>>( &self, predicate: P, e: ErrorKind, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,513 fn split_at_position1<P, E: ParseError<Self>>(
514 &self,
515 predicate: P,
516 e: ErrorKind,
517 ) -> IResult<Self, Self, E>
518 where
519 P: Fn(Self::Item) -> bool,
520 {
521 match self.position(predicate) {
522 Some(0) => Err(Err::Error(E::from_error_kind(self.clone(), e))),
523 Some(n) => Ok(self.take_split(n)),
524 None => Err(Err::Incomplete(Needed::new(1))),
525 }
526 }
527
split_at_position_complete<P, E: ParseError<Self>>( &self, predicate: P, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,528 fn split_at_position_complete<P, E: ParseError<Self>>(
529 &self,
530 predicate: P,
531 ) -> IResult<Self, Self, E>
532 where
533 P: Fn(Self::Item) -> bool,
534 {
535 match self.split_at_position(predicate) {
536 Err(Err::Incomplete(_)) => Ok(self.take_split(self.input_len())),
537 res => res,
538 }
539 }
540
split_at_position1_complete<P, E: ParseError<Self>>( &self, predicate: P, e: ErrorKind, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,541 fn split_at_position1_complete<P, E: ParseError<Self>>(
542 &self,
543 predicate: P,
544 e: ErrorKind,
545 ) -> IResult<Self, Self, E>
546 where
547 P: Fn(Self::Item) -> bool,
548 {
549 match self.split_at_position1(predicate, e) {
550 Err(Err::Incomplete(_)) => {
551 if self.input_len() == 0 {
552 Err(Err::Error(E::from_error_kind(self.clone(), e)))
553 } else {
554 Ok(self.take_split(self.input_len()))
555 }
556 }
557 res => res,
558 }
559 }
560 }
561
562 impl<'a> InputTakeAtPosition for &'a [u8] {
563 type Item = u8;
564
split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,565 fn split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
566 where
567 P: Fn(Self::Item) -> bool,
568 {
569 match self.iter().position(|c| predicate(*c)) {
570 Some(i) => Ok(self.take_split(i)),
571 None => Err(Err::Incomplete(Needed::new(1))),
572 }
573 }
574
split_at_position1<P, E: ParseError<Self>>( &self, predicate: P, e: ErrorKind, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,575 fn split_at_position1<P, E: ParseError<Self>>(
576 &self,
577 predicate: P,
578 e: ErrorKind,
579 ) -> IResult<Self, Self, E>
580 where
581 P: Fn(Self::Item) -> bool,
582 {
583 match self.iter().position(|c| predicate(*c)) {
584 Some(0) => Err(Err::Error(E::from_error_kind(self, e))),
585 Some(i) => Ok(self.take_split(i)),
586 None => Err(Err::Incomplete(Needed::new(1))),
587 }
588 }
589
split_at_position_complete<P, E: ParseError<Self>>( &self, predicate: P, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,590 fn split_at_position_complete<P, E: ParseError<Self>>(
591 &self,
592 predicate: P,
593 ) -> IResult<Self, Self, E>
594 where
595 P: Fn(Self::Item) -> bool,
596 {
597 match self.iter().position(|c| predicate(*c)) {
598 Some(i) => Ok(self.take_split(i)),
599 None => Ok(self.take_split(self.input_len())),
600 }
601 }
602
split_at_position1_complete<P, E: ParseError<Self>>( &self, predicate: P, e: ErrorKind, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,603 fn split_at_position1_complete<P, E: ParseError<Self>>(
604 &self,
605 predicate: P,
606 e: ErrorKind,
607 ) -> IResult<Self, Self, E>
608 where
609 P: Fn(Self::Item) -> bool,
610 {
611 match self.iter().position(|c| predicate(*c)) {
612 Some(0) => Err(Err::Error(E::from_error_kind(self, e))),
613 Some(i) => Ok(self.take_split(i)),
614 None => {
615 if self.is_empty() {
616 Err(Err::Error(E::from_error_kind(self, e)))
617 } else {
618 Ok(self.take_split(self.input_len()))
619 }
620 }
621 }
622 }
623 }
624
625 impl<'a> InputTakeAtPosition for &'a str {
626 type Item = char;
627
split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,628 fn split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
629 where
630 P: Fn(Self::Item) -> bool,
631 {
632 match self.find(predicate) {
633 // find() returns a byte index that is already in the slice at a char boundary
634 Some(i) => unsafe { Ok((self.get_unchecked(i..), self.get_unchecked(..i))) },
635 None => Err(Err::Incomplete(Needed::new(1))),
636 }
637 }
638
split_at_position1<P, E: ParseError<Self>>( &self, predicate: P, e: ErrorKind, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,639 fn split_at_position1<P, E: ParseError<Self>>(
640 &self,
641 predicate: P,
642 e: ErrorKind,
643 ) -> IResult<Self, Self, E>
644 where
645 P: Fn(Self::Item) -> bool,
646 {
647 match self.find(predicate) {
648 Some(0) => Err(Err::Error(E::from_error_kind(self, e))),
649 // find() returns a byte index that is already in the slice at a char boundary
650 Some(i) => unsafe { Ok((self.get_unchecked(i..), self.get_unchecked(..i))) },
651 None => Err(Err::Incomplete(Needed::new(1))),
652 }
653 }
654
split_at_position_complete<P, E: ParseError<Self>>( &self, predicate: P, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,655 fn split_at_position_complete<P, E: ParseError<Self>>(
656 &self,
657 predicate: P,
658 ) -> IResult<Self, Self, E>
659 where
660 P: Fn(Self::Item) -> bool,
661 {
662 match self.find(predicate) {
663 // find() returns a byte index that is already in the slice at a char boundary
664 Some(i) => unsafe { Ok((self.get_unchecked(i..), self.get_unchecked(..i))) },
665 // the end of slice is a char boundary
666 None => unsafe {
667 Ok((
668 self.get_unchecked(self.len()..),
669 self.get_unchecked(..self.len()),
670 ))
671 },
672 }
673 }
674
split_at_position1_complete<P, E: ParseError<Self>>( &self, predicate: P, e: ErrorKind, ) -> IResult<Self, Self, E> where P: Fn(Self::Item) -> bool,675 fn split_at_position1_complete<P, E: ParseError<Self>>(
676 &self,
677 predicate: P,
678 e: ErrorKind,
679 ) -> IResult<Self, Self, E>
680 where
681 P: Fn(Self::Item) -> bool,
682 {
683 match self.find(predicate) {
684 Some(0) => Err(Err::Error(E::from_error_kind(self, e))),
685 // find() returns a byte index that is already in the slice at a char boundary
686 Some(i) => unsafe { Ok((self.get_unchecked(i..), self.get_unchecked(..i))) },
687 None => {
688 if self.is_empty() {
689 Err(Err::Error(E::from_error_kind(self, e)))
690 } else {
691 // the end of slice is a char boundary
692 unsafe {
693 Ok((
694 self.get_unchecked(self.len()..),
695 self.get_unchecked(..self.len()),
696 ))
697 }
698 }
699 }
700 }
701 }
702 }
703
704 /// Indicates wether a comparison was successful, an error, or
705 /// if more data was needed
706 #[derive(Debug, PartialEq)]
707 pub enum CompareResult {
708 /// Comparison was successful
709 Ok,
710 /// We need more data to be sure
711 Incomplete,
712 /// Comparison failed
713 Error,
714 }
715
716 /// Abstracts comparison operations
717 pub trait Compare<T> {
718 /// Compares self to another value for equality
compare(&self, t: T) -> CompareResult719 fn compare(&self, t: T) -> CompareResult;
720 /// Compares self to another value for equality
721 /// independently of the case.
722 ///
723 /// Warning: for `&str`, the comparison is done
724 /// by lowercasing both strings and comparing
725 /// the result. This is a temporary solution until
726 /// a better one appears
compare_no_case(&self, t: T) -> CompareResult727 fn compare_no_case(&self, t: T) -> CompareResult;
728 }
729
lowercase_byte(c: u8) -> u8730 fn lowercase_byte(c: u8) -> u8 {
731 match c {
732 b'A'..=b'Z' => c - b'A' + b'a',
733 _ => c,
734 }
735 }
736
737 impl<'a, 'b> Compare<&'b [u8]> for &'a [u8] {
738 #[inline(always)]
compare(&self, t: &'b [u8]) -> CompareResult739 fn compare(&self, t: &'b [u8]) -> CompareResult {
740 let pos = self.iter().zip(t.iter()).position(|(a, b)| a != b);
741
742 match pos {
743 Some(_) => CompareResult::Error,
744 None => {
745 if self.len() >= t.len() {
746 CompareResult::Ok
747 } else {
748 CompareResult::Incomplete
749 }
750 }
751 }
752
753 /*
754 let len = self.len();
755 let blen = t.len();
756 let m = if len < blen { len } else { blen };
757 let reduced = &self[..m];
758 let b = &t[..m];
759
760 if reduced != b {
761 CompareResult::Error
762 } else if m < blen {
763 CompareResult::Incomplete
764 } else {
765 CompareResult::Ok
766 }
767 */
768 }
769
770 #[inline(always)]
compare_no_case(&self, t: &'b [u8]) -> CompareResult771 fn compare_no_case(&self, t: &'b [u8]) -> CompareResult {
772 if self
773 .iter()
774 .zip(t)
775 .any(|(a, b)| lowercase_byte(*a) != lowercase_byte(*b))
776 {
777 CompareResult::Error
778 } else if self.len() < t.len() {
779 CompareResult::Incomplete
780 } else {
781 CompareResult::Ok
782 }
783 }
784 }
785
786 impl<
787 T: InputLength + InputIter<Item = u8> + InputTake + UnspecializedInput,
788 O: InputLength + InputIter<Item = u8> + InputTake,
789 > Compare<O> for T
790 {
791 #[inline(always)]
compare(&self, t: O) -> CompareResult792 fn compare(&self, t: O) -> CompareResult {
793 let pos = self
794 .iter_elements()
795 .zip(t.iter_elements())
796 .position(|(a, b)| a != b);
797
798 match pos {
799 Some(_) => CompareResult::Error,
800 None => {
801 if self.input_len() >= t.input_len() {
802 CompareResult::Ok
803 } else {
804 CompareResult::Incomplete
805 }
806 }
807 }
808 }
809
810 #[inline(always)]
compare_no_case(&self, t: O) -> CompareResult811 fn compare_no_case(&self, t: O) -> CompareResult {
812 if self
813 .iter_elements()
814 .zip(t.iter_elements())
815 .any(|(a, b)| lowercase_byte(a) != lowercase_byte(b))
816 {
817 CompareResult::Error
818 } else if self.input_len() < t.input_len() {
819 CompareResult::Incomplete
820 } else {
821 CompareResult::Ok
822 }
823 }
824 }
825
826 impl<'a, 'b> Compare<&'b str> for &'a [u8] {
827 #[inline(always)]
compare(&self, t: &'b str) -> CompareResult828 fn compare(&self, t: &'b str) -> CompareResult {
829 self.compare(AsBytes::as_bytes(t))
830 }
831 #[inline(always)]
compare_no_case(&self, t: &'b str) -> CompareResult832 fn compare_no_case(&self, t: &'b str) -> CompareResult {
833 self.compare_no_case(AsBytes::as_bytes(t))
834 }
835 }
836
837 impl<'a, 'b> Compare<&'b str> for &'a str {
838 #[inline(always)]
compare(&self, t: &'b str) -> CompareResult839 fn compare(&self, t: &'b str) -> CompareResult {
840 self.as_bytes().compare(t.as_bytes())
841 }
842
843 //FIXME: this version is too simple and does not use the current locale
844 #[inline(always)]
compare_no_case(&self, t: &'b str) -> CompareResult845 fn compare_no_case(&self, t: &'b str) -> CompareResult {
846 let pos = self
847 .chars()
848 .zip(t.chars())
849 .position(|(a, b)| a.to_lowercase().ne(b.to_lowercase()));
850
851 match pos {
852 Some(_) => CompareResult::Error,
853 None => {
854 if self.len() >= t.len() {
855 CompareResult::Ok
856 } else {
857 CompareResult::Incomplete
858 }
859 }
860 }
861 }
862 }
863
864 impl<'a, 'b> Compare<&'b [u8]> for &'a str {
865 #[inline(always)]
compare(&self, t: &'b [u8]) -> CompareResult866 fn compare(&self, t: &'b [u8]) -> CompareResult {
867 AsBytes::as_bytes(self).compare(t)
868 }
869 #[inline(always)]
compare_no_case(&self, t: &'b [u8]) -> CompareResult870 fn compare_no_case(&self, t: &'b [u8]) -> CompareResult {
871 AsBytes::as_bytes(self).compare_no_case(t)
872 }
873 }
874
875 /// Look for a token in self
876 pub trait FindToken<T> {
877 /// Returns true if self contains the token
find_token(&self, token: T) -> bool878 fn find_token(&self, token: T) -> bool;
879 }
880
881 impl<'a> FindToken<u8> for &'a [u8] {
find_token(&self, token: u8) -> bool882 fn find_token(&self, token: u8) -> bool {
883 memchr::memchr(token, self).is_some()
884 }
885 }
886
887 impl<'a> FindToken<u8> for &'a str {
find_token(&self, token: u8) -> bool888 fn find_token(&self, token: u8) -> bool {
889 self.as_bytes().find_token(token)
890 }
891 }
892
893 impl<'a, 'b> FindToken<&'a u8> for &'b [u8] {
find_token(&self, token: &u8) -> bool894 fn find_token(&self, token: &u8) -> bool {
895 self.find_token(*token)
896 }
897 }
898
899 impl<'a, 'b> FindToken<&'a u8> for &'b str {
find_token(&self, token: &u8) -> bool900 fn find_token(&self, token: &u8) -> bool {
901 self.as_bytes().find_token(token)
902 }
903 }
904
905 impl<'a> FindToken<char> for &'a [u8] {
find_token(&self, token: char) -> bool906 fn find_token(&self, token: char) -> bool {
907 self.iter().any(|i| *i == token as u8)
908 }
909 }
910
911 impl<'a> FindToken<char> for &'a str {
find_token(&self, token: char) -> bool912 fn find_token(&self, token: char) -> bool {
913 self.chars().any(|i| i == token)
914 }
915 }
916
917 /// Look for a substring in self
918 pub trait FindSubstring<T> {
919 /// Returns the byte position of the substring if it is found
find_substring(&self, substr: T) -> Option<usize>920 fn find_substring(&self, substr: T) -> Option<usize>;
921 }
922
923 impl<'a, 'b> FindSubstring<&'b [u8]> for &'a [u8] {
find_substring(&self, substr: &'b [u8]) -> Option<usize>924 fn find_substring(&self, substr: &'b [u8]) -> Option<usize> {
925 if substr.len() > self.len() {
926 return None;
927 }
928
929 let (&substr_first, substr_rest) = match substr.split_first() {
930 Some(split) => split,
931 // an empty substring is found at position 0
932 // This matches the behavior of str.find("").
933 None => return Some(0),
934 };
935
936 if substr_rest.is_empty() {
937 return memchr::memchr(substr_first, self);
938 }
939
940 let mut offset = 0;
941 let haystack = &self[..self.len() - substr_rest.len()];
942
943 while let Some(position) = memchr::memchr(substr_first, &haystack[offset..]) {
944 offset += position;
945 let next_offset = offset + 1;
946 if &self[next_offset..][..substr_rest.len()] == substr_rest {
947 return Some(offset);
948 }
949
950 offset = next_offset;
951 }
952
953 None
954 }
955 }
956
957 impl<'a, 'b> FindSubstring<&'b str> for &'a [u8] {
find_substring(&self, substr: &'b str) -> Option<usize>958 fn find_substring(&self, substr: &'b str) -> Option<usize> {
959 self.find_substring(AsBytes::as_bytes(substr))
960 }
961 }
962
963 impl<'a, 'b> FindSubstring<&'b str> for &'a str {
964 //returns byte index
find_substring(&self, substr: &'b str) -> Option<usize>965 fn find_substring(&self, substr: &'b str) -> Option<usize> {
966 self.find(substr)
967 }
968 }
969
970 /// Used to integrate `str`'s `parse()` method
971 pub trait ParseTo<R> {
972 /// Succeeds if `parse()` succeeded. The byte slice implementation
973 /// will first convert it to a `&str`, then apply the `parse()` function
parse_to(&self) -> Option<R>974 fn parse_to(&self) -> Option<R>;
975 }
976
977 impl<'a, R: FromStr> ParseTo<R> for &'a [u8] {
parse_to(&self) -> Option<R>978 fn parse_to(&self) -> Option<R> {
979 from_utf8(self).ok().and_then(|s| s.parse().ok())
980 }
981 }
982
983 impl<'a, R: FromStr> ParseTo<R> for &'a str {
parse_to(&self) -> Option<R>984 fn parse_to(&self) -> Option<R> {
985 self.parse().ok()
986 }
987 }
988
989 /// Slicing operations using ranges.
990 ///
991 /// This trait is loosely based on
992 /// `Index`, but can actually return
993 /// something else than a `&[T]` or `&str`
994 pub trait Slice<R> {
995 /// Slices self according to the range argument
slice(&self, range: R) -> Self996 fn slice(&self, range: R) -> Self;
997 }
998
999 macro_rules! impl_fn_slice {
1000 ( $ty:ty ) => {
1001 fn slice(&self, range: $ty) -> Self {
1002 &self[range]
1003 }
1004 };
1005 }
1006
1007 macro_rules! slice_range_impl {
1008 ( [ $for_type:ident ], $ty:ty ) => {
1009 impl<'a, $for_type> Slice<$ty> for &'a [$for_type] {
1010 impl_fn_slice!($ty);
1011 }
1012 };
1013 ( $for_type:ty, $ty:ty ) => {
1014 impl<'a> Slice<$ty> for &'a $for_type {
1015 impl_fn_slice!($ty);
1016 }
1017 };
1018 }
1019
1020 macro_rules! slice_ranges_impl {
1021 ( [ $for_type:ident ] ) => {
1022 slice_range_impl! {[$for_type], Range<usize>}
1023 slice_range_impl! {[$for_type], RangeTo<usize>}
1024 slice_range_impl! {[$for_type], RangeFrom<usize>}
1025 slice_range_impl! {[$for_type], RangeFull}
1026 };
1027 ( $for_type:ty ) => {
1028 slice_range_impl! {$for_type, Range<usize>}
1029 slice_range_impl! {$for_type, RangeTo<usize>}
1030 slice_range_impl! {$for_type, RangeFrom<usize>}
1031 slice_range_impl! {$for_type, RangeFull}
1032 };
1033 }
1034
1035 slice_ranges_impl! {str}
1036 slice_ranges_impl! {[T]}
1037
1038 macro_rules! array_impls {
1039 ($($N:expr)+) => {
1040 $(
1041 impl InputLength for [u8; $N] {
1042 #[inline]
1043 fn input_len(&self) -> usize {
1044 self.len()
1045 }
1046 }
1047
1048 impl<'a> InputLength for &'a [u8; $N] {
1049 #[inline]
1050 fn input_len(&self) -> usize {
1051 self.len()
1052 }
1053 }
1054
1055 impl<'a> InputIter for &'a [u8; $N] {
1056 type Item = u8;
1057 type Iter = Enumerate<Self::IterElem>;
1058 type IterElem = Copied<Iter<'a, u8>>;
1059
1060 fn iter_indices(&self) -> Self::Iter {
1061 (&self[..]).iter_indices()
1062 }
1063
1064 fn iter_elements(&self) -> Self::IterElem {
1065 (&self[..]).iter_elements()
1066 }
1067
1068 fn position<P>(&self, predicate: P) -> Option<usize>
1069 where P: Fn(Self::Item) -> bool {
1070 (&self[..]).position(predicate)
1071 }
1072
1073 fn slice_index(&self, count: usize) -> Result<usize, Needed> {
1074 (&self[..]).slice_index(count)
1075 }
1076 }
1077
1078 impl<'a> Compare<[u8; $N]> for &'a [u8] {
1079 #[inline(always)]
1080 fn compare(&self, t: [u8; $N]) -> CompareResult {
1081 self.compare(&t[..])
1082 }
1083
1084 #[inline(always)]
1085 fn compare_no_case(&self, t: [u8;$N]) -> CompareResult {
1086 self.compare_no_case(&t[..])
1087 }
1088 }
1089
1090 impl<'a,'b> Compare<&'b [u8; $N]> for &'a [u8] {
1091 #[inline(always)]
1092 fn compare(&self, t: &'b [u8; $N]) -> CompareResult {
1093 self.compare(&t[..])
1094 }
1095
1096 #[inline(always)]
1097 fn compare_no_case(&self, t: &'b [u8;$N]) -> CompareResult {
1098 self.compare_no_case(&t[..])
1099 }
1100 }
1101
1102 impl FindToken<u8> for [u8; $N] {
1103 fn find_token(&self, token: u8) -> bool {
1104 memchr::memchr(token, &self[..]).is_some()
1105 }
1106 }
1107
1108 impl<'a> FindToken<&'a u8> for [u8; $N] {
1109 fn find_token(&self, token: &u8) -> bool {
1110 self.find_token(*token)
1111 }
1112 }
1113 )+
1114 };
1115 }
1116
1117 array_impls! {
1118 0 1 2 3 4 5 6 7 8 9
1119 10 11 12 13 14 15 16 17 18 19
1120 20 21 22 23 24 25 26 27 28 29
1121 30 31 32
1122 }
1123
1124 /// Abstracts something which can extend an `Extend`.
1125 /// Used to build modified input slices in `escaped_transform`
1126 pub trait ExtendInto {
1127 /// The current input type is a sequence of that `Item` type.
1128 ///
1129 /// Example: `u8` for `&[u8]` or `char` for `&str`
1130 type Item;
1131
1132 /// The type that will be produced
1133 type Extender;
1134
1135 /// Create a new `Extend` of the correct type
new_builder(&self) -> Self::Extender1136 fn new_builder(&self) -> Self::Extender;
1137 /// Accumulate the input into an accumulator
extend_into(&self, acc: &mut Self::Extender)1138 fn extend_into(&self, acc: &mut Self::Extender);
1139 }
1140
1141 #[cfg(feature = "alloc")]
1142 impl ExtendInto for [u8] {
1143 type Item = u8;
1144 type Extender = Vec<u8>;
1145
1146 #[inline]
new_builder(&self) -> Vec<u8>1147 fn new_builder(&self) -> Vec<u8> {
1148 Vec::new()
1149 }
1150 #[inline]
extend_into(&self, acc: &mut Vec<u8>)1151 fn extend_into(&self, acc: &mut Vec<u8>) {
1152 acc.extend(self.iter().cloned());
1153 }
1154 }
1155
1156 #[cfg(feature = "alloc")]
1157 impl ExtendInto for &[u8] {
1158 type Item = u8;
1159 type Extender = Vec<u8>;
1160
1161 #[inline]
new_builder(&self) -> Vec<u8>1162 fn new_builder(&self) -> Vec<u8> {
1163 Vec::new()
1164 }
1165 #[inline]
extend_into(&self, acc: &mut Vec<u8>)1166 fn extend_into(&self, acc: &mut Vec<u8>) {
1167 acc.extend_from_slice(self);
1168 }
1169 }
1170
1171 #[cfg(feature = "alloc")]
1172 impl ExtendInto for str {
1173 type Item = char;
1174 type Extender = String;
1175
1176 #[inline]
new_builder(&self) -> String1177 fn new_builder(&self) -> String {
1178 String::new()
1179 }
1180 #[inline]
extend_into(&self, acc: &mut String)1181 fn extend_into(&self, acc: &mut String) {
1182 acc.push_str(self);
1183 }
1184 }
1185
1186 #[cfg(feature = "alloc")]
1187 impl ExtendInto for &str {
1188 type Item = char;
1189 type Extender = String;
1190
1191 #[inline]
new_builder(&self) -> String1192 fn new_builder(&self) -> String {
1193 String::new()
1194 }
1195 #[inline]
extend_into(&self, acc: &mut String)1196 fn extend_into(&self, acc: &mut String) {
1197 acc.push_str(self);
1198 }
1199 }
1200
1201 #[cfg(feature = "alloc")]
1202 impl ExtendInto for char {
1203 type Item = char;
1204 type Extender = String;
1205
1206 #[inline]
new_builder(&self) -> String1207 fn new_builder(&self) -> String {
1208 String::new()
1209 }
1210 #[inline]
extend_into(&self, acc: &mut String)1211 fn extend_into(&self, acc: &mut String) {
1212 acc.push(*self);
1213 }
1214 }
1215
1216 /// Helper trait to convert numbers to usize.
1217 ///
1218 /// By default, usize implements `From<u8>` and `From<u16>` but not
1219 /// `From<u32>` and `From<u64>` because that would be invalid on some
1220 /// platforms. This trait implements the conversion for platforms
1221 /// with 32 and 64 bits pointer platforms
1222 pub trait ToUsize {
1223 /// converts self to usize
to_usize(&self) -> usize1224 fn to_usize(&self) -> usize;
1225 }
1226
1227 impl ToUsize for u8 {
1228 #[inline]
to_usize(&self) -> usize1229 fn to_usize(&self) -> usize {
1230 *self as usize
1231 }
1232 }
1233
1234 impl ToUsize for u16 {
1235 #[inline]
to_usize(&self) -> usize1236 fn to_usize(&self) -> usize {
1237 *self as usize
1238 }
1239 }
1240
1241 impl ToUsize for usize {
1242 #[inline]
to_usize(&self) -> usize1243 fn to_usize(&self) -> usize {
1244 *self
1245 }
1246 }
1247
1248 #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
1249 impl ToUsize for u32 {
1250 #[inline]
to_usize(&self) -> usize1251 fn to_usize(&self) -> usize {
1252 *self as usize
1253 }
1254 }
1255
1256 #[cfg(target_pointer_width = "64")]
1257 impl ToUsize for u64 {
1258 #[inline]
to_usize(&self) -> usize1259 fn to_usize(&self) -> usize {
1260 *self as usize
1261 }
1262 }
1263
1264 /// Equivalent From implementation to avoid orphan rules in bits parsers
1265 pub trait ErrorConvert<E> {
1266 /// Transform to another error type
convert(self) -> E1267 fn convert(self) -> E;
1268 }
1269
1270 impl<I> ErrorConvert<(I, ErrorKind)> for ((I, usize), ErrorKind) {
convert(self) -> (I, ErrorKind)1271 fn convert(self) -> (I, ErrorKind) {
1272 ((self.0).0, self.1)
1273 }
1274 }
1275
1276 impl<I> ErrorConvert<((I, usize), ErrorKind)> for (I, ErrorKind) {
convert(self) -> ((I, usize), ErrorKind)1277 fn convert(self) -> ((I, usize), ErrorKind) {
1278 ((self.0, 0), self.1)
1279 }
1280 }
1281
1282 use crate::error;
1283 impl<I> ErrorConvert<error::Error<I>> for error::Error<(I, usize)> {
convert(self) -> error::Error<I>1284 fn convert(self) -> error::Error<I> {
1285 error::Error {
1286 input: self.input.0,
1287 code: self.code,
1288 }
1289 }
1290 }
1291
1292 impl<I> ErrorConvert<error::Error<(I, usize)>> for error::Error<I> {
convert(self) -> error::Error<(I, usize)>1293 fn convert(self) -> error::Error<(I, usize)> {
1294 error::Error {
1295 input: (self.input, 0),
1296 code: self.code,
1297 }
1298 }
1299 }
1300
1301 #[cfg(feature = "alloc")]
1302 #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
1303 impl<I> ErrorConvert<error::VerboseError<I>> for error::VerboseError<(I, usize)> {
convert(self) -> error::VerboseError<I>1304 fn convert(self) -> error::VerboseError<I> {
1305 error::VerboseError {
1306 errors: self.errors.into_iter().map(|(i, e)| (i.0, e)).collect(),
1307 }
1308 }
1309 }
1310
1311 #[cfg(feature = "alloc")]
1312 #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
1313 impl<I> ErrorConvert<error::VerboseError<(I, usize)>> for error::VerboseError<I> {
convert(self) -> error::VerboseError<(I, usize)>1314 fn convert(self) -> error::VerboseError<(I, usize)> {
1315 error::VerboseError {
1316 errors: self.errors.into_iter().map(|(i, e)| ((i, 0), e)).collect(),
1317 }
1318 }
1319 }
1320
1321 #[cfg(feature = "std")]
1322 #[cfg_attr(feature = "docsrs", doc(cfg(feature = "std")))]
1323 /// Helper trait to show a byte slice as a hex dump
1324 pub trait HexDisplay {
1325 /// Converts the value of `self` to a hex dump, returning the owned
1326 /// `String`.
to_hex(&self, chunk_size: usize) -> String1327 fn to_hex(&self, chunk_size: usize) -> String;
1328
1329 /// Converts the value of `self` to a hex dump beginning at `from` address, returning the owned
1330 /// `String`.
to_hex_from(&self, chunk_size: usize, from: usize) -> String1331 fn to_hex_from(&self, chunk_size: usize, from: usize) -> String;
1332 }
1333
1334 #[cfg(feature = "std")]
1335 static CHARS: &[u8] = b"0123456789abcdef";
1336
1337 #[cfg(feature = "std")]
1338 impl HexDisplay for [u8] {
1339 #[allow(unused_variables)]
to_hex(&self, chunk_size: usize) -> String1340 fn to_hex(&self, chunk_size: usize) -> String {
1341 self.to_hex_from(chunk_size, 0)
1342 }
1343
1344 #[allow(unused_variables)]
to_hex_from(&self, chunk_size: usize, from: usize) -> String1345 fn to_hex_from(&self, chunk_size: usize, from: usize) -> String {
1346 let mut v = Vec::with_capacity(self.len() * 3);
1347 let mut i = from;
1348 for chunk in self.chunks(chunk_size) {
1349 let s = format!("{:08x}", i);
1350 for &ch in s.as_bytes().iter() {
1351 v.push(ch);
1352 }
1353 v.push(b'\t');
1354
1355 i += chunk_size;
1356
1357 for &byte in chunk {
1358 v.push(CHARS[(byte >> 4) as usize]);
1359 v.push(CHARS[(byte & 0xf) as usize]);
1360 v.push(b' ');
1361 }
1362 if chunk_size > chunk.len() {
1363 for j in 0..(chunk_size - chunk.len()) {
1364 v.push(b' ');
1365 v.push(b' ');
1366 v.push(b' ');
1367 }
1368 }
1369 v.push(b'\t');
1370
1371 for &byte in chunk {
1372 if (byte >= 32 && byte <= 126) || byte >= 128 {
1373 v.push(byte);
1374 } else {
1375 v.push(b'.');
1376 }
1377 }
1378 v.push(b'\n');
1379 }
1380
1381 String::from_utf8_lossy(&v[..]).into_owned()
1382 }
1383 }
1384
1385 #[cfg(feature = "std")]
1386 impl HexDisplay for str {
1387 #[allow(unused_variables)]
to_hex(&self, chunk_size: usize) -> String1388 fn to_hex(&self, chunk_size: usize) -> String {
1389 self.to_hex_from(chunk_size, 0)
1390 }
1391
1392 #[allow(unused_variables)]
to_hex_from(&self, chunk_size: usize, from: usize) -> String1393 fn to_hex_from(&self, chunk_size: usize, from: usize) -> String {
1394 self.as_bytes().to_hex_from(chunk_size, from)
1395 }
1396 }
1397
1398 #[cfg(test)]
1399 mod tests {
1400 use super::*;
1401
1402 #[test]
test_offset_u8()1403 fn test_offset_u8() {
1404 let s = b"abcd123";
1405 let a = &s[..];
1406 let b = &a[2..];
1407 let c = &a[..4];
1408 let d = &a[3..5];
1409 assert_eq!(a.offset(b), 2);
1410 assert_eq!(a.offset(c), 0);
1411 assert_eq!(a.offset(d), 3);
1412 }
1413
1414 #[test]
test_offset_str()1415 fn test_offset_str() {
1416 let s = "abcřèÂßÇd123";
1417 let a = &s[..];
1418 let b = &a[7..];
1419 let c = &a[..5];
1420 let d = &a[5..9];
1421 assert_eq!(a.offset(b), 7);
1422 assert_eq!(a.offset(c), 0);
1423 assert_eq!(a.offset(d), 5);
1424 }
1425 }
1426