From 688281961d270978eb8e1aca07087cd410a2acac Mon Sep 17 00:00:00 2001 From: Mark Date: Sun, 26 Oct 2025 01:24:58 +0200 Subject: [PATCH] fix: object assignment from multitype --- mers/Cargo.toml | 2 +- mers_lib/Cargo.toml | 2 +- mers_lib/src/program/run/object.rs | 70 ++++++++++++++++++++++-------- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/mers/Cargo.toml b/mers/Cargo.toml index a455596..d729363 100644 --- a/mers/Cargo.toml +++ b/mers/Cargo.toml @@ -15,7 +15,7 @@ default = ["colored-output"] colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"] [dependencies] -mers_lib = "0.9.23" +mers_lib = "0.9.24" # mers_lib = { path = "../mers_lib" } clap = { version = "4.3.19", features = ["derive"] } colored = { version = "2.1.0", optional = true } diff --git a/mers_lib/Cargo.toml b/mers_lib/Cargo.toml index 6ccd167..0d9535c 100755 --- a/mers_lib/Cargo.toml +++ b/mers_lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mers_lib" -version = "0.9.23" +version = "0.9.24" edition = "2021" license = "MIT OR Apache-2.0" description = "library to use the mers language in other projects" diff --git a/mers_lib/src/program/run/object.rs b/mers_lib/src/program/run/object.rs index b7ca930..e552583 100644 --- a/mers_lib/src/program/run/object.rs +++ b/mers_lib/src/program/run/object.rs @@ -24,18 +24,65 @@ impl MersStatement for Object { let print_is_part_of = init_to.types.len() > 1; let mut init_fields = HashMap::new(); for t in init_to.types.iter() { - if let Some(t) = t.as_any().downcast_ref::() { - for (field, t) in t.iter() { + if let Some(ot) = t.as_any().downcast_ref::() { + let mut fields = self.fields.iter().map(|(t, _)| *t).collect::>(); + fields.sort(); + for (field, t) in ot.iter() { + if let Ok(i) = fields.binary_search(field) { + fields.remove(i); + } init_fields .entry(*field) .or_insert_with(Type::empty) .add_all(t); } + if !fields.is_empty() { + return Err(CheckError::new().msg(vec![ + ("can't init an ".to_owned(), None), + ("object".to_owned(), Some(EColor::InitTo)), + (" from type ".to_owned(), None), + (t.simplified_as_string(info), Some(EColor::InitFrom)), + if print_is_part_of { + (", which is part of ".to_owned(), None) + } else { + (format!(""), None) + }, + if print_is_part_of { + (init_to.simplified_as_string(info), Some(EColor::InitFrom)) + } else { + (format!(""), None) + }, + ( + format!(" - missing fields {}", { + let object_fields_rev = + info.global.object_fields_rev.lock().unwrap(); + fields + .iter() + .map(|f| { + object_fields_rev + .get(*f) + .map(|f| f.as_str()) + .unwrap_or("") + }) + .enumerate() + .map(|(i, f)| { + if i == 0 { + f.to_owned() + } else { + format!(", {f}") + } + }) + .collect::() + }), + None, + ), + ])); + } } else { return Err(CheckError::new().msg(vec![ ("can't init an ".to_owned(), None), ("object".to_owned(), Some(EColor::InitTo)), - (" with type ".to_owned(), None), + (" from type ".to_owned(), None), (t.simplified_as_string(info), Some(EColor::InitFrom)), if print_is_part_of { (", which is part of ".to_owned(), None) @@ -72,22 +119,7 @@ impl MersStatement for Object { } else if init_to_is_empty_type { Type::empty() } else { - return Err(CheckError::new().msg(vec![ - ("can't init an ".to_owned(), None), - ("object".to_owned(), Some(EColor::InitTo)), - (" with type ".to_owned(), None), - ( - init_to.as_ref().unwrap().simplified_as_string(info), - Some(EColor::InitFrom), - ), - ( - format!( - " - field {} is missing", - info.display_info().get_object_field_name(*field) - ), - None, - ), - ])); + unreachable!("type-checking earlier in check_custom() should prevent this") }) } else { None