twilic 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.editorconfig +18 -0
- data/.gitattributes +1 -0
- data/.gitignore +9 -0
- data/.markdownlint.jsonc +22 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +53 -0
- data/LICENSE +21 -0
- data/README.md +119 -0
- data/Rakefile +12 -0
- data/docs/CHANGELOG.md +31 -0
- data/docs/CONTRIBUTING.md +51 -0
- data/docs/SPEC-TEST-TRACEABILITY.md +87 -0
- data/lib/twilic/core/api.rb +30 -0
- data/lib/twilic/core/codec.rb +766 -0
- data/lib/twilic/core/dictionary.rb +236 -0
- data/lib/twilic/core/errors.rb +87 -0
- data/lib/twilic/core/interop_fixtures.rb +340 -0
- data/lib/twilic/core/model.rb +506 -0
- data/lib/twilic/core/protocol.rb +2044 -0
- data/lib/twilic/core/protocol_helpers.rb +512 -0
- data/lib/twilic/core/session.rb +461 -0
- data/lib/twilic/core/v2.rb +387 -0
- data/lib/twilic/core/wire.rb +158 -0
- data/lib/twilic/version.rb +5 -0
- data/lib/twilic.rb +147 -0
- data/package.json +14 -0
- data/pnpm-lock.yaml +723 -0
- data/twilic.gemspec +32 -0
- metadata +118 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 77255a004384acecbf760c61ac408ed7b68e2c7fc024fe531eaa12d22a98871f
|
|
4
|
+
data.tar.gz: '06395f1bc4a676a50b35d7579a9840f27ce344b7dd67ac5043dcb3864dd989de'
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8a7c06ce15e75fbeb76a8b0c71fd7d652accb1a2e1fe2033eb4bcae7c458be638918850daad0780a8cce27d6ee6ef20de2e74736923b190c25b9a8df1558acbb
|
|
7
|
+
data.tar.gz: 83f906d9fd124badec3bcb963aa0c9e9279012dd46dfd435872b63d29518e5c5598cc8ea2c39b22fc0ce2ac53f3bc0b37ecaac9acfe52d2333ee3782f3b60212
|
data/.editorconfig
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*.{rb,rake,yml,yaml,md,sh}]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
insert_final_newline = true
|
|
7
|
+
trim_trailing_whitespace = true
|
|
8
|
+
|
|
9
|
+
[*.{rb,rake}]
|
|
10
|
+
indent_style = space
|
|
11
|
+
indent_size = 2
|
|
12
|
+
|
|
13
|
+
[*.{yml,yaml,md,sh}]
|
|
14
|
+
indent_style = space
|
|
15
|
+
indent_size = 2
|
|
16
|
+
|
|
17
|
+
[*.md]
|
|
18
|
+
trim_trailing_whitespace = false
|
data/.gitattributes
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* text=auto eol=lf
|
data/.gitignore
ADDED
data/.markdownlint.jsonc
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"default": true,
|
|
3
|
+
"MD013": false,
|
|
4
|
+
"MD004": {
|
|
5
|
+
"style": "dash"
|
|
6
|
+
},
|
|
7
|
+
"MD007": {
|
|
8
|
+
"indent": 2
|
|
9
|
+
},
|
|
10
|
+
"MD029": {
|
|
11
|
+
"style": "ordered"
|
|
12
|
+
},
|
|
13
|
+
"MD031": true,
|
|
14
|
+
"MD032": true,
|
|
15
|
+
"MD040": true,
|
|
16
|
+
"MD046": {
|
|
17
|
+
"style": "fenced"
|
|
18
|
+
},
|
|
19
|
+
"MD024": {
|
|
20
|
+
"siblings_only": true
|
|
21
|
+
}
|
|
22
|
+
}
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
twilic (3.0.0)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
ast (2.4.3)
|
|
10
|
+
json (2.19.5)
|
|
11
|
+
language_server-protocol (3.17.0.5)
|
|
12
|
+
lint_roller (1.1.0)
|
|
13
|
+
minitest (5.27.0)
|
|
14
|
+
parallel (2.1.0)
|
|
15
|
+
parser (3.3.11.1)
|
|
16
|
+
ast (~> 2.4.1)
|
|
17
|
+
racc
|
|
18
|
+
prism (1.9.0)
|
|
19
|
+
racc (1.8.1)
|
|
20
|
+
rainbow (3.1.1)
|
|
21
|
+
rake (13.4.2)
|
|
22
|
+
regexp_parser (2.12.0)
|
|
23
|
+
rubocop (1.86.2)
|
|
24
|
+
json (~> 2.3)
|
|
25
|
+
language_server-protocol (~> 3.17.0.2)
|
|
26
|
+
lint_roller (~> 1.1.0)
|
|
27
|
+
parallel (>= 1.10)
|
|
28
|
+
parser (>= 3.3.0.2)
|
|
29
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
30
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
31
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
32
|
+
ruby-progressbar (~> 1.7)
|
|
33
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
34
|
+
rubocop-ast (1.49.1)
|
|
35
|
+
parser (>= 3.3.7.2)
|
|
36
|
+
prism (~> 1.7)
|
|
37
|
+
ruby-progressbar (1.13.0)
|
|
38
|
+
unicode-display_width (3.2.0)
|
|
39
|
+
unicode-emoji (~> 4.1)
|
|
40
|
+
unicode-emoji (4.2.0)
|
|
41
|
+
|
|
42
|
+
PLATFORMS
|
|
43
|
+
arm64-darwin-24
|
|
44
|
+
ruby
|
|
45
|
+
|
|
46
|
+
DEPENDENCIES
|
|
47
|
+
minitest (~> 5.25)
|
|
48
|
+
rake (~> 13.2)
|
|
49
|
+
rubocop (~> 1.69)
|
|
50
|
+
twilic!
|
|
51
|
+
|
|
52
|
+
BUNDLED WITH
|
|
53
|
+
2.5.23
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Twilic (maintained by Minagishl)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Twilic (Ruby)
|
|
2
|
+
|
|
3
|
+
Ruby implementation of the Twilic wire format and session-aware encoder/decoder.
|
|
4
|
+
|
|
5
|
+
This gem's default `Twilic.encode` / `Twilic.decode` API targets Twilic v2.
|
|
6
|
+
|
|
7
|
+
## What this gem provides
|
|
8
|
+
|
|
9
|
+
- Dynamic encoding/decoding (`Twilic.encode`, `Twilic.decode`)
|
|
10
|
+
- Schema-aware encoding (`Twilic.encode_with_schema`)
|
|
11
|
+
- Batch and micro-batch encoding (`Twilic.encode_batch`, `SessionEncoder#encode_micro_batch`)
|
|
12
|
+
- Stateful features (base snapshots, state patch, template batch, control stream, trained dictionary)
|
|
13
|
+
|
|
14
|
+
## Project layout
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
twilic-ruby/
|
|
18
|
+
lib/twilic.rb # public API
|
|
19
|
+
lib/twilic/core/ # wire, model, codec, session, protocol, v2
|
|
20
|
+
scripts/ # Rust interop fixtures and smoke checks
|
|
21
|
+
docs/
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The repository root stays thin: `require "twilic"` only. Implementation details live under `lib/twilic/core/`, similar to `internal/core/` in the Go module.
|
|
25
|
+
|
|
26
|
+
## Requirements
|
|
27
|
+
|
|
28
|
+
- Ruby 3.3 or later
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
gem install twilic
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or add to your Gemfile:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
gem "twilic"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick start
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
require "twilic"
|
|
46
|
+
|
|
47
|
+
value = Twilic.map(
|
|
48
|
+
"id" => Twilic.u64(1001),
|
|
49
|
+
"name" => Twilic.string("alice")
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
bytes = Twilic.encode(value)
|
|
53
|
+
decoded = Twilic.decode(bytes)
|
|
54
|
+
puts Twilic.equal(decoded, value) # => true
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Session encoder example
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
require "twilic"
|
|
61
|
+
|
|
62
|
+
enc = Twilic.new_session_encoder
|
|
63
|
+
|
|
64
|
+
value = Twilic.map(
|
|
65
|
+
"id" => Twilic.u64(1),
|
|
66
|
+
"role" => Twilic.string("admin")
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
bytes = enc.encode(value)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Development
|
|
73
|
+
|
|
74
|
+
Run checks locally:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
bundle install
|
|
78
|
+
bundle exec rake test
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Rust client interop smoke check (Ruby server -> Rust client):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
bash scripts/check-rust-client-interop.sh
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Ruby client interop smoke check (Rust server -> Ruby client):
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
bash scripts/check-ruby-client-interop.sh
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Run both directions:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
bash scripts/check-interop.sh
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Note: these scripts expect `../twilic-rust` to exist as a sibling directory.
|
|
100
|
+
|
|
101
|
+
## Markdown formatting
|
|
102
|
+
|
|
103
|
+
Documentation is formatted and linted with Prettier and markdownlint (see [`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md)).
|
|
104
|
+
|
|
105
|
+
## CI and release (GitHub Actions)
|
|
106
|
+
|
|
107
|
+
- CI workflow: `.github/workflows/ci.yml`
|
|
108
|
+
- Interop workflow: `.github/workflows/interop.yml`
|
|
109
|
+
- Release workflow: `.github/workflows/publish-gem.yml` (tag `v*` must match `lib/twilic/version.rb`)
|
|
110
|
+
|
|
111
|
+
## Spec parity
|
|
112
|
+
|
|
113
|
+
This gem mirrors the Twilic wire format spec at [twilic/twilic](https://github.com/twilic/twilic) and stays in lockstep with the [Rust](https://github.com/twilic/twilic-rust), [Go](https://github.com/twilic/twilic-go), and [Zig](https://github.com/twilic/twilic-zig) reference implementations.
|
|
114
|
+
|
|
115
|
+
See [`docs/SPEC-TEST-TRACEABILITY.md`](docs/SPEC-TEST-TRACEABILITY.md) for the spec-section to test mapping.
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
data/Rakefile
ADDED
data/docs/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [3.0.0] - 2026-05-24
|
|
10
|
+
|
|
11
|
+
Initial public release of the Ruby implementation of Twilic, tracking the v3 release line shared with [twilic-rust](https://github.com/twilic/twilic-rust) and [twilic-js](https://github.com/twilic/twilic-js).
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Core wire format with dynamic `Value` model and `Encode` / `Decode` APIs.
|
|
16
|
+
- Schema-aware encoding (`encode_with_schema`), batch encoding (`encode_batch`), and session-based micro-batch and patch support.
|
|
17
|
+
- Stateful transport features: base snapshots, state patch encoding, template batch handling, control stream support, and trained dictionary support.
|
|
18
|
+
- Public gem API at `Twilic` with implementation under `lib/twilic/core/`.
|
|
19
|
+
- Spec conformance tests and traceability mapping in [`docs/SPEC-TEST-TRACEABILITY.md`](SPEC-TEST-TRACEABILITY.md).
|
|
20
|
+
- Rust interop fixture stream, value parity tests, and bidirectional smoke scripts under `scripts/`.
|
|
21
|
+
- Interop helpers in `lib/twilic/core/interop_fixtures.rb` for cross-language fixture emission and decoding.
|
|
22
|
+
- GitHub Actions workflows for CI, Interop, commitlint, invisible character check, PR message validation, and tagged gem publish via RubyGems Trusted Publishing (OIDC).
|
|
23
|
+
- GitHub issue templates, pull request template, and contributor documentation.
|
|
24
|
+
- Markdown formatting with Prettier and markdownlint.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- PR Message Check: skip template validation for Dependabot pull requests.
|
|
29
|
+
|
|
30
|
+
[unreleased]: https://github.com/twilic/twilic-ruby/compare/v3.0.0...HEAD
|
|
31
|
+
[3.0.0]: https://github.com/twilic/twilic-ruby/releases/tag/v3.0.0
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for improving the Twilic Ruby implementation.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
This gem implements the Twilic wire format and session-aware encoder/decoder. Keep changes aligned with the normative spec in [twilic/twilic](https://github.com/twilic/twilic).
|
|
8
|
+
|
|
9
|
+
## Development
|
|
10
|
+
|
|
11
|
+
Requirements:
|
|
12
|
+
|
|
13
|
+
- Ruby 3.3 or later
|
|
14
|
+
- Bundler
|
|
15
|
+
|
|
16
|
+
Implementation code belongs in `lib/twilic/core/`. The repository root (`lib/twilic.rb`) re-exports the stable public API.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bundle install
|
|
20
|
+
bundle exec rake test
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Markdown in this repository is formatted with Prettier and linted with markdownlint (same tooling as [twilic/twilic](https://github.com/twilic/twilic)):
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm install
|
|
27
|
+
pnpm format # write
|
|
28
|
+
pnpm format:check # CI check
|
|
29
|
+
pnpm lint # markdownlint
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Interop scripts under `scripts/` expect `../twilic-rust` as a sibling clone. They verify Rust and Ruby decode the same logical values and that `bundle exec rake test TEST=test/twilic/core/interop_fixtures_test.rb` passes (encode/decode roundtrip, wire parity, and cross-language value checks).
|
|
33
|
+
|
|
34
|
+
## Commit Messages
|
|
35
|
+
|
|
36
|
+
We follow [Conventional Commits](https://www.conventionalcommits.org/).
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
|
|
40
|
+
- `feat: add FOR bitpack vector codec`
|
|
41
|
+
- `fix(session): reset intern table on control frame`
|
|
42
|
+
|
|
43
|
+
## Contribution Checklist
|
|
44
|
+
|
|
45
|
+
- Tests added or updated for behavior changes
|
|
46
|
+
- `bundle exec rake test` passes locally
|
|
47
|
+
- `pnpm format:check` and `pnpm lint` pass when Markdown changes
|
|
48
|
+
- Interop fixtures updated when wire behavior changes
|
|
49
|
+
- Commit messages follow Conventional Commits
|
|
50
|
+
|
|
51
|
+
By contributing to this repository, you agree that your contribution may be distributed under the MIT license used by the project.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# SPEC Test Traceability (5/6/8/10/13/15/18)
|
|
2
|
+
|
|
3
|
+
This file maps `twilic/SPEC.md` requirements to Ruby tests in `twilic-ruby`.
|
|
4
|
+
|
|
5
|
+
## 5. Dynamic Profile
|
|
6
|
+
|
|
7
|
+
| SPEC section | Requirement (short) | Tests |
|
|
8
|
+
| --------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| 5.2 key table | First key literal, later key ref by id | `DynamicProfileSpecTest#test_two_field_map_keeps_map_and_uses_key_ids` |
|
|
10
|
+
| 5.3 shape table | Repeated shape registration/promotion behavior | `DynamicProfileSpecTest#test_shape_promotes_after_second_three_field_map` |
|
|
11
|
+
| 5.4 MAP | Map roundtrip and key-ref decode behavior | `DynamicProfileSpecTest#test_two_field_map_keeps_map_and_uses_key_ids`, `TwilicTest#test_codec_roundtrip_dynamic_value` |
|
|
12
|
+
| 5.5 ARRAY | ARRAY vs typed vector threshold behavior | `DynamicProfileSpecTest#test_typed_vector_threshold_is_applied` |
|
|
13
|
+
|
|
14
|
+
## 6. Bound Profile
|
|
15
|
+
|
|
16
|
+
| SPEC section | Requirement (short) | Tests |
|
|
17
|
+
| ----------------- | --------------------------------------- | ----------------- |
|
|
18
|
+
| 6.1 schema | Required field handling, schema decode | _not yet covered_ |
|
|
19
|
+
| 6.2 schema_id | Emit on first use, omit in same context | _not yet covered_ |
|
|
20
|
+
| 6.3 SCHEMA_OBJECT | Schema object message roundtrip | _not yet covered_ |
|
|
21
|
+
|
|
22
|
+
## 8. Numeric Encoding
|
|
23
|
+
|
|
24
|
+
| SPEC section | Requirement (short) | Tests |
|
|
25
|
+
| --------------------------- | ------------------------------------------------------------------------- | ----------------- |
|
|
26
|
+
| 8.1 scalar integer | Zigzag/varuint scalar integer behavior | _not yet covered_ |
|
|
27
|
+
| 8.2 range-aware bit packing | Bounded integer handling in schema context with fixed-width range offsets | _not yet covered_ |
|
|
28
|
+
| 8.4 vector integer codecs | Plain/direct/delta/FOR/delta-FOR/delta-delta/RLE/patched/Simple8b | _not yet covered_ |
|
|
29
|
+
| 8.5 float vector codecs | XOR float vs plain behavior | _not yet covered_ |
|
|
30
|
+
|
|
31
|
+
## 10. Strings
|
|
32
|
+
|
|
33
|
+
| SPEC section | Requirement (short) | Tests |
|
|
34
|
+
| --------------------------- | --------------------------------------------------- | ----------------- |
|
|
35
|
+
| 10.2 LITERAL | Literal mode encode/decode | _not yet covered_ |
|
|
36
|
+
| 10.3 REF | String ref reuse behavior | _not yet covered_ |
|
|
37
|
+
| 10.4 PREFIX_DELTA | Prefix-delta mode encode/decode | _not yet covered_ |
|
|
38
|
+
| 10.5 string table | Reset clears string table state | _not yet covered_ |
|
|
39
|
+
| 10.6 field-local dictionary | String dictionary/ref behavior in column codec path | _not yet covered_ |
|
|
40
|
+
| 10.8 INLINE_ENUM | Control-driven enum promotion path | _not yet covered_ |
|
|
41
|
+
|
|
42
|
+
## 13. Batch / Stateful Extensions
|
|
43
|
+
|
|
44
|
+
| SPEC section | Requirement (short) | Tests |
|
|
45
|
+
| ----------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
46
|
+
| 13.1 ROW_BATCH | Small batch uses row batch | _not yet covered_ |
|
|
47
|
+
| 13.2 COLUMN_BATCH | Large batch uses column batch and null strategy paths | _not yet covered_ |
|
|
48
|
+
| 13.5.1 session state | Unknown reference policy behavior (base/template/dict families) | `TwilicTest#test_unknown_reference_policy_supports_stateless_retry` |
|
|
49
|
+
| 13.5.2 BASE_SNAPSHOT | Snapshot registration/reference | `InteropFixturesTest#test_codec_encode_decode_roundtrip` |
|
|
50
|
+
| 13.5.3 STATE_PATCH | Patch roundtrip and bounds checks | `TwilicTest#test_session_patch_and_micro_batch`, `InteropFixturesTest#test_session_encode_decode_roundtrip` |
|
|
51
|
+
| 13.5.4 previous-message patch | Previous-message patch selection | _not yet covered_ |
|
|
52
|
+
| 13.5.5 TEMPLATE_BATCH | Template create/reuse and changed mask | `TwilicTest#test_session_patch_and_micro_batch`, `InteropFixturesTest#test_session_encode_decode_roundtrip` |
|
|
53
|
+
| 13.5.6 CONTROL_STREAM | Plain/RLE/Bitpack/Huffman/Fse paths and compaction behavior | `InteropFixturesTest#test_decode_rust_server_frames` |
|
|
54
|
+
| 13.5.7 trained dictionary | Dictionary id assignment and `dict_id + compressed block` path in column encoding | _not yet covered_ |
|
|
55
|
+
| 13.5.8 RESET_STATE | Reset clears tables/state references | _not yet covered_ |
|
|
56
|
+
|
|
57
|
+
## 18. Encoder Auto-Selection Rules
|
|
58
|
+
|
|
59
|
+
| Rule cluster | Requirement (short) | Tests |
|
|
60
|
+
| ------------------------ | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
61
|
+
| Dynamic map/shape rules | Repeated-shape promotion, map fallback, key refs | `DynamicProfileSpecTest#test_shape_promotes_after_second_three_field_map`, `DynamicProfileSpecTest#test_two_field_map_keeps_map_and_uses_key_ids` |
|
|
62
|
+
| Typed vector rules | Array cardinality/type based vectorization | `DynamicProfileSpecTest#test_typed_vector_threshold_is_applied` |
|
|
63
|
+
| String mode rules | Empty/literal/ref/prefix-delta transitions | _not yet covered_ |
|
|
64
|
+
| Batch selection rules | Row vs column threshold, micro-batch shape requirement | _not yet covered_ |
|
|
65
|
+
| Stateful patch threshold | Prefer patch only at low change ratio | _not yet covered_ |
|
|
66
|
+
| Numeric codec choice | i64/u64/float codec heuristics | _not yet covered_ |
|
|
67
|
+
|
|
68
|
+
## 15. Trained Dictionary Transport
|
|
69
|
+
|
|
70
|
+
| SPEC section | Requirement (short) | Tests |
|
|
71
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------------ | ----------------- |
|
|
72
|
+
| 15.4 trained dictionary transport | Dictionary transport carries id/version/hash/invalidation/fallback metadata and validates payload hash | _not yet covered_ |
|
|
73
|
+
|
|
74
|
+
## Interop Coverage
|
|
75
|
+
|
|
76
|
+
| Area | Tests |
|
|
77
|
+
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
|
|
78
|
+
| Ruby fixture encode/decode roundtrip | `InteropFixturesTest#test_codec_encode_decode_roundtrip`, `InteropFixturesTest#test_session_encode_decode_roundtrip` |
|
|
79
|
+
| Rust server -> Ruby client | `InteropFixturesTest#test_decode_rust_server_frames`, `scripts/check-ruby-client-interop.sh` |
|
|
80
|
+
| Ruby server -> Rust client | `InteropFixturesTest#test_rust_decodes_ruby_frames_with_same_values`, `scripts/check-rust-client-interop.sh` |
|
|
81
|
+
|
|
82
|
+
## Current Gaps (explicit)
|
|
83
|
+
|
|
84
|
+
- Most bound-profile, numeric codec, string mode, batch selection, and trained-dictionary spec sections are not yet covered by dedicated Ruby tests.
|
|
85
|
+
- Optional-only extension note: Section 6.4 (zero-copy layout) is not implemented as a conformance target.
|
|
86
|
+
- Optional-only extension note: Section 10.7 (static dictionary) is not implemented as a conformance target.
|
|
87
|
+
- Rust-dependent interop tests skip when `twilic-rust` is not checked out (expected `../twilic-rust` sibling or `TWILIC_RUST_ROOT`).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "twilic/core/v2"
|
|
4
|
+
require "twilic/core/protocol"
|
|
5
|
+
|
|
6
|
+
module Twilic
|
|
7
|
+
module Core
|
|
8
|
+
module API
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def encode(value)
|
|
12
|
+
V2.encode_v2(value)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def decode(bytes)
|
|
16
|
+
V2.decode_v2(bytes)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def encode_with_schema(schema, value)
|
|
20
|
+
enc = Protocol::SessionEncoder.new(Session::SessionOptions.default)
|
|
21
|
+
enc.encode_with_schema(schema, value)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def encode_batch(values)
|
|
25
|
+
enc = Protocol::SessionEncoder.new(Session::SessionOptions.default)
|
|
26
|
+
enc.encode_batch(values)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|