diego-ninja/cartoon

High-performance TOON (Token-Oriented Object Notation) encoder/decoder for PHP 8.4+

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/diego-ninja/cartoon

v1.0.0 2025-11-19 01:14 UTC

This package is auto-updated.

Last update: 2025-11-19 01:24:50 UTC


README

High-performance PHP 8.4+ library for encoding and decoding TOON (Token-Oriented Object Notation) format with full spec compliance.

Latest Version on Packagist Total Downloads PHP Version License: MIT GitHub last commit wakatime Tests Static Analysis Code Style Coveralls

Features

  • ๐Ÿš€ High Performance: AST-based parser with JIT optimization
  • ๐ŸŽฏ Spec Compliant: Full adherence to TOON specification
  • ๐Ÿ”’ Type Safe: PHPStan level 10, strict types throughout
  • ๐Ÿงช Well Tested: 95%+ code coverage
  • ๐ŸŽจ Modern PHP: Leverages PHP 8.4+ features (readonly, enums, union types)
  • ๐Ÿ“ฆ Zero Dependencies: No runtime dependencies

Installation

composer require diego-ninja/cartoon

Requirements: PHP 8.4 or higher

Quick Start

Decoding TOON to PHP

use Ninja\Cartoon\Toon;

$toon = <<<TOON
name: Alice
age: 30
active: true
TOON;

$data = Toon::decode($toon); //or
$data = toon_decode($toon);
// ['name' => 'Alice', 'age' => 30, 'active' => true]

Encoding PHP to TOON

use Ninja\Cartoon\Toon;

$data = [
    'name' => 'Bob',
    'age' => 25,
    'tags' => ['php', 'toon', 'awesome'],
];

$toon = Toon::encode($data); //or
$toon = toon_encode($data)

Output:

name: Bob
age: 25
tags[3]: php,toon,awesome

Advanced Usage

Custom Encoding Options

use Ninja\Cartoon\{EncodeOptions,Enum\DelimiterType,Enum\IndentationType,Toon};

$options = new EncodeOptions(
    preferredDelimiter: DelimiterType::Tab,
    indentSize: 4,
    indentationType: IndentationType::Tabs,
    maxCompactArrayLength: 20,
);

$toon = Toon::encode($data, $options);

Custom Decoding Options

use Ninja\Cartoon\{Toon, DecodeOptions};

$options = new DecodeOptions(
    strict: false,              // Allow non-canonical input
    preserveKeyOrder: true,     // Maintain key order
);

$data = Toon::decode($toon, $options);

Strict vs Permissive Mode

Strict mode (default):

  • Validates array lengths exactly
  • Requires canonical number format
  • Enforces consistent indentation

Permissive mode:

  • Tolerates array length mismatches
  • Accepts non-canonical numbers
  • Allows mixed indentation

TOON Format Overview

TOON is a line-oriented, indentation-based format encoding the JSON data model:

Objects:

name: Alice
age: 30

Arrays:

items[3]: a,b,c

Nested structures:

user:
  name: Bob
  address:
    city: NYC

Tabular data:

users[2]{id,name}:
1,Alice
2,Bob

See the official spec for complete details.

Development

Setup

git clone https://github.com/diego-ninja/cartoon.git
cd cartoon
composer install

Running Tests

# All tests
vendor/bin/phpunit

# With coverage
vendor/bin/phpunit --coverage-html coverage

# Specific test suite
vendor/bin/phpunit tests/Unit
vendor/bin/phpunit tests/Integration

Code Quality

# PHPStan (level 10)
vendor/bin/phpstan analyse

# PHP-CS-Fixer (PER coding style)
vendor/bin/php-cs-fixer fix

# All checks
composer test
composer analyze
composer fix

Error Handling

The library provides specific exceptions for different error cases:

  • SyntaxException: Invalid TOON syntax
  • ValidationException: Spec violations in strict mode
  • EscapeException: Invalid escape sequences
  • UnencodableException: PHP value cannot be encoded (resources, INF, NAN)
  • CircularReferenceException: Circular reference detected

All exceptions extend ToonException for easy catching.

Limitations

  • Multi-line strings: Not supported (TOON spec doesn't allow them)
  • Special floats: INF, -INF, NAN cannot be encoded
  • Control characters: Only \n, \r, \t can be escaped
  • Resources: Cannot be encoded
  • Closures: Cannot be encoded

Contributing

Contributions welcome! Please:

  1. Follow PER coding style
  2. Add tests for new features
  3. Ensure PHPStan level 10 passes
  4. Update documentation as needed

License

MIT License. See LICENSE file.

Links