1
Fork 0

Move str::escape_* to libcore

This commit is contained in:
Simon Sapin 2019-02-02 10:34:36 +01:00
parent 55216f82a6
commit 92cce78d06
4 changed files with 169 additions and 165 deletions

View file

@ -29,13 +29,8 @@
#![allow(unused_imports)]
use core::borrow::Borrow;
use core::fmt::{self, Write};
use core::char;
use core::iter::{Chain, Flatten, FlatMap};
use core::str::pattern::{Pattern, Searcher, ReverseSearcher, DoubleEndedSearcher};
use core::mem;
use core::ops::Try;
use core::option;
use core::ptr;
use core::iter::FusedIterator;
use core::unicode::conversions;
@ -446,40 +441,6 @@ impl str {
return s;
}
/// Escapes each char in `s` with [`char::escape_debug`].
///
/// Note: only extended grapheme codepoints that begin the string will be
/// escaped.
///
/// [`char::escape_debug`]: primitive.char.html#method.escape_debug
#[stable(feature = "str_escape", since = "1.34.0")]
pub fn escape_debug(&self) -> EscapeDebug {
let mut chars = self.chars();
EscapeDebug {
inner: chars.next()
.map(|first| first.escape_debug_ext(true))
.into_iter()
.flatten()
.chain(chars.flat_map(CharEscapeDebugContinue))
}
}
/// Escapes each char in `s` with [`char::escape_default`].
///
/// [`char::escape_default`]: primitive.char.html#method.escape_default
#[stable(feature = "str_escape", since = "1.34.0")]
pub fn escape_default(&self) -> EscapeDefault {
EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) }
}
/// Escapes each char in `s` with [`char::escape_unicode`].
///
/// [`char::escape_unicode`]: primitive.char.html#method.escape_unicode
#[stable(feature = "str_escape", since = "1.34.0")]
pub fn escape_unicode(&self) -> EscapeUnicode {
EscapeUnicode { inner: self.chars().flat_map(CharEscapeUnicode) }
}
/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
///
/// [`String`]: string/struct.String.html
@ -611,82 +572,3 @@ pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
Box::from_raw(Box::into_raw(v) as *mut str)
}
impl_fn_for_zst! {
#[derive(Clone)]
struct CharEscapeDebugContinue impl Fn = |c: char| -> char::EscapeDebug {
c.escape_debug_ext(false)
};
#[derive(Clone)]
struct CharEscapeUnicode impl Fn = |c: char| -> char::EscapeUnicode {
c.escape_unicode()
};
#[derive(Clone)]
struct CharEscapeDefault impl Fn = |c: char| -> char::EscapeDefault {
c.escape_default()
};
}
macro_rules! escape_types {
($(
struct $Name: ident<'a> {
inner: $Inner: ty,
}
)+) => {$(
#[stable(feature = "str_escape", since = "1.34.0")]
#[derive(Clone, Debug)]
pub struct $Name<'a> {
inner: $Inner,
}
#[stable(feature = "str_escape", since = "1.34.0")]
impl<'a> fmt::Display for $Name<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.clone().try_for_each(|c| f.write_char(c))
}
}
#[stable(feature = "str_escape", since = "1.34.0")]
impl<'a> Iterator for $Name<'a> {
type Item = char;
#[inline]
fn next(&mut self) -> Option<char> { 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
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: 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)
}
}
#[stable(feature = "str_escape", since = "1.34.0")]
impl<'a> FusedIterator for $Name<'a> {}
)+}
}
escape_types! {
struct EscapeDebug<'a> {
inner: Chain<
Flatten<option::IntoIter<char::EscapeDebug>>,
FlatMap<Chars<'a>, char::EscapeDebug, CharEscapeDebugContinue>
>,
}
struct EscapeUnicode<'a> {
inner: FlatMap<Chars<'a>, char::EscapeUnicode, CharEscapeUnicode>,
}
struct EscapeDefault<'a> {
inner: FlatMap<Chars<'a>, char::EscapeDefault, CharEscapeDefault>,
}
}

View file

@ -75,3 +75,47 @@ macro_rules! forward_ref_op_assign {
}
}
}
/// Create a zero-size type similar to a closure type, but named.
#[unstable(feature = "std_internals", issue = "0")]
macro_rules! impl_fn_for_zst {
($(
$( #[$attr: meta] )*
// FIXME: when libcore is in the 2018 edition, use `?` repetition in
// $( <$( $li : lifetime ),+> )?
struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )* Fn =
|$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
$body: block;
)+) => {
$(
$( #[$attr] )*
struct $Name;
impl $( <$( $lifetime ),+> )* Fn<($( $ArgTy, )*)> for $Name {
#[inline]
extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
$body
}
}
impl $( <$( $lifetime ),+> )* FnMut<($( $ArgTy, )*)> for $Name {
#[inline]
extern "rust-call" fn call_mut(
&mut self,
($( $arg, )*): ($( $ArgTy, )*)
) -> $ReturnTy {
Fn::call(&*self, ($( $arg, )*))
}
}
impl $( <$( $lifetime ),+> )* FnOnce<($( $ArgTy, )*)> for $Name {
type Output = $ReturnTy;
#[inline]
extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
Fn::call(&self, ($( $arg, )*))
}
}
)+
}
}

View file

