feat(engine): event normalizer#16
Merged
Merged
Conversation
Add `src/ocpp/normalizer.zig` — the second S1 engine module — turning raw trace inputs into canonical `Event`s. Mirrors the toolkit's normalizer behavior (the shared conformance contract), not its source. - Message classification and field extraction (action, payload, error code / description) over the `std.json.Value` boundary. - Timestamp normalization: ISO 8601 (UTC and ±hh:mm offset, via a self-contained days-from-civil parser) and epoch seconds / milliseconds with the 10^12 threshold. Untrusted magnitudes are guarded against integer overflow and out-of-range float casts. - Direction inference from the CS→CSMS / CSMS→CS action tables (DataTransfer resolves CS→CSMS), plus two-pass resolution of response directions from their matched Call. The toolkit's normalizer test cases are ported. Closes #12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Second slice of S1 — Engine core:
src/ocpp/normalizer.zig, which turns rawTraceEventInputentries into canonicalEvents. Mirrors the toolkit'score/normalizer.ts— the shared conformance contract — including its exactaction tables and the 10^12 epoch threshold, so the two implementations agree.
Changes
classifyMessageTypeplusextractAction/extractPayload/extractErrorCode/extractErrorDescription, reading[typeId, uniqueId, …]off thestd.json.Valueboundary.normalizeTimestamphandles ISO 8601 (UTC and±hh:mmoffset, with optional fractional seconds) via a self-containeddays-from-civil parser, plus epoch seconds / milliseconds (as JSON number or
numeric string) split on the 10^12 threshold. Missing zone ⇒ UTC, so results
don't depend on the host's local time.
inferDirectionfrom the CS→CSMS / CSMS→CS action tables(
DataTransfer, present in both, resolves CS→CSMS),reverseDirection, and atwo-pass
normalizeEventsthat resolves each response's direction from itsmatched Call. Explicit input direction (even
unknown) is respected;sequential
evt-0001ids; input order preserved.Security (untrusted input)
Timestamps come from untrusted traces, so the numeric paths guard against
overflow: seconds→ms multiplication uses checked
std.math.mul, and thefloat→int cast is range-checked. Absurd magnitudes (e.g.
1e300) return nullinstead of panicking — covered by a test.
Testing
native test -Dplatform=null→ 17/17 pass (9 new normalizer tests portedfrom the toolkit: timestamp variants, direction inference/reversal, field
extraction, response matching, explicit-direction respect, empty input).
2024-01-15T10:00:00Zand its+02:00equivalent both resolveto
1_705_312_800_000, matching the toolkit'sDate.parse.native check --strictandzig fmt --checkclean.Closes #12