Complete Dimension host model coverage for all nine subtypes

Adds a hand-written flat Dimension model to the adapter (manifest
manual_kinds hook) and a synthetic-property section to the host coverage
policy. The host derives actual_measurement and the base definition point on
scripted create/edit. staged_python_dimension_lifecycle_over_real_ipc passes
the full gate for every subtype including DWG and DXF reopen. Python ints are
now accepted for coordinates and angles.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Felix RiestraandClaude Sonnet 5 committed 2026-09-20 14:15:03 +02:00
1 parent a86d5bc727
commit 6b4c86fd7a
13 files changed
+1281 -49

No files matched your search

+28
View File
@@ -25,6 +25,10 @@ use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct Manifest {
/// Kinds whose payload is a nested enum: converted by hand-written
/// `<snake>_to_dict`/`<snake>_from_dict`/`<snake>_apply` functions.
#[serde(default)]
pub manual_kinds: Vec<String>,
/// Entity kinds exposed to `ocs.add`/`ocs.update`/`entity_to_dict`. The
/// central, easy-to-widen filter for Phase 2 (see the plan doc).
pub type_filter: Vec<String>,
@@ -164,6 +168,9 @@ fn helper_closure(manifest: &Manifest, registry: &TypeRegistry) -> Vec<String> {
let mut queue: Vec<String> = Vec::new();
for kind in &manifest.type_filter {
if manifest.manual_kinds.contains(kind) {
continue;
}
let Some(info) = get(registry, kind) else {
panic!("entity_manifest.json: unknown entity kind {kind}");
};
@@ -683,6 +690,13 @@ fn resolve_entity_fields(
fn gen_entity_to_dict(manifest: &Manifest, registry: &TypeRegistry) -> String {
let mut arms = String::new();
for kind in &manifest.type_filter {
if manifest.manual_kinds.contains(kind) {
arms.push_str(&format!(
" acadrust::EntityType::{kind}(value) => {}_to_dict(vm, value),\n",
snake_case(kind)
));
continue;
}
let info = get(registry, kind).unwrap();
let var = "value";
let fields = resolve_entity_fields(manifest, registry, kind, info, var, Mode::Add);
@@ -734,6 +748,13 @@ fn gen_dict_to_entity(manifest: &Manifest, registry: &TypeRegistry) -> String {
if manifest.overrides.get(kind).is_some_and(|override_def| override_def.update_only) {
continue;
}
if manifest.manual_kinds.contains(kind) {
arms.push_str(&format!(
" \"{kind}\" => acadrust::EntityType::{kind}({}_from_dict(dict, vm)?),\n",
snake_case(kind)
));
continue;
}
let info = get(registry, kind).unwrap();
let var = "value";
let fields = resolve_entity_fields(manifest, registry, kind, info, var, Mode::Add);
@@ -792,6 +813,13 @@ pub(crate) fn dict_to_entity(dict: &rustpython_vm::builtins::PyDictRef, vm: &Vir
fn gen_apply_dict_to_entity(manifest: &Manifest, registry: &TypeRegistry) -> String {
let mut arms = String::new();
for kind in &manifest.type_filter {
if manifest.manual_kinds.contains(kind) {
arms.push_str(&format!(
" acadrust::EntityType::{kind}(existing_value) => acadrust::EntityType::{kind}({}_apply(existing_value, dict, vm)?),\n",
snake_case(kind)
));
continue;
}
let info = get(registry, kind).unwrap();
let var = "value";
let fields = resolve_entity_fields(manifest, registry, kind, info, var, Mode::Update);