Skip to content

Commit 63cace3

Browse files
authored
Merge pull request #1 from KaririCode-Framework/develop
Develop
2 parents 3efe63a + 324b8a3 commit 63cace3

17 files changed

Lines changed: 128 additions & 20 deletions

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,8 @@ src/
228228

229229
| Metric | Value |
230230
|---|---|
231-
| PHP source files | 19 |
232-
| Source lines | ~720 |
231+
| PHP source files | 20 |
232+
| Source lines | ~810 |
233233
| Test files | 13 |
234234
| Test lines | ~700 |
235235
| External runtime dependencies | 1 (kariricode/property-inspector) |

src/Attribute/Serialize.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
/**
88
* Marks a property for serialization control.
99
*
10-
* Parameters: name (wire-name override), groups (string[]), format-specific options.
10+
* Parameters: name (wire-name override), groups (string[]), ignore (bool).
11+
* Properties without this attribute are included automatically using their property name.
12+
*
13+
* @package KaririCode\Serializer\Attribute
14+
* @author Walmir Silva <walmir.silva@kariricode.org>
15+
* @since 3.1.0 ARFA 1.3
1116
*/
1217
#[\Attribute(\Attribute::TARGET_PROPERTY)]
1318
final readonly class Serialize

src/Configuration/SerializerConfiguration.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44

55
namespace KaririCode\Serializer\Configuration;
66

