Last codec-side prerequisite before F13 (NmxClient high-level write
wrappers) can land. Two small additions, both wire-byte-direct ports
of the .NET reference's MxDataType → MxValueKind lookup logic.
mxaccess-codec
- MxValueKind::for_data_type(MxDataType, is_array) -> Option<MxValueKind>:
fuses NmxWriteMessage.cs:58-86 (TryGetValueKind's 12 base mappings
for data types 1..=6 scalar+array) with the two scalar fallbacks the
.NET GalaxyTagMetadata.ProjectWriteValue layers on top
(GalaxyRepositoryTagResolver.cs:65-69): ElapsedTime → Int32,
InternationalizedString → String. Returns None for any other
combination — including arrays of those two types and unsupported
scalars (ReferenceType, StatusType, Enum, etc.).
- 6 new tests covering the base table, both fallbacks, the array-of-
unsupported rejection, and the no-mapping branch for ReferenceType /
StatusType / Enum / DataQualityType / BigString / Unknown / NoData /
End sentinels.
mxaccess-galaxy
- GalaxyTagMetadata::resolve_write_kind() -> Result<MxValueKind,
UnsupportedDataType>: pure delegation to MxValueKind::for_data_type
+ a typed error carrying (mx_data_type, is_array) for diagnostics.
- GalaxyTagMetadata::is_writable() — Ok-side accessor for browse UIs.
- UnsupportedDataType public error type (re-exported from lib.rs).
- 7 new tests: Double scalar → Float64, Boolean array → BoolArray,
ElapsedTime scalar → Int32 (the fallback path), array-of-ElapsedTime
rejected, InternationalizedString → String, ReferenceType rejected,
Unknown sentinel rejected.
Test count delta: 446 -> 459 (+13; codec 215 -> 221, galaxy 49 -> 56).
All four DoD gates green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lands the user-resolver half of M3 stream A. Pure-Rust foundation —
the tiberius-backed SQL impl is logged as F14 and stays gated behind
the existing galaxy-resolver Cargo feature.
New
- role_blob.rs (~270 LoC, 12 tests including a garbage-between-roles
edge case) — port of ParseRoleBlob (cs:87-133). Sliding-window scan
over hex-decoded UTF-16LE bytes; rejects non-printable code units;
case-insensitive dedup. Pure function, no I/O.
- user.rs (~290 LoC, 8 tests including 4 tokio-driven InMemoryUserResolver
cases) — GalaxyUserProfile (port of cs:5-11) + from_columns helper
bridging into role_blob + UserResolver async trait + UserResolverError
with NotFound / Backend variants.
- sql.rs additions: USER_SELECT_SQL + USER_BY_GUID_SQL + USER_BY_NAME_SQL
constants (port of cs:135-148). Inline concatcp! macro composes the
base SELECT with each WHERE clause at compile time without pulling
const_format.
Cargo.toml: added uuid (Galaxy user_guid is a uniqueidentifier).
design/followups.md: added F14 (P2) for the tiberius-backed SQL impl
behind the galaxy-resolver feature.
Test count delta: 427 -> 446 (+19; mxaccess-galaxy 30 -> 49). All four
DoD gates green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lands M3 stream A — the pure-Rust foundation of the Galaxy resolver:
the data type, the tag-reference parser, the async trait, and the
canonical SQL strings. Unblocks F13 (NmxClient::write_* wrappers depend
on GalaxyTagMetadata) without pulling in tiberius yet.
New
- metadata.rs (~195 LoC, 7 tests) — GalaxyTagMetadata record (port of
cs:6-73). Includes is_buffer_property + to_reference_handle(galaxy_id)
bridging into mxaccess-codec::MxReferenceHandle::from_names.
- parser.rs (~330 LoC, 12 tests) — ParsedTagReference parser. Handles
Object.Attribute (1 candidate), Object.Primitive.Attribute (2
candidates: primitive-attr first, dotted-attr second per cs:181-185),
and the case-insensitive .property(buffer) suffix. Pure-Rust, no I/O.
- resolver.rs (~200 LoC, 5 tests including a tokio-driven InMemoryResolver
proving the trait is implementable without SQL) — async Resolver trait
+ ResolverError. Default browse returns Backend("not implemented") so
read-only backends don't need to override it.
- sql.rs (~280 LoC, 5 smoke tests) — RESOLVE_SQL + BROWSE_SQL constants
ported byte-for-byte from cs:208-432. Available publicly so any
backend (the planned tiberius impl, a wwtools/grdb snapshot replay,
etc.) can grab the canonical query.
Cargo.toml: added mxaccess-codec (path), async-trait, thiserror;
tokio added as dev-dependency for the resolver-trait async tests.
Deliberately deferred to a later iteration:
- The tiberius-backed Resolver impl behind the galaxy-resolver feature.
- ToValueKind / TryGetValueKind / ProjectWriteValue helpers on
GalaxyTagMetadata (cs:41-72) — these need a MxDataType -> MxValueKind
lookup that the codec doesn't currently expose; landing them with
F13's write-helper iteration keeps the iteration coherent.
Test count delta: 397 -> 427 (+30). All four DoD gates green.
Open followups touched: F13 prerequisite (GalaxyTagMetadata) now in
place; F13 itself stays open until the write helpers wire it up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>