Code organization problem

Hi ,

I have an annoying problem with code organization that apparently should be designed in the following way...

I have my library that contains the main object O together with all its methods. In that library I have a definition of trait X like so:


//in lib.rs
struct O {
    g: usize,
}

impl O {
    pub fn new() -> Self {
        O { g: 56 }
    }
}

trait X {
    fn a(&self) -> usize;
    fn b(&self) -> usize;
}

//in main.rs
fn main() {
    let j = O::new();

    println!("{}", j.a());
}

now each function of my X trait needs to be in its own file for various different reasons


// this is file a.rs
impl X for O {
    fn a(&self) -> usize {
        self.g.clone()
    }
}

// this is file b.rs
impl X for O {
    fn b(&self) -> usize {
        self.g.clone()
    }
}

I cannot reimplementthe same trait twice for the same objects (at least i think so) but I need to have it organized in such way. Is there a way to achieve this? so that my src looks like:

   src+--main  -> main.rs
      |
      +--lib.rs   // object O here + trair X impl for O
      +--a.rs    // fn a()  of X in  here
      +--b.rs    // fn b()  of X in  here
      

You could move the actual implementation of the two methods into two separate free functions in a.rs and b.rs then simply call those functions from a single impl X for O.

Although I'm wondering, what puts a hard (and weird) requirement on the two functions that they need to be in separate files?

2 Likes

You can't split trait implementations. One way to get around this is to make some inherent functions and then defer to those in your trait implementation.

// lib.rs
struct O {
    g: usize,
}

impl O {
    pub fn new() -> Self {
        O { g: 56 }
    }
}

trait X {
    fn a(&self) -> usize;
    fn b(&self) -> usize;
}

impl X for O {
    fn a(&self) -> usize { self.a_impl() }
    fn b(&self) -> usize { self.b_impl() }
}

// file a.rs

impl O {
    pub(crate) fn a_impl(&self) -> usize {
        // impl for a
    }
}

// file b.rs

impl O {
    pub(crate) fn b_impl(&self) -> usize {
        // impl for b
    }
}
2 Likes

Another way might be to split your trait into smaller traits:

trait X: Xa + Xb { }
trait Xa {
   fn a(&self) -> usize;
}
trait Xb {
   fn b(&self) -> usize;
}
impl<T: Xa + Xb> X for T { }
1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.