|
1 | 1 | //! Operations on ASCII `[u8]`.
|
2 | 2 |
|
| 3 | +use crate::ascii; |
| 4 | +use crate::fmt::{self, Write}; |
| 5 | +use crate::iter; |
3 | 6 | use crate::mem;
|
| 7 | +use crate::ops; |
4 | 8 |
|
5 | 9 | #[lang = "slice_u8"]
|
6 | 10 | #[cfg(not(test))]
|
@@ -55,6 +59,97 @@ impl [u8] {
|
55 | 59 | byte.make_ascii_lowercase();
|
56 | 60 | }
|
57 | 61 | }
|
| 62 | + |
| 63 | + /// Returns an iterator that produces an escaped version of this slice, |
| 64 | + /// treating it as an ASCII string. |
| 65 | + /// |
| 66 | + /// # Examples |
| 67 | + /// |
| 68 | + /// ``` |
| 69 | + /// #![feature(inherent_ascii_escape)] |
| 70 | + /// |
| 71 | + /// let s = b"0\t\r\n'\"\\\x9d"; |
| 72 | + /// let escaped = s.escape_ascii().to_string(); |
| 73 | + /// assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d"); |
| 74 | + /// ``` |
| 75 | + #[unstable(feature = "inherent_ascii_escape", issue = "77174")] |
| 76 | + pub fn escape_ascii(&self) -> EscapeAscii<'_> { |
| 77 | + EscapeAscii { inner: self.iter().flat_map(EscapeByte) } |
| 78 | + } |
| 79 | +} |
| 80 | + |
| 81 | +impl_fn_for_zst! { |
| 82 | + #[derive(Clone)] |
| 83 | + struct EscapeByte impl Fn = |byte: &u8| -> ascii::EscapeDefault { |
| 84 | + ascii::escape_default(*byte) |
| 85 | + }; |
| 86 | +} |
| 87 | + |
| 88 | +/// An iterator over the escaped version of a byte slice. |
| 89 | +/// |
| 90 | +/// This `struct` is created by the [`[u8]::escape_ascii`] method. See its |
| 91 | +/// documentation for more. |
| 92 | +/// |
| 93 | +/// [`[u8]::escape_ascii`]: ../../std/primitive.slice.html#method.escape_ascii |
| 94 | +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] |
| 95 | +#[derive(Clone)] |
| 96 | +pub struct EscapeAscii<'a> { |
| 97 | + inner: iter::FlatMap<super::Iter<'a, u8>, ascii::EscapeDefault, EscapeByte>, |
| 98 | +} |
| 99 | + |
| 100 | +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] |
| 101 | +impl<'a> iter::Iterator for EscapeAscii<'a> { |
| 102 | + type Item = u8; |
| 103 | + #[inline] |
| 104 | + fn next(&mut self) -> Option<u8> { |
| 105 | + self.inner.next() |
| 106 | + } |
| 107 | + #[inline] |
| 108 | + fn size_hint(&self) -> (usize, Option<usize>) { |
| 109 | + self.inner.size_hint() |
| 110 | + } |
| 111 | + #[inline] |
| 112 | + fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R |
| 113 | + where |
| 114 | + Fold: FnMut(Acc, Self::Item) -> R, |
| 115 | + R: ops::Try<Ok = Acc>, |
| 116 | + { |
| 117 | + self.inner.try_fold(init, fold) |
| 118 | + } |
| 119 | + #[inline] |
| 120 | + fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc |
| 121 | + where |
| 122 | + Fold: FnMut(Acc, Self::Item) -> Acc, |
| 123 | + { |
| 124 | + self.inner.fold(init, fold) |
| 125 | + } |
| 126 | + #[inline] |
| 127 | + fn last(mut self) -> Option<u8> { |
| 128 | + self.next_back() |
| 129 | + } |
| 130 | +} |
| 131 | + |
| 132 | +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] |
| 133 | +impl<'a> iter::DoubleEndedIterator for EscapeAscii<'a> { |
| 134 | + fn next_back(&mut self) -> Option<u8> { |
| 135 | + self.inner.next_back() |
| 136 | + } |
| 137 | +} |
| 138 | +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] |
| 139 | +impl<'a> iter::ExactSizeIterator for EscapeAscii<'a> {} |
| 140 | +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] |
| 141 | +impl<'a> iter::FusedIterator for EscapeAscii<'a> {} |
| 142 | +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] |
| 143 | +impl<'a> fmt::Display for EscapeAscii<'a> { |
| 144 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 145 | + self.clone().try_for_each(|b| f.write_char(b as char)) |
| 146 | + } |
| 147 | +} |
| 148 | +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] |
| 149 | +impl<'a> fmt::Debug for EscapeAscii<'a> { |
| 150 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 151 | + f.pad("EscapeAscii { .. }") |
| 152 | + } |
58 | 153 | }
|
59 | 154 |
|
60 | 155 | /// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed
|
|
0 commit comments