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
//! `Rust` string types with a defined `#[repr(C)]` layout, albeit not `char *`
//! compatible (_fat_ pointers).

use_prelude!();

pub use self::slice::*;
mod slice;

cfg_alloc! {
    ReprC! {
        #[repr(transparent)]
        #[cfg_attr(all(docs, feature = "nightly"), doc(cfg(feature = "alloc")))]
        /// Same as [`String`][`rust::String`], but with guaranteed `#[repr(C)]` layout
        pub
        struct String (
            Vec<u8>,
        );
    }

    impl From<rust::String>
        for String
    {
        #[inline]
        fn from (s: rust::String) -> String
        {
            Self(rust::Vec::from(s).into())
        }
    }
    impl Into<rust::String>
        for String
    {
        #[inline]
        fn into (self: String) -> rust::String
        {
            unsafe {
                rust::String::from_utf8_unchecked(
                    self.0.into()
                )
            }
        }
    }

    impl Deref
        for String
    {
        type Target = str;

        fn deref (self: &'_ Self) -> &'_ Self::Target
        {
            unsafe {
                ::core::str::from_utf8_unchecked(&* self.0)
            }
        }
    }

    impl fmt::Debug
        for String
    {
        fn fmt (self: &'_ Self, fmt: &'_ mut fmt::Formatter<'_>)
        -> fmt::Result
        {
            <str as fmt::Debug>::fmt(self, fmt)
        }
    }

    impl String {
        pub
        const EMPTY: Self = Self(Vec::EMPTY);

        pub
        fn with_rust_mut<R> (
            self: &'_ mut String,
            f: impl FnOnce(&'_ mut rust::String) -> R,
        ) -> R
        {
            self.0.with_rust_mut(|v: &'_ mut rust::Vec<u8>| {
                let s: &'_ mut rust::String = unsafe { mem::transmute(v) };
                f(s)
            })
        }
    }
}