0

I have been following a Rust tutorial, that uses a custom type. So a library was defined, that was used in a rust binary later via a cargo.toml dependency. I ended up with a couple of issues:

Does Rust:

  1. necessitate Traits that provide these capability to be defined back in library code (money_typesafe below) referenced by the cargo.toml dependency (of main.rs) that gets used in the binary.
  2. allow Traits to be applied in the using binary.
  3. allow both 1) & 2)?

If 2, is permitted, does the syntax change on defining the Trait in any way?

cargo.toml

...
[dependencies]
money_typesafe = {path = "../../../2-Traits/10-Day-2-Assignment/day2assign/"}`

main.rs

...
use money_typesafe::currencies::{Money,GBP};

i.e. For 2) Can I add traits to Money or GBP in main.rs?

Footnote:

I did find the code for the tutorial on github. It followed the option 1 scenario. Not sure if other option exists extending capability of type in another place.

It involved:

  • AddAssign
  • Neg (I think the example give here isn't helpful. Not doing something with a numeric type and using an enum just muddies the waters).
use std::ops::AddAssign;
use std::ops::Neg;
JGFMK
  • 8,425
  • 4
  • 58
  • 92

1 Answers1

2

The terminology you have used in your question is a little ambiguous - I am not sure what you mean by "applying" a trait. There are three main ways in which a trait appears:

  1. A trait can be defined (where you specify the methods it has and its associated types).

  2. A trait can be implemented (where you implement the trait's methods on some type)

  3. A trait can be used (where you bring it into scope and call its methods).

There are some restrictions on where you can implement a trait. These restrictions are referred to as the "orphan rule", which you will find described on this page.

The rule states that you cannot implement a trait on a type unless either the trait is defined in your crate, and/or the type you are implementing it on is defined in your crate.

For example, you are free to define your own traits and then implement them on foreign types (such as those in the std library or other crates you are importing). You are also free to implement foreign traits on your own types. Both are common patterns.

There is a workaround for the orphan rule: the "newtype pattern". You can find info about that in this question.

So, to answer your specific questions:

Does rust necessitate Traits that provide these capability to be defined back in library code (money_typesafe below) referenced by the cargo.toml dependency (of main.rs) that gets used in the binary.

No. Traits can be defined in the binary crate.

Does rust allow Traits to be applied implemented in the using binary.

Yes, as long as either the trait, or the type it is implemented for, or both are defined in the binary crate.

allow both 1) & 2)?

Yes, traits can be both defined and implemented externally or inside the binary crate, subject to the orphan rule.

If 2, is permitted, does the syntax change on defining the Trait in any way?

No it does not. One thing to note though is that a trait has to be in scope for you to call its methods, so it is necessary to use traits that are not defined in the current scope.

harmic
  • 28,606
  • 5
  • 67
  • 91
  • This helps somewhat.. But I meant a type was defined in a library... But the traits weren't exhaustive enough.. I use the type in my binary via a dependency. Can I create new traits 'there' (outside the library where the type was declared) and say the type from the library implements this trait? Those traits might sometimes only apply to my code and not be worth placing in the library code. – JGFMK Aug 09 '20 at 05:16
  • The new type pattern was what I was after. Cheers. – JGFMK Aug 09 '20 at 05:35