Skip to content

Commit 7f74155

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/recursion-protection
# Conflicts: # Sources/ToonFormat/Decoder.swift
2 parents 2afb0bb + d17c428 commit 7f74155

6 files changed

Lines changed: 443 additions & 383 deletions

File tree

README.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,18 @@
55
[![SPEC v3.0](https://img.shields.io/badge/spec-v3.0-fef3c0?labelColor=1b1b1f)](https://github.com/toon-format/spec)
66
[![License: MIT](https://img.shields.io/badge/license-MIT-fef3c0?labelColor=1b1b1f)](./LICENSE.md)
77

8-
Compact, human-readable serialization format for LLM contexts with **30-60% token reduction** vs JSON. Combines YAML-like indentation with CSV-like tabular arrays. Full compatibility with the [official TOON specification](https://github.com/toon-format/spec).
9-
10-
**Key Features:** Minimal syntax • Tabular arrays for uniform data • Array length validation • Swift 6.0+ • Configurable delimiters • Key folding / Path expansion support • Linux compatible.
8+
Compact, human-readable serialization format for LLM contexts with **30-60% token reduction** vs JSON.
9+
Combines YAML-like indentation with CSV-like tabular arrays.
10+
Full compatibility with the [official TOON specification](https://github.com/toon-format/spec).
11+
12+
**Key Features:**
13+
Minimal syntax •
14+
Tabular arrays for uniform data •
15+
Array length validation •
16+
Swift 6.0+ •
17+
Configurable delimiters •
18+
Key folding / Path expansion support •
19+
Linux compatibility.
1120

1221
LLM tokens are expensive, and JSON is verbose.
1322
TOON saves tokens while remaining human-readable by
@@ -283,7 +292,11 @@ print(toonSpecVersion) // "3.0"
283292

284293
## Contributing
285294

286-
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on how to get started, coding standards, and the process for submitting pull requests.
295+
Contributions are welcome!
296+
Please read our [Contributing Guide](CONTRIBUTING.md) for
297+
details on how to get started,
298+
coding standards,
299+
and the process for submitting pull requests.
287300

288301
Before contributing, please review:
289302

@@ -292,11 +305,14 @@ Before contributing, please review:
292305

293306
## Code of Conduct
294307

295-
This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to hello@johannschopplich.com.
308+
This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md).
309+
By participating, you are expected to uphold this code.
310+
Please report unacceptable behavior to hello@johannschopplich.com.
296311

297312
## Project Status
298313

299-
This library implements **TOON specification version 3.0** (2025-11-24) with full encoding and decoding support.
314+
This library implements **TOON specification version 3.0** (2025-11-24)
315+
with full encoding and decoding support.
300316

301317
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
302318

Sources/ToonFormat/Decoder.swift

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,23 +1723,23 @@ private func decodeUInt32(from value: Value) throws -> UInt32 {
17231723
return result
17241724
}
17251725

1726-
private func decodeUInt64(from value: Value) throws -> UInt64 {
1727-
// Try integer path first
1728-
if let intValue = value.intValue {
1729-
guard let result = UInt64(exactly: intValue) else {
1730-
throw TOONDecodingError.dataCorrupted("Value \(intValue) does not fit in UInt64")
1731-
}
1732-
return result
1733-
}
1734-
1735-
// Try string path (for large UInt64s)
1736-
if let stringValue = value.stringValue, let result = UInt64(stringValue) {
1737-
return result
1726+
private func decodeUInt64(from value: Value) throws -> UInt64 {
1727+
// Try integer path first
1728+
if let intValue = value.intValue {
1729+
guard let result = UInt64(exactly: intValue) else {
1730+
throw TOONDecodingError.dataCorrupted("Value \(intValue) does not fit in UInt64")
17381731
}
1732+
return result
1733+
}
17391734

1740-
throw TOONDecodingError.typeMismatch(expected: "uint64", actual: value.typeName)
1735+
// Try string path (for large UInt64s)
1736+
if let stringValue = value.stringValue, let result = UInt64(stringValue) {
1737+
return result
17411738
}
17421739

1740+
throw TOONDecodingError.typeMismatch(expected: "uint64", actual: value.typeName)
1741+
}
1742+
17431743
// MARK: -
17441744

17451745
private extension String {

Tests/ToonFormatTests/BugHuntingTests.swift

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,45 +23,7 @@ extension Value: Encodable {
2323

2424
final class BugHuntingTests: XCTestCase {
2525

26-
// MARK: - 1. Dictionary Non-Determinism in Value.from
27-
28-
func testValueFromDictionaryKeyOrder() {
29-
// Create a dictionary with enough keys to have a high probability of random ordering
30-
let dict: [String: Any] = [
31-
"z": 1, "a": 2, "m": 3, "c": 4, "k": 5, "b": 6, "y": 7
32-
]
33-
34-
// This relies on Value.from which takes [String: Any]
35-
let value = Value.from(dict)
36-
37-
guard case .object(_, let keyOrder) = value else {
38-
XCTFail("Value.from(dict) should return .object")
39-
return
40-
}
41-
42-
let sortedKeys = keyOrder.sorted()
43-
44-
// Assert that keys are sorted. If checks fail, it confirms non-deterministic behavior.
45-
// XCTAssertEqual(keyOrder, sortedKeys, "Value.from produced unsorted keys")
46-
}
47-
48-
// MARK: - 2. Double Negative Zero
49-
50-
func testNegativeZeroEncoding() throws {
51-
/*
52-
let negativeZero: Double = -0.0
53-
let encoder = TOONEncoder()
54-
55-
// Encode directly
56-
let data = try encoder.encode(["value": negativeZero])
57-
let string = String(data: data, encoding: .utf8)!
58-
59-
print("Encoded Negative Zero: \(string)")
60-
61-
// Expect strict -0 preservation or at least consistent float representation
62-
XCTAssertTrue(string.contains("-0"), "Negative zero sign lost: \(string)")
63-
*/
64-
}
26+
6527

6628
// MARK: - 3. Recursion Limit (Stack Overflow)
6729

0 commit comments

Comments
 (0)