Skip to content

Commit 77c246d

Browse files
committed
Revert "Give all assets an agent ID and rework candidate_assets_for_next_year accordingly"
This reverts commit 3edbd42.
1 parent a686c9b commit 77c246d

4 files changed

Lines changed: 109 additions & 112 deletions

File tree

src/asset.rs

Lines changed: 68 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,28 @@ pub enum AssetState {
5151
Commissioned {
5252
/// The ID of the asset
5353
id: AssetID,
54+
/// The ID of the agent that owns the asset
55+
agent_id: AgentID,
5456
},
5557
/// The asset has been decommissioned
5658
Decommissioned {
5759
/// The ID of the asset
5860
id: AssetID,
61+
/// The ID of the agent that owned the asset
62+
agent_id: AgentID,
5963
/// The year the asset was decommissioned
6064
decommission_year: u32,
6165
},
6266
/// The asset is planned for commissioning in the future
63-
Future,
67+
Future {
68+
/// The ID of the agent that will own the asset
69+
agent_id: AgentID,
70+
},
6471
/// The asset has been selected for investment, but not yet confirmed
65-
Selected,
72+
Selected {
73+
/// The ID of the agent that would own the asset
74+
agent_id: AgentID,
75+
},
6676
/// The asset is a candidate for investment but has not yet been selected by an agent
6777
Candidate,
6878
}
@@ -72,8 +82,6 @@ pub enum AssetState {
7282
pub struct Asset {
7383
/// The status of the asset
7484
state: AssetState,
75-
/// The ID of the agent that owns the asset
76-
agent_id: AgentID,
7785
/// The [`Process`] that this asset corresponds to
7886
process: Rc<Process>,
7987
/// Activity limits for this asset
@@ -93,15 +101,13 @@ pub struct Asset {
93101
impl Asset {
94102
/// Create a new candidate asset
95103
pub fn new_candidate(
96-
agent_id: AgentID,
97104
process: Rc<Process>,
98105
region_id: RegionID,
99106
capacity: Capacity,
100107
commission_year: u32,
101108
) -> Result<Self> {
102109
Self::new_with_state(
103110
AssetState::Candidate,
104-
agent_id,
105111
process,
106112
region_id,
107113
capacity,
@@ -129,8 +135,7 @@ impl Asset {
129135
) -> Result<Self> {
130136
check_capacity_valid_for_asset(capacity)?;
131137
Self::new_with_state(
132-
AssetState::Future,
133-
agent_id,
138+
AssetState::Future { agent_id },
134139
process,
135140
region_id,
136141
capacity,
@@ -151,8 +156,7 @@ impl Asset {
151156
commission_year: u32,
152157
) -> Result<Self> {
153158
Self::new_with_state(
154-
AssetState::Selected,
155-
agent_id,
159+
AssetState::Selected { agent_id },
156160
process,
157161
region_id,
158162
capacity,
@@ -163,7 +167,6 @@ impl Asset {
163167
/// Private helper to create an asset with the given state
164168
fn new_with_state(
165169
state: AssetState,
166-
agent_id: AgentID,
167170
process: Rc<Process>,
168171
region_id: RegionID,
169172
capacity: Capacity,
@@ -214,7 +217,6 @@ impl Asset {
214217

215218
Ok(Self {
216219
state,
217-
agent_id,
218220
process,
219221
activity_limits,
220222
flows,
@@ -360,8 +362,14 @@ impl Asset {
360362
}
361363

362364
/// Get the agent ID for this asset
363-
pub fn agent_id(&self) -> &AgentID {
364-
&self.agent_id
365+
pub fn agent_id(&self) -> Option<&AgentID> {
366+
match &self.state {
367+
AssetState::Commissioned { agent_id, .. }
368+
| AssetState::Decommissioned { agent_id, .. }
369+
| AssetState::Future { agent_id }
370+
| AssetState::Selected { agent_id } => Some(agent_id),
371+
AssetState::Candidate => None,
372+
}
365373
}
366374

367375
/// Get the capacity for this asset
@@ -391,20 +399,21 @@ impl Asset {
391399

392400
/// Decommission this asset
393401
fn decommission(&mut self, decommission_year: u32, reason: &str) {
394-
let id = match &self.state {
395-
AssetState::Commissioned { id } => *id,
402+
let (id, agent_id) = match &self.state {
403+
AssetState::Commissioned { id, agent_id } => (*id, agent_id.clone()),
396404
_ => panic!("Cannot decommission an asset that hasn't been commissioned"),
397405
};
398406
debug!(
399407
"Decommissioning '{}' asset (ID: {}) for agent '{}' (reason: {})",
400408
self.process_id(),
401409
id,
402-
self.agent_id,
410+
agent_id,
403411
reason
404412
);
405413

406414
self.state = AssetState::Decommissioned {
407415
id,
416+
agent_id,
408417
decommission_year,
409418
};
410419
}
@@ -419,29 +428,31 @@ impl Asset {
419428
/// * `id` - The ID to give the newly commissioned asset
420429
/// * `reason` - The reason for commissioning (included in log)
421430
fn commission(&mut self, id: AssetID, reason: &str) {
422-
assert!(
423-
matches!(self.state, AssetState::Future | AssetState::Selected),
424-
"Assets with state {} cannot be commissioned",
425-
self.state
426-
);
431+
let agent_id = match &self.state {
432+
AssetState::Future { agent_id } | AssetState::Selected { agent_id } => agent_id,
433+
state => panic!("Assets with state {state} cannot be commissioned"),
434+
};
427435
debug!(
428436
"Commissioning '{}' asset (ID: {}) for agent '{}' (reason: {})",
429437
self.process_id(),
430438
id,
431-
self.agent_id,
439+
agent_id,
432440
reason
433441
);
434-
self.state = AssetState::Commissioned { id };
442+
self.state = AssetState::Commissioned {
443+
id,
444+
agent_id: agent_id.clone(),
445+
};
435446
}
436447

437448
/// Select a Candidate asset for investment, converting it to a Selected state
438-
pub fn select_candidate_for_investment(&mut self) {
449+
pub fn select_candidate_for_investment(&mut self, agent_id: AgentID) {
439450
assert!(
440451
self.state == AssetState::Candidate,
441452
"select_candidate_for_investment can only be called on Candidate assets"
442453
);
443454
check_capacity_valid_for_asset(self.capacity).unwrap();
444-
self.state = AssetState::Selected;
455+
self.state = AssetState::Selected { agent_id };
445456
}
446457
}
447458

@@ -546,8 +557,8 @@ impl Eq for AssetRef {}
546557
impl Hash for AssetRef {
547558
/// Hash an asset according to its state:
548559
/// - Commissioned assets are hashed based on their ID alone
549-
/// - Candidate and Selected assets are hashed based on `state`, `process_id`, `region_id`,
550-
/// `commission_year` and `agent_id`
560+
/// - Selected assets are hashed based on `process_id`, `region_id`, `commission_year` and `agent_id`
561+
/// - Candidate assets are hashed based on `process_id`, `region_id` and `commission_year`
551562
/// - Future and Decommissioned assets cannot currently be hashed
552563
fn hash<H: Hasher>(&self, state: &mut H) {
553564
match &self.0.state {
@@ -556,14 +567,15 @@ impl Hash for AssetRef {
556567
// asset
557568
id.hash(state);
558569
}
559-
AssetState::Candidate | AssetState::Selected => {
560-
self.0.state.hash(state);
570+
AssetState::Candidate | AssetState::Selected { .. } => {
571+
// Hashed based on process_id, region_id, commission_year and (for Selected assets)
572+
// agent_id
561573
self.0.process.id.hash(state);
562574
self.0.region_id.hash(state);
563575
self.0.commission_year.hash(state);
564-
self.0.agent_id.hash(state);
576+
self.0.agent_id().hash(state);
565577
}
566-
AssetState::Future | AssetState::Decommissioned { .. } => {
578+
AssetState::Future { .. } | AssetState::Decommissioned { .. } => {
567579
// We shouldn't currently need to hash Future or Decommissioned assets
568580
unimplemented!("Cannot hash Future or Decommissioned assets");
569581
}
@@ -747,7 +759,7 @@ impl AssetPool {
747759
// then commission them
748760
let assets = assets.into_iter().map(|mut asset| match &asset.state {
749761
AssetState::Commissioned { .. } => asset,
750-
AssetState::Selected => {
762+
AssetState::Selected { .. } => {
751763
asset
752764
.make_mut()
753765
.commission(AssetID(self.next_id), "selected");
@@ -777,7 +789,7 @@ where
777789
{
778790
/// Filter assets by the agent that owns them
779791
fn filter_agent(self, agent_id: &'a AgentID) -> impl Iterator<Item = &'a AssetRef> + 'a {
780-
self.filter(move |asset| asset.agent_id() == agent_id)
792+
self.filter(move |asset| asset.agent_id() == Some(agent_id))
781793
}
782794

783795
/// Iterate over assets that have the given commodity as a primary output
@@ -813,8 +825,7 @@ mod tests {
813825
use super::*;
814826
use crate::commodity::{Commodity, CommodityID, CommodityType};
815827
use crate::fixture::{
816-
agent_id, assert_error, asset, commodity_id, process, process_parameter_map, region_id,
817-
time_slice,
828+
assert_error, asset, commodity_id, process, process_parameter_map, region_id, time_slice,
818829
};
819830
use crate::process::{
820831
FlowType, Process, ProcessActivityLimitsMap, ProcessFlow, ProcessFlowsMap, ProcessID,
@@ -836,7 +847,6 @@ mod tests {
836847

837848
#[rstest]
838849
fn test_get_input_cost_from_prices(
839-
agent_id: AgentID,
840850
region_id: RegionID,
841851
commodity_id: CommodityID,
842852
mut process_parameter_map: ProcessParameterMap,
@@ -892,8 +902,7 @@ mod tests {
892902
});
893903

894904
// Create asset
895-
let asset = Asset::new_candidate(agent_id, process, region_id.clone(), Capacity(1.0), 2020)
896-
.unwrap();
905+
let asset = Asset::new_candidate(process, region_id.clone(), Capacity(1.0), 2020).unwrap();
897906

898907
// Set input prices
899908
let mut input_prices = HashMap::new();
@@ -1213,11 +1222,11 @@ mod tests {
12131222
assert_eq!(asset_pool.active[original_count + 1].id(), Some(AssetID(3)));
12141223
assert_eq!(
12151224
asset_pool.active[original_count].agent_id(),
1216-
&"agent2".into()
1225+
Some(&"agent2".into())
12171226
);
12181227
assert_eq!(
12191228
asset_pool.active[original_count + 1].agent_id(),
1220-
&"agent3".into()
1229+
Some(&"agent3".into())
12211230
);
12221231
}
12231232

@@ -1250,7 +1259,7 @@ mod tests {
12501259
asset_pool
12511260
.active
12521261
.iter()
1253-
.any(|a| a.agent_id() == &"agent_new".into())
1262+
.any(|a| a.agent_id() == Some(&"agent_new".into()))
12541263
);
12551264
}
12561265

@@ -1428,13 +1437,13 @@ mod tests {
14281437
}
14291438

14301439
#[rstest]
1431-
fn test_asset_state_transitions(agent_id: AgentID, process: Process, region_id: RegionID) {
1440+
fn test_asset_state_transitions(process: Process) {
14321441
// Test successful commissioning of Future asset
1433-
let process = Rc::new(process);
1442+
let process_rc = Rc::new(process);
14341443
let mut asset1 = Asset::new_future(
1435-
agent_id.clone(),
1436-
Rc::clone(&process),
1437-
region_id.clone(),
1444+
"agent1".into(),
1445+
Rc::clone(&process_rc),
1446+
"GBR".into(),
14381447
Capacity(1.0),
14391448
2020,
14401449
)
@@ -1444,8 +1453,14 @@ mod tests {
14441453
assert_eq!(asset1.id(), Some(AssetID(1)));
14451454

14461455
// Test successful commissioning of Selected asset
1447-
let mut asset2 =
1448-
Asset::new_selected(agent_id, process, region_id, Capacity(1.0), 2020).unwrap();
1456+
let mut asset2 = Asset::new_selected(
1457+
"agent1".into(),
1458+
Rc::clone(&process_rc),
1459+
"GBR".into(),
1460+
Capacity(1.0),
1461+
2020,
1462+
)
1463+
.unwrap();
14491464
asset2.commission(AssetID(2), "");
14501465
assert!(asset2.is_commissioned());
14511466
assert_eq!(asset2.id(), Some(AssetID(2)));
@@ -1458,17 +1473,17 @@ mod tests {
14581473

14591474
#[rstest]
14601475
#[should_panic(expected = "Assets with state Candidate cannot be commissioned")]
1461-
fn test_commission_wrong_states(agent_id: AgentID, process: Process, region_id: RegionID) {
1476+
fn test_commission_wrong_states(process: Process) {
14621477
let mut asset =
1463-
Asset::new_candidate(agent_id, process.into(), region_id, Capacity(1.0), 2020).unwrap();
1478+
Asset::new_candidate(process.into(), "GBR".into(), Capacity(1.0), 2020).unwrap();
14641479
asset.commission(AssetID(1), "");
14651480
}
14661481

14671482
#[rstest]
14681483
#[should_panic(expected = "Cannot decommission an asset that hasn't been commissioned")]
1469-
fn test_decommission_wrong_state(agent_id: AgentID, process: Process, region_id: RegionID) {
1484+
fn test_decommission_wrong_state(process: Process) {
14701485
let mut asset =
1471-
Asset::new_candidate(agent_id, process.into(), region_id, Capacity(1.0), 2020).unwrap();
1486+
Asset::new_candidate(process.into(), "GBR".into(), Capacity(1.0), 2020).unwrap();
14721487
asset.decommission(2025, "");
14731488
}
14741489
}

src/output.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl AssetRow {
124124
asset_id: asset.id().unwrap(),
125125
process_id: asset.process_id().clone(),
126126
region_id: asset.region_id().clone(),
127-
agent_id: asset.agent_id().clone(),
127+
agent_id: asset.agent_id().unwrap().clone(),
128128
commission_year: asset.commission_year(),
129129
decommission_year: asset.decommission_year(),
130130
capacity: asset.capacity(),

0 commit comments

Comments
 (0)