1use super::*;
6
7impl From<NoError> for io::Error {
10 fn from(n: NoError) -> io::Error {
11 match n {}
12 }
13}
14impl From<NoError> for NonUtf8Error {
15 fn from(n: NoError) -> NonUtf8Error {
16 match n {}
17 }
18}
19
20impl TryConvertFrom<Box<[u8]>> for String {
25 type Error = NonUtf8Error;
26 fn try_convert_from(v: Box<[u8]>, f: &str) -> Result<Self, Self::Error> {
27 let v: Vec<u8> = v.into();
28 let v = String::from_utf8(v)
29 .map_err(|_| NonUtf8Error { field: f.into() })?;
30 Ok(v)
31 }
32}
33impl TryConvertFrom<Box<[u8]>> for Box<str> {
34 type Error = NonUtf8Error;
35 fn try_convert_from(v: Box<[u8]>, f: &str) -> Result<Self, Self::Error> {
36 let v: String = TryConvertFrom::try_convert_from(v, f)?;
37 Ok(v.into())
38 }
39}
40impl TryConvertFrom<Box<str>> for Box<[u8]> {
41 type Error = NoError;
42 fn try_convert_from(v: Box<str>, _f: &str) -> Result<Self, Self::Error> {
43 let v: String = v.into();
44 let v = v.into_bytes();
45 Ok(v.into())
46 }
47}
48
49impl<T, U> TryConvertFrom<Box<[T]>> for Box<[U]>
50where
51 U: TryConvertFrom<T>,
52{
53 type Error = U::Error;
54 fn try_convert_from(v: Box<[T]>, f: &str) -> Result<Self, Self::Error> {
55 let v: Vec<_> = v.into();
56 IntoIterator::into_iter(v)
57 .map(|v| U::try_convert_from(v, f))
58 .collect()
59 }
60}
61
62define_derive_deftly! {
65 TryConvertFrom for struct, expect items:
67
68 impl<T, S> TryConvertFrom<$tname<T>> for $tname<S>
69 where S: TryConvertFrom<T>,
70 {
71 type Error = S::Error;
72 fn try_convert_from(v: $tname<T>, _f: &str)
73 -> Result<Self, Self::Error>
74 {
75 Ok($tname { $( ${select1 fmeta(dummy) {
76 $fname: NonExhaustive {},
77 } else {
78 $fname: TryConvertFrom::try_convert_from(
79 v.$fname,
80 stringify!(${paste ${tmeta(abbrev) as str} _ $fname}),
81 )?,
82 }}) })
83 }
84 }
85}
86
87macro_rules! impl_try_convert_from_via_into { { $T:ty, $U:ty } => {
90 impl TryConvertFrom<$T> for $U {
91 type Error = NoError;
92 fn try_convert_from(v: $T, _f: &str) -> Result<Self, Self::Error> {
93 Ok(v.into())
94 }
95 }
96} }
97macro_rules! impl_infallible_std_from_into { { $T:ty, $U:ty
98 $(, via $VIA:ty )? } => {
99 impl From<Passwd<$T>> for Passwd<$U> {
100 fn from(v: Passwd<$T>) -> Passwd<$U> {
101 $( let v: Passwd<$VIA> = v.into(); )?
102 TryConvertFrom::try_convert_from(v, "")
103 .unwrap_or_else(|e | match e { })
104 }
105 }
106
107 impl From<Group<$T>> for Group<$U> {
108 fn from(v: Group<$T>) -> Group<$U> {
109 $( let v: Group<$VIA> = v.into(); )?
110 TryConvertFrom::try_convert_from(v, "")
111 .unwrap_or_else(|e | match e { })
112 }
113 }
114} }
115macro_rules! impl_infallible_conversions { { $T:ty, $U:ty } => {
116 impl_try_convert_from_via_into!($T, $U);
117 impl_infallible_std_from_into!($T, $U);
118} }
119
120impl_try_convert_from_via_into!(Id, Id);
121impl_try_convert_from_via_into!(Box<[u8]>, Box<[u8]>);
122
123impl_infallible_conversions!(Box<[u8]>, Vec<u8>); impl_infallible_conversions!(Vec<u8>, Box<[u8]>); impl_infallible_conversions!(Box<str>, String); impl_infallible_conversions!(String, Box<str>); impl_infallible_conversions!(String, Vec<u8>); impl_infallible_std_from_into!(Box<str>, Box<[u8]>); impl_infallible_std_from_into!(String, Box<[u8]>, via Box<str>); macro_rules! impl_std_try_from_into { { $P:ident, $T:ty, $U:ty } => {
134 impl TryFrom<$P<$T>> for $P<$U> {
135 type Error = NonUtf8Error;
136 fn try_from(v: $P<$T>) -> Result<$P<$U>, Self::Error> {
137 let v: $P<RawSafe> = v.into();
138 let v: $P<Box<str>> = TryConvertFrom::try_convert_from(v, "")?;
139 Ok(v.into())
140 }
141 }
142} }
143
144impl_std_try_from_into!(Passwd, Vec<u8>, String); impl_std_try_from_into!(Passwd, Box<[u8]>, Box<str>); impl_std_try_from_into!(Group, Vec<u8>, String); impl_std_try_from_into!(Group, Box<[u8]>, Box<str>); pub(crate) fn handle_nul_in_name_as_io(e: NulError) -> io::Error {
152 io::Error::new(InvalidInput, e)
153}
154
155pub(crate) fn cstring_from(name: &[u8]) -> io::Result<CString> {
156 CString::new(name).map_err(handle_nul_in_name_as_io)
157}