Files
mxaccess/rust
Joseph Doherty 0441a2e693 [M5] mxaccess-asb: F25 step 9 — Write operation
Closes the highest-value remaining IASBIDataV2 op. With Write landed,
the read+write+subscribe path is functionally complete in-memory.

API additions:
* `MinimalWriteValue { value: AsbVariant }` — carries just the Value
  payload. Optional ArrayElementIndex / Comment / HasQT / Status /
  Timestamp fields are deferred to a later iteration once a live
  capture confirms the WCF DataContract XML form.
* `build_write_request_body(items, values, write_handle)` per
  `AsbContracts.cs:181-194`:
  ```xml
  <WriteBasicRequest xmlns="urn:msg.data.asb.iom:2">
    <Items><ASBIData>{ItemIdentity[] binary}</ASBIData></Items>
    <Values>
      <WriteValue><Value><ASBIData>{Variant binary}</ASBIData></Value></WriteValue>
      ...
    </Values>
    <WriteHandle>{i32}</WriteHandle>
  </WriteBasicRequest>
  ```
  Items array uses the IAsbCustomSerializableType binary fast-path;
  each Value's inner Variant also uses the fast-path. WriteHandle is
  an Int32 (opaque correlation echoed in PublishWriteComplete).
* `decode_write_response` — per-item Status array (mirrors the
  unregister/register pattern).
* `AsbClient::write(items, values, write_handle)` — thin wrapper.

4 new tests:
* `write_request_body_carries_items_values_and_write_handle` — body
  shape sanity (WriteHandle = 7 Int32, WriteValue element present).
* `write_request_body_pairs_items_and_values_arrays` — 2 items + 2
  values produces 2 WriteValue elements.
* `write_response_round_trips_status_array` — Status decode.
* `write_response_missing_status_fails` — graceful MissingField
  error.

Workspace: 695 tests pass (was 691, +4).

Stubbed for next F25 iterations:
* `PublishWriteComplete` — empty request, `ItemWriteComplete[]`
  response.
* `DeleteMonitoredItems` — mirrors AddMonitoredItems pattern.
* Optional WriteValue fields (Comment / Timestamp / etc.) once a
  live capture confirms the wire-byte layout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 13:04:11 -04:00
..

mxaccess (Rust port)

Native Rust replacement for AVEVA / Wonderware MXAccess. See ../design/ for the architectural specification, ../src/ for the .NET reference (the executable spec), and ../CLAUDE.md for project-wide rules.

Status

M0 — Workspace skeleton. Stub types compile; nothing is implemented yet. See ../design/60-roadmap.md for the M0M6 milestone plan.

Layout

rust/
  Cargo.toml                 workspace root
  rust-toolchain.toml        1.85 stable
  crates/
    mxaccess-codec/          pure protocol codec, no I/O
    mxaccess-galaxy/         Galaxy SQL resolver (tiberius)
    mxaccess-rpc/            DCE/RPC + NTLMv2 + OXID + OBJREF
    mxaccess-callback/       INmxSvcCallback RPC server
    mxaccess-nmx/            INmxService2 client
    mxaccess-asb-nettcp/     net.tcp framing (MC-NMF + MC-NBFX/NBFS)
    mxaccess-asb/            IASBIDataV2 client
    mxaccess/                async session + Transport trait + public API
    mxaccess-compat/         LMXProxyServer-shaped facade

Build

cargo build --workspace
cargo test --workspace
cargo clippy --workspace -- -D warnings
cargo fmt --check

Live probes

. ..\tools\Setup-LiveProbeEnv.ps1
cargo test -p mxaccess --features live -- --ignored

The setup script fetches credentials from Infisical via wwtools/secrets/Get-Secret.ps1. Never inline plaintext credentials.

License

MIT — see ../LICENSE.