I guess I could append to a master slotmap. I would just have to slotmap.insert() each and every item as I don't see an option to use .extend().
Current struct that would need to be merged is:
#[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)]
#[serde(default)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Project {
/// contains all cables read in from files, and/or added in via program logic.
pub cables: BTreeMap<String, cable::Cable>,
/// `connections` contains all connections between different equipment/cables/wires.
pub connections: Vec<connection::Connection>,
//TODO: are connectors going to be read in separately?
/// contains all connectors read in from files, and/or added in via program logic.
pub connectors: BTreeMap<String, connector::Connector>,
/// contains all enclosures read in from files, and/or added in via program logic.
pub enclosures: BTreeMap<String, enclosure::Enclosure>,
/// contains all equipment read in from files, and/or added in via program logic.
pub equipment: BTreeMap<String, equipment::Equipment>,
/// contains all mounting rails read in from files, and/or added in via program logic.
pub mounting_rails: BTreeMap<String, mounting_rail::MountingRail>,
/// contains all pathways read in from files and/or added in via program logic.
pub pathways: BTreeMap<String, pathway::Pathway>,
/// contains all term cables read in from files, and/or added in via program logic.
pub term_cables: BTreeMap<String, term_cable::TermCable>,
/// contains all terminal strips read in from files and/or added in via program logic.
pub terminal_strips: BTreeMap<String, terminal_strip::TerminalStrip>,
/// `wires` contains all wires read in from files, and/or added in via program logic.
pub wires: BTreeMap<String, wire::Wire>,
}
I plan on changing connections to a Slotmap instead of a Vec.
My current merge() function is below:
pub fn merge(&mut self, test_map: Project, test_file: &Path) -> Result<(), Error> {
util_functions::merge_btreemaps(&mut self.cables, test_map.cables, test_file)?;
self.connections.extend(test_map.connections);
//TODO: are connectors going to be read in separately?
//util_functions::merge_btreemaps(&mut self.connectors, test_map.connectors, test_file)?;
util_functions::merge_btreemaps(&mut self.enclosures, test_map.enclosures, test_file)?;
util_functions::merge_btreemaps(&mut self.equipment, test_map.equipment, test_file)?;
util_functions::merge_btreemaps(&mut self.mounting_rails, test_map.mounting_rails, test_file)?;
util_functions::merge_btreemaps(&mut self.pathways, test_map.pathways, test_file)?;
util_functions::merge_btreemaps(&mut self.term_cables, test_map.term_cables, test_file)?;
util_functions::merge_btreemaps(&mut self.terminal_strips, test_map.terminal_strips, test_file)?;
util_functions::merge_btreemaps(&mut self.wires, test_map.wires, test_file)?;
Ok(())
}
And merge_btree_maps() is here:
pub fn merge_btreemaps<U, V>(origin_map: &mut BTreeMap<U, V>, test_map: BTreeMap<U, V>, test_file: &Path) -> Result<(), Error>
where
U: Ord + Clone + ToString,
V: FromFile,
{
// don't need to do any work if test map is empty
if test_map.is_empty() {
return Ok(());
}
for (key, value) in test_map {
if let Entry::Vacant(entry) = origin_map.entry(key.clone()) {
entry.insert(value);
} else {
return Err(Error::DuplicateKey {
key: key.clone().to_string(),
origin_file: value.datafile().clone(),
test_file: test_file.to_path_buf(),
});
}
}
Ok(())
}