1use crate::patch::FilePatch;
5use anyhow::{Context, Result};
6use std::{collections::BTreeMap, sync::LazyLock};
7pub struct PatchInfo {
9 pub base_example: &'static str,
11 pub file_patches: Vec<FilePatch>,
13 pub toml_patch: Option<&'static str>,
15}
16
17impl PatchInfo {
18 pub fn new(
20 base_example: &'static str,
21 file_patches: Vec<FilePatch>,
22 toml_patch: Option<&'static str>,
23 ) -> Self {
24 Self {
25 base_example,
26 file_patches,
27 toml_patch,
28 }
29 }
30 pub fn new_with_toml_patch(
32 base_example: &'static str,
33 file_patches: Vec<FilePatch>,
34 toml_patch: &'static str,
35 ) -> Self {
36 Self {
37 base_example,
38 file_patches,
39 toml_patch: Some(toml_patch),
40 }
41 }
42}
43type PatchMap = BTreeMap<&'static str, PatchInfo>;
45
46static PATCHES: LazyLock<PatchMap> = LazyLock::new(get_all_patches);
48
49fn get_all_patches() -> PatchMap {
51 [
52 (
54 "simple_divisible",
55 PatchInfo::new(
56 "simple",
57 vec![
58 FilePatch::new("processes.csv")
59 .with_deletion("RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0,")
60 .with_addition("RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0,1000"),
61 ],
62 None,
63 ),
64 ),
65 (
67 "simple_npv",
68 PatchInfo::new(
69 "simple",
70 vec![
71 FilePatch::new("agent_objectives.csv")
72 .with_deletion("A0_RES,all,lcox,,")
73 .with_addition("A0_RES,all,npv,,"),
74 ],
75 None,
76 ),
77 ),
78 (
79 "simple_marginal",
81 PatchInfo::new(
82 "simple",
83 vec![FilePatch::new("commodities.csv").with_replacement(&[
84 "id,description,type,time_slice_level,pricing_strategy,units",
85 "GASPRD,Gas produced,sed,season,,PJ",
86 "GASNAT,Natural gas,sed,season,,PJ",
87 "ELCTRI,Electricity,sed,daynight,marginal,PJ",
88 "RSHEAT,Residential heating,svd,daynight,,PJ",
89 "CO2EMT,CO2 emitted,oth,annual,,ktCO2",
90 ])],
91 None,
92 ),
93 ),
94 (
95 "simple_full",
97 PatchInfo::new(
98 "simple",
99 vec![FilePatch::new("commodities.csv").with_replacement(&[
100 "id,description,type,time_slice_level,pricing_strategy,units",
101 "GASPRD,Gas produced,sed,season,full,PJ",
102 "GASNAT,Natural gas,sed,season,full,PJ",
103 "ELCTRI,Electricity,sed,daynight,,PJ",
104 "RSHEAT,Residential heating,svd,daynight,,PJ",
105 "CO2EMT,CO2 emitted,oth,annual,,ktCO2",
106 ])],
107 None,
108 ),
109 ),
110 (
111 "simple_marginal_average",
113 PatchInfo::new(
114 "simple",
115 vec![FilePatch::new("commodities.csv").with_replacement(&[
116 "id,description,type,time_slice_level,pricing_strategy,units",
117 "GASPRD,Gas produced,sed,season,,PJ",
118 "GASNAT,Natural gas,sed,season,,PJ",
119 "ELCTRI,Electricity,sed,daynight,marginal_average,PJ",
120 "RSHEAT,Residential heating,svd,daynight,,PJ",
121 "CO2EMT,CO2 emitted,oth,annual,,ktCO2",
122 ])],
123 None,
124 ),
125 ),
126 (
127 "simple_shadow",
129 PatchInfo::new(
130 "simple",
131 vec![FilePatch::new("commodities.csv").with_replacement(&[
132 "id,description,type,time_slice_level,pricing_strategy,units",
133 "GASPRD,Gas produced,sed,season,,PJ",
134 "GASNAT,Natural gas,sed,season,,PJ",
135 "ELCTRI,Electricity,sed,daynight,shadow,PJ",
136 "RSHEAT,Residential heating,svd,daynight,,PJ",
137 "CO2EMT,CO2 emitted,oth,annual,,ktCO2",
138 ])],
139 None,
140 ),
141 ),
142 (
144 "simple_ironing_out",
145 PatchInfo::new("simple", vec![], Some("max_ironing_out_iterations = 10")),
146 ),
147 ]
148 .into_iter()
149 .collect()
150}
151
152pub fn get_patch_names() -> impl Iterator<Item = &'static str> {
154 PATCHES.keys().copied()
155}
156
157pub fn get_patches(name: &str) -> Result<&'static PatchInfo> {
159 PATCHES
160 .get(name)
161 .with_context(|| format!("Patched example '{name}' not found"))
162}