内部の型を取り出す

ここまでで外側の (新しく用意した) 型の値を作成する実装ができたので、次は逆向き、内側の値を取り出す実装である。 これは失敗しないので簡単だ。


#![allow(unused)]
fn main() {
// 追加の制約なしの型の場合。

#[repr(transparent)]
pub struct MyStr(str);
impl MyStr {
    fn as_str(&self) -> &str { unimplemented!() }
    fn as_mut_str(&mut self) -> &mut str { unimplemented!() }
}

pub struct MyString(String);

impl<'a> From<&'a MyStr> for &'a str {
    #[inline]
    fn from(s: &'a MyStr) -> Self {
        s.as_str()
    }
}

impl<'a> From<&'a mut MyStr> for &'a mut str {
    #[inline]
    fn from(s: &'a mut MyStr) -> Self {
        s.as_mut_str()
    }
}

impl From<MyString> for String {
    #[inline]
    fn from(s: MyString) -> Self {
        s.0
    }
}
}

#![allow(unused)]
fn main() {
// 追加の制約付きの型の場合。

#[repr(transparent)]
pub struct AsciiStr(str);
impl AsciiStr {
    fn as_str(&self) -> &str { unimplemented!() }
}

pub struct AsciiString(String);

impl<'a> From<&'a AsciiStr> for &'a str {
    #[inline]
    fn from(s: &'a AsciiStr) -> Self {
        s.as_str()
    }
}

impl From<AsciiString> for String {
    #[inline]
    fn from(s: AsciiString) -> Self {
        s.0
    }
}
}

コードを載せる価値があるか疑問さえ湧いてくるつまらなさである。 AsciiBytesAsciiByteBuf 用の実装も AsciiStr / AsciiString と同様なので省略する。

ただ、 AsciiBytes では From<_> for &str のみならず From<_> for &[u8] のようなものも欲しくなるかもしれないので、その場合は好きに実装すれば良い。 当然 AsciiStringMyString の場合でもそのような変換は (適当だと思えば) 自由に実装すれば良い。

追加の制約付きの型では、 From<&'a mut AsciiStr> for &'a mut str のような中身を mutable に露出する実装がないことに注意。 まあうっかり書きそうになっても as_mut_str() は unsafe な関数なので、書いている途中でおかしいと気付くはずである。