1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#![no_std]

use containers::collections::Vec;
use core::{borrow::{Borrow, BorrowMut}, convert::TryFrom, ops::{Deref, DerefMut}, str::{self, Utf8Error}};

#[repr(transparent)]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct String(Vec<u8>);

impl String {
    #[inline]
    pub fn new() -> Self { Self(Vec::new()) }

    #[inline]
    pub fn from_str(s: &str) -> Option<Self> {
        Vec::from_slice(s.as_bytes()).map(|x| unsafe { Self::from_vec_unchecked(x) })
    }

    #[inline(always)]
    pub unsafe fn from_vec_unchecked(x: Vec<u8>) -> Self { Self(x) }
}

impl From<String> for Vec<u8> {
    #[inline(always)]
    fn from(x: String) -> Self { x.0 }
}

impl TryFrom<Vec<u8>> for String {
    type Error = FromUtf8Error;

    #[inline]
    fn try_from(bs: Vec<u8>) -> Result<Self, FromUtf8Error> {
        match str::from_utf8(&bs) {
            Ok(_) => Ok(String(bs)),
            Err(e) => Err(FromUtf8Error { bytes: bs, error: e })
        }
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct FromUtf8Error {
    bytes: Vec<u8>,
    error: Utf8Error,
}

impl FromUtf8Error {
    #[inline]
    pub fn into_bytes(self) -> Vec<u8> { self.bytes }

    #[inline]
    pub fn utf8_error(&self) -> Utf8Error { self.error }
}

impl Deref for String {
    type Target = str;

    #[inline]
    fn deref(&self) -> &str { unsafe { core::str::from_utf8_unchecked(&self.0) } }
}

impl DerefMut for String {
    #[inline]
    fn deref_mut(&mut self) -> &mut str { unsafe { core::str::from_utf8_unchecked_mut(&mut self.0) } }
}

impl Borrow<str> for String {
    #[inline]
    fn borrow(&self) -> &str { self.deref() }
}

impl BorrowMut<str> for String {
    fn borrow_mut(&mut self) -> &mut str { self.deref_mut() }
}

impl core::fmt::Display for String {
    #[inline]
    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { self.deref().fmt(fmt) }
}

#[macro_export]
macro_rules! format {
    ($($x:tt)*) => ({
        let s = $crate::String::new();
        core::fmt::write(&mut s, format_args!($($x)*)).ok().map(|()| s)
    });
}