7+
/**
8+
* Immutable configuration value object for the serializer engine.
9+
*
10+
* @package KaririCode\Serializer\Configuration
11+
* @author Walmir Silva <walmir.silva@kariricode.org>
12+
* @since 3.1.0 ARFA 1.3
13+
*/
714
final readonly class SerializerConfiguration
815
{
916
public function __construct(

src/Contract/EncoderRegistry.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44

55
namespace KaririCode\Serializer\Contract;
66

7+
/**
8+
* Contract for format-encoder registries.
9+
*
10+
* @package KaririCode\Serializer\Contract
11+
* @author Walmir Silva <walmir.silva@kariricode.org>
12+
* @since 3.1.0 ARFA 1.3
13+
*/
714
interface EncoderRegistry
815
{
916
public function register(Encoder $encoder): void;

src/Core/InMemoryEncoderRegistry.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88
use KaririCode\Serializer\Contract\EncoderRegistry;
99
use KaririCode\Serializer\Exception\SerializationException;
1010

11+
/**
12+
* In-memory encoder registry backed by a plain PHP array.
13+
*
14+
* Throws SerializationException on duplicate registration or unknown format lookup.
15+
*
16+
* @package KaririCode\Serializer\Core
17+
* @author Walmir Silva <walmir.silva@kariricode.org>
18+
* @since 3.1.0 ARFA 1.3
19+
*/
1120
final class InMemoryEncoderRegistry implements EncoderRegistry
1221
{
1322
/** @var array<string, Encoder> */

src/Core/SerializationContextImpl.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66

77
use KaririCode\Serializer\Contract\SerializationContext;
88

9+
/**
10+
* Immutable serialization context carrying the active format and parameters.
11+
*
12+
* Uses the named-constructor pattern: instantiate via `SerializationContextImpl::create()`.
13+
* `withFormat()` and `withParameters()` return new instances (full immutability).
14+
*
15+
* @package KaririCode\Serializer\Core
16+
* @author Walmir Silva <walmir.silva@kariricode.org>
17+
* @since 3.1.0 ARFA 1.3
18+
*/
919
final readonly class SerializationContextImpl implements SerializationContext
1020
{
1121
/**

src/Core/SerializerEngine.php

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
* Central serialization orchestrator.
1313
*
1414
* Delegates to format-specific encoders via the registry.
15+
* Resolves the active format from the request or falls back to the
16+
* configured default, then delegates encode/decode to the matching encoder.
1517
*
1618
* @package KaririCode\Serializer\Core
1719
* @author Walmir Silva <walmir.silva@kariricode.org>
@@ -34,20 +36,20 @@ public function __construct(
3436
public function serialize(array $data, ?string $format = null, array $parameters = []): SerializationResult
3537
{
3638
$config = $this->configuration ?? new SerializerConfiguration();
37-
$fmt = $format ?? $config->defaultFormat;
38-
$encoder = $this->registry->resolve($fmt);
39+
$resolvedFormat = $format ?? $config->defaultFormat;
40+
$encoder = $this->registry->resolve($resolvedFormat);
3941

40-
$ctx = SerializationContextImpl::create($fmt);
42+
$serializationContext = SerializationContextImpl::create($resolvedFormat);
4143
if ($config->prettyPrint) {
42-
$ctx = $ctx->withParameters(['pretty' => true]);
44+
$serializationContext = $serializationContext->withParameters(['pretty' => true]);
4345
}
4446
if ($parameters !== []) {
45-
$ctx = $ctx->withParameters($parameters);
47+
$serializationContext = $serializationContext->withParameters($parameters);
4648
}
4749

48-
$payload = $encoder->encode($data, $ctx);
50+
$payload = $encoder->encode($data, $serializationContext);
4951

50-
return new SerializationResult($data, $payload, $fmt);
52+
return new SerializationResult($data, $payload, $resolvedFormat);
5153
}
5254

5355
/**
@@ -59,14 +61,14 @@ public function serialize(array $data, ?string $format = null, array $parameters
5961
public function deserialize(string $payload, ?string $format = null, array $parameters = []): array
6062
{
6163
$config = $this->configuration ?? new SerializerConfiguration();
62-
$fmt = $format ?? $config->defaultFormat;
63-
$encoder = $this->registry->resolve($fmt);
64+
$resolvedFormat = $format ?? $config->defaultFormat;
65+
$encoder = $this->registry->resolve($resolvedFormat);
6466

65-
$ctx = SerializationContextImpl::create($fmt);
67+
$serializationContext = SerializationContextImpl::create($resolvedFormat);
6668
if ($parameters !== []) {
67-
$ctx = $ctx->withParameters($parameters);
69+
$serializationContext = $serializationContext->withParameters($parameters);
6870
}
6971

70-
return $encoder->decode($payload, $ctx);
72+
return $encoder->decode($payload, $serializationContext);
7173
}
7274
}

src/Encoder/CsvEncoder.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@
99
use KaririCode\Serializer\Exception\SerializationException;
1010

1111
/**
12-
* Encodes/decodes flat arrays-of-arrays as CSV.
12+
* Encodes/decodes flat arrays-of-arrays as RFC 4180-compliant CSV via php://temp.
1313
*
1414
* Parameters: separator (string, ','), enclosure (string, '"'), header (bool, true).
15+
*
16+
* @package KaririCode\Serializer\Encoder
17+
* @author Walmir Silva <walmir.silva@kariricode.org>
18+
* @since 3.1.0 ARFA 1.3
1519
*/
1620
final readonly class CsvEncoder implements Encoder
1721
{
@@ -38,13 +42,13 @@ public function encode(array $data, SerializationContext $context): string
3842
if ($hasHeader && \is_array($firstRow)) {
3943
/** @var array<int|string, string> $keys */
4044
$keys = array_keys($firstRow);
41-
fputcsv($stream, $keys, $separator, $enclosure);
45+
fputcsv($stream, $keys, $separator, $enclosure, escape: '\\');
4246
}
4347

4448
foreach ($data as $row) {
4549
if (\is_array($row)) {
4650
/** @var array<int|string, bool|float|int|string|null> $row */
47-
fputcsv($stream, $row, $separator, $enclosure);
51+
fputcsv($stream, $row, $separator, $enclosure, escape: '\\');
4852
}
4953
}
5054

@@ -75,7 +79,7 @@ public function decode(string $payload, SerializationContext $context): array
7579
}
7680

7781
$rows = array_values(
78-
array_map(static fn (string $line) => str_getcsv($line, $separator, $enclosure), $lines),
82+
array_map(static fn (string $line) => str_getcsv($line, $separator, $enclosure, escape: '\\'), $lines),
7983
);
8084

8185
if ($hasHeader && \count($rows) > 1) {

src/Encoder/JsonEncoder.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88
use KaririCode\Serializer\Contract\SerializationContext;
99
use KaririCode\Serializer\Exception\SerializationException;
1010

11+
/**
12+
* Encodes/decodes data as RFC 8259-compliant JSON.
13+
*
14+
* Uses JSON_THROW_ON_ERROR for deterministic error handling.
15+
* Supports `pretty` context parameter for human-readable output.
16+
*
17+
* @package KaririCode\Serializer\Encoder
18+
* @author Walmir Silva <walmir.silva@kariricode.org>
19+
* @since 3.1.0 ARFA 1.3
20+
*/
1121
final readonly class JsonEncoder implements Encoder
1222
{
1323
/** @param array<mixed> $data */

src/Encoder/QueryStringEncoder.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
use KaririCode\Serializer\Contract\Encoder;
88
use KaririCode\Serializer\Contract\SerializationContext;
99

10-
/** Encodes/decodes URL query strings (application/x-www-form-urlencoded). */
10+
/**
11+
* Encodes/decodes data as RFC 3986-compliant URL query strings (application/x-www-form-urlencoded).
12+
*
13+
* @package KaririCode\Serializer\Encoder
14+
* @author Walmir Silva <walmir.silva@kariricode.org>
15+
* @since 3.1.0 ARFA 1.3
16+
*/
1117
final readonly class QueryStringEncoder implements Encoder
1218
{
1319
/** @param array<mixed> $data */

0 commit comments

Comments
 (0)