Skip to content

feat(ogar-from-ruff): typed scalar emit + reserved-word escaping (Odoo field_type)#141

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/odoo-rs-transcode-lf8ya5
Jun 29, 2026
Merged

feat(ogar-from-ruff): typed scalar emit + reserved-word escaping (Odoo field_type)#141
AdaWorldAPI merged 1 commit into
mainfrom
claude/odoo-rs-transcode-lf8ya5

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Consume the new ruff field_type predicate so the per-language SDK emitters produce concrete typed columns instead of a uniform OgScalar, and fix the uncompilable keyword-collision emit.

What changed

  • project_odoo_fields sets Attribute.type_name from Field.field_type (the lowercased Odoo constructor), so scalar columns carry their type to the emitters.
  • emit.rs og_scalar_type maps the constructor to a wrapper-contract type: char/text/htmlOgStr, integerOgInt, floatOgFloat, monetaryOgMoney (Decimal-backed, ERP money doctrine), booleanOgBool, dateOgDate, datetimeOgDateTime, binaryOgBytes, selectionOgSelection, jsonOgJson; None/unknown → OgScalar (fallback, always well-typed).
  • emit.rs escape_ident escapes reserved-word field names per target so the generated source compiles: Rust raw identifiers (r#type, _-suffix for the four non-raw-able), C# @-prefix (@ref), Python none (Odoo source field names cannot be Python keywords). Fixes the prior pub type: OgScalar, emit for an Odoo field literally named type/ref. Applied to attributes and associations across all three emitters.
  • Cargo.toml: ⚠️ TEMPORARILY rev-pins the ruff deps to the field_type commit (4860e79, which also carries the soc operator-veto fix 101928a), because Field.field_type is not yet on ruff main.

⚠️ Merge ordering (depends on the ruff PR)

This PR consumes ruff_spo_triplet::Field.field_type, which lands in the companion ruff PR (fix(soc): land dropped operator veto + capture Odoo field_type). The rev-pin makes this PR build independently, but after the ruff PR merges, a one-line follow-up should flip both ruff deps from rev = "4860e7…" back to branch = "main". Merge the ruff PR first.

Verification

  • ogar-from-ruff: 41 tests green, incl. og_scalar_type_maps_odoo_constructors, escape_ident_per_language_reserved_words, and the three emit tests (Rust/C#/Python) asserting typed wrappers + escaping + the OgScalar fallback.
  • End-to-end on real Odoo (account.move / account.analytic.line / product.template): product.template's type field now emits pub r#type: OgSelection, (was the uncompilable pub type:); account.analytic.line amount → OgMoney, date → OgDate, category → OgSelection, analytic_distribution → OgJson.

Generated by Claude Code

…o field_type)

Consume the new ruff `field_type` predicate so the per-language SDK emitters
produce concrete typed columns instead of a uniform `OgScalar`, and fix the
uncompilable keyword-collision emit.

- project_odoo_fields: set `Attribute.type_name` from `Field.field_type` (the
  lowercased Odoo constructor), so scalars carry their type to the emitters.
- emit.rs `og_scalar_type`: map the constructor to a wrapper-contract type —
  char/text/html → OgStr, integer → OgInt, float → OgFloat, monetary → OgMoney
  (Decimal-backed, ERP money doctrine), boolean → OgBool, date → OgDate,
  datetime → OgDateTime, binary → OgBytes, selection → OgSelection, json →
  OgJson; None/unknown → OgScalar (fallback, always well-typed).
- emit.rs `escape_ident`: escape reserved-word field names per target so the
  generated source compiles — Rust raw identifiers (`r#type`, with `_` suffix
  for the four non-raw-able), C# `@`-prefix (`@ref`), Python none (Odoo source
  field names can't be keywords). Fixes the prior `pub type: OgScalar,` emit for
  an Odoo field literally named `type`/`ref`. Applied to attributes AND
  associations across all three emitters.
- Cargo.toml: TEMPORARILY rev-pin the ruff deps to the field_type commit
  (4860e79, which also carries the soc operator-veto fix); flip back to
  branch="main" once the ruff field_type PR merges.

Verified end-to-end on real Odoo (account.move / account.analytic.line /
product.template): product.template's `type` field now emits
`pub r#type: OgSelection,`; `amount` → `OgMoney`. ogar-from-ruff 41 tests green.
@AdaWorldAPI AdaWorldAPI merged commit 7d0dca2 into main Jun 29, 2026
1 check failed
AdaWorldAPI pushed a commit that referenced this pull request Jun 29, 2026
… merged)

ruff #37 (field_type capture + soc operator-veto fix) merged to ruff main, so
the temporary rev-pin to 4860e79 introduced in #141 is no longer needed.
Restore branch = "main" for ruff_spo_triplet and ruff_spo_address.
AdaWorldAPI pushed a commit that referenced this pull request Jun 30, 2026
…sembler

Adds the keystone gap named in E-KEEP-AR-REMOVE-ORM / the OP convergence
assessment: a Rails-correct sibling of compile_graph_python. Identical
shape (mint_graph::<P> + per-class facet resolution) but routes through
the existing lift_model_graph (Language::Ruby) instead of
lift_model_graph_python — pure operator-reuse, no new lift, and
project_odoo_fields is correctly never invoked for Rails (it would
double-count; lift_model_graph_python's own doc-comment says so).

Proves the convergence claim in code: compile_graph_ruby::<OpenProjectPort>
on a WorkPackage graph and compile_graph_ruby::<RedminePort> on an Issue
graph mint to the SAME low-u16 concept (0x0102 project_work_item) and
DIFFERENT high-u16 render prefixes (0x0001 vs 0x0007) — one canonical
concept, two render skins, machine-checked rather than asserted.

Drive-by fix: 3 pre-existing Function{...} literal constructions
(emit.rs, mint.rs's account_move fixture, lib.rs) broke against the
already-merged ruff#38 (writes/calls fields) because this crate's
ruff_spo_triplet dep floats on branch=main. Added ..Default::default()
to each — no behavior change, restores compilation.

Verification: standalone probe workspace (path-dep ogar-vocab +
ogar-from-ruff, git-dep ruff branch=main) — the OGAR workspace itself
can't resolve in-sandbox (ogar-adapter-surrealql's surrealdb-ast git dep
403s), the same pattern prior PRs (#131/#132/#136/#138/#141) used.
44/44 tests pass (3 new + 41 pre-existing unbroken); clippy --no-deps
-D warnings clean at the pinned 1.95.0 toolchain (ogar-vocab itself has
pre-existing unrelated clippy debt from never being --workspace-gated,
out of scope here); doc-links resolve.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants