mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 22:53:28 +00:00
Rollup merge of #83130 - clarfonthey:escape, r=m-ou-se
escape_ascii take 2 The previous PR, #73111 was closed for inactivity; since I've had trouble in the past reopening closed PRs, I'm just making a new one. I'm still running the tests locally but figured I'd open the PR in the meantime. Will fix whatever errors show up so we don't have to wait again for this. r? ``@m-ou-se``
This commit is contained in:
commit
68964d1fc2
@ -2,6 +2,7 @@
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::ascii;
|
||||
use crate::intrinsics;
|
||||
use crate::mem;
|
||||
use crate::str::FromStr;
|
||||
@ -661,6 +662,31 @@ impl u8 {
|
||||
pub const fn is_ascii_control(&self) -> bool {
|
||||
matches!(*self, b'\0'..=b'\x1F' | b'\x7F')
|
||||
}
|
||||
|
||||
/// Returns an iterator that produces an escaped version of a `u8`,
|
||||
/// treating it as an ASCII character.
|
||||
///
|
||||
/// The behavior is identical to [`ascii::escape_default`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inherent_ascii_escape)]
|
||||
///
|
||||
/// assert_eq!("0", b'0'.escape_ascii().to_string());
|
||||
/// assert_eq!("\\t", b'\t'.escape_ascii().to_string());
|
||||
/// assert_eq!("\\r", b'\r'.escape_ascii().to_string());
|
||||
/// assert_eq!("\\n", b'\n'.escape_ascii().to_string());
|
||||
/// assert_eq!("\\'", b'\''.escape_ascii().to_string());
|
||||
/// assert_eq!("\\\"", b'"'.escape_ascii().to_string());
|
||||
/// assert_eq!("\\\\", b'\\'.escape_ascii().to_string());
|
||||
/// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string());
|
||||
/// ```
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
#[inline]
|
||||
pub fn escape_ascii(&self) -> ascii::EscapeDefault {
|
||||
ascii::escape_default(*self)
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "u16"]
|
||||
|
@ -1,7 +1,10 @@
|
||||
//! Operations on ASCII `[u8]`.
|
||||
|
||||
use crate::ascii;
|
||||
use crate::fmt::{self, Write};
|
||||
use crate::iter;
|
||||
use crate::mem;
|
||||
use crate::ops;
|
||||
|
||||
#[lang = "slice_u8"]
|
||||
#[cfg(not(test))]
|
||||
@ -56,6 +59,95 @@ impl [u8] {
|
||||
byte.make_ascii_lowercase();
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator that produces an escaped version of this slice,
|
||||
/// treating it as an ASCII string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inherent_ascii_escape)]
|
||||
///
|
||||
/// let s = b"0\t\r\n'\"\\\x9d";
|
||||
/// let escaped = s.escape_ascii().to_string();
|
||||
/// assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
|
||||
/// ```
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
pub fn escape_ascii(&self) -> EscapeAscii<'_> {
|
||||
EscapeAscii { inner: self.iter().flat_map(EscapeByte) }
|
||||
}
|
||||
}
|
||||
|
||||
impl_fn_for_zst! {
|
||||
#[derive(Clone)]
|
||||
struct EscapeByte impl Fn = |byte: &u8| -> ascii::EscapeDefault {
|
||||
ascii::escape_default(*byte)
|
||||
};
|
||||
}
|
||||
|
||||
/// An iterator over the escaped version of a byte slice.
|
||||
///
|
||||
/// This `struct` is created by the [`slice::escape_ascii`] method. See its
|
||||
/// documentation for more information.
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
#[derive(Clone)]
|
||||
pub struct EscapeAscii<'a> {
|
||||
inner: iter::FlatMap<super::Iter<'a, u8>, ascii::EscapeDefault, EscapeByte>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
impl<'a> iter::Iterator for EscapeAscii<'a> {
|
||||
type Item = u8;
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<u8> {
|
||||
self.inner.next()
|
||||
}
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.inner.size_hint()
|
||||
}
|
||||
#[inline]
|
||||
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
|
||||
where
|
||||
Fold: FnMut(Acc, Self::Item) -> R,
|
||||
R: ops::Try<Ok = Acc>,
|
||||
{
|
||||
self.inner.try_fold(init, fold)
|
||||
}
|
||||
#[inline]
|
||||
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
|
||||
where
|
||||
Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
{
|
||||
self.inner.fold(init, fold)
|
||||
}
|
||||
#[inline]
|
||||
fn last(mut self) -> Option<u8> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
impl<'a> iter::DoubleEndedIterator for EscapeAscii<'a> {
|
||||
fn next_back(&mut self) -> Option<u8> {
|
||||
self.inner.next_back()
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
impl<'a> iter::ExactSizeIterator for EscapeAscii<'a> {}
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
impl<'a> iter::FusedIterator for EscapeAscii<'a> {}
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
impl<'a> fmt::Display for EscapeAscii<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.clone().try_for_each(|b| f.write_char(b as char))
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
impl<'a> fmt::Debug for EscapeAscii<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.pad("EscapeAscii { .. }")
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed
|
||||
|
@ -81,6 +81,9 @@ pub use index::SliceIndex;
|
||||
#[unstable(feature = "slice_range", issue = "76393")]
|
||||
pub use index::range;
|
||||
|
||||
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
|
||||
pub use ascii::EscapeAscii;
|
||||
|
||||
#[lang = "slice"]
|
||||
#[cfg(not(test))]
|
||||
impl<T> [T] {
|
||||
|
Loading…
Reference in New Issue
Block a user