feat(plugin): name-addressed XRecord CRUD on the HostApi (API v8)

Add create/read/update/delete/list for XRecord objects under
named-object-dictionary paths to the plugin HostApi, with five additive
PluginRequest/PluginResponse variants, dispatch through the shared
handler, in-process HostSession methods and both out-of-process proxies.

- dictionary paths walk from the NOD root; create seeds missing
  dictionaries (ensure_image_dictionary bootstrap) and refuses existing
  names; update refuses missing ones; refusals precede the undo step
- entry group codes validated (1..=369, never 5/105); payload content is
  the plugin's own
- each mutating call is one undo step: the pending history snapshot
  restores the objects map byte-exactly, auto-created dictionaries
  included (tested)
- typed entries survive DWG and DXF write/reload round-trips (tested);
  update drops verbatim raw bytes so saves emit the new content
- bump API_VERSION 7 -> 8 with the build.rs version_info in lockstep,
  mirroring the v7 addition; MIN_SUPPORTED stays 3
This commit is contained in:
Sebastian committed 2026-10-11 19:57:20 +02:00
1 parent 6cde0e02d8
commit ca2f0c9857
11 files changed
+1212 -3

No files matched your search

+34
View File
@@ -117,5 +117,39 @@ pub fn handle_plugin_request(
PluginResponse::TableResult(host.table_operation(operation))
}
RunCommand { request } => PluginResponse::CommandResult(host.run_command(request)),
CreateXRecord {
dictionary_path,
name,
entries,
} => {
let path: Vec<&str> = dictionary_path.iter().map(String::as_str).collect();
PluginResponse::XRecordCreateResult(host.create_xrecord(&path, &name, entries))
}
ReadXRecord {
dictionary_path,
name,
} => {
let path: Vec<&str> = dictionary_path.iter().map(String::as_str).collect();
PluginResponse::XRecordEntries(host.read_xrecord(&path, &name))
}
UpdateXRecord {
dictionary_path,
name,
entries,
} => {
let path: Vec<&str> = dictionary_path.iter().map(String::as_str).collect();
PluginResponse::XRecordUpdateResult(host.update_xrecord(&path, &name, entries))
}
DeleteXRecord {
dictionary_path,
name,
} => {
let path: Vec<&str> = dictionary_path.iter().map(String::as_str).collect();
PluginResponse::XRecordDeleteResult(host.delete_xrecord(&path, &name))
}
ListXRecords { dictionary_path } => {
let path: Vec<&str> = dictionary_path.iter().map(String::as_str).collect();
PluginResponse::XRecordNames(host.list_xrecords(&path))
}
}
}