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 1Contracttype that accepts an enum in constructor, how would you be able to accept different arguments forcontracted_revenues?