I have a problem with how to force a trait bound on a struct. The struct will not make sense without the trait and therefore I want to enforce that user-defined model implement PricingModel. The issue arises because the trait also takes the Options struct as an argument to compute values. It could be avoided by passing fields individually but this seems like a hacky solution.
The Options struct holds a Model struct which has to implement PricingModel. PricingModel however needs to take a reference to Options as an argument.
The below is something of a condensed example:
struct Model<M: PricingModel<M>>;
trait PricingModel<M: PricingModel<M>> {
fn get_price(&self, opt: &Options<M>) -> f64;
}
impl<M: PricingModel<M>> PricingModel<M> for Model<M> {
fn get_price(&self, opt: &Options<M>) -> f64 {
opt.price + 1.0
}
}
struct Options<M: PricingModel<M>> {
price: f64,
model: M,
}
impl<M: PricingModel<M>> Options<M> {
fn new(price: f64, model: Model<M>) -> Self {
Options {
price,
model
}
}
}
fn main() {
let model = Model;
let opts = Options::new(1.0, model);
opts.model.get_price()
}
This particular code only generates the error...
error[E0392]: parameter `M` is never used
--> src\main.rs:1:14
|
1 | struct Model<M: PricingModel<M>>;
| ^ unused parameter
|
= help: consider removing `M`, referring to it in a field, or using a marker such as `PhantomData`
...but is not the central part of the question.
I have not been able to figure out the idiomatic way to express this dependency that doesn't break the compiler (the last attempt was a circular reference for the trait bounds).
This seems like a rather simple problem, but the answer eludes me. Thoughts?