derive_more icon indicating copy to clipboard operation
derive_more copied to clipboard

Support From for other datatypes

Open Susurrus opened this issue 8 years ago • 3 comments

newtype_derive seems to allow this, but appears to be unmaintained. Allow specifying #[From(usize)] for a u32 newtype. The conversion would just use as to do the conversion.

My use case for this is that I have several u32 newtypes and commonly usize indexes are received from slice lengths and I'd like to convert them easily.

Susurrus avatar Jun 01 '17 16:06 Susurrus

Is this for structs or enum derives? Because if it's for structs I think a nicer solution would be to generate code to generate code like this (untested) instead of allowing attributes:

impl<_Into_i32: Into<i32>>  ::std::convert::From<(_Into_i32)> for MyInt {
    fn from(original: (_into_i32)) -> MyInt {
        MyInt(original.into())
    }
}

That way it will work automatically for all types that i32 has From implemented for.

I don't have a lot of time to allocate to this at the moment though. If you like you could try to implement it, PRs are always welcome.

If you do you should edit this file: https://github.com/JelteF/derive_more/blob/master/src/from.rs

And these two helper functions could be quite useful: https://github.com/JelteF/derive_more/blob/master/src/utils.rs#L26-L49

One thing to note is that this shouldn't be done for enums though. Because then two from implementations could overlap. So you would have to keep this function the same for use inside the enum_from creation: https://github.com/JelteF/derive_more/blob/master/src/from.rs#L18-L31

JelteF avatar Jun 01 '17 17:06 JelteF

I don't think this approach works because of the identity conversion provided by std.

   | impl<T: Into<String>> From<T> for MyNewType {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T> std::convert::From<T> for T;

Trying with a single-element tuple like you suggested results in the same error:

   | impl<T: Into<String>> From<(T)> for Email {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T> std::convert::From<T> for T;

It seems from types have to be explicit. How about an attribute?

#[derive(
    Clone, Debug, PartialEq, Eq, Hash, From, Into, FromStr,
)]
#[derive_from(&str, Box<str>)]
pub struct MyType(pub String);

magnet avatar May 05 '19 18:05 magnet

Does #135 cover this?

tyranron avatar Jul 17 '20 21:07 tyranron

I'm pretty sure this is now fixed, closing.

JelteF avatar Dec 22 '23 00:12 JelteF