Skip to content

Commit 68827a0

Browse files
author
Robert Gasch
committed
Switched to using helgesverre/toon
1 parent 830f454 commit 68827a0

File tree

9 files changed

+112
-88
lines changed

9 files changed

+112
-88
lines changed

README.md

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
Laravel integration for TOON - A human-readable data serialization format.
44

5-
This package provides Laravel-specific features on top of the [robertgdev/php-toon](https://github.com/robertgdev/php-toon) core library.
5+
This package provides Laravel-specific features on top of the [helgesverre/toon](https://github.com/helgesverre/toon) core library.
66

77
## Installation
88

99
```bash
1010
composer require robertgdev/laravel-toon
1111
```
1212

13-
This will automatically install the `robertgdev/php-toon` core library as a dependency.
13+
This will automatically install the `helgesverre/toon` core library as a dependency.
1414

1515
## Configuration
1616

@@ -57,7 +57,6 @@ TOON_ENCODE_LENGTH_MARKER=false
5757
# Decoding options
5858
TOON_DECODE_INDENT=2
5959
TOON_DECODE_STRICT=true
60-
TOON_DECODE_OBJECTS_AS_STDCLASS=false
6160
```
6261

6362
**Available Delimiters:**
@@ -69,9 +68,7 @@ TOON_DECODE_OBJECTS_AS_STDCLASS=false
6968
- `false` (default) - no marker
7069
- `true` or `#` - adds `#` prefix to array lengths
7170

72-
**Objects as StdClass:**
73-
- `false` (default) - objects decode to associative arrays
74-
- `true` - objects decode to `StdClass` instances (enables perfect round-trips)
71+
7572

7673
### Using Configured Defaults
7774

@@ -85,7 +82,7 @@ $encoded = Toon::encode($data);
8582
$decoded = Toon::decode($encoded);
8683

8784
// Override with custom options
88-
use RobertGDev\Toon\Types\EncodeOptions;
85+
use HelgeSverre\Toon\EncodeOptions;
8986
$encoded = Toon::encode($data, new EncodeOptions(indent: 4));
9087
```
9188

@@ -97,7 +94,7 @@ The package provides a Laravel facade for easy access:
9794

9895
```php
9996
use RobertGDev\LaravelToon\Facades\Toon;
100-
use RobertGDev\Toon\Types\EncodeOptions;
97+
use HelgeSverre\Toon\EncodeOptions;
10198

10299
// Simple encoding
103100
$data = ['name' => 'Ada', 'age' => 30, 'active' => true];
@@ -127,13 +124,13 @@ $decoded = \Toon::decode($encoded);
127124
You can also use the core library directly:
128125

129126
```php
130-
use RobertGDev\Toon\Toon;
127+
use HelgeSverre\Toon\Toon;
131128

132129
$encoded = Toon::encode(['name' => 'Ada']);
133130
$decoded = Toon::decode($encoded);
134131
```
135132

136-
For detailed API documentation, see the [robertgdev/php-toon](https://github.com/robertgdev/php-toon) package.
133+
For detailed API documentation, see the [helgesverre/toon](https://github.com/helgesverre/toon) package.
137134

138135
## Artisan Command
139136

@@ -194,7 +191,7 @@ php artisan toon:convert input.toon --no-strict
194191

195192
## Package Structure
196193

197-
This package is a thin Laravel integration layer. The core TOON functionality is provided by the `robertgdev/php-toon` package, which is a standalone PHP library.
194+
This package is a thin Laravel integration layer. The core TOON functionality is provided by the `helgesverre/toon` package, which is a standalone PHP library.
198195

199196
### What's in this package:
200197
- [`ToonServiceProvider`](src/ToonServiceProvider.php) - Registers the service and command
@@ -208,13 +205,13 @@ This package is a thin Laravel integration layer. The core TOON functionality is
208205
- Type definitions and options
209206
- Core TOON parser and serializer
210207

211-
See [robertgdev/php-toon](https://github.com/robertgdev/php-toon) for the core library documentation.
208+
See [helgesverre/toon](https://github.com/helgesverre/toon) for the core library documentation.
212209

213210
## Requirements
214211

215212
- PHP 8.2+
216213
- Laravel 10.x or 11.x or 12.x
217-
- robertgdev/php-toon (automatically installed)
214+
- helgesverre/toon (automatically installed)
218215

219216
## Testing
220217

composer.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010
],
1111
"require": {
1212
"php": "^8.2",
13+
"helgesverre/toon": "^1.4",
1314
"illuminate/console": ">10",
14-
"illuminate/support": ">10",
15-
"robertgdev/php-toon": "^1.0"
15+
"illuminate/support": ">10"
1616
},
1717
"require-dev": {
18+
"larastan/larastan": "^3.0",
19+
"orchestra/testbench": "^9.0",
1820
"pestphp/pest": "^4.0",
19-
"phpunit/phpunit": "^12.0",
20-
"orchestra/testbench": "^9.0"
21+
"phpunit/phpunit": "^12.0"
2122
},
2223
"autoload": {
2324
"psr-4": {

config/toon.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@
3737

3838
// Enforce strict validation of array lengths and indentation
3939
'strict' => env('TOON_DECODE_STRICT', true),
40-
41-
// Decode objects as StdClass instances instead of arrays
42-
'objectsAsStdClass' => env('TOON_DECODE_OBJECTS_AS_STDCLASS', false),
4340
],
4441

4542
];

phpstan.neon

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
includes:
2+
- vendor/larastan/larastan/extension.neon
3+
- vendor/nesbot/carbon/extension.neon
4+
5+
parameters:
6+
parallel:
7+
jobSize: 20
8+
maximumNumberOfProcesses: 8
9+
minimumNumberOfJobsPerProcess: 2
10+
11+
paths:
12+
- src/
13+
14+
# Level 9 is the highest level
15+
level: 9
16+
17+
# ignoreErrors:
18+
#
19+
# excludePaths:
20+
# - ./*/*/FileToBeExcluded.php
21+
#
22+
# checkMissingIterableValueType: false
23+
#
24+
# universalObjectCratesClasses:
25+
# - App\Datatypes\Collection

src/Console/ToonCommand.php

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
namespace RobertGDev\LaravelToon\Console;
44

55
use Illuminate\Console\Command;
6-
use RobertGDev\Toon\Toon;
7-
use RobertGDev\Toon\Types\DecodeOptions;
8-
use RobertGDev\Toon\Types\EncodeOptions;
6+
use HelgeSverre\Toon\Toon;
7+
use HelgeSverre\Toon\DecodeOptions;
8+
use HelgeSverre\Toon\EncodeOptions;
99

1010
class ToonCommand extends Command
1111
{
@@ -39,46 +39,46 @@ class ToonCommand extends Command
3939
public function handle(): int
4040
{
4141
$input = $this->argument('input');
42+
if (!is_string($input)) {
43+
$this->error('Input argument is required and must be a string');
44+
return self::FAILURE;
45+
}
46+
4247
$output = $this->option('output');
48+
$output = is_string($output) || $output === null ? $output : null;
4349

4450
// Parse and validate indent
45-
$indent = (int) $this->option('indent');
51+
$indentOption = $this->option('indent');
52+
$indent = is_numeric($indentOption) ? (int)$indentOption : 2;
4653
if ($indent < 0) {
47-
$this->error("Invalid indent value: {$this->option('indent')}");
54+
$this->error("Invalid indent value: {$indent}");
4855
return self::FAILURE;
4956
}
5057

5158
// Validate delimiter
5259
$delimiter = $this->option('delimiter');
60+
if (!is_string($delimiter)) {
61+
$delimiter = ',';
62+
}
5363
$validDelimiters = [',', "\t", '|'];
5464
if (!in_array($delimiter, $validDelimiters, true)) {
5565
$this->error("Invalid delimiter \"{$delimiter}\". Valid delimiters are: comma (,), tab (\\t), pipe (|)");
5666
return self::FAILURE;
5767
}
5868

59-
$mode = $this->detectMode(
60-
$input,
61-
$this->option('encode'),
62-
$this->option('decode')
63-
);
69+
$encode = (bool)$this->option('encode');
70+
$decode = (bool)$this->option('decode');
71+
72+
$mode = $this->detectMode($input, $encode, $decode);
6473

6574
try {
6675
if ($mode === 'encode') {
67-
$this->encodeToToon(
68-
$input,
69-
$output,
70-
$delimiter,
71-
$indent,
72-
$this->option('length-marker'),
73-
$this->option('stats')
74-
);
76+
$lengthMarker = (bool)$this->option('length-marker');
77+
$stats = (bool)$this->option('stats');
78+
79+
$this->encodeToToon($input, $output, $delimiter, $indent, $lengthMarker, $stats);
7580
} else {
76-
$this->decodeToJson(
77-
$input,
78-
$output,
79-
$indent,
80-
!$this->option('no-strict')
81-
);
81+
$this->decodeToJson($input, $output, $indent, !$this->option('no-strict'));
8282
}
8383

8484
return self::SUCCESS;
@@ -102,10 +102,10 @@ private function detectMode(?string $inputFile, bool $encodeFlag, bool $decodeFl
102102
}
103103

104104
// Auto-detect based on file extension
105-
if (str_ends_with($inputFile, '.json')) {
105+
if ($inputFile !== null && str_ends_with($inputFile, '.json')) {
106106
return 'encode';
107107
}
108-
if (str_ends_with($inputFile, '.toon')) {
108+
if ($inputFile !== null && str_ends_with($inputFile, '.toon')) {
109109
return 'decode';
110110
}
111111

@@ -129,6 +129,9 @@ private function encodeToToon(
129129
}
130130

131131
$jsonContent = file_get_contents($input);
132+
if ($jsonContent === false) {
133+
throw new \RuntimeException("Failed to read input file: {$input}");
134+
}
132135

133136
try {
134137
$data = json_decode($jsonContent, true, 512, JSON_THROW_ON_ERROR);
@@ -179,6 +182,9 @@ private function decodeToJson(
179182
}
180183

181184
$toonContent = file_get_contents($input);
185+
if ($toonContent === false) {
186+
throw new \RuntimeException("Failed to read input file: {$input}");
187+
}
182188

183189
try {
184190
$decodeOptions = new DecodeOptions(
@@ -190,7 +196,10 @@ private function decodeToJson(
190196
throw new \RuntimeException("Failed to decode TOON: {$e->getMessage()}");
191197
}
192198

193-
$jsonOutput = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE, $indent);
199+
$jsonOutput = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE, 512);
200+
if ($jsonOutput === false) {
201+
throw new \RuntimeException("Failed to encode JSON output");
202+
}
194203

195204
if ($output) {
196205
file_put_contents($output, $jsonOutput);
@@ -208,7 +217,7 @@ private function decodeToJson(
208217
private function getRelativePath(string $path): string
209218
{
210219
$cwd = getcwd();
211-
if (str_starts_with($path, $cwd)) {
220+
if ($cwd !== false && str_starts_with($path, $cwd)) {
212221
return substr($path, strlen($cwd) + 1);
213222
}
214223
return $path;

src/Facades/Toon.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
use Illuminate\Support\Facades\Facade;
66

77
/**
8-
* @method static string encode(mixed $input, ?\RobertGDev\Toon\Types\EncodeOptions $options = null)
9-
* @method static mixed decode(string $input, ?\RobertGDev\Toon\Types\DecodeOptions $options = null)
8+
* @method static string encode(mixed $input, ?\HelgeSverre\Toon\EncodeOptions $options = null)
9+
* @method static mixed decode(string $input, ?\HelgeSverre\Toon\DecodeOptions $options = null)
1010
*
1111
* @see \RobertGDev\LaravelToon\Toon
1212
*/

src/Toon.php

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace RobertGDev\LaravelToon;
44

5-
use RobertGDev\Toon\Toon as BaseToon;
6-
use RobertGDev\Toon\Types\DecodeOptions;
7-
use RobertGDev\Toon\Types\EncodeOptions;
5+
use HelgeSverre\Toon\Toon as BaseToon;
6+
use HelgeSverre\Toon\DecodeOptions;
7+
use HelgeSverre\Toon\EncodeOptions;
88

99
/**
1010
* Laravel wrapper for Toon encoding/decoding with config support.
@@ -34,23 +34,32 @@ public function decode(string $input, ?DecodeOptions $options = null): mixed
3434
*/
3535
protected function getDefaultEncodeOptions(): EncodeOptions
3636
{
37-
return new EncodeOptions(
38-
indent: config('toon.encode.indent', 2),
39-
delimiter: config('toon.encode.delimiter', ','),
40-
lengthMarker: $this->parseLengthMarker(config('toon.encode.lengthMarker', false))
41-
);
37+
$indent = config('toon.encode.indent', 2);
38+
$indent = is_numeric($indent) ? (int)$indent : 2;
39+
40+
$delimiter = config('toon.encode.delimiter', ',');
41+
if (!is_string($delimiter)) {
42+
$delimiter = ',';
43+
}
44+
45+
$lengthMarker = config('toon.encode.lengthMarker', false);
46+
$lengthMarker = $this->parseLengthMarker($lengthMarker);
47+
48+
return new EncodeOptions($indent, $delimiter, $lengthMarker);
4249
}
4350

4451
/**
4552
* Get default decode options from Laravel config.
4653
*/
4754
protected function getDefaultDecodeOptions(): DecodeOptions
4855
{
49-
return new DecodeOptions(
50-
indent: config('toon.decode.indent', 2),
51-
strict: config('toon.decode.strict', true),
52-
objectsAsStdClass: config('toon.decode.objectsAsStdClass', false)
53-
);
56+
$indent = config('toon.decode.indent', 2);
57+
$indent = is_numeric($indent) ? (int)$indent : 2;
58+
59+
$strict = config('toon.decode.strict', true);
60+
$strict = is_bool($strict) || $strict === 'true' || $strict === 1;
61+
62+
return new DecodeOptions($indent, $strict);
5463
}
5564

5665
/**

tests/ConfigTest.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
expect(config('toon.encode.lengthMarker'))->toBe(false);
1010
expect(config('toon.decode.indent'))->toBe(2);
1111
expect(config('toon.decode.strict'))->toBe(true);
12-
expect(config('toon.decode.objectsAsStdClass'))->toBe(false);
1312
});
1413

1514
it('can be overridden via config', function () {
@@ -67,7 +66,7 @@
6766
expect($config)->toHaveKey('encode');
6867
expect($config)->toHaveKey('decode');
6968
expect($config['encode'])->toHaveKey('indent');
70-
expect($config['decode'])->toHaveKey('objectsAsStdClass');
69+
expect($config['decode'])->toHaveKey('strict');
7170

7271
// Clean up
7372
File::delete($configPath);
@@ -109,14 +108,11 @@
109108
});
110109

111110
it('applies config defaults when decoding', function () {
112-
config(['toon.decode.objectsAsStdClass' => true]);
113-
114111
$toon = app('toon');
115112
$toonStr = "name: Ada";
116113
$decoded = $toon->decode($toonStr);
117114

118-
expect($decoded)->toBeInstanceOf(StdClass::class);
119-
expect($decoded->name)->toBe('Ada');
115+
expect($decoded)->toBe(['name' => 'Ada']);
120116
});
121117

122118
it('allows overriding config with explicit options', function () {
@@ -126,7 +122,7 @@
126122
$data = ['user' => ['name' => 'Ada']];
127123

128124
// Override with 4-space indent
129-
$options = new \RobertGDev\Toon\Types\EncodeOptions(indent: 4);
125+
$options = new \HelgeSverre\Toon\EncodeOptions(indent: 4);
130126
$encoded = $toon->encode($data, $options);
131127

132128
expect($encoded)->toBe("user:\n name: Ada");

0 commit comments

Comments
 (0)