encode_unicode/
utf16_char.rs

1/* Copyright 2016 The encode_unicode Developers
2 *
3 * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4 * http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5 * http://opensource.org/licenses/MIT>, at your option. This file may not be
6 * copied, modified, or distributed except according to those terms.
7 */
8
9use utf16_iterators::Utf16Iterator;
10use traits::{CharExt, U16UtfExt};
11use utf8_char::Utf8Char;
12use errors::{InvalidUtf16Slice, InvalidUtf16Tuple, NonBMPError, EmptyStrError, FromStrError};
13extern crate core;
14use self::core::{hash,fmt};
15use self::core::cmp::Ordering;
16use self::core::borrow::Borrow;
17use self::core::ops::Deref;
18use self::core::str::FromStr;
19#[cfg(feature="std")]
20use self::core::iter::FromIterator;
21#[cfg(feature="std")]
22#[allow(deprecated)]
23use std::ascii::AsciiExt;
24#[cfg(feature="ascii")]
25use self::core::char;
26#[cfg(feature="ascii")]
27extern crate ascii;
28#[cfg(feature="ascii")]
29use self::ascii::{AsciiChar,ToAsciiChar,ToAsciiCharError};
30
31
32// I don't think there is any good default value for char, but char does.
33#[derive(Default)]
34// char doesn't do anything more advanced than u32 for Eq/Ord, so we shouldn't either.
35// When it's a single unit, the second is zero, so Eq works.
36// #[derive(Ord)] however, breaks on surrogate pairs.
37#[derive(PartialEq,Eq)]
38#[derive(Clone,Copy)]
39
40
41/// An unicode codepoint stored as UTF-16.
42///
43/// It can be borrowed as an `u16` slice, and has the same size as `char`.
44pub struct Utf16Char {
45    units: [u16; 2],
46}
47
48
49  /////////////////////
50 //conversion traits//
51/////////////////////
52impl FromStr for Utf16Char {
53    type Err = FromStrError;
54    /// Create an `Utf16Char` from a string slice.
55    /// The string must contain exactly one codepoint.
56    ///
57    /// # Examples
58    ///
59    /// ```
60    /// use encode_unicode::error::FromStrError::*;
61    /// use encode_unicode::Utf16Char;
62    /// use std::str::FromStr;
63    ///
64    /// assert_eq!(Utf16Char::from_str("a"), Ok(Utf16Char::from('a')));
65    /// assert_eq!(Utf16Char::from_str("🂠"), Ok(Utf16Char::from('🂠')));
66    /// assert_eq!(Utf16Char::from_str(""), Err(Empty));
67    /// assert_eq!(Utf16Char::from_str("ab"), Err(MultipleCodepoints));
68    /// assert_eq!(Utf16Char::from_str("é"), Err(MultipleCodepoints));// 'e'+u301 combining mark
69    /// ```
70    fn from_str(s: &str) -> Result<Self, FromStrError> {
71        match Utf16Char::from_str_start(s) {
72            Ok((u16c,bytes)) if bytes == s.len() => Ok(u16c),
73            Ok((_,_)) => Err(FromStrError::MultipleCodepoints),
74            Err(EmptyStrError) => Err(FromStrError::Empty),
75        }
76    }
77}
78impl From<char> for Utf16Char {
79    fn from(c: char) -> Self {
80        let (first, second) = c.to_utf16_tuple();
81        Utf16Char{ units: [first, second.unwrap_or(0)] }
82    }
83}
84impl From<Utf8Char> for Utf16Char {
85    fn from(utf8: Utf8Char) -> Utf16Char {
86        let (b, utf8_len) = utf8.to_array();
87        match utf8_len {
88            1 => Utf16Char{ units: [b[0] as u16, 0] },
89            4 => {// need surrogate
90                let mut first = 0xd800 - (0x01_00_00u32 >> 10) as u16;
91                first += (b[0] as u16 & 0x07) << 8;
92                first += (b[1] as u16 & 0x3f) << 2;
93                first += (b[2] as u16 & 0x30) >> 4;
94                let mut second = 0xdc00;
95                second |= (b[2] as u16 & 0x0f) << 6;
96                second |=  b[3] as u16 & 0x3f;
97                Utf16Char{ units: [first, second] }
98            },
99            _ => { // 2 or 3
100                let mut unit = ((b[0] as u16 & 0x1f) << 6) | (b[1] as u16 & 0x3f);
101                if utf8_len == 3 {
102                    unit = (unit << 6) | (b[2] as u16 & 0x3f);
103                }
104                Utf16Char{ units: [unit, 0] }
105            },
106        }
107    }
108}
109impl From<Utf16Char> for char {
110    fn from(uc: Utf16Char) -> char {
111        unsafe{ char::from_utf16_tuple_unchecked(uc.to_tuple()) }
112    }
113}
114impl IntoIterator for Utf16Char {
115    type Item=u16;
116    type IntoIter=Utf16Iterator;
117    /// Iterate over the units.
118    fn into_iter(self) -> Utf16Iterator {
119        Utf16Iterator::from(self)
120    }
121}
122
123#[cfg(feature="std")]
124impl Extend<Utf16Char> for Vec<u16> {
125    fn extend<I:IntoIterator<Item=Utf16Char>>(&mut self,  iter: I) {
126        let iter = iter.into_iter();
127        self.reserve(iter.size_hint().0);
128        for u16c in iter {
129            self.push(u16c.units[0]);
130            if u16c.units[1] != 0 {
131                self.push(u16c.units[1]);
132            }
133        }
134    }
135}
136#[cfg(feature="std")]
137impl<'a> Extend<&'a Utf16Char> for Vec<u16> {
138    fn extend<I:IntoIterator<Item=&'a Utf16Char>>(&mut self,  iter: I) {
139        self.extend(iter.into_iter().cloned())
140    }
141}
142#[cfg(feature="std")]
143impl FromIterator<Utf16Char> for Vec<u16> {
144    fn from_iter<I:IntoIterator<Item=Utf16Char>>(iter: I) -> Self {
145        let mut vec = Vec::new();
146        vec.extend(iter);
147        return vec;
148    }
149}
150#[cfg(feature="std")]
151impl<'a> FromIterator<&'a Utf16Char> for Vec<u16> {
152    fn from_iter<I:IntoIterator<Item=&'a Utf16Char>>(iter: I) -> Self {
153        Self::from_iter(iter.into_iter().cloned())
154    }
155}
156
157#[cfg(feature="std")]
158impl Extend<Utf16Char> for String {
159    fn extend<I:IntoIterator<Item=Utf16Char>>(&mut self,  iter: I) {
160        self.extend(iter.into_iter().map(|u16c| Utf8Char::from(u16c) ));
161    }
162}
163#[cfg(feature="std")]
164impl<'a> Extend<&'a Utf16Char> for String {
165    fn extend<I:IntoIterator<Item=&'a Utf16Char>>(&mut self,  iter: I) {
166        self.extend(iter.into_iter().cloned());
167    }
168}
169#[cfg(feature="std")]
170impl FromIterator<Utf16Char> for String {
171    fn from_iter<I:IntoIterator<Item=Utf16Char>>(iter: I) -> Self {
172        let mut s = String::new();
173        s.extend(iter);
174        return s;
175    }
176}
177#[cfg(feature="std")]
178impl<'a> FromIterator<&'a Utf16Char> for String {
179    fn from_iter<I:IntoIterator<Item=&'a Utf16Char>>(iter: I) -> Self {
180        Self::from_iter(iter.into_iter().cloned())
181    }
182}
183
184
185  /////////////////
186 //getter traits//
187/////////////////
188impl AsRef<[u16]> for Utf16Char {
189    #[inline]
190    fn as_ref(&self) -> &[u16] {
191        &self.units[..self.len()]
192    }
193}
194impl Borrow<[u16]> for Utf16Char {
195    #[inline]
196    fn borrow(&self) -> &[u16] {
197        self.as_ref()
198    }
199}
200impl Deref for Utf16Char {
201    type Target = [u16];
202    #[inline]
203    fn deref(&self) -> &[u16] {
204        self.as_ref()
205    }
206}
207
208
209  ////////////////
210 //ascii traits//
211////////////////
212#[cfg(feature="std")]
213#[allow(deprecated)]
214impl AsciiExt for Utf16Char {
215    type Owned = Self;
216    fn is_ascii(&self) -> bool {
217        self.units[0] < 128
218    }
219    fn eq_ignore_ascii_case(&self,  other: &Self) -> bool {
220        self.to_ascii_lowercase() == other.to_ascii_lowercase()
221    }
222    fn to_ascii_uppercase(&self) -> Self {
223        let n = self.units[0].wrapping_sub(b'a' as u16);
224        if n < 26 {Utf16Char{ units: [n+b'A' as u16, 0] }}
225        else      {*self}
226    }
227    fn to_ascii_lowercase(&self) -> Self {
228        let n = self.units[0].wrapping_sub(b'A' as u16);
229        if n < 26 {Utf16Char{ units: [n+b'a' as u16, 0] }}
230        else      {*self}
231    }
232    fn make_ascii_uppercase(&mut self) {
233        *self = self.to_ascii_uppercase()
234    }
235    fn make_ascii_lowercase(&mut self) {
236        *self = self.to_ascii_lowercase();
237    }
238}
239
240#[cfg(feature="ascii")]
241/// Requires the feature "ascii".
242impl From<AsciiChar> for Utf16Char {
243    #[inline]
244    fn from(ac: AsciiChar) -> Self {
245        Utf16Char{ units: [ac.as_byte() as u16, 0] }
246    }
247}
248#[cfg(feature="ascii")]
249/// Requires the feature "ascii".
250impl ToAsciiChar for Utf16Char {
251    #[inline]
252    fn to_ascii_char(self) -> Result<AsciiChar, ToAsciiCharError> {
253        unsafe{ AsciiChar::from(char::from_u32_unchecked(self.units[0] as u32)) }
254    }
255    #[inline]
256    unsafe fn to_ascii_char_unchecked(self) -> AsciiChar {
257        AsciiChar::from_unchecked(self.units[0] as u8)
258    }
259}
260
261
262  /////////////////////////////////////////////////////////
263 //Genaral traits that cannot be derived to emulate char//
264/////////////////////////////////////////////////////////
265impl hash::Hash for Utf16Char {
266    fn hash<H : hash::Hasher>(&self,  state: &mut H) {
267        self.to_char().hash(state);
268    }
269}
270impl fmt::Debug for Utf16Char {
271    fn fmt(&self,  fmtr: &mut fmt::Formatter) -> fmt::Result {
272        fmt::Debug::fmt(&self.to_char(), fmtr)
273    }
274}
275impl fmt::Display for Utf16Char {
276    fn fmt(&self,  fmtr: &mut fmt::Formatter) -> fmt::Result {
277        fmt::Display::fmt(&Utf8Char::from(*self), fmtr)
278    }
279}
280// Cannot derive these impls because two-unit characters must always compare
281// greater than one-unit ones.
282impl PartialOrd for Utf16Char {
283    #[inline]
284    fn partial_cmp(&self,  rhs: &Self) -> Option<Ordering> {
285        Some(self.cmp(rhs))
286    }
287}
288impl Ord for Utf16Char {
289    #[inline]
290    fn cmp(&self,  rhs: &Self) -> Ordering {
291        // Shift the first unit by 0xd if surrogate, and 0 otherwise.
292        // This ensures surrogates are always greater than 0xffff, and
293        // that the second unit only affect the result when the first are equal.
294        // Multiplying by a constant factor isn't enough because that factor
295        // would have to be greater than 1023 and smaller than 5.5.
296        // This transformation is less complicated than combine_surrogates().
297        let lhs = (self.units[0] as u32, self.units[1] as u32);
298        let rhs = (rhs.units[0] as u32, rhs.units[1] as u32);
299        let lhs = (lhs.0 << (lhs.1 >> 12)) + lhs.1;
300        let rhs = (rhs.0 << (rhs.1 >> 12)) + rhs.1;
301        lhs.cmp(&rhs)
302    }
303}
304
305
306  ////////////////////////////////
307 //Comparisons with other types//
308////////////////////////////////
309impl PartialEq<char> for Utf16Char {
310    fn eq(&self,  u32c: &char) -> bool {
311        *self == Utf16Char::from(*u32c)
312    }
313}
314impl PartialEq<Utf16Char> for char {
315    fn eq(&self,  u16c: &Utf16Char) -> bool {
316        Utf16Char::from(*self) == *u16c
317    }
318}
319impl PartialOrd<char> for Utf16Char {
320    fn partial_cmp(&self,  u32c: &char) -> Option<Ordering> {
321        self.partial_cmp(&Utf16Char::from(*u32c))
322    }
323}
324impl PartialOrd<Utf16Char> for char {
325    fn partial_cmp(&self,  u16c: &Utf16Char) -> Option<Ordering> {
326        Utf16Char::from(*self).partial_cmp(u16c)
327    }
328}
329
330impl PartialEq<Utf8Char> for Utf16Char {
331    fn eq(&self,  u8c: &Utf8Char) -> bool {
332        *self == Utf16Char::from(*u8c)
333    }
334}
335impl PartialOrd<Utf8Char> for Utf16Char {
336    fn partial_cmp(&self,  u8c: &Utf8Char) -> Option<Ordering> {
337        self.partial_cmp(&Utf16Char::from(*u8c))
338    }
339}
340// The other direction reverse impls in utf8_char.rs
341
342/// Only considers the unit equal if the codepoint of the `Utf16Char` is not
343/// made up of a surrogate pair.
344///
345/// There is no impl in the opposite direction, as this should only be used to
346/// compare `Utf16Char`s against constants.
347///
348/// # Examples
349///
350/// ```
351/// # use encode_unicode::Utf16Char;
352/// assert!(Utf16Char::from('6') == b'6' as u16);
353/// assert!(Utf16Char::from('\u{FFFF}') == 0xffff_u16);
354/// assert!(Utf16Char::from_tuple((0xd876, Some(0xdef9))).unwrap() != 0xd876_u16);
355/// ```
356impl PartialEq<u16> for Utf16Char {
357    fn eq(&self,  unit: &u16) -> bool {
358        self.units[0] == *unit  &&  self.units[1] == 0
359    }
360}
361/// Only considers the byte equal if the codepoint of the `Utf16Char` is <= U+FF.
362///
363/// # Examples
364///
365/// ```
366/// # use encode_unicode::Utf16Char;
367/// assert!(Utf16Char::from('6') == b'6');
368/// assert!(Utf16Char::from('\u{00FF}') == b'\xff');
369/// assert!(Utf16Char::from('\u{0100}') != b'\0');
370/// ```
371impl PartialEq<u8> for Utf16Char {
372    fn eq(&self,  byte: &u8) -> bool {
373        self.units[0] == *byte as u16
374    }
375}
376#[cfg(feature = "ascii")]
377/// `Utf16Char`s that are not ASCII never compare equal.
378impl PartialEq<AsciiChar> for Utf16Char {
379    #[inline]
380    fn eq(&self,  ascii: &AsciiChar) -> bool {
381        self.units[0] == *ascii as u16
382    }
383}
384#[cfg(feature = "ascii")]
385/// `Utf16Char`s that are not ASCII never compare equal.
386impl PartialEq<Utf16Char> for AsciiChar {
387    #[inline]
388    fn eq(&self,  u16c: &Utf16Char) -> bool {
389        *self as u16 == u16c.units[0]
390    }
391}
392#[cfg(feature = "ascii")]
393/// `Utf16Char`s that are not ASCII always compare greater.
394impl PartialOrd<AsciiChar> for Utf16Char {
395    #[inline]
396    fn partial_cmp(&self,  ascii: &AsciiChar) -> Option<Ordering> {
397        self.units[0].partial_cmp(&(*ascii as u16))
398    }
399}
400#[cfg(feature = "ascii")]
401/// `Utf16Char`s that are not ASCII always compare greater.
402impl PartialOrd<Utf16Char> for AsciiChar {
403    #[inline]
404    fn partial_cmp(&self,  u16c: &Utf16Char) -> Option<Ordering> {
405        (*self as u16).partial_cmp(&u16c.units[0])
406    }
407}
408
409
410  ///////////////////////////////////////////////////////
411 //pub impls that should be together for nicer rustdoc//
412///////////////////////////////////////////////////////
413impl Utf16Char {
414    /// Create an `Utf16Char` from the first codepoint in a string slice,
415    /// converting from UTF-8 to UTF-16.
416    ///
417    /// The returned `usize` is the number of UTF-8 bytes used from the str,
418    /// and not the number of UTF-16 units.
419    ///
420    /// Returns an error if the `str` is empty.
421    ///
422    /// # Examples
423    ///
424    /// ```
425    /// use encode_unicode::Utf16Char;
426    ///
427    /// assert_eq!(Utf16Char::from_str_start("a"), Ok((Utf16Char::from('a'),1)));
428    /// assert_eq!(Utf16Char::from_str_start("ab"), Ok((Utf16Char::from('a'),1)));
429    /// assert_eq!(Utf16Char::from_str_start("🂠 "), Ok((Utf16Char::from('🂠'),4)));
430    /// assert_eq!(Utf16Char::from_str_start("é"), Ok((Utf16Char::from('e'),1)));// 'e'+u301 combining mark
431    /// assert!(Utf16Char::from_str_start("").is_err());
432    /// ```
433    pub fn from_str_start(s: &str) -> Result<(Self,usize), EmptyStrError> {
434        if s.is_empty() {
435            return Err(EmptyStrError);
436        }
437        let b = s.as_bytes();
438        // Read the last byte first to reduce the number of unnecesary length checks.
439        match b[0] {
440            0...127 => {// 1 byte => 1 unit
441                let unit = b[0] as u16;// 0b0000_0000_0xxx_xxxx
442                Ok((Utf16Char{ units: [unit, 0] }, 1))
443            },
444            0b1000_0000...0b1101_1111 => {// 2 bytes => 1 unit
445                let unit = (((b[1] & 0x3f) as u16) << 0) // 0b0000_0000_00xx_xxxx
446                         | (((b[0] & 0x1f) as u16) << 6);// 0b0000_0xxx_xx00_0000
447                Ok((Utf16Char{ units: [unit, 0] }, 2))
448            },
449            0b1110_0000...0b1110_1111 => {// 3 bytes => 1 unit
450                let unit = (((b[2] & 0x3f) as u16) <<  0) // 0b0000_0000_00xx_xxxx
451                         | (((b[1] & 0x3f) as u16) <<  6) // 0b0000_xxxx_xx00_0000
452                         | (((b[0] & 0x0f) as u16) << 12);// 0bxxxx_0000_0000_0000
453                Ok((Utf16Char{ units: [unit, 0] }, 3))
454            },
455            _ => {// 4 bytes => 2 units
456                let second = 0xdc00                        // 0b1101_1100_0000_0000
457                           | (((b[3] & 0x3f) as u16) << 0) // 0b0000_0000_00xx_xxxx
458                           | (((b[2] & 0x0f) as u16) << 6);// 0b0000_00xx_xx00_0000
459                let first = 0xd800-(0x01_00_00u32>>10) as u16// 0b1101_0111_1100_0000
460                          + (((b[2] & 0x30) as u16) >> 4)    // 0b0000_0000_0000_00xx
461                          + (((b[1] & 0x3f) as u16) << 2)    // 0b0000_0000_xxxx_xx00
462                          + (((b[0] & 0x07) as u16) << 8);   // 0b0000_0xxx_0000_0000
463                Ok((Utf16Char{ units: [first, second] }, 4))
464            }
465        }
466    }
467    /// Validate and store the first UTF-16 codepoint in the slice.
468    /// Also return how many units were needed.
469    pub fn from_slice_start(src: &[u16]) -> Result<(Self,usize), InvalidUtf16Slice> {
470        char::from_utf16_slice_start(src).map(|(_,len)| {
471            let second = if len==2 {src[1]} else {0};
472            (Utf16Char{ units: [src[0], second] }, len)
473        })
474    }
475    /// Store the first UTF-16 codepoint of the slice.
476    ///
477    /// # Safety
478    /// The slice must be non-empty and start with a valid UTF-16 codepoint.  
479    /// The length of the slice is never checked.
480    pub unsafe fn from_slice_start_unchecked(src: &[u16]) -> (Self,usize) {
481        let first = *src.get_unchecked(0);
482        if first.is_utf16_leading_surrogate() {
483            (Utf16Char{ units: [first, *src.get_unchecked(1)] }, 2)
484        } else {
485            (Utf16Char{ units: [first, 0] }, 1)
486        }
487    }
488    /// Validate and store a UTF-16 pair as returned from `char.to_utf16_tuple()`.
489    pub fn from_tuple(utf16: (u16,Option<u16>)) -> Result<Self,InvalidUtf16Tuple> {
490        unsafe {char::from_utf16_tuple(utf16).map(|_|
491            Self::from_tuple_unchecked(utf16)
492        )}
493    }
494    /// Create an `Utf16Char` from a tuple as returned from `char.to_utf16_tuple()`.
495    ///
496    /// # Safety
497    ///
498    /// The units must represent a single valid codepoint.
499    pub unsafe fn from_tuple_unchecked(utf16: (u16,Option<u16>)) -> Self {
500        Utf16Char{ units: [utf16.0, utf16.1.unwrap_or(0)] }
501    }
502    /// Create an `Utf16Char` from a single unit.
503    ///
504    /// The unit must be a codepoint in the basic multilingual plane,
505    /// or, not a part of a surrogate pair.
506    ///
507    /// # Errors
508    ///
509    /// Returns `NonBMPError` if the unit is in the range `0xd800..0xe000`.
510    ///
511    /// # Examples
512    ///
513    /// ```
514    /// # use encode_unicode::Utf16Char;
515    /// assert_eq!(Utf16Char::from_bmp(0x40).unwrap(), '@');
516    /// assert_eq!(Utf16Char::from_bmp('ø' as u16).unwrap(), 'ø');
517    /// assert!(Utf16Char::from_bmp(0xdddd).is_err());
518    /// ```
519    pub fn from_bmp(bmp_codepoint: u16) -> Result<Self,NonBMPError> {
520        if bmp_codepoint & 0xf800 != 0xd800 {
521            Ok(Utf16Char{ units: [bmp_codepoint, 0] })
522        } else {
523            Err(NonBMPError)
524        }
525    }
526    /// Create an `Utf16Char` from a single unit without checking that it's a
527    /// valid codepoint on its own.
528    ///
529    /// # Safety
530    ///
531    /// The unit must be less than 0xd800 or greater than 0xdfff codepoint in the basic multilingual plane,
532    /// or, not a surrogate.
533    #[inline]
534    pub unsafe fn from_bmp_unchecked(bmp_codepoint: u16) -> Self {
535        Utf16Char{ units: [bmp_codepoint, 0] }
536    }
537
538    /// The number of units this character is made up of.
539    ///
540    /// Is either 1 or 2 and identical to `.as_char().len_utf16()`
541    /// or `.as_ref().len()`.
542    #[inline]
543    pub fn len(self) -> usize {
544        1 + (self.units[1] as usize >> 15)
545    }
546    // There is no `.is_emty()` because it would always return false.
547
548    /// Checks that the codepoint is an ASCII character.
549    #[inline]
550    pub fn is_ascii(&self) -> bool {
551        self.units[0] <= 127
552    }
553    /// Checks that two characters are an ASCII case-insensitive match.
554    ///
555    /// Is equivalent to `a.to_ascii_lowercase() == b.to_ascii_lowercase()`.
556    #[cfg(feature="std")]
557    pub fn eq_ignore_ascii_case(&self,  other: &Self) -> bool {
558        self.to_ascii_lowercase() == other.to_ascii_lowercase()
559    }
560    /// Converts the character to its ASCII upper case equivalent.
561    ///
562    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
563    /// but non-ASCII letters are unchanged.
564    #[cfg(feature="std")]
565    pub fn to_ascii_uppercase(&self) -> Self {
566        let n = self.units[0].wrapping_sub(b'a' as u16);
567        if n < 26 {Utf16Char{ units: [n+b'A' as u16, 0] }}
568        else      {*self}
569    }
570    /// Converts the character to its ASCII lower case equivalent.
571    ///
572    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
573    /// but non-ASCII letters are unchanged.
574    #[cfg(feature="std")]
575    pub fn to_ascii_lowercase(&self) -> Self {
576        let n = self.units[0].wrapping_sub(b'A' as u16);
577        if n < 26 {Utf16Char{ units: [n+b'a' as u16, 0] }}
578        else      {*self}
579    }
580    /// Converts the character to its ASCII upper case equivalent in-place.
581    ///
582    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
583    /// but non-ASCII letters are unchanged.
584    #[cfg(feature="std")]
585    pub fn make_ascii_uppercase(&mut self) {
586        *self = self.to_ascii_uppercase()
587    }
588    /// Converts the character to its ASCII lower case equivalent in-place.
589    ///
590    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
591    /// but non-ASCII letters are unchanged.
592    #[cfg(feature="std")]
593    pub fn make_ascii_lowercase(&mut self) {
594        *self = self.to_ascii_lowercase();
595    }
596
597    /// Convert from UTF-16 to UTF-32
598    pub fn to_char(self) -> char {
599        self.into()
600    }
601    /// Write the internal representation to a slice,
602    /// and then returns the number of `u16`s written.
603    ///
604    /// # Panics
605    /// Will panic the buffer is too small;
606    /// You can get the required length from `.len()`,
607    /// but a buffer of length two is always large enough.
608    pub fn to_slice(self,  dst: &mut[u16]) -> usize {
609        // Write the last unit first to avoid repeated length checks.
610        let extra = self.units[1] as usize >> 15;
611        match dst.get_mut(extra) {
612            Some(first) => *first = self.units[extra],
613            None => panic!("The provided buffer is too small.")
614        }
615        if extra != 0 {dst[0] = self.units[0];}
616        extra+1
617    }
618    /// The second `u16` is used for surrogate pairs.
619    #[inline]
620    pub fn to_tuple(self) -> (u16,Option<u16>) {
621        (self.units[0],  if self.units[1]==0 {None} else {Some(self.units[1])})
622    }
623}