Paid rust mentoring

I am looking for someone to help me shapen my skills on my Rust learning journey.

Even though I am feeling productive on the language and doing some open source work, I feel like there are areas that I am deeply lacking, more recently stubling on some problems that I would love to overcome and reshape my mental model around them.

The way I envision the engagement would be spending a few hours a week, either on 1:1 sessions or async Q/A exchanges. And, with some luck, a combination of both.

I recently reached out to Ferrous Systems Rust Experts, but didn't get a response yet.

If it's something you are willing to do or if you know any other people or even places where I can find someone that would like to help me on this, let me know. I'd really appreciate it!

Thank you!

What kind of problems you would like to overcome?

There are a few, but the one that I keep going back to and trying to resolve is the following, and I have tried to solve it before here, but I think I was too specific.

What I want to do is create a struct that can save a Record (R) (a struct that is serializable via serde in my case) using a given PersistenceStrategy (P).

I was able to achieve some level of this, but I can't create a Struct that is generic over R but carries the concrete implementation of the PersistenceStrategy with it. The idea is that on a test context, I can inject a "mock" implementation of the strategy and still test code behavior with it.

I was able to create some code redux of the problem below, let me know if it makese sense (link to Playground):

use serde_json::{json, Map, Value};

type Data = Map<String, Value>;

trait Persistence {
    fn save(&self, data: &Data);
}

struct Mongo;
impl Persistence for Mongo {
    fn save(&self, data: &Data) {
        println!("saving with Mongo: {:?}", data);
    }
}

struct Postgres;
impl Persistence for Postgres {
    fn save(&self, data: &Data) {
        println!("saving with Postgres: {:?}", data);
    }
}

struct Store;
impl Store {
    fn save<P: Persistence>(p: P, data: &Data) {
        p.save(data);
    }
}

fn main() {
    let data = json!({
        "name": "John Doe",
        "age": 43,
        "phones": [
            "+44 1234567",
            "+44 2345678"
        ]
    })
    .as_object()
    .unwrap()
    .clone();

    // Instead of always passing the Persistence implementation when saving the data here:
    Store::save(Mongo, &data);
    // or
    Store::save(Postgres, &data);

    // I'd like to create a version of store that would carry the Persistence implementation.
    // Something like:
    // ```
    // let store = Store::new(Mongo);
    // store.save(&data);
    // let app = App::new(store);
    // // call app methods without passing the persistence around
    // let otherStruct = OtherStruct::new(app);
    // otherStruct.save(&data);
    // ```
}

There are other problems that I am having but I will try to enumerate them on a separate thread, but I would love to have a mentor to guide me through those things on a screenshare session from time to time.

Thank you!

If you need to carry persistence around, then there are basically 3 options:

  • Make it a generic parameter on your struct, and carry a field persistence: P inside.
  • If the set of persistences is finite and known ahead of time, put them all into a single enum, and carry a variant of that enum.
  • Put a Box<dyn Persistence> inside of your struct. You may also consider Rc<dyn Persistence> or some other kind of pointer, depending on your use case.

The first option is most flexible, but complicates the type signature (which will also have to be propagated to functions using it generically). The second option works only when you don't expect downstream crates to provide their own persistences, but in that case it's usually the best one. The third option doesn't have any of those restrictions, but carries a (usually negligible) performance penalty, and cannot use all features of traits (static methods, consts, associated types etc).

You can ask questions here, but if you want live consultation, pm me and we'll work something out.

1 Like

I tried the Box<dyn Persistence> approach, but stumbled on a range of other issues, including Traits not being able to become an object, amongst others. For now, I went with the enum approach but I am carrying around unrelated Enum members, like Memory which is only used for testing.

Let me try to replicate the issues I described above once again and post an update here.

I also PMed you about the live consultation option, so thank you on both instances.