@ -749,49 +749,3 @@ mod builtin {
($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ });
}
}
/// Create a named zero-size type similar to a closure.
#[doc(hidden)]
#[macro_export]
#[unstable(feature = "std_internals", issue = "0")]
macro_rules! impl_fn_for_zst {
($(
$( #[$attr: meta] )*
// FIXME: when libcore is in the 2018 edition, use `?` repetition in
// $( <$( $li : lifetime ),+> )?
struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )* Fn =
|$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
$body: block;
)+) => {
$(
$( #[$attr] )*
struct $Name;
impl $( <$( $lifetime ),+> )* Fn<($( $ArgTy, )*)> for $Name {
#[inline]
extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
$body
}
}
impl $( <$( $lifetime ),+> )* FnMut<($( $ArgTy, )*)> for $Name {
#[inline]
extern "rust-call" fn call_mut(
&mut self,
($( $arg, )*): ($( $ArgTy, )*)
) -> $ReturnTy {
Fn::call(&*self, ($( $arg, )*))
}
}
impl $( <$( $lifetime ),+> )* FnOnce<($( $ArgTy, )*)> for $Name {
type Output = $ReturnTy;
#[inline]
extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
Fn::call(&self, ($( $arg, )*))
}
}
)+
}
}

View file

@ -8,10 +8,13 @@ use self::pattern::Pattern;
use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
use char;
use fmt;
use fmt::{self, Write};
use iter::{Map, Cloned, FusedIterator, TrustedLen, TrustedRandomAccess, Filter};
use iter::{Flatten, FlatMap, Chain};
use slice::{self, SliceIndex, Split as SliceSplit};
use mem;
use ops::Try;
use option;
pub mod pattern;
@ -3945,6 +3948,56 @@ impl str {
let me = unsafe { self.as_bytes_mut() };
me.make_ascii_lowercase()
}
/// Escapes each char in `s` with [`char::escape_debug`].
///
/// Note: only extended grapheme codepoints that begin the string will be
/// escaped.
///
/// [`char::escape_debug`]: ../std/primitive.char.html#method.escape_debug
#[stable(feature = "str_escape", since = "1.34.0")]
pub fn escape_debug(&self) -> EscapeDebug {
let mut chars = self.chars();
EscapeDebug {
inner: chars.next()
.map(|first| first.escape_debug_ext(true))
.into_iter()
.flatten()
.chain(chars.flat_map(CharEscapeDebugContinue))
}
}
/// Escapes each char in `s` with [`char::escape_default`].
///
/// [`char::escape_default`]: ../std/primitive.char.html#method.escape_default
#[stable(feature = "str_escape", since = "1.34.0")]
pub fn escape_default(&self) -> EscapeDefault {
EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) }
}
/// Escapes each char in `s` with [`char::escape_unicode`].
///
/// [`char::escape_unicode`]: ../std/primitive.char.html#method.escape_unicode
#[stable(feature = "str_escape", since = "1.34.0")]
pub fn escape_unicode(&self) -> EscapeUnicode {
EscapeUnicode { inner: self.chars().flat_map(CharEscapeUnicode) }
}
}
impl_fn_for_zst! {
#[derive(Clone)]
struct CharEscapeDebugContinue impl Fn = |c: char| -> char::EscapeDebug {
c.escape_debug_ext(false)
};
#[derive(Clone)]
struct CharEscapeUnicode impl Fn = |c: char| -> char::EscapeUnicode {
c.escape_unicode()
};
#[derive(Clone)]
struct CharEscapeDefault impl Fn = |c: char| -> char::EscapeDefault {
c.escape_default()
};
}
#[stable(feature = "rust1", since = "1.0.0")]
@ -4131,3 +4184,74 @@ impl<'a> Iterator for EncodeUtf16<'a> {
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for EncodeUtf16<'_> {}
/// The return type of [`str::escape_debug`].
///
/// [`str::escape_debug`]: ../../std/primitive.str.html#method.escape_debug
#[stable(feature = "str_escape", since = "1.34.0")]
#[derive(Clone, Debug)]
pub struct EscapeDebug<'a> {
inner: Chain<
Flatten<option::IntoIter<char::EscapeDebug>>,
FlatMap<Chars<'a>, char::EscapeDebug, CharEscapeDebugContinue>
>,
}
/// The return type of [`str::escape_default`].
///
/// [`str::escape_default`]: ../../std/primitive.str.html#method.escape_default
#[stable(feature = "str_escape", since = "1.34.0")]
#[derive(Clone, Debug)]
pub struct EscapeDefault<'a> {
inner: FlatMap<Chars<'a>, char::EscapeDefault, CharEscapeDefault>,
}
/// The return type of [`str::escape_unicode`].
///
/// [`str::escape_unicode`]: ../../std/primitive.str.html#method.escape_unicode
#[stable(feature = "str_escape", since = "1.34.0")]
#[derive(Clone, Debug)]
pub struct EscapeUnicode<'a> {
inner: FlatMap<Chars<'a>, char::EscapeUnicode, CharEscapeUnicode>,
}
macro_rules! escape_types_impls {
($( $Name: ident ),+) => {$(
#[stable(feature = "str_escape", since = "1.34.0")]
impl<'a> fmt::Display for $Name<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.clone().try_for_each(|c| f.write_char(c))
}
}
#[stable(feature = "str_escape", since = "1.34.0")]
impl<'a> Iterator for $Name<'a> {
type Item = char;
#[inline]
fn next(&mut self) -> Option<char> { 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
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: 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)
}
}
#[stable(feature = "str_escape", since = "1.34.0")]
impl<'a> FusedIterator for $Name<'a> {}
)+}
}
escape_types_impls!(EscapeDebug, EscapeDefault, EscapeUnicode);