Skip to content

Add TOONDecoder#11

Merged
mattt merged 14 commits into
toon-format:mainfrom
alexey1312:alexey1312/TOONDecoder
Dec 5, 2025
Merged

Add TOONDecoder#11
mattt merged 14 commits into
toon-format:mainfrom
alexey1312:alexey1312/TOONDecoder

Conversation

@alexey1312
Copy link
Copy Markdown
Contributor

@alexey1312 alexey1312 commented Dec 3, 2025

Description

This PR adds TOONDecoder class for parsing TOON format data into Swift Decodable types, completing the full encode/decode cycle for TOON format in Swift. The decoder is ported from alexey1312/TOONDecoder and adapted to the ToonFormat package structure from #5.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test coverage improvement

Related Issues

Closes #6

Changes Made

  • Add TOONDecoder class with full TOON spec 3.0 compliance
  • Add TOONDecodingError enum with detailed error types
  • Add configurable DecodingLimits for security (maxDepth: 32, maxObjectKeys: 10,000, maxArrayLength: 100,000)
  • Add PathExpansion with .automatic mode as default (falls back gracefully on collision)
  • Add auto-detection of indentation size from input
  • Add toonSpecVersion constant for spec version declaration
  • Add comprehensive test suite covering all decoder features
  • Update README.md with round-trip example in Quick Start section

SPEC Compliance

  • This PR implements/fixes spec compliance
  • Spec section(s) affected: All sections (primitives, arrays, objects, tabular format, escape sequences)
  • Spec version: 3.0

Testing

  • All existing tests pass
  • Added new tests for changes
  • Tested on Swift 6.0
  • Tested on Swift 6.1
  • Tested on Swift 6.2

Test Output

$ swift test
...
Suite "TOONDecoder Tests" passed after 0.011 seconds.
Suite "TOONEncoder Tests" passed after 0.011 seconds.
Test run with 167 tests passed after 0.011 seconds.

Code Quality

  • Ran swift test - all tests pass
  • Ran swift-format - code follows format guidelines
  • Added documentation comments for public APIs
  • Code follows Swift conventions

Checklist

  • My code follows the project's coding standards
  • I have added documentation comments to new public APIs
  • I have added tests that prove my fix/feature works
  • New and existing tests pass locally
  • I have updated documentation (README.md if needed)
  • My changes do not introduce new dependencies (or are justified)
  • I have maintained Swift 6.0+ compatibility
  • I have reviewed the TOON specification for relevant sections

Performance Impact

  • No performance impact

Breaking Changes

  • No breaking changes

Screenshots / Examples

import ToonFormat

struct User: Codable {
    let id: Int
    let name: String
    let active: Bool
}

// Encoding
let user = User(id: 123, name: "Ada", active: true)
let encoder = TOONEncoder()
let data = try encoder.encode(user)

// Decoding
let decoder = TOONDecoder()
let decoded = try decoder.decode(User.self, from: data)

Tabular array decoding:

struct Item: Codable {
    let id: Int
    let name: String
    let price: Double
}

let toon = """
items[2]{id,name,price}:
  1,Widget,9.99
  2,Gadget,14.5
"""

struct Container: Codable { let items: [Item] }
let container = try decoder.decode(Container.self, from: toon.data(using: .utf8)!)

Additional Context

@alexey1312 alexey1312 requested a review from mattt as a code owner December 3, 2025 04:31
@mattt mattt mentioned this pull request Dec 3, 2025
21 tasks
Comment thread .github/workflows/ci.yml
Copy link
Copy Markdown
Collaborator

@mattt mattt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for re-opening this, @alexey1312. I left a few comments about the implementation, but this is looking really good.

