diff --git a/src/controllers/apotheosis.rs b/src/controllers/apotheosis.rs index 7139341..2381d7a 100644 --- a/src/controllers/apotheosis.rs +++ b/src/controllers/apotheosis.rs @@ -12,6 +12,12 @@ use std::fs::{self, File}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; +/// Last path segment of the type name, e.g. +/// "apotheosis2::datalayer::algorithms::TlshDistance" -> "TlshDistance". +fn distance_name() -> &'static str { + std::any::type_name::().rsplit("::").next().unwrap() +} + #[derive(serde::Serialize, serde::Deserialize)] #[serde(bound( serialize = "R: ApotheosisRecord + serde::Serialize, D: DistanceAlgorithm + serde::Serialize, R::MetricId: serde::Serialize", @@ -137,6 +143,9 @@ where file.write_all(&(M0 as u32).to_le_bytes())?; file.write_all(&(EF as u32).to_le_bytes())?; file.write_all(&[HEURISTIC as u8])?; + let name = distance_name::().as_bytes(); + file.write_all(&[u8::try_from(name.len())?])?; + file.write_all(name)?; // Then write the model data bincode::serialize_into(file, self)?; @@ -149,7 +158,7 @@ where { let mut file = File::open(path)?; - // Read and verify header (17 bytes) + // Read and verify header (17 bytes + distance type name) let mut header = [0u8; 17]; file.read_exact(&mut header)?; @@ -169,6 +178,22 @@ where ).into()); } + // Explicit check of distance type (does not rely on bincode) + let mut name_len = [0u8; 1]; + file.read_exact(&mut name_len)?; + let mut name = vec![0u8; name_len[0] as usize]; + file.read_exact(&mut name)?; + let file_distance = String::from_utf8_lossy(&name); + + let expected = distance_name::(); + if file_distance != expected { + return Err(format!( + "Distance type mismatch. File was built with {} but is being loaded as {}", + file_distance, expected + ) + .into()); + } + let decoded = bincode::deserialize_from(file)?; Ok(decoded) } @@ -179,7 +204,6 @@ where /// /// # Parameters /// * `path` - Base filename for output (e.g., "model" creates "model_layer0.gexf", "model_layer1.gexf", etc.) - pub fn draw>(&self, path: P) { let base_path = path.as_ref(); diff --git a/src/datalayer/algorithms.rs b/src/datalayer/algorithms.rs index e45490c..4116f05 100644 --- a/src/datalayer/algorithms.rs +++ b/src/datalayer/algorithms.rs @@ -16,7 +16,7 @@ impl DistanceAlgorithm for NormalDistance { pub struct TlshDistance; impl DistanceAlgorithm for TlshDistance { fn calculate_distance(&self, a: &TlshDefault, b: &TlshDefault) -> u32 { - let diff = a.diff(&b, true); + let diff = a.diff(b, true); diff as u32 } }