2

Suppose I have the following type:

#[derive(Default)] struct Foo(pub i32); // public 

Since it's a tuple with a public member, any conversions from/to i32 can simply be made using the 0 member:

let foo = Foo::default(); let num: i32 = foo.0; // Foo to i32 let goo = Foo(123); // i32 to Foo 

Now I want to make the 0 member non-public, implementing From trait:

#[derive(Default)] struct Foo(i32); // non-public impl From<i32> for Foo { fn from(n: i32) -> Foo { Foo(n) } } 

But the conversion fails from i32 to Foo:

let foo = ay::Foo::default(); let num: i32 = foo.into(); // error! let goo = ay::Foo::from(123); // okay 

What's the correct way to implement this bidirectional conversion? Rust playground here.

1
  • You have to implement both directions independently as they have nothing to do with one another, most infaillible conversions are injective rather than bijective e.g. str -> path or i32 -> i64 but not the other way around. Commented Jun 9, 2020 at 12:25

1 Answer 1

5

You have to implement the other direction (impl From<Foo> for i32) manually:

mod x { #[derive(Default)] pub struct Foo(i32); impl From<i32> for Foo { fn from(n: i32) -> Foo { Foo(n) } } impl From<Foo> for i32 { fn from(foo: Foo) -> i32 { foo.0 } } } fn main() { let foo = x::Foo::default(); let _num: i32 = foo.into(); // okay let _goo = x::Foo::from(123); // also okay } 

You can test this in the playground

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.