Comment thread Package.swift Outdated
Comment thread README.md
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread Sources/TOONDecoder/TOONDecoder.swift Outdated
Comment thread Sources/TOONDecoder/TOONDecoder.swift Outdated
Comment thread Sources/TOONDecoder/TOONDecoder.swift Outdated
Comment thread Sources/TOONDecoder/TOONDecoder.swift Outdated
Comment thread Sources/TOONDecoder/TOONDecoder.swift Outdated
@alexey1312 alexey1312 force-pushed the alexey1312/TOONDecoder branch 2 times, most recently from ce7f3ba to d5e3d27 Compare December 3, 2025 14:25
@alexey1312 alexey1312 requested a review from mattt December 3, 2025 14:33
# Conflicts:
#	.github/workflows/ci.yml
- Remove configurable indent property; auto-detect from first indented line
- Add .automatic path expansion mode as new default (falls back on collision)
- Consolidate specVersion into top-level toonSpecVersion constant
- Remove separate TOONEncoder/TOONDecoder library exports from Package.swift
- Reduce default maxDepth from 128 to 32 for stack safety
- Simplify README with unified quick start example
@alexey1312 alexey1312 force-pushed the alexey1312/TOONDecoder branch from d5e3d27 to 9a89d7e Compare December 5, 2025 04:46
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds comprehensive TOON format decoding capabilities to the Swift package, completing the encode/decode cycle. The decoder is ported from an external repository and adapted to work alongside the existing TOONEncoder, with full TOON specification 3.0 compliance.

Key Changes:

  • Added TOONDecoder class with support for all TOON format features including tabular arrays, path expansion, and configurable security limits
  • Extracted shared Value enum and IndexedCodingKey to a separate Value.swift file for reuse between encoder and decoder
  • Added toonSpecVersion constant in Version.swift to replace the encoder-specific TOONEncoder.specVersion

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
Sources/ToonFormat/Version.swift New file defining the shared toonSpecVersion constant ("3.0")
Sources/ToonFormat/Value.swift New file with extracted Value enum (intermediate representation) and IndexedCodingKey struct, now shared between encoder and decoder
Sources/ToonFormat/Decoder.swift New comprehensive decoder implementation with parser, error types, decoding containers, and security limits
Sources/ToonFormat/Encoder.swift Refactored to use shared Value enum from Value.swift; improved documentation; made String extension internal (previously private)
Tests/ToonFormatTests/EncoderTests.swift Updated test suite name from "TOONEncoder Tests" to "Encoder Tests" and changed version check to use toonSpecVersion
Tests/ToonFormatTests/DecoderTests.swift New comprehensive test suite with 167 tests covering primitives, objects, arrays, path expansion, round-trip encoding/decoding, error cases, and security limits
README.md Updated with decoder features, round-trip usage examples, decoding limits configuration, and updated package version to 0.3.0
Package.swift Removed boilerplate comments for cleaner appearance
Comments suppressed due to low confidence (1)

Sources/ToonFormat/Encoder.swift:1453

  • Inconsistent access control modifiers in String extension. The properties isNumericLike and isPaddedWithWhitespace are marked fileprivate (lines 1378, 1387), while escaped, isSafeUnquoted, isValidUnquotedKey, and isValidIdentifierSegment (lines 1369, 1391, 1441, 1447) have no explicit modifier and default to internal. Since these methods are only used within the Encoder file, they should all be consistently marked as fileprivate to prevent accidental usage from other files in the module.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Sources/ToonFormat/Value.swift
Copy link
Copy Markdown
Collaborator

@mattt mattt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic work on this, @alexey1312! I'm extremely happy with how all of this turned out. Thank you so much for your help. I think our Swift implementation stacks up quite favorably to the others.

@mattt mattt enabled auto-merge (squash) December 5, 2025 10:34
@mattt
Copy link
Copy Markdown
Collaborator

mattt commented Dec 5, 2025

Requesting a review from @johannschopplich since I was the last pusher and my review isn't sufficient for merging this PR.

Copy link
Copy Markdown
Contributor

@johannschopplich johannschopplich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@mattt Actually, I'm not sure my review is sufficient either. If you mean the PR review requirements – I have set it to 0. So you can merge your own PRs and others, since you are the sole maintainer of the community-driven implementation. I'm only here for governance on some core files or README changes. :)

@mattt mattt merged commit 8ee0041 into toon-format:main Dec 5, 2025
6 checks passed
@alexey1312 alexey1312 deleted the alexey1312/TOONDecoder branch December 5, 2025 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TOON Decoder

4 participants