@@ -38,11 +38,12 @@ use serde::{Deserialize, Serialize};
3838/// `pub enum` / `pub struct` in this module: the OGAR vocabulary is
3939/// expected to evolve over time, and every base type is forward-
4040/// compatible-by-construction.
41- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
41+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Default ) ]
4242#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
4343#[ non_exhaustive]
4444pub enum Language {
4545 /// Ruby ActiveRecord (`class Foo < ApplicationRecord`).
46+ #[ default]
4647 Ruby ,
4748 /// Python — covers Django ORM and Odoo `models.Model`.
4849 Python ,
@@ -305,7 +306,7 @@ pub struct MethodDecl {
305306/// Method kind — distinguishes overrides from helpers from plain
306307/// methods. The producer determines kind from decorator + name
307308/// inspection; see `docs/ODOO-TRANSCODING.md` §13.
308- #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
309+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Default ) ]
309310#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
310311#[ non_exhaustive]
311312pub enum MethodKind {
@@ -318,37 +319,27 @@ pub enum MethodKind {
318319 /// Odoo's bulk-create override.
319320 ApiModelCreateMulti ,
320321 /// Plain instance method, no special semantics.
322+ #[ default]
321323 Instance ,
322324}
323325
324- impl Default for MethodKind {
325- fn default ( ) -> Self {
326- Self :: Instance
327- }
328- }
329-
330326/// Recordset semantics — Odoo methods can bind to a record (single),
331327/// a recordset (the default for most methods), or be class-level
332328/// (`@api.model`). Captured for cross-language consumers that
333329/// project to per-record vs per-collection APIs.
334- #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
330+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Default ) ]
335331#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
336332#[ non_exhaustive]
337333pub enum RecordSemantics {
338334 /// Single-record context.
339335 Record ,
340336 /// Recordset (Odoo default for most methods).
337+ #[ default]
341338 Recordset ,
342339 /// Class-level (`@api.model` or no `self`).
343340 ClassLevel ,
344341}
345342
346- impl Default for RecordSemantics {
347- fn default ( ) -> Self {
348- Self :: Recordset
349- }
350- }
351-
352343// ─────────────────────────────────────────────────────────────────────
353344// Sprint 3 — Action vocabulary with SPO + TeKaMoLo grammar
354345// (per docs/ADAPTERS-AND-ACTORS.md + brutal-review cycle 3 fixes)
@@ -368,7 +359,6 @@ impl Default for RecordSemantics {
368359#[ derive( Debug , Clone , Default , PartialEq , Eq ) ]
369360#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
370361#[ non_exhaustive]
371-
372362pub struct ActionDef {
373363 /// Stable identity for the action declaration (e.g.
374364 /// `ogit-erp/sale.order::action_def::action_confirm`).
@@ -446,23 +436,18 @@ impl EnterEffect {
446436/// Disposition when a `KausalSpec::StateGuard` is not satisfied — the Modal
447437/// sub-property for the Rubicon statem lowering (OGAR-AST-CONTRACT §6).
448438/// `#[non_exhaustive]` per the vocabulary forward-compat convention.
449- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
439+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Default ) ]
450440#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
451441#[ non_exhaustive]
452442pub enum GuardFailurePolicy {
453443 /// Transient failure — stay `Pending` and replay after the next
454444 /// transition. Lowers to `Transition::Postpone`.
455445 Postponable ,
456446 /// Hard failure — `Pending → Failed` (the default).
447+ #[ default]
457448 Reject ,
458449}
459450
460- impl Default for GuardFailurePolicy {
461- fn default ( ) -> Self {
462- Self :: Reject
463- }
464- }
465-
466451/// A runtime invocation of an `ActionDef` — one per (S, P, O, context)
467452/// tuple. Captures the actual subject (which user / cron / cascade
468453/// fired this), provenance for tracing, and lifecycle state.
@@ -509,13 +494,14 @@ pub struct ActionInvocation {
509494}
510495
511496/// Subject of a business action — who/what initiated it.
512- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
497+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Default ) ]
513498#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
514499#[ non_exhaustive]
515500pub enum ActionSubject {
516501 /// A human user (UI button click, RPC call from authenticated user).
517502 User ,
518503 /// Internal system trigger (no specific user).
504+ #[ default]
519505 System ,
520506 /// Scheduled (`ir.cron`, Rails `Whenever`).
521507 Cron ,
@@ -525,19 +511,14 @@ pub enum ActionSubject {
525511 Cascade ,
526512}
527513
528- impl Default for ActionSubject {
529- fn default ( ) -> Self {
530- Self :: System
531- }
532- }
533-
534514/// Temporal context — when does the action happen relative to its
535515/// trigger.
536- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
516+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Default ) ]
537517#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
538518#[ non_exhaustive]
539519pub enum TemporalSpec {
540520 /// Synchronous, on-call.
521+ #[ default]
541522 Immediate ,
542523 /// Queued, async background.
543524 Deferred ,
@@ -548,20 +529,15 @@ pub enum TemporalSpec {
548529 OnCommit ,
549530}
550531
551- impl Default for TemporalSpec {
552- fn default ( ) -> Self {
553- Self :: Immediate
554- }
555- }
556-
557532/// Modal context — how is the action performed.
558533/// Per B3 YAGNI: dropped `Requires` (no v1 consumer); kept Idempotent
559534/// because it gates the dedup mechanism in `ActionInvocation`.
560- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
535+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Default ) ]
561536#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
562537#[ non_exhaustive]
563538pub enum ModalSpec {
564539 /// Synchronous, blocking.
540+ #[ default]
565541 Sync ,
566542 /// Fire-and-forget.
567543 Async ,
@@ -571,12 +547,6 @@ pub enum ModalSpec {
571547 Atomic ,
572548}
573549
574- impl Default for ModalSpec {
575- fn default ( ) -> Self {
576- Self :: Sync
577- }
578- }
579-
580550/// Causal precondition — what triggered this action. **Sum type** per
581551/// B1 review fix. Producers populate one variant; the runtime guard
582552/// evaluator dispatches on the variant.
@@ -630,11 +600,12 @@ pub struct LokalSpec {
630600/// Lifecycle state of an `ActionInvocation`.
631601/// Per B2 production-blocker #3: explicit state machine prevents
632602/// the silent-gap problem (action started, didn't complete, no record).
633- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
603+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Default ) ]
634604#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
635605#[ non_exhaustive]
636606pub enum ActionState {
637607 /// Emitted but not yet processed by the callcenter.
608+ #[ default]
638609 Pending ,
639610 /// Successfully processed; effects committed.
640611 Committed ,
@@ -645,12 +616,6 @@ pub enum ActionState {
645616 Cancelled ,
646617}
647618
648- impl Default for ActionState {
649- fn default ( ) -> Self {
650- Self :: Pending
651- }
652- }
653-
654619// ─────────────────────────────────────────────────────────────────────
655620// Sprint 3 constructors (per #[non_exhaustive] convention)
656621// ─────────────────────────────────────────────────────────────────────
@@ -719,11 +684,12 @@ impl KausalSpec {
719684/// Rails `belongs_to`/`has_one`/`has_many`/`has_and_belongs_to_many`,
720685/// Odoo `Many2one`/`One2many`/`Many2many` (Odoo collapses `has_one` into
721686/// `One2many` constrained to 1).
722- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
687+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Default ) ]
723688#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
724689#[ non_exhaustive]
725690pub enum AssociationKind {
726691 /// Owning side of a 1:N — the FK lives on this class's table.
692+ #[ default]
727693 BelongsTo ,
728694 /// Non-owning side of a 1:1.
729695 HasOne ,
@@ -801,12 +767,6 @@ pub struct Association {
801767 pub delegate : Option < bool > ,
802768}
803769
804- impl Default for AssociationKind {
805- fn default ( ) -> Self {
806- Self :: BelongsTo
807- }
808- }
809-
810770/// An enum-backed column declaration.
811771///
812772/// The `source` field captures three Odoo cases (static / computed /
@@ -1543,8 +1503,8 @@ pub mod class_ids {
15431503 /// Promoted Phase-3 from the cross-axis identity gap surfaced in odoo-rs
15441504 /// PR #14: the alignment table seeds `product.template → schema:Product`
15451505 /// + BillingCore (0x61); this id is the OGAR-side identity that closes
1546- /// the same axis. `OdooPort` carries `product.template` and
1547- /// `product.product` as aliases of `PRODUCT`.
1506+ /// the same axis. `OdooPort` carries `product.template` and
1507+ /// `product.product` as aliases of `PRODUCT`.
15481508 pub const PRODUCT : u16 = 0x0207 ;
15491509 /// `accounting_account` (`0x0208`) — general-ledger account (SKR-aligned
15501510 /// chart concept). OSB `Account`, Odoo `account.account` +
@@ -5682,9 +5642,3 @@ mod tests {
56825642 }
56835643 }
56845644}
5685-
5686- impl Default for Language {
5687- fn default ( ) -> Self {
5688- Self :: Ruby
5689- }
5690- }
0 commit comments