Skip to content

codegen: refactor ProtocolRustBinding — collapse stringly-typed maps into typed HandleBridgeFeedbackBinding #338

@lukacf

Description

@lukacf

Background

After PR #336, `ProtocolRustBinding` has 18 fields including three `BTreeMap<String, String>` / `BTreeMap<String, Vec>` maps keyed on feedback input variants:

```rust
pub handle_method_names: BTreeMap<String, String>,
// Keys: feedback.input_variant → handle-trait method name

pub handle_arg_accessors: BTreeMap<String, String>,
// Keys: "{input_variant}.{obligation_field}" → Rust suffix text (".0", ".clone()", ".into()")

pub handle_method_forwarded_fields: BTreeMap<String, Vec>,
// Keys: feedback.input_variant → ordered list of obligation field names
```

Problems flagged by review:

  1. Inconsistent composite key schemes — `handle_arg_accessors` uses dotted composite keys while the other two use bare input_variant keys.
  2. `handle_arg_accessors` is effectively a raw Rust suffix text escape hatch (".iter().map(ToString::to_string).collect()" in one concrete case) — this is stringly-typed transformation logic that should live in code, not data.
  3. No compile-time guarantee that every feedback input has all required entries across the three maps.

Proposed refactor

Introduce a typed container that groups all HandleBridge bindings for one feedback input:

```rust
pub struct HandleBridgeFeedbackBinding {
/// Handle trait method to call.
pub method: String,
/// Positional arguments (in order) with per-arg conversion.
pub args: Vec,
}

pub enum HandleBridgeArg {
/// Pass `obligation.` through the specified accessor.
Obligation {
field: String,
access: HandleBridgeAccess,
},
/// Pass an owner-supplied value at call time (String / Into).
OwnerContext { name: String },
}

pub enum HandleBridgeAccess {
/// Pass `obligation.` directly.
Direct,
/// Pass `obligation..0` (unwrap typed newtype to its inner value).
NewtypeInner,
/// Pass `obligation..clone()`.
Clone,
/// Pass `obligation..iter().map(ToString::to_string).collect()`
/// (typed ID set to BTreeSet).
StringifySet,
}
```

Replace all three maps on `ProtocolRustBinding` with:

```rust
pub handle_bridge_bindings: BTreeMap<String, HandleBridgeFeedbackBinding>,
// Keys: feedback.input_variant
```

Validation then becomes a single "every HandleBridge feedback input has a binding entry" check, and the codegen emits real typed logic instead of gluing Rust suffix text.

Estimated size

~60 lines of schema changes, ~30 lines of codegen refactor, plus migration of the three existing compositions to the new shape. Not a large change; mostly data-layout work.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions