Skip to content

Commit 351b315

Browse files
committed
feat: add PHP 7.0-8.0 compatibility for v1.0.0
- Remove enum support (PHP 8.1+ feature) - Convert constructor property promotion to traditional syntax - Replace mixed type hints with docblock annotations - Replace match expressions with if/else statements - Replace arrow functions with traditional closures - Replace str_contains/str_starts_with/str_ends_with with strpos - Convert ToonDelimiter enum to constants class - Update composer.json for PHP ^7.0|^8.0 - Update GitHub Actions workflow for PHP 7.0-8.0 testing - Remove enum test for PHP 7 compatibility - Update PHPStan to level 6 - All 32 tests passing
1 parent f3e1555 commit 351b315

11 files changed

Lines changed: 303 additions & 128 deletions

File tree

.github/workflows/run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
fail-fast: true
2222
matrix:
2323
os: [ubuntu-latest, windows-latest]
24-
php: [8.0, 8.1, 8.2, 8.3, 8.4]
24+
php: [7.0, 7.1, 7.2, 7.3, 7.4, 8.0]
2525
stability: [prefer-lowest, prefer-stable]
2626

2727
name: P${{ matrix.php }} - ${{ matrix.stability }} - ${{ matrix.os }}

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,30 @@
22

33
All notable changes to `toon-php` will be documented in this file.
44

5+
## 1.0.0 - 2025-11-09
6+
7+
Legacy PHP support release for PHP 7.0-8.0
8+
9+
### Added
10+
- Complete TOON encoding and decoding for PHP 7.0-8.0
11+
- Support for all PHP data types (except Enums - PHP 8.1+ only)
12+
- Multiple formatting modes (compact, readable, tabular)
13+
- Helper functions for common operations
14+
- PHPStan level 6 compliance
15+
- PSR-12 code style
16+
- Comprehensive test coverage (32 tests)
17+
- PHP 7.0-8.0 compatibility
18+
19+
### Technical Details
20+
- Removed enum support (PHP 8.1+ feature)
21+
- Converted constructor property promotion to traditional syntax
22+
- Replaced `mixed` type hints with docblock annotations
23+
- Replaced match expressions with if/else statements
24+
- Replaced arrow functions with traditional closures
25+
- Replaced `str_contains`, `str_starts_with`, `str_ends_with` with `strpos`
26+
- Enum class converted to constants class
27+
- Full PHP 7.0 compatibility maintained
28+
529
## 2.0.0 - 2025-11-09
630

731
Initial release with full TOON format support for PHP 8.0+

composer.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"name": "iamgerwin/toon-php",
3-
"description": "A lightweight, fast, and feature-rich TOON (Token-Oriented Object Notation) library for PHP - optimized for LLM contexts with 30-60% token savings",
3+
"description": "A lightweight, fast, and feature-rich TOON (Token-Oriented Object Notation) library for PHP - optimized for LLM contexts with 30-60% token savings (PHP 7.0-8.0 compatible)",
44
"keywords": [
55
"toon",
66
"toon-php",
77
"serialization",
88
"llm",
99
"token-optimization",
10-
"data-format"
10+
"data-format",
11+
"php7"
1112
],
1213
"homepage": "https://github.com/iamgerwin/toon-php",
1314
"license": "MIT",
@@ -19,12 +20,12 @@
1920
}
2021
],
2122
"require": {
22-
"php": "^8.0"
23+
"php": "^7.0|^8.0"
2324
},
2425
"require-dev": {
25-
"pestphp/pest": "^3.0|^4.0",
26+
"pestphp/pest": "^1.21|^2.0",
2627
"laravel/pint": "^1.0",
27-
"phpstan/phpstan": "^2.0",
28+
"phpstan/phpstan": "^1.10",
2829
"phpstan/extension-installer": "^1.3"
2930
},
3031
"autoload": {

src/DecodeOptions.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,38 @@
99
*/
1010
class DecodeOptions
1111
{
12+
/** @var bool */
13+
public $strict;
14+
15+
/** @var bool */
16+
public $associative;
17+
18+
/** @var int */
19+
public $depth;
20+
1221
public function __construct(
13-
public bool $strict = true,
14-
public bool $associative = true,
15-
public int $depth = 512,
16-
) {}
22+
bool $strict = true,
23+
bool $associative = true,
24+
int $depth = 512
25+
) {
26+
$this->strict = $strict;
27+
$this->associative = $associative;
28+
$this->depth = $depth;
29+
}
1730

1831
/**
1932
* Create strict decoding options (validation enabled).
2033
*/
2134
public static function strict(): self
2235
{
23-
return new self(strict: true);
36+
return new self(true);
2437
}
2538

2639
/**
2740
* Create lenient decoding options (relaxed validation).
2841
*/
2942
public static function lenient(): self
3043
{
31-
return new self(strict: false);
44+
return new self(false);
3245
}
3346
}

src/EncodeOptions.php

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,50 @@
1111
*/
1212
class EncodeOptions
1313
{
14+
/** @var int */
15+
public $indent;
16+
17+
/** @var string */
18+
public $delimiter;
19+
20+
/** @var bool */
21+
public $useLengthMarker;
22+
23+
/** @var bool */
24+
public $preferTabular;
25+
26+
/** @var bool */
27+
public $quoteStrings;
28+
29+
/** @var bool */
30+
public $sortKeys;
31+
1432
public function __construct(
15-
public int $indent = 2,
16-
public ToonDelimiter $delimiter = ToonDelimiter::COMMA,
17-
public bool $useLengthMarker = true,
18-
public bool $preferTabular = true,
19-
public bool $quoteStrings = false,
20-
public bool $sortKeys = false,
21-
) {}
33+
int $indent = 2,
34+
string $delimiter = ToonDelimiter::COMMA,
35+
bool $useLengthMarker = true,
36+
bool $preferTabular = true,
37+
bool $quoteStrings = false,
38+
bool $sortKeys = false
39+
) {
40+
$this->indent = $indent;
41+
$this->delimiter = $delimiter;
42+
$this->useLengthMarker = $useLengthMarker;
43+
$this->preferTabular = $preferTabular;
44+
$this->quoteStrings = $quoteStrings;
45+
$this->sortKeys = $sortKeys;
46+
}
2247

2348
/**
2449
* Create compact encoding options (minimal whitespace).
2550
*/
2651
public static function compact(): self
2752
{
2853
return new self(
29-
indent: 0,
30-
preferTabular: false,
31-
useLengthMarker: false,
54+
0,
55+
ToonDelimiter::COMMA,
56+
false,
57+
false
3258
);
3359
}
3460

@@ -38,8 +64,10 @@ public static function compact(): self
3864
public static function readable(): self
3965
{
4066
return new self(
41-
indent: 4,
42-
preferTabular: false,
67+
4,
68+
ToonDelimiter::COMMA,
69+
true,
70+
false
4371
);
4472
}
4573

@@ -49,9 +77,10 @@ public static function readable(): self
4977
public static function tabular(): self
5078
{
5179
return new self(
52-
indent: 2,
53-
preferTabular: true,
54-
useLengthMarker: true,
80+
2,
81+
ToonDelimiter::COMMA,
82+
true,
83+
true
5584
);
5685
}
5786
}

src/Enums/ToonDelimiter.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,25 @@
77
/**
88
* Delimiter options for TOON array encoding.
99
*/
10-
enum ToonDelimiter: string
10+
class ToonDelimiter
1111
{
12-
case COMMA = ',';
13-
case TAB = "\t";
14-
case PIPE = '|';
12+
public const COMMA = ',';
13+
public const TAB = "\t";
14+
public const PIPE = '|';
15+
16+
/**
17+
* Get the default delimiter.
18+
*/
19+
public static function default(): string
20+
{
21+
return self::COMMA;
22+
}
23+
24+
/**
25+
* Validate if a delimiter is supported.
26+
*/
27+
public static function isValid(string $delimiter): bool
28+
{
29+
return in_array($delimiter, [self::COMMA, self::TAB, self::PIPE], true);
30+
}
1531
}

src/Toon.php

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ class Toon
2424
*
2525
* @throws ToonException
2626
*/
27-
public static function encode(mixed $value, ?EncodeOptions $options = null): string
27+
public static function encode($value, $options = null): string
2828
{
29-
$options ??= new EncodeOptions;
29+
if ($options === null) {
30+
$options = new EncodeOptions();
31+
}
3032

3133
return ToonSerializer::serialize($value, $options);
3234
}
@@ -40,33 +42,44 @@ public static function encode(mixed $value, ?EncodeOptions $options = null): str
4042
*
4143
* @throws ToonException
4244
*/
43-
public static function decode(string $toon, ?DecodeOptions $options = null): mixed
45+
public static function decode(string $toon, $options = null)
4446
{
45-
$options ??= new DecodeOptions;
47+
if ($options === null) {
48+
$options = new DecodeOptions();
49+
}
4650

4751
return ToonDeserializer::deserialize($toon, $options);
4852
}
4953

5054
/**
5155
* Encode to compact TOON format (minimal whitespace).
56+
*
57+
* @param mixed $value
58+
* @return string
5259
*/
53-
public static function compact(mixed $value): string
60+
public static function compact($value): string
5461
{
5562
return self::encode($value, EncodeOptions::compact());
5663
}
5764

5865
/**
5966
* Encode to readable TOON format (more whitespace for readability).
67+
*
68+
* @param mixed $value
69+
* @return string
6070
*/
61-
public static function readable(mixed $value): string
71+
public static function readable($value): string
6272
{
6373
return self::encode($value, EncodeOptions::readable());
6474
}
6575

6676
/**
6777
* Encode to tabular TOON format (optimized for uniform arrays).
78+
*
79+
* @param mixed $value
80+
* @return string
6881
*/
69-
public static function tabular(mixed $value): string
82+
public static function tabular($value): string
7083
{
7184
return self::encode($value, EncodeOptions::tabular());
7285
}
@@ -85,19 +98,22 @@ public static function estimateTokens(string $toon): int
8598
/**
8699
* Compare TOON vs JSON token usage.
87100
*
88-
* @return array{toon: string, json: string, toon_tokens: int, json_tokens: int, savings_percent: float}
101+
* @param mixed $value
102+
* @param EncodeOptions|null $options
103+
* @return array<string, mixed> Array with keys: toon, json, toon_tokens, json_tokens, savings_percent
89104
*/
90-
public static function compare(mixed $value, ?EncodeOptions $options = null): array
105+
public static function compare($value, $options = null): array
91106
{
92107
$toon = self::encode($value, $options);
93108
$json = json_encode($value, JSON_THROW_ON_ERROR);
94109

95110
$toonTokens = self::estimateTokens($toon);
96111
$jsonTokens = self::estimateTokens($json);
97112

98-
$savingsPercent = $jsonTokens > 0
99-
? round((($jsonTokens - $toonTokens) / $jsonTokens) * 100, 2)
100-
: 0.0;
113+
$savingsPercent = 0.0;
114+
if ($jsonTokens > 0) {
115+
$savingsPercent = round((($jsonTokens - $toonTokens) / $jsonTokens) * 100, 2);
116+
}
101117

102118
return [
103119
'toon' => $toon,

0 commit comments

Comments
 (0)