4

Is it possible to require that a struct have a particular field as part of a trait? I am doing some web automation in Rust with the thirtyfour_sync crate. I want to write some traits with default implementations for page objects that will implement them. Basically, I know for a fact that every struct that is going to implement this trait will have a field called "driver" that holds a reference to a WebDriver struct. I want to use this driver field in my default implementation of the trait.

error[E0609]: no field `driver` on type `&Self`
  --> src\base_order_details.rs:13:30
   |
10 | / pub trait BaseOrderDetails {
11 | |
12 | |     fn oid(&self) -> WebDriverResult<String> {
13 | |         let oid_title = self.driver.find_element(By::XPath("//*[text()=\"Order ID:\"]"))?;
   | |                              ^^^^^^
...  |

Is there a way to let the compiler know that anything implementing this trait will have a field driver of type &WebDriver?

  • Does this answer your question? [Is it possible to access struct fields from within a trait?](https://stackoverflow.com/questions/28219730/is-it-possible-to-access-struct-fields-from-within-a-trait) – loganfsmyth Jun 29 '21 at 05:36

1 Answers1

4

I discovered the answer to my question while drafting it. No, you cannot access fields from traits. As a solution, I have added a get_driver method to the trait and used it within the default implementation, so the user can simply implement the get_driver method and default the rest.

pub trait BaseOrderDetails {

    fn get_driver(&self) -> &WebDriver;

    fn oid(&self) -> WebDriverResult<String> {
        let oid_title = self.get_driver().find_element(By::XPath("//*[text()=\"Order ID:\"]"))?;

        // do some other stuff

I found this solution in the Rust Book chapter on traits, under Default Implementations: https://doc.rust-lang.org/book/ch10-02-traits.html

  • 1
    Good answer! Yep, you're right. Some languages, such as Kotlin, allow interfaces to specify property-like values, but Rust takes the perspective that a method call should always syntactically look like a method call, and field access should always look like field access. So having a `get_driver` method is the exact right way to do it – Silvio Mayolo Jun 29 '21 at 03:23