Zig 0.16#1
Merged
Merged
Conversation
Migrate std usage to the new APIs introduced in 0.16. - Replace ArrayListUnmanaged empty-init braces with .empty. - Switch the encoder output buffer to std.Io.Writer.Allocating. - Pass std.Io to the file and directory operations in tests. - Bump zest test runner to its 0.16-compatible commit.
Diagnostics is the conventional name for attached source-position info on a parse failure. Adds ParseFromValueError, the concrete error set returned from value-tree decoding paths landing in subsequent commits.
Decodes directly into the caller's allocator without wrapping in Parsed(T). The intended pairing is an ArenaAllocator passed by the caller, which gets the same all-or-nothing cleanup as Parsed without the double indirection. Factors out parseToNode as the shared scan/parse step between the two entry points.
Renames variants for std.json parity: boolean->bool, sequence->array, mapping->object. Array is std.ArrayList(Value); ObjectMap is std.array_hash_map.Custom keyed by Value, preserving YAML's ability to use any node as a mapping key (integers, floats, sequences, etc.) while exposing the std.json-style put/get/iterator interface. A ValueContext supplies hash and eql for the map; eql is the same recursive equality previously on Value. Adds an objectGet convenience method for string-keyed lookup, replacing the old mappingGet. The decoder, encoder, and tests are all reworked to construct values through put/append rather than parallel-slice literals.
Decodes a Value tree into a typed T without re-parsing source bytes. The wrapped form returns Parsed(T) whose arena owns deep-cloned strings and containers, so the source Value can be released independently. The leaky form decodes straight into the caller's allocator. Includes a yamlParseFromValue hook hatch on user types, enabled via the comptime hasYamlParseFromValue check (parallel to the existing yamlParse path used by parseFromSlice).
The free functions stringify and stringifyAlloc become Stringify.value and Stringify.valueAlloc; StringifyOptions becomes Stringify.Options. yaml.zig drops the free re-exports and pulls Stringify in directly. This commit is just the rename. The follow-up turns Stringify into a struct (writer, options, indent_level fields) with the streaming API methods (beginMapping, mappingField, beginSequence, write, etc.) needed for yamlStringify hooks. The encodeToNode stub is also dropped here.
Stringify gains writer/options/indent_level fields, a container stack, beginObject/endObject/objectField, beginArray/endArray, and write. Also removes writeSliceTop (unused) and testEncodeWithOptions (a duplicate of testEncodeOpts).
The writeValue family of helpers used writer: anytype as a holdover from before std.Io.Writer became a concrete type. Every caller passes *std.Io.Writer now, so make the type explicit.
The container kind stack is now 1 bit per level (8 bytes for 64 levels) instead of one Container enum per level. endObject and endArray now read the parent container after popping so the state machine returns to .in_object or .in_array as appropriate, rather than unconditionally setting the state from the closed container's kind.
The new third argument matches the shape yamlParseFromValue already uses and lets hooks forward parser settings into their own decodeNode calls.
When T declares yamlStringify(self, *Stringify), writeValue builds a Stringify positioned at the current depth and hands control to the hook. Replaces the old stub yamlStringify(self, Allocator) !Node shape, which was never called. Drops the unused Node import.
A custom type with yamlParse, yamlParseFromValue, and yamlStringify round-trips through the slice, value, and stringify paths. Confirms the three hook entry points dispatch correctly together on one type.
Frees the ParseError name for the umbrella error matching std.json's role. ParseFromValueError keeps its existing name and shape; ParseError is an alias since yaml-zig has no streaming Source variant that would change the set.
Mirrors std.json's static.zig location for the typed-decoding facade. yaml.zig re-exports the four functions (parseFromSlice, parseFromSliceLeaky, parseFromValue, parseFromValueLeaky) directly from static.zig. decode.zig keeps the type walking; AnchorMap, parseToNode, decodeNodeInternal, and decodeValueInternal become public so static.zig can call them.
Custom yamlParse hooks call innerParse to recurse on a sub-node. Custom yamlParseFromValue hooks call innerParseFromValue to recurse on a sub-value. Both are re-exported from yaml.zig.
ignore_unknown_fields now defaults to false. duplicate_field_behavior is new with default .@"error" so a YAML mapping that names the same key twice is rejected unless the caller opts into .use_first or .use_last. The existing line-based dedup helper now supports both keep-the-first and keep-the-last semantics. A few existing tests relied on the old lenient defaults; they now opt in via testDecodeLenient or testDecodeUseLast helpers. New tests cover all three duplicate behaviors.
The Value type now declares the same four methods that other types can declare to opt into custom parsing and serialization. dump writes a YAML rendering to a writer. yamlParse builds a Value from an AST node. yamlParseFromValue clones a Value. yamlStringify emits a Value through the streaming Stringify writer. The encoder and decoder still have direct if (T == Value) shortcuts that run before the hook check. Removing those is remaining work, which needs new tests first to prove the tag-aware paths still work. Makes writeValueUnion, writeFlowValueUnion, decodeToValue, and cloneValue public so the Value methods can call them.
These five paths (!!binary, !!bool, !!float, !!null, !!str into a Value) were previously uncovered. Locking down current behavior before reorganizing the tag handling.
The decoder no longer has if (T == Value) shortcuts in its main dispatch paths. The encoder no longer special-cases Value in its union arms. Value satisfies the same hook protocol that user types use, so the same dispatch logic handles it. Tag-aware decoding into Value (!!binary, !!bool, !!float, !!null, !!str) moves into decodeToValue's tag arm, which is what Value.yamlParse calls. Fixes hasYamlParse / hasYamlParseFromValue / hasYamlStringify so they recognize unions as well as structs. Without that change the hooks would not fire for Value at all.
print emits a formatted scalar through the streaming Stringify state machine. Use it inside a yamlStringify hook when a type wants to render itself with std.fmt-style formatting rather than field-by-field dispatch. Also fixes writeFieldValue so a struct field whose type declares yamlStringify routes to the hook. Without that change the encoder would walk the field type's children instead of letting the hook take over.
Lets callers use the standard {f} formatting verb to print any value
as YAML. yaml.fmt(my_struct, .{}) returns a wrapper whose format
method writes through Stringify.value.
A generic factory: ArrayHashMap(T) wraps a string-keyed hash map of
T values and declares the three hooks. Use it as a struct field to
round-trip a YAML mapping where keys are arbitrary strings and
values share one type.
Tests cover the slice path, the Value path, an empty map, error
cases for non-mapping input and non-string keys, struct values, and
deinit.
Also fixes endObject and endArray so an empty container emits the
inline form "{}" or "[]" instead of nothing. The empty-map test
caught this latent bug in the streaming API.
Comments describing the dynamic Value type and its serialization options now match the variant names: array and object. YAML 1.2 spec terminology (mapping, sequence) stays in places that describe the input grammar or the AST, since those are the spec's own words.
In Zig 0.16 the unmanaged form became the default name and ArrayListUnmanaged is a deprecated alias for ArrayList.
Per the Zig 0.16 release notes, managed containers are being phased out. This moves AnchorMap to the unmanaged form internally.
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.
No description provided.