# PureYAML Design | Field | Value | |---|---| | Status | draft | | Created | 2026-06-05 | | Last revised | 2026-06-05 | ## Purpose PureYAML exists to provide a dependency-free YAML implementation in Swift that can build on macOS, Linux, and WebAssembly/WASI. The first user is OpenAPIDoctor, which needs YAML parsing and mutation without a C-backed parser blocking browser deployment. ## Goals - Parse a useful YAML subset with no external dependencies. - Preserve mapping order. - Emit YAML from the same model. - Validate YAML structures with path-aware issues. - Build the library target for `wasm32-unknown-wasip1`. - Grow toward Yams-compatible behavior through tests, not source copying. ## Non-Goals - No C source in the public package. - No external SwiftPM dependency. - No JavaScript parser or build-time generator. - No claim of complete YAML 1.2 coverage until the test corpus proves it. ## Current Architecture ```text PureYAML ├── Model │ ├── Value │ ├── Mapping │ └── Pair ├── Parsing │ ├── Parser │ ├── Reader │ ├── Scanner │ ├── Token │ ├── TokenCursor │ ├── TokenEventParser │ ├── EventComposer │ ├── Event │ ├── Mark │ └── ParseError ├── Emitting │ └── Dumper └── Validation ├── Validator ├── Rule ├── Issue └── Path ``` `PureYAML.parse(_:)` and `PureYAML.dump(_:)` are convenience entry points. Parsing runs through the scanner, token-event parser, and event composer before returning `PureYAML.Model.Value`. The implementation lives in namespaced parser, dumper, and validator types. ## First Milestone The initial parser supports: - block mappings - block sequences - ordered mappings - strings - ints - doubles - bools - nulls - quoted strings - comments outside quoted strings - flow sequences and mappings - literal and folded block scalars - anchors and aliases - YAML directives and document markers for single-document streams - explicit built-in scalar tags for strings, integers, floats, booleans, and nulls The parser layer also has an internal event contract. `Parsing.Event` can represent stream, document, scalar, sequence, mapping, and alias events, with marks plus scalar and collection styles. Anchors and tags are carried as event metadata so the later scanner/composer work can add YAML feature coverage without changing the event shape. The parser layer now also has an internal reader/scanner/event contract. `Parsing.Reader` advances through Swift `String` input while tracking UTF-8 byte indexes, lines, and columns. `Parsing.Scanner` emits lexical `Parsing.Token` values for comments, indentation, block entries, mapping indicators, flow delimiters, quoted scalar starts, block scalar headers, anchors, aliases, tags, YAML directives, document markers, and source mark ranges. `Parsing.Scanner` also expands tag handles from `%TAG` directives before emitting tag tokens. `Parsing.TokenEventParser` consumes that token stream and emits `Parsing.Event` values for block collections, flow collections, aliases, anchors, tags, and scalars. `Parsing.EventComposer` consumes those events into `PureYAML.Model.Value`, preserving ordered mapping pairs, block scalar text, alias-resolved values, and explicit built-in scalar tags where the current model can represent them. The initial dumper emits block-style YAML from the model. The initial validator traverses parsed YAML values and reports path-aware issues. The default rule rejects duplicate mapping keys, and callers can build a blank validator plus custom rules for project-specific checks. ## Planned Compatibility Work Compatibility should be added in small, test-backed slices: 1. Tag-aware collection handling and merge keys. 2. Validation rules beyond duplicate-key behavior. 3. Codable-style decoding and encoding. 4. Yams corpus comparison tests in a separate compatibility suite. The private `PureYAMLResearch` repository may be used to study Yams behavior, but the public implementation must be written in Swift and must not copy C parser source. ## Attribution Boundary Yams and its bundled `CYaml` / libyaml-derived C parser are compatibility references for PureYAML. They should guide test cases and behavior questions. They are not source material to copy into this package.