//! Parameterized string expansion
use std::{char, vec, util};
-use std::num::strconv::{SignNone,SignNeg,SignAll,DigAll,to_str_bytes_common};
+use std::num::strconv::{SignNone,SignNeg,SignAll,int_to_str_bytes_common};
use std::iterator::IteratorUtil;
#[deriving(Eq)]
FormatHex|FormatHEX => 16,
FormatString => util::unreachable()
};
- let (s,_) = match op {
+ let mut s = ~[];
+ match op {
FormatDigit => {
let sign = if flags.sign { SignAll } else { SignNeg };
- to_str_bytes_common(&d, radix, false, sign, DigAll)
+ do int_to_str_bytes_common(d, radix, sign) |c| {
+ s.push(c);
+ }
+ }
+ _ => {
+ do int_to_str_bytes_common(d as uint, radix, SignNone) |c| {
+ s.push(c);
+ }
}
- _ => to_str_bytes_common(&(d as uint), radix, false, SignNone, DigAll)
};
- let mut s = s;
if flags.precision > s.len() {
let mut s_ = vec::with_capacity(flags.precision);
let n = flags.precision - s.len();
//! Utilities for manipulating the char type
-use container::Container;
use option::{None, Option, Some};
+use int;
use str::StrSlice;
use unicode::{derived_property, general_category};
///
#[inline]
pub fn to_str(num: f32) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 10u, true, strconv::SignNeg, strconv::DigAll);
+ let (r, _) = strconv::float_to_str_common(
+ num, 10u, true, strconv::SignNeg, strconv::DigAll);
r
}
///
#[inline]
pub fn to_str_hex(num: f32) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 16u, true, strconv::SignNeg, strconv::DigAll);
+ let (r, _) = strconv::float_to_str_common(
+ num, 16u, true, strconv::SignNeg, strconv::DigAll);
r
}
///
#[inline]
pub fn to_str_radix(num: f32, rdx: uint) -> ~str {
- let (r, special) = strconv::to_str_common(
- &num, rdx, true, strconv::SignNeg, strconv::DigAll);
+ let (r, special) = strconv::float_to_str_common(
+ num, rdx, true, strconv::SignNeg, strconv::DigAll);
if special { fail!("number has a special value, \
try to_str_radix_special() if those are expected") }
r
///
#[inline]
pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
- strconv::to_str_common(&num, rdx, true,
+ strconv::float_to_str_common(num, rdx, true,
strconv::SignNeg, strconv::DigAll)
}
///
#[inline]
pub fn to_str_exact(num: f32, dig: uint) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
+ let (r, _) = strconv::float_to_str_common(
+ num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
r
}
///
#[inline]
pub fn to_str_digits(num: f32, dig: uint) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
+ let (r, _) = strconv::float_to_str_common(
+ num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
r
}
///
#[inline]
pub fn to_str(num: f64) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 10u, true, strconv::SignNeg, strconv::DigAll);
+ let (r, _) = strconv::float_to_str_common(
+ num, 10u, true, strconv::SignNeg, strconv::DigAll);
r
}
///
#[inline]
pub fn to_str_hex(num: f64) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 16u, true, strconv::SignNeg, strconv::DigAll);
+ let (r, _) = strconv::float_to_str_common(
+ num, 16u, true, strconv::SignNeg, strconv::DigAll);
r
}
///
#[inline]
pub fn to_str_radix(num: f64, rdx: uint) -> ~str {
- let (r, special) = strconv::to_str_common(
- &num, rdx, true, strconv::SignNeg, strconv::DigAll);
+ let (r, special) = strconv::float_to_str_common(
+ num, rdx, true, strconv::SignNeg, strconv::DigAll);
if special { fail!("number has a special value, \
try to_str_radix_special() if those are expected") }
r
///
#[inline]
pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
- strconv::to_str_common(&num, rdx, true,
+ strconv::float_to_str_common(num, rdx, true,
strconv::SignNeg, strconv::DigAll)
}
///
#[inline]
pub fn to_str_exact(num: f64, dig: uint) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
+ let (r, _) = strconv::float_to_str_common(
+ num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
r
}
///
#[inline]
pub fn to_str_digits(num: f64, dig: uint) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
+ let (r, _) = strconv::float_to_str_common(
+ num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
r
}
///
#[inline]
pub fn to_str(num: float) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 10u, true, strconv::SignNeg, strconv::DigAll);
+ let (r, _) = strconv::float_to_str_common(
+ num, 10u, true, strconv::SignNeg, strconv::DigAll);
r
}
///
#[inline]
pub fn to_str_hex(num: float) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 16u, true, strconv::SignNeg, strconv::DigAll);
+ let (r, _) = strconv::float_to_str_common(
+ num, 16u, true, strconv::SignNeg, strconv::DigAll);
r
}
///
#[inline]
pub fn to_str_radix(num: float, radix: uint) -> ~str {
- let (r, special) = strconv::to_str_common(
- &num, radix, true, strconv::SignNeg, strconv::DigAll);
+ let (r, special) = strconv::float_to_str_common(
+ num, radix, true, strconv::SignNeg, strconv::DigAll);
if special { fail!("number has a special value, \
try to_str_radix_special() if those are expected") }
r
///
#[inline]
pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
- strconv::to_str_common(&num, radix, true,
+ strconv::float_to_str_common(num, radix, true,
strconv::SignNeg, strconv::DigAll)
}
///
#[inline]
pub fn to_str_exact(num: float, digits: uint) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 10u, true, strconv::SignNeg, strconv::DigExact(digits));
+ let (r, _) = strconv::float_to_str_common(
+ num, 10u, true, strconv::SignNeg, strconv::DigExact(digits));
r
}
///
#[inline]
pub fn to_str_digits(num: float, digits: uint) -> ~str {
- let (r, _) = strconv::to_str_common(
- &num, 10u, true, strconv::SignNeg, strconv::DigMax(digits));
+ let (r, _) = strconv::float_to_str_common(
+ num, 10u, true, strconv::SignNeg, strconv::DigMax(digits));
r
}
use num::{ToStrRadix, FromStrRadix};
use num::{Zero, One, strconv};
use prelude::*;
+use str;
pub use cmp::{min, max};
/// Convert to a string as a byte slice in a given base.
#[inline]
pub fn to_str_bytes<U>(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
- let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
- strconv::SignNeg, strconv::DigAll);
- f(buf)
+ // The radix can be as low as 2, so we need at least 64 characters for a
+ // base 2 number, and then we need another for a possible '-' character.
+ let mut buf = [0u8, ..65];
+ let mut cur = 0;
+ do strconv::int_to_str_bytes_common(n, radix, strconv::SignNeg) |i| {
+ buf[cur] = i;
+ cur += 1;
+ }
+ f(buf.slice(0, cur))
}
/// Convert to a string in base 10.
#[inline]
pub fn to_str(num: $T) -> ~str {
- let (buf, _) = strconv::to_str_common(&num, 10u, false,
- strconv::SignNeg, strconv::DigAll);
- buf
+ to_str_radix(num, 10u)
}
/// Convert to a string in a given base.
#[inline]
pub fn to_str_radix(num: $T, radix: uint) -> ~str {
- let (buf, _) = strconv::to_str_common(&num, radix, false,
- strconv::SignNeg, strconv::DigAll);
- buf
+ let mut buf: ~[u8] = ~[];
+ do strconv::int_to_str_bytes_common(num, radix, strconv::SignNeg) |i| {
+ buf.push(i);
+ }
+ // We know we generated valid utf-8, so we don't need to go through that
+ // check.
+ unsafe { str::raw::from_bytes_owned(buf) }
}
impl ToStr for $T {
use option::{None, Option, Some};
use char;
use str;
-use str::{StrSlice};
+use str::StrSlice;
use kinds::Copy;
use vec;
use vec::{CopyableVector, ImmutableVector};
use vec::OwnedVector;
-use num::{NumCast, Zero, One, cast, pow_with_uint};
-use f64;
+use num::{NumCast, Zero, One, cast, pow_with_uint, Integer};
+use num::{Round, Float, FPNaN, FPInfinite};
pub enum ExponentFormat {
ExpNone,
SignAll
}
-#[inline]
-fn is_NaN<T:Eq>(num: &T) -> bool {
- *num != *num
-}
-
-#[inline]
-fn is_inf<T:Eq+NumStrConv>(num: &T) -> bool {
- match NumStrConv::inf() {
- None => false,
- Some(n) => *num == n
- }
-}
-
-#[inline]
-fn is_neg_inf<T:Eq+NumStrConv>(num: &T) -> bool {
- match NumStrConv::neg_inf() {
- None => false,
- Some(n) => *num == n
- }
-}
-
-#[inline]
-fn is_neg_zero<T:Eq+One+Zero+NumStrConv+Div<T,T>>(num: &T) -> bool {
- let _0: T = Zero::zero();
- let _1: T = One::one();
-
- *num == _0 && is_neg_inf(&(_1 / *num))
-}
-
pub trait NumStrConv {
fn NaN() -> Option<Self>;
fn inf() -> Option<Self>;
fn neg_zero() -> Option<$t> { Some(-0.0 ) }
#[inline]
- fn round_to_zero(&self) -> $t {
- ( if *self < 0.0 { f64::ceil(*self as f64) }
- else { f64::floor(*self as f64) }
- ) as $t
- }
-
+ fn round_to_zero(&self) -> $t { self.trunc() }
#[inline]
- fn fractional_part(&self) -> $t {
- *self - self.round_to_zero()
- }
+ fn fractional_part(&self) -> $t { self.fract() }
}
))
'f' as u8];
static nan_buf: [u8, ..3] = ['N' as u8, 'a' as u8, 'N' as u8];
+/**
+ * Converts an integral number to its string representation as a byte vector.
+ * This is meant to be a common base implementation for all integral string
+ * conversion functions like `to_str()` or `to_str_radix()`.
+ *
+ * # Arguments
+ * - `num` - The number to convert. Accepts any number that
+ * implements the numeric traits.
+ * - `radix` - Base to use. Accepts only the values 2-36.
+ * - `sign` - How to emit the sign. Options are:
+ * - `SignNone`: No sign at all. Basically emits `abs(num)`.
+ * - `SignNeg`: Only `-` on negative values.
+ * - `SignAll`: Both `+` on positive, and `-` on negative numbers.
+ * - `f` - a callback which will be invoked for each ascii character
+ * which composes the string representation of this integer
+ *
+ * # Return value
+ * A tuple containing the byte vector, and a boolean flag indicating
+ * whether it represents a special value like `inf`, `-inf`, `NaN` or not.
+ * It returns a tuple because there can be ambiguity between a special value
+ * and a number representation at higher bases.
+ *
+ * # Failure
+ * - Fails if `radix` < 2 or `radix` > 36.
+ */
+pub fn int_to_str_bytes_common<T:NumCast+Zero+Eq+Ord+Integer+
+ Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
+ num: T, radix: uint, sign: SignFormat, f: &fn(u8)) {
+ assert!(2 <= radix && radix <= 36);
+
+ let _0: T = Zero::zero();
+
+ let neg = num < _0;
+ let radix_gen: T = cast(radix);
+
+ let mut deccum = num;
+ // This is just for integral types, the largest of which is a u64. The
+ // smallest base that we can have is 2, so the most number of digits we're
+ // ever going to have is 64
+ let mut buf = [0u8, ..64];
+ let mut cur = 0;
+
+ // Loop at least once to make sure at least a `0` gets emitted.
+ loop {
+ // Calculate the absolute value of each digit instead of only
+ // doing it once for the whole number because a
+ // representable negative number doesn't necessary have an
+ // representable additive inverse of the same type
+ // (See twos complement). But we assume that for the
+ // numbers [-35 .. 0] we always have [0 .. 35].
+ let current_digit_signed = deccum % radix_gen;
+ let current_digit = if current_digit_signed < _0 {
+ -current_digit_signed
+ } else {
+ current_digit_signed
+ };
+ buf[cur] = match current_digit.to_u8() {
+ i @ 0..9 => '0' as u8 + i,
+ i => 'a' as u8 + (i - 10),
+ };
+ cur += 1;
+
+ deccum = deccum / radix_gen;
+ // No more digits to calculate for the non-fractional part -> break
+ if deccum == _0 { break; }
+ }
+
+ // Decide what sign to put in front
+ match sign {
+ SignNeg | SignAll if neg => { f('-' as u8); }
+ SignAll => { f('+' as u8); }
+ _ => ()
+ }
+
+ // We built the number in reverse order, so un-reverse it here
+ while cur > 0 {
+ cur -= 1;
+ f(buf[cur]);
+ }
+}
+
/**
* Converts a number to its string representation as a byte vector.
* This is meant to be a common base implementation for all numeric string
* # Failure
* - Fails if `radix` < 2 or `radix` > 36.
*/
-pub fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
+pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
- num: &T, radix: uint, negative_zero: bool,
+ num: T, radix: uint, negative_zero: bool,
sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) {
- if (radix as int) < 2 {
- fail!("to_str_bytes_common: radix %? to low, must lie in the range [2, 36]", radix);
- } else if radix as int > 36 {
- fail!("to_str_bytes_common: radix %? to high, must lie in the range [2, 36]", radix);
- }
+ assert!(2 <= radix && radix <= 36);
let _0: T = Zero::zero();
let _1: T = One::one();
- if is_NaN(num) {
- return ("NaN".as_bytes().to_owned(), true);
- }
- else if is_inf(num){
- return match sign {
- SignAll => ("+inf".as_bytes().to_owned(), true),
- _ => ("inf".as_bytes().to_owned(), true)
+ match num.classify() {
+ FPNaN => { return ("NaN".as_bytes().to_owned(), true); }
+ FPInfinite if num > _0 => {
+ return match sign {
+ SignAll => ("+inf".as_bytes().to_owned(), true),
+ _ => ("inf".as_bytes().to_owned(), true)
+ };
}
- }
- else if is_neg_inf(num) {
- return match sign {
- SignNone => ("inf".as_bytes().to_owned(), true),
- _ => ("-inf".as_bytes().to_owned(), true),
+ FPInfinite if num < _0 => {
+ return match sign {
+ SignNone => ("inf".as_bytes().to_owned(), true),
+ _ => ("-inf".as_bytes().to_owned(), true),
+ };
}
+ _ => {}
}
- let neg = *num < _0 || (negative_zero && is_neg_zero(num));
+ let neg = num < _0 || (negative_zero && _1 / num == Float::neg_infinity());
let mut buf: ~[u8] = ~[];
let radix_gen: T = cast(radix as int);
- let mut deccum;
-
// First emit the non-fractional part, looping at least once to make
// sure at least a `0` gets emitted.
- deccum = num.round_to_zero();
+ let mut deccum = num.trunc();
loop {
// Calculate the absolute value of each digit instead of only
// doing it once for the whole number because a
// representable additive inverse of the same type
// (See twos complement). But we assume that for the
// numbers [-35 .. 0] we always have [0 .. 35].
- let current_digit_signed = deccum % radix_gen;
- let current_digit = if current_digit_signed < _0 {
- -current_digit_signed
- } else {
- current_digit_signed
- };
+ let current_digit = (deccum % radix_gen).abs();
// Decrease the deccumulator one digit at a time
deccum = deccum / radix_gen;
- deccum = deccum.round_to_zero();
+ deccum = deccum.trunc();
buf.push(char::from_digit(current_digit.to_int() as uint, radix)
.unwrap() as u8);
let start_fractional_digits = buf.len();
// Now emit the fractional part, if any
- deccum = num.fractional_part();
+ deccum = num.fract();
if deccum != _0 || (limit_digits && exact && digit_count > 0) {
buf.push('.' as u8);
let mut dig = 0u;
// Calculate the absolute value of each digit.
// See note in first loop.
- let current_digit_signed = deccum.round_to_zero();
- let current_digit = if current_digit_signed < _0 {
- -current_digit_signed
- } else {
- current_digit_signed
- };
+ let current_digit = deccum.trunc().abs();
buf.push(char::from_digit(
current_digit.to_int() as uint, radix).unwrap() as u8);
// Decrease the deccumulator one fractional digit at a time
- deccum = deccum.fractional_part();
+ deccum = deccum.fract();
dig += 1u;
}
* `to_str_bytes_common()`, for details see there.
*/
#[inline]
-pub fn to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
- Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
- num: &T, radix: uint, negative_zero: bool,
+pub fn float_to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Float+Round+
+ Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
+ num: T, radix: uint, negative_zero: bool,
sign: SignFormat, digits: SignificantDigits) -> (~str, bool) {
- let (bytes, special) = to_str_bytes_common(num, radix,
+ let (bytes, special) = float_to_str_bytes_common(num, radix,
negative_zero, sign, digits);
(str::from_bytes(bytes), special)
}
use num::{ToStrRadix, FromStrRadix};
use num::{Zero, One, strconv};
use prelude::*;
+use str;
pub use cmp::{min, max};
/// Convert to a string as a byte slice in a given base.
#[inline]
pub fn to_str_bytes<U>(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
- let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
- strconv::SignNeg, strconv::DigAll);
- f(buf)
+ // The radix can be as low as 2, so we need at least 64 characters for a
+ // base 2 number.
+ let mut buf = [0u8, ..64];
+ let mut cur = 0;
+ do strconv::int_to_str_bytes_common(n, radix, strconv::SignNone) |i| {
+ buf[cur] = i;
+ cur += 1;
+ }
+ f(buf.slice(0, cur))
}
/// Convert to a string in base 10.
#[inline]
pub fn to_str(num: $T) -> ~str {
- let (buf, _) = strconv::to_str_common(&num, 10u, false,
- strconv::SignNeg, strconv::DigAll);
- buf
+ to_str_radix(num, 10u)
}
/// Convert to a string in a given base.
#[inline]
pub fn to_str_radix(num: $T, radix: uint) -> ~str {
- let (buf, _) = strconv::to_str_common(&num, radix, false,
- strconv::SignNeg, strconv::DigAll);
- buf
+ let mut buf = ~[];
+ do strconv::int_to_str_bytes_common(num, radix, strconv::SignNone) |i| {
+ buf.push(i);
+ }
+ // We know we generated valid utf-8, so we don't need to go through that
+ // check.
+ unsafe { str::raw::from_bytes_owned(buf) }
}
impl ToStr for $T {
}
}
-impl Repr for int {
- fn write_repr(&self, writer: @Writer) { writer.write_int(*self); }
-}
-impl Repr for i8 {
- fn write_repr(&self, writer: @Writer) { writer.write_int(*self as int); }
-}
-impl Repr for i16 {
- fn write_repr(&self, writer: @Writer) { writer.write_int(*self as int); }
-}
-impl Repr for i32 {
- fn write_repr(&self, writer: @Writer) { writer.write_int(*self as int); }
-}
-impl Repr for i64 {
- // FIXME #4424: This can lose precision.
- fn write_repr(&self, writer: @Writer) { writer.write_int(*self as int); }
-}
-
-impl Repr for uint {
- fn write_repr(&self, writer: @Writer) { writer.write_uint(*self); }
-}
-impl Repr for u8 {
- fn write_repr(&self, writer: @Writer) {
- writer.write_uint(*self as uint);
- }
-}
-impl Repr for u16 {
- fn write_repr(&self, writer: @Writer) {
- writer.write_uint(*self as uint);
- }
-}
-impl Repr for u32 {
- fn write_repr(&self, writer: @Writer) {
- writer.write_uint(*self as uint);
- }
-}
-impl Repr for u64 {
- // FIXME #4424: This can lose precision.
+macro_rules! int_repr(($ty:ident) => (impl Repr for $ty {
fn write_repr(&self, writer: @Writer) {
- writer.write_uint(*self as uint);
+ do ::$ty::to_str_bytes(*self, 10u) |bits| {
+ writer.write(bits);
+ }
}
-}
+}))
-impl Repr for float {
- // FIXME #4423: This mallocs.
- fn write_repr(&self, writer: @Writer) { writer.write_str(self.to_str()); }
-}
-impl Repr for f32 {
- // FIXME #4423 This mallocs.
- fn write_repr(&self, writer: @Writer) { writer.write_str(self.to_str()); }
-}
-impl Repr for f64 {
- // FIXME #4423: This mallocs.
- fn write_repr(&self, writer: @Writer) { writer.write_str(self.to_str()); }
-}
+int_repr!(int)
+int_repr!(i8)
+int_repr!(i16)
+int_repr!(i32)
+int_repr!(i64)
+int_repr!(uint)
+int_repr!(u8)
+int_repr!(u16)
+int_repr!(u32)
+int_repr!(u64)
-impl Repr for char {
- fn write_repr(&self, writer: @Writer) { writer.write_char(*self); }
-}
+macro_rules! num_repr(($ty:ident) => (impl Repr for $ty {
+ fn write_repr(&self, writer: @Writer) {
+ let s = self.to_str();
+ writer.write(s.as_bytes());
+ }
+}))
+num_repr!(float)
+num_repr!(f32)
+num_repr!(f64)
// New implementation using reflect::MovePtr
*
* Raises the `not_utf8` condition if invalid UTF-8
*/
-
pub fn from_bytes(vv: &[u8]) -> ~str {
use str::not_utf8::cond;
}
}
+/**
+ * Consumes a vector of bytes to create a new utf-8 string
+ *
+ * # Failure
+ *
+ * Raises the `not_utf8` condition if invalid UTF-8
+ */
+pub fn from_bytes_owned(vv: ~[u8]) -> ~str {
+ use str::not_utf8::cond;
+
+ if !is_utf8(vv) {
+ let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).get();
+ cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
+ first_bad_byte as uint))
+ } else {
+ return unsafe { raw::from_bytes_owned(vv) }
+ }
+}
+
/**
* Convert a vector of bytes to a UTF-8 string.
* The vector needs to be one byte longer than the string, and end with a 0 byte.
}
}
+ /// Converts an owned vector of bytes to a new owned string. This assumes
+ /// that the utf-8-ness of the vector has already been validated
+ pub unsafe fn from_bytes_owned(mut v: ~[u8]) -> ~str {
+ v.push(0u8);
+ cast::transmute(v)
+ }
+
/// Converts a vector of bytes to a string.
/// The byte slice needs to contain valid utf8 and needs to be one byte longer than
/// the string, if possible ending in a 0 byte.
let mut out: ~str = ~"";
out.reserve_at_least(self.len());
for self.iter().advance |c| {
- out.push_str(char::escape_default(c));
+ do c.escape_default |c| {
+ out.push_char(c);
+ }
}
out
}
let mut out: ~str = ~"";
out.reserve_at_least(self.len());
for self.iter().advance |c| {
- out.push_str(char::escape_unicode(c));
+ do c.escape_unicode |c| {
+ out.push_char(c);
+ }
}
out
}