Module: Dms
- Defined in:
- lib/dms/parser.rb,
lib/dms.rb,
lib/dms/tier1.rb,
lib/dms/types.rb,
lib/dms/emitter.rb
Overview
DMS parser - port of the Python/Rust reference, optimized for Ruby.
Hand-written recursive-descent + stateful lexer. Errors carry (line, column, message). Tables are insertion-ordered Hashes.
Hot-path strategy: positions are byte offsets into a UTF-8 source. Inline scanners use String#getbyte (returns Integer or nil) which is allocation-free, vs. String#[] which copies a 1-char String per call. DMS structural characters (‘:’, ‘+’, ‘-’, ‘n’, digits, ASCII keys) are all ASCII, so byte-level checks are exact for the common cases. Multi-byte content only matters in string bodies (handled via byteslice + force_encoding) and for non-ASCII bare-key chars (label- class check has a UTF-8 multi-byte fallback).
Defined Under Namespace
Modules: Tier1 Classes: AttachedComment, Comment, DecodeError, Document, Emitter, EncodeError, HeredocModifierCall, LocalDate, LocalDateTime, LocalTime, OffsetDateTime, OriginalLiteral, Parser, StringForm, UnorderedHash
Constant Summary collapse
- VERSION =
"0.3.0"- SUPPORTS_LITE_MODE =
Capability flag — this port ships lite-mode decode + lite-mode encode_lite. See SPEC §Decoding modes — full and lite.
true- SUPPORTS_IGNORE_ORDER =
Capability flag — this port ships unordered-table decode mode. See SPEC §Unordered tables.
true- ParseError =
Deprecated alias. Use ‘Dms::DecodeError`. Referencing this constant emits a one-shot warning via `deprecate_constant`.
DecodeError- INDENT_STR =
" "
Class Method Summary collapse
-
._contains_unordered_table?(v) ⇒ Boolean
Recursive walk: returns true iff ‘v` (or any descendant) is an `UnorderedHash`.
- ._warn_deprecated(old, new_name) ⇒ Object
-
.decode(src) ⇒ Object
Decode a DMS source string and return the body value tree.
-
.decode_document(src) ⇒ Object
Decode a DMS source string and return the full Document (body, meta, comments, original_forms).
-
.decode_document_unordered(src) ⇒ Object
Unordered full-mode decode (SPEC §“Unordered tables”).
-
.decode_front_matter(src) ⇒ Object
Front-matter-only decode (SPEC §Front-matter-only decode).
-
.decode_lite(src) ⇒ Object
Lite-mode decode: same data tree, no comment AST, no original_forms.
- .decode_lite_document(src) ⇒ Object
-
.decode_lite_document_unordered(src) ⇒ Object
Unordered lite-mode decode.
-
.encode(doc) ⇒ Object
Encode a parsed Document back to DMS source (SPEC §encode).
-
.encode_lite(doc) ⇒ Object
Canonical-form emit.
- .parse(src) ⇒ Object
- .parse_document(src) ⇒ Object
- .parse_document_unordered(src) ⇒ Object
- .parse_lite(src) ⇒ Object
- .parse_lite_document(src) ⇒ Object
- .parse_lite_document_unordered(src) ⇒ Object
-
.supports_ignore_order ⇒ Object
Capability flag (SPEC §“Unordered tables”).
- .to_dms(doc) ⇒ Object
- .to_dms_lite(doc) ⇒ Object
Class Method Details
._contains_unordered_table?(v) ⇒ Boolean
Recursive walk: returns true iff ‘v` (or any descendant) is an `UnorderedHash`. Used by `encode` to enforce the SPEC contract that full-mode round-trip refuses unordered documents.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/dms/emitter.rb', line 30 def self._contains_unordered_table?(v) case v when UnorderedHash true when Hash v.each_value { |vv| return true if _contains_unordered_table?(vv) } false when Array v.each { |vv| return true if _contains_unordered_table?(vv) } false else false end end |
._warn_deprecated(old, new_name) ⇒ Object
113 114 115 116 117 118 119 |
# File 'lib/dms.rb', line 113 def self._warn_deprecated(old, new_name) return if @_deprecation_warned[old] @_deprecation_warned[old] = true warn "[DEPRECATION] `Dms.#{old}` is deprecated and will be removed " \ "in the next release. Use `Dms.#{new_name}` instead.", uplevel: 2 end |
.decode(src) ⇒ Object
Decode a DMS source string and return the body value tree.
37 38 39 |
# File 'lib/dms.rb', line 37 def self.decode(src) Parser.parse_document(src).body end |
.decode_document(src) ⇒ Object
Decode a DMS source string and return the full Document (body, meta, comments, original_forms).
43 44 45 |
# File 'lib/dms.rb', line 43 def self.decode_document(src) Parser.parse_document(src) end |
.decode_document_unordered(src) ⇒ Object
Unordered full-mode decode (SPEC §“Unordered tables”). Body tables are built as ‘Dms::UnorderedHash` (a Hash subclass) with keys shuffled at end-of-build so callers cannot rely on insertion order. Front matter remains insertion-ordered.
‘Dms.encode` (full-mode round-trip) refuses Documents containing unordered tables — use `Dms.encode_lite` for canonical emit.
64 65 66 |
# File 'lib/dms.rb', line 64 def self.decode_document_unordered(src) Parser.parse_document_unordered(src) end |
.decode_front_matter(src) ⇒ Object
Front-matter-only decode (SPEC §Front-matter-only decode). Scans leading trivia + ‘+++` + contents + `+++` and stops; the body is not tokenized. Returns the front-matter Hash (empty when the FM block is empty), or nil when the document has no FM at all. In-FM diagnostics are byte-identical to a full decode and raise `Dms::DecodeError`. Required at tier 0 — there is no capability flag for this entry point.
82 83 84 |
# File 'lib/dms.rb', line 82 def self.decode_front_matter(src) Parser.parse_front_matter_only(src) end |
.decode_lite(src) ⇒ Object
Lite-mode decode: same data tree, no comment AST, no original_forms. Not suitable for ‘encode` round-trip. SPEC §Decoding modes — full and lite.
49 50 51 |
# File 'lib/dms.rb', line 49 def self.decode_lite(src) Parser.parse_lite_document(src).body end |
.decode_lite_document(src) ⇒ Object
53 54 55 |
# File 'lib/dms.rb', line 53 def self.decode_lite_document(src) Parser.parse_lite_document(src) end |
.decode_lite_document_unordered(src) ⇒ Object
Unordered lite-mode decode. The fastest read-only path: no comment AST, no original_forms, body tables built as ‘Dms::UnorderedHash` with shuffled key order. SPEC §“Unordered tables”.
71 72 73 |
# File 'lib/dms.rb', line 71 def self.decode_lite_document_unordered(src) Parser.parse_lite_document_unordered(src) end |
.encode(doc) ⇒ Object
Encode a parsed Document back to DMS source (SPEC §encode). Refuses Documents containing ‘Dms::UnorderedHash` — use `encode_lite` for canonical emit of unordered Documents.
89 90 91 |
# File 'lib/dms.rb', line 89 def self.encode(doc) Emitter._encode_full(doc) end |
.encode_lite(doc) ⇒ Object
Canonical-form emit. Drops comments and original_forms. Accepts both full-mode and lite-mode Documents. SPEC §encode.
95 96 97 |
# File 'lib/dms.rb', line 95 def self.encode_lite(doc) Emitter._encode_lite(doc) end |
.parse(src) ⇒ Object
121 122 123 124 |
# File 'lib/dms.rb', line 121 def self.parse(src) _warn_deprecated(:parse, :decode) decode(src) end |
.parse_document(src) ⇒ Object
126 127 128 129 |
# File 'lib/dms.rb', line 126 def self.parse_document(src) _warn_deprecated(:parse_document, :decode_document) decode_document(src) end |
.parse_document_unordered(src) ⇒ Object
141 142 143 144 |
# File 'lib/dms.rb', line 141 def self.parse_document_unordered(src) _warn_deprecated(:parse_document_unordered, :decode_document_unordered) decode_document_unordered(src) end |
.parse_lite(src) ⇒ Object
131 132 133 134 |
# File 'lib/dms.rb', line 131 def self.parse_lite(src) _warn_deprecated(:parse_lite, :decode_lite) decode_lite(src) end |
.parse_lite_document(src) ⇒ Object
136 137 138 139 |
# File 'lib/dms.rb', line 136 def self.parse_lite_document(src) _warn_deprecated(:parse_lite_document, :decode_lite_document) decode_lite_document(src) end |
.parse_lite_document_unordered(src) ⇒ Object
146 147 148 149 150 |
# File 'lib/dms.rb', line 146 def self.parse_lite_document_unordered(src) _warn_deprecated(:parse_lite_document_unordered, :decode_lite_document_unordered) decode_lite_document_unordered(src) end |
.supports_ignore_order ⇒ Object
Capability flag (SPEC §“Unordered tables”). True iff this port ships ‘decode_document_unordered` / `decode_lite_document_unordered` with spec-correct semantics. Callers probe before opting in.
102 103 104 |
# File 'lib/dms.rb', line 102 def self.supports_ignore_order true end |
.to_dms(doc) ⇒ Object
152 153 154 155 |
# File 'lib/dms.rb', line 152 def self.to_dms(doc) _warn_deprecated(:to_dms, :encode) encode(doc) end |
.to_dms_lite(doc) ⇒ Object
157 158 159 160 |
# File 'lib/dms.rb', line 157 def self.to_dms_lite(doc) _warn_deprecated(:to_dms_lite, :encode_lite) encode_lite(doc) end |