@@ -117,6 +117,8 @@ assert_eq!(
117117
118118Code like this is generated:
119119``` rust
120+ # use core :: str :: FromStr ;
121+ #
120122# enum EnumNoFields {
121123# Foo ,
122124# Bar ,
@@ -126,7 +128,7 @@ Code like this is generated:
126128#
127129impl derive_more :: core :: str :: FromStr for EnumNoFields {
128130 type Err = derive_more :: FromStrError ;
129- fn from_str (s : & str ) -> Result <Self , derive_more :: FromStrError > {
131+ fn from_str (s : & str ) -> Result <Self , < Self as FromStr > :: Err > {
130132 Ok (match s . to_lowercase (). as_str () {
131133 " foo" => Self :: Foo ,
132134 " bar" => Self :: Bar ,
@@ -158,11 +160,13 @@ assert_eq!("FOO".parse::<Foo>().unwrap(), Foo);
158160
159161Code like this is generated:
160162``` rust
163+ # use core :: str :: FromStr ;
164+ #
161165# struct Foo ;
162166#
163167impl derive_more :: core :: str :: FromStr for Foo {
164168 type Err = derive_more :: FromStrError ;
165- fn from_str (s : & str ) -> Result <Self , derive_more :: FromStrError > {
169+ fn from_str (s : & str ) -> Result <Self , < Self as FromStr > :: Err > {
166170 Ok (match s . to_lowercase (). as_str () {
167171 " foo" => Self ,
168172 _ => return Err (derive_more :: FromStrError :: new (" Foo" )),
@@ -228,3 +232,212 @@ assert_eq!("variant-two".parse::<Enum>().unwrap(), Enum::VariantTwo);
228232> # assert_eq! (" Bar" . parse :: <Enum >(). unwrap (), Enum :: Bar );
229233> # assert_eq! (" Ba_R" . parse :: <Enum >(). unwrap (), Enum :: Ba_R );
230234> ```
235+
236+
237+
238+
239+ ## Custom error
240+
241+ The `#[from_str(error(<ty>[, <conv>]))]` attribute can be used to convert the `FromStr `' `Err` type
242+ into a custom error type. If the conversion function is not provided, the custom error type must implement
243+ `From<FromStr::Err>`.
244+
245+
246+ ### Forwarding
247+
248+ Given the following struct:
249+ ```rust
250+ # use derive_more::{From, FromStr};
251+ #
252+ #[derive(From)]
253+ struct CustomError(core::num::ParseIntError);
254+
255+ #[derive(FromStr, Debug, Eq, PartialEq)]
256+ #[from_str(error(CustomError))]
257+ struct MyInt(i32);
258+ ```
259+ Code like this is generated:
260+ ```rust
261+ # use core::str::FromStr;
262+ # use derive_more::From;
263+ #
264+ # #[derive(From)]
265+ # struct CustomError(core::num::ParseIntError);
266+ #
267+ # struct MyInt(i32);
268+ #
269+ impl derive_more::core::str::FromStr for MyInt {
270+ type Err = CustomError;
271+ fn from_str(s: &str) -> Result<Self, Self::Err> {
272+ FromStr::from_str(s)
273+ .map(|v| Self(v))
274+ .map_err(Into::into)
275+ }
276+ }
277+ ```
278+
279+ For the explicitly specified error conversion:
280+ ```rust
281+ # use derive_more::FromStr;
282+ #
283+ struct CustomError(core::num::ParseIntError);
284+
285+ impl CustomError {
286+ fn new(err: core::num::ParseIntError) -> Self {
287+ Self(err)
288+ }
289+ }
290+
291+ #[derive(FromStr, Debug, Eq, PartialEq)]
292+ #[from_str(error(CustomError, CustomError::new))]
293+ struct MyInt(i32);
294+ ```
295+ Code like this is generated:
296+ ```rust
297+ # use core::str::FromStr;
298+ #
299+ # struct CustomError(core::num::ParseIntError);
300+ #
301+ # impl CustomError {
302+ # fn new(err: core::num::ParseIntError) -> Self {
303+ # Self(err)
304+ # }
305+ # }
306+ #
307+ # struct MyInt(i32);
308+ #
309+ impl derive_more::core::str::FromStr for MyInt {
310+ type Err = CustomError;
311+ fn from_str(s: &str) -> Result<Self, Self::Err> {
312+ FromStr::from_str(s)
313+ .map(|v| Self(v))
314+ .map_err(CustomError::new)
315+ }
316+ }
317+ ```
318+
319+ Custom error for a newtype struct with one named field, *e.g*,
320+ ```rust
321+ # use derive_more::{From, FromStr};
322+ #
323+ #[derive(From)]
324+ struct CustomError(core::num::ParseIntError);
325+
326+ #[derive(FromStr)]
327+ #[from_str(error(CustomError))]
328+ struct Point1D {
329+ x: i32,
330+ }
331+ ```
332+ works similarly.
333+
334+
335+ ### Flat representation
336+
337+ Custom error type is also supported for empty enums and unit structs.
338+
339+ Given the following enum:
340+ ```rust
341+ # use derive_more::{From, FromStr};
342+ #
343+ #[derive(From)]
344+ struct CustomError(derive_more::FromStrError);
345+
346+ #[derive(FromStr, Debug, Eq, PartialEq)]
347+ #[from_str(error(CustomError))]
348+ enum EnumNoFields {
349+ Foo,
350+ Bar,
351+ Baz,
352+ }
353+ ```
354+ Code like this is generated:
355+ ```rust
356+ # use core::str::FromStr;
357+ # use derive_more::From;
358+ #
359+ # #[derive(From)]
360+ # struct CustomError(derive_more::FromStrError);
361+ #
362+ # enum EnumNoFields {
363+ # Foo,
364+ # Bar,
365+ # Baz,
366+ # }
367+ #
368+ impl derive_more::core::str::FromStr for EnumNoFields {
369+ type Err = CustomError;
370+ fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
371+ Ok(match s.to_lowercase().as_str() {
372+ "foo" => Self::Foo,
373+ "bar" => Self::Bar,
374+ "baz" => Self::Baz,
375+ _ => return Err(derive_more::FromStrError::new("EnumNoFields").into()),
376+ })
377+ }
378+ }
379+ ```
380+
381+ For the explicitly specified error conversion:
382+ ```rust
383+ # use derive_more::FromStr;
384+ #
385+ struct CustomError(derive_more::FromStrError);
386+
387+ impl CustomError {
388+ pub fn new(err: derive_more::FromStrError) -> Self {
389+ Self(err)
390+ }
391+ }
392+
393+ #[derive(FromStr, Debug, Eq, PartialEq)]
394+ #[from_str(error(CustomError, CustomError::new))]
395+ enum EnumNoFields {
396+ Foo,
397+ Bar,
398+ Baz,
399+ }
400+ ```
401+ Code like this is generated:
402+ ```rust
403+ # use core::str::FromStr;
404+ #
405+ # struct CustomError(derive_more::FromStrError);
406+ #
407+ # impl CustomError {
408+ # pub fn new(err: derive_more::FromStrError) -> Self {
409+ # Self(err)
410+ # }
411+ # }
412+ #
413+ # enum EnumNoFields {
414+ # Foo,
415+ # Bar,
416+ # Baz,
417+ # }
418+ #
419+ impl derive_more::core::str::FromStr for EnumNoFields {
420+ type Err = CustomError;
421+ fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
422+ Ok(match s.to_lowercase().as_str() {
423+ "foo" => Self::Foo,
424+ "bar" => Self::Bar,
425+ "baz" => Self::Baz,
426+ _ => return Err(CustomError::new(derive_more::FromStrError::new("EnumNoFields"))),
427+ })
428+ }
429+ }
430+ ```
431+
432+ Custom error type for unit structs, *e.g*,
433+ ```rust
434+ # use derive_more::{From, FromStr};
435+ #
436+ #[derive(From)]
437+ struct CustomError(derive_more::FromStrError);
438+
439+ #[derive(FromStr)]
440+ #[from_str(error(CustomError))]
441+ struct Foo;
442+ ```
443+ works similarly.
0 commit comments