I am modeling a ship that has contracts. Each contract can either be a fixed rate contract which pays a set fixed amount every day or a market index contract which pays an amount that varies based on a market index.
I hope to run simulations on each ship where I would provide required information on what the market index is in the future to calculate the earnings from each contract.
I had approached this as follows using rust
where a ship has a vector of ContractLike
contracts:
struct Ship {
pub name: String,
pub contracts: Vec<Box<dyn ContractLike>>,
}
pub struct FixedContract {
dayrate: i32,
start_date: NaiveDate,
end_date: NaiveDate,
}
pub struct MarketIndexContract {
// no fixed dayrate since function of index price which is not known
// should I store the MarketIndex data here?
start_date: NaiveDate,
end_date: NaiveDate,
}
Both contract types however are ContractLike
in that they implement the trait ContractedRevenues
which tells you how much money is due under the contract between 2 dates (I return it as a vector of ints for each day):
pub trait ContractLike: ContractedRevenues{}
impl<T: ContractedRevenues> ContractLike for T {}
pub trait ContractedRevenues {
fn contracted_revenues(&self, date1: NaiveDate, date2: NaiveDate) -> Vec<i32>;
}
The problem is that MarketIndexContract
needs more than just date1
and date2
to compute the ContractedRevenues
.
I was thinking I should store the future Market Index values in the MarketIndexContract
struct by changing the MarketIndexContract
constructor. Then when I ran each simulation I would re-construct the MarketIndexContracts
structs with new future index prices and the ContractedRevenues
trait implementation for MarketIndexContracts
could get the data from the struct's data member.
The downside, however, is it seems to make the Ship
dependent on a simulation existing to construct it. There are uses where I want to use my Ship
without there being a simulation. For instance, what if I wanted to query my Ship
for how many contracts it has? That use case doesn't depend on a simulation existing (i.e. the future index prices being known).
How best should I approach this design?
contracted_revenues()
function? (2) Are all types of contracts known upfront? Consider using an enum instead of aBox<dyn ...>
object. Since enums allow access to fields of their variants, you have far more flexibility and are not constrained to the trait's methods.contracted_revenues()
but wasn't sure how to make a trait that allows the parameters to change inrust
. (2) They are not all known but would be acceptable to lock in to these types. Could you elaborate on how to use an enum here? Assuming you instead have 1Contract
type that accepts an enum in constructor, how would you be able to accept different arguments forcontracted_revenues
?