内部の型を取り出す
ここまでで外側の (新しく用意した) 型の値を作成する実装ができたので、次は逆向き、内側の値を取り出す実装である。 これは失敗しないので簡単だ。
#![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 } } }
コードを載せる価値があるか疑問さえ湧いてくるつまらなさである。
AsciiBytes
と AsciiByteBuf
用の実装も AsciiStr
/ AsciiString
と同様なので省略する。
ただ、 AsciiBytes
では From<_> for &str
のみならず From<_> for &[u8]
のようなものも欲しくなるかもしれないので、その場合は好きに実装すれば良い。
当然 AsciiString
や MyString
の場合でもそのような変換は (適当だと思えば) 自由に実装すれば良い。
追加の制約付きの型では、 From<&'a mut AsciiStr> for &'a mut str
のような中身を mutable に露出する実装がないことに注意。
まあうっかり書きそうになっても as_mut_str()
は unsafe な関数なので、書いている途中でおかしいと気付くはずである。