fix: honor ModifiedBy all="true" (ignore ValidModifierClass restriction)
This commit is contained in:
+23
-24
@@ -31,9 +31,12 @@ struct ModifierClassDef {
|
||||
struct ModifiedByRef {
|
||||
/// The modifier code (value of the `code` attribute).
|
||||
code: String,
|
||||
/// When `all="false"` and `valid` is non-empty, only the listed
|
||||
/// `true` when the `all` attribute was `"true"` (or absent/self-closing):
|
||||
/// all ModifierClass codes apply regardless of any `<ValidModifierClass>` children.
|
||||
/// `false` when `all="false"`: restrict to the listed `valid` codes.
|
||||
unrestricted: bool,
|
||||
/// When `unrestricted` is `false` and `valid` is non-empty, only the listed
|
||||
/// `<ModifierClass code=…>` values are allowed for this parent.
|
||||
/// When `all="true"` or `valid` is empty, all ModifierClass codes apply.
|
||||
valid: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -141,7 +144,11 @@ pub fn load(path: &str) -> Result<HashMap<String, IcdMeta>, AppError> {
|
||||
}
|
||||
}
|
||||
if !mb_code.is_empty() {
|
||||
cur_refs.push(ModifiedByRef { code: mb_code, valid: Vec::new() });
|
||||
cur_refs.push(ModifiedByRef {
|
||||
code: mb_code,
|
||||
unrestricted: true,
|
||||
valid: Vec::new(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,24 +278,14 @@ pub fn load(path: &str) -> Result<HashMap<String, IcdMeta>, AppError> {
|
||||
if !mb_code.is_empty() {
|
||||
// Store in cur_mb; ValidModifierClass children will populate valid.
|
||||
// On End(ModifiedBy) we'll push it to cur_refs.
|
||||
// `unrestricted` is set from all="true"/"false"; when true,
|
||||
// expand_modifiers ignores any ValidModifierClass children and
|
||||
// uses the modifier's full ModifierClass list.
|
||||
cur_mb = Some(ModifiedByRef {
|
||||
code: mb_code,
|
||||
// Pre-populate as empty; if all="false" the End handler
|
||||
// will use whatever ValidModifierClass children collected.
|
||||
// If all="true", valid stays empty = unrestricted.
|
||||
unrestricted: all_true,
|
||||
valid: Vec::new(),
|
||||
});
|
||||
// If all="true", mark it as unrestricted even if no children.
|
||||
// We track this implicitly: valid is empty ↔ unrestricted.
|
||||
// But for all="true" we still want to keep it empty.
|
||||
// For all="false", children will push codes into mb.valid.
|
||||
// So no extra flag needed; empty valid = unrestricted.
|
||||
// However, if all="false" but NO ValidModifierClass children
|
||||
// appeared (unusual but possible), empty valid = unrestricted,
|
||||
// which is the safest fallback (full set).
|
||||
if all_true {
|
||||
// Explicitly mark unrestricted; empty valid is the signal.
|
||||
} // else: children will fill valid; if none appear → unrestricted.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -422,10 +419,11 @@ pub fn load(path: &str) -> Result<HashMap<String, IcdMeta>, AppError> {
|
||||
/// ICD code (e.g. `E11` + `.9` + `0` = `E11.90`, `I10.0` + `1` = `I10.01`),
|
||||
/// which exactly matches the Alpha-ID corpus code format.
|
||||
///
|
||||
/// When a `<ModifiedBy>` ref carries a non-empty `valid` set (sourced from
|
||||
/// `<ValidModifierClass>` children with `all="false"`), only those specific
|
||||
/// `<ModifierClass>` codes are included for that level of the cartesian product;
|
||||
/// the full modifier list is used when the set is empty (i.e. `all="true"`).
|
||||
/// When a `<ModifiedBy>` ref has `unrestricted = false` (i.e. `all="false"`),
|
||||
/// only the `<ValidModifierClass>` codes listed in `valid` are included for that
|
||||
/// level of the cartesian product. When `unrestricted = true` (`all="true"`),
|
||||
/// the modifier's full `<ModifierClass>` list is always used regardless of any
|
||||
/// `valid` entries that were parsed.
|
||||
///
|
||||
/// Only the terminal leaf (every modifier in the chain applied) is emitted as
|
||||
/// a synthesized code. Its `Para295`/`Para301` values are inherited from the
|
||||
@@ -457,11 +455,12 @@ fn expand_modifiers(
|
||||
Some(list) if !list.is_empty() => {
|
||||
// Fix 1: if a non-empty valid set is given (all="false"),
|
||||
// restrict this level to only those ModifierClass codes.
|
||||
let filtered: Vec<&ModifierClassDef> = if r.valid.is_empty() {
|
||||
// all="true" or no restriction: use everything.
|
||||
let filtered: Vec<&ModifierClassDef> = if r.unrestricted {
|
||||
// all="true": use the modifier's full ModifierClass list,
|
||||
// ignoring any ValidModifierClass children that were parsed.
|
||||
list.iter().collect()
|
||||
} else {
|
||||
// all="false": keep only the listed valid codes.
|
||||
// all="false": restrict to the listed valid codes.
|
||||
list.iter().filter(|mc| r.valid.contains(&mc.code)).collect()
|
||||
};
|
||||
if filtered.is_empty() {
|
||||
|
||||
Reference in New Issue
Block a user