diff --git a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/EntryNormalizer.php b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/EntryNormalizer.php index c86282c98..84dd069cf 100644 --- a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/EntryNormalizer.php +++ b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/EntryNormalizer.php @@ -5,8 +5,25 @@ namespace Flow\ETL\Adapter\CSV\RowsNormalizer; use function Flow\ETL\DSL\date_interval_to_microseconds; +use Flow\ETL\Exception\InvalidArgumentException; use Flow\ETL\Row\Entry; -use Flow\ETL\Row\Entry\{DateEntry, DateTimeEntry, EnumEntry, JsonEntry, ListEntry, MapEntry, StructureEntry, TimeEntry, UuidEntry, XMLElementEntry, XMLEntry}; +use Flow\ETL\Row\Entry\{BooleanEntry, + DateEntry, + DateTimeEntry, + EnumEntry, + FloatEntry, + HTMLElementEntry, + HTMLEntry, + IntegerEntry, + JsonEntry, + ListEntry, + MapEntry, + StringEntry, + StructureEntry, + TimeEntry, + UuidEntry, + XMLElementEntry, + XMLEntry}; final readonly class EntryNormalizer { @@ -21,56 +38,30 @@ public function __construct( */ public function normalize(Entry $entry) : string|float|int|bool|null { - $value = match ($entry::class) { - UuidEntry::class, - XMLElementEntry::class, - XMLEntry::class => $entry->toString(), + return match ($entry::class) { + BooleanEntry::class, + IntegerEntry::class, + FloatEntry::class, + StringEntry::class => $entry->value(), DateTimeEntry::class => $entry->value()?->format($this->dateTimeFormat), DateEntry::class => $entry->value()?->format($this->dateFormat), TimeEntry::class => $entry->value() ? date_interval_to_microseconds($entry->value()) : null, - EnumEntry::class => $entry->value()?->name, + JsonEntry::class, ListEntry::class, MapEntry::class, - StructureEntry::class => \json_encode($entry->value(), \JSON_THROW_ON_ERROR), - JsonEntry::class => $entry->toString(), - default => $entry->value(), + StructureEntry::class => $this->normalizeToJson($entry->value()), + EnumEntry::class, + UuidEntry::class, + XMLEntry::class, + XMLElementEntry::class, + HTMLEntry::class, + HTMLElementEntry::class => $entry->toString(), + default => throw new InvalidArgumentException('Unknown entry type: ' . $entry::class), }; + } - // Ensure we return only the expected types - if (\is_string($value)) { - return $value; - } - - if (\is_float($value)) { - return $value; - } - - if (\is_int($value)) { - return $value; - } - - if (\is_bool($value)) { - return $value; - } - - if ($value === null) { - return null; - } - - // Handle remaining types - if (\is_resource($value)) { - return (string) $value; - } - - if (\is_object($value) && \method_exists($value, '__toString')) { - return $value->__toString(); - } - - if (\is_array($value) || \is_object($value)) { - return ''; - } - - // At this point, we should have covered all cases - return ''; + private function normalizeToJson(mixed $value) : ?string + { + return $value !== null ? \json_encode($value, JSON_THROW_ON_ERROR) : null; } } diff --git a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelLoader.php b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelLoader.php index 15a4efefe..46996a867 100644 --- a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelLoader.php +++ b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelLoader.php @@ -4,7 +4,7 @@ namespace Flow\ETL\Adapter\Excel; -use Flow\ETL\Adapter\Excel\RowsNormalizer\ExcelRowsNormalizer; +use Flow\ETL\Adapter\Excel\RowsNormalizer\EntryNormalizer; use Flow\ETL\Adapter\Excel\Sheet\SheetNameAssertion; use Flow\ETL\Exception\InvalidArgumentException; use Flow\ETL\{FlowContext, Loader, Row, Rows}; @@ -68,7 +68,7 @@ public function destination() : Path public function load(Rows $rows, FlowContext $context) : void { - $normalizer = new ExcelRowsNormalizer( + $normalizer = new EntryNormalizer( dateFormat: $this->dateFormat, dateTimeFormat: $this->dateTimeFormat, timeFormat: $this->timeFormat, diff --git a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/RowsNormalizer/ExcelRowsNormalizer.php b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/RowsNormalizer/EntryNormalizer.php similarity index 87% rename from src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/RowsNormalizer/ExcelRowsNormalizer.php rename to src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/RowsNormalizer/EntryNormalizer.php index bc7add897..ab1c08584 100644 --- a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/RowsNormalizer/ExcelRowsNormalizer.php +++ b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/RowsNormalizer/EntryNormalizer.php @@ -25,7 +25,7 @@ XMLElementEntry, XMLEntry}; -final readonly class ExcelRowsNormalizer +final readonly class EntryNormalizer { public function __construct( private string $dateFormat = 'Y-m-d', @@ -75,11 +75,11 @@ private function normalizeEntry(Entry $entry) : bool|float|int|string|null DateTimeEntry::class => $entry->value()?->format($this->dateTimeFormat), DateEntry::class => $entry->value()?->format($this->dateFormat), TimeEntry::class => $entry->value()?->format($this->timeFormat), - EnumEntry::class => $this->normalizeEnumEntry($entry), JsonEntry::class, ListEntry::class, MapEntry::class, StructureEntry::class => $this->normalizeToJson($entry->value()), + EnumEntry::class, UuidEntry::class, XMLEntry::class, XMLElementEntry::class, @@ -89,17 +89,6 @@ private function normalizeEntry(Entry $entry) : bool|float|int|string|null }; } - private function normalizeEnumEntry(EnumEntry $entry) : ?string - { - $value = $entry->value(); - - if ($value instanceof \BackedEnum) { - return (string) $value->value; - } - - return $value?->name; - } - private function normalizeToJson(mixed $value) : ?string { return $value !== null ? \json_encode($value, JSON_THROW_ON_ERROR) : null; diff --git a/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/RowsNormalizer/ExcelRowsNormalizerTest.php b/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/RowsNormalizer/EntryNormalizerTest.php similarity index 84% rename from src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/RowsNormalizer/ExcelRowsNormalizerTest.php rename to src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/RowsNormalizer/EntryNormalizerTest.php index 9d04f363c..5618fc9b2 100644 --- a/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/RowsNormalizer/ExcelRowsNormalizerTest.php +++ b/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/RowsNormalizer/EntryNormalizerTest.php @@ -6,7 +6,7 @@ use function Flow\ETL\DSL\{enum_entry, float_entry, int_entry, json_entry, list_entry, map_entry, row, string_entry, structure_entry, xml_entry}; use function Flow\Types\DSL\{type_integer, type_list, type_map, type_string, type_structure}; -use Flow\ETL\Adapter\Excel\RowsNormalizer\ExcelRowsNormalizer; +use Flow\ETL\Adapter\Excel\RowsNormalizer\EntryNormalizer; use Flow\ETL\Tests\FlowTestCase; enum BackedStringTestEnum : string @@ -27,11 +27,11 @@ enum UnitTestEnum case PENDING; } -final class ExcelRowsNormalizerTest extends FlowTestCase +final class EntryNormalizerTest extends FlowTestCase { public function test_headers() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $headers = $normalizer->headers( row( @@ -46,7 +46,7 @@ public function test_headers() : void public function test_normalize_backed_int_enum() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(enum_entry('count', BackedIntTestEnum::TWO)) @@ -57,7 +57,7 @@ public function test_normalize_backed_int_enum() : void public function test_normalize_backed_string_enum() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(enum_entry('status', BackedStringTestEnum::ACTIVE)) @@ -68,7 +68,7 @@ public function test_normalize_backed_string_enum() : void public function test_normalize_json_entry_with_null_value() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(json_entry('data', null)) @@ -79,7 +79,7 @@ public function test_normalize_json_entry_with_null_value() : void public function test_normalize_json_entry_with_value() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(json_entry('data', ['key' => 'value'])) @@ -90,7 +90,7 @@ public function test_normalize_json_entry_with_value() : void public function test_normalize_list_entry() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(list_entry('items', [1, 2, 3], type_list(type_integer()))) @@ -101,7 +101,7 @@ public function test_normalize_list_entry() : void public function test_normalize_map_entry() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(map_entry('mapping', ['a' => 1, 'b' => 2], type_map(type_string(), type_integer()))) @@ -112,7 +112,7 @@ public function test_normalize_map_entry() : void public function test_normalize_mixed_row() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row( @@ -128,7 +128,7 @@ enum_entry('status', BackedStringTestEnum::ACTIVE) public function test_normalize_null_enum_entry() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(enum_entry('status', null)) @@ -139,7 +139,7 @@ public function test_normalize_null_enum_entry() : void public function test_normalize_structure_entry() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(structure_entry('person', ['name' => 'John', 'age' => 30], type_structure(['name' => type_string(), 'age' => type_integer()]))) @@ -150,7 +150,7 @@ public function test_normalize_structure_entry() : void public function test_normalize_unit_enum() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(enum_entry('status', UnitTestEnum::PENDING)) @@ -161,7 +161,7 @@ public function test_normalize_unit_enum() : void public function test_normalize_xml_entry() : void { - $normalizer = new ExcelRowsNormalizer(); + $normalizer = new EntryNormalizer(); $result = $normalizer->normalize( row(xml_entry('xml', 'value')) diff --git a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer/EntryNormalizer.php b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer/EntryNormalizer.php index d8afd396a..dda9d744e 100644 --- a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer/EntryNormalizer.php +++ b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer/EntryNormalizer.php @@ -5,8 +5,25 @@ namespace Flow\ETL\Adapter\JSON\RowsNormalizer; use function Flow\ETL\DSL\date_interval_to_microseconds; +use Flow\ETL\Exception\InvalidArgumentException; use Flow\ETL\Row\Entry; -use Flow\ETL\Row\Entry\{DateEntry, DateTimeEntry, EnumEntry, JsonEntry, ListEntry, MapEntry, StructureEntry, TimeEntry, UuidEntry, XMLElementEntry, XMLEntry}; +use Flow\ETL\Row\Entry\{BooleanEntry, + DateEntry, + DateTimeEntry, + EnumEntry, + FloatEntry, + HTMLElementEntry, + HTMLEntry, + IntegerEntry, + JsonEntry, + ListEntry, + MapEntry, + StringEntry, + StructureEntry, + TimeEntry, + UuidEntry, + XMLElementEntry, + XMLEntry}; final readonly class EntryNormalizer { @@ -24,18 +41,24 @@ public function __construct( public function normalize(Entry $entry) : string|float|int|bool|array|null { return match ($entry::class) { - UuidEntry::class => $entry->toString(), + BooleanEntry::class, + IntegerEntry::class, + FloatEntry::class, + StringEntry::class => $entry->value(), DateTimeEntry::class => $entry->value()?->format($this->dateTimeFormat), DateEntry::class => $entry->value()?->format($this->dateFormat), TimeEntry::class => $entry->value() ? date_interval_to_microseconds($entry->value()) : null, - EnumEntry::class => $entry->value()?->name, JsonEntry::class => $this->normalizeJsonValue($entry->value()?->toArray()), + EnumEntry::class, ListEntry::class, MapEntry::class, StructureEntry::class, - XMLElementEntry::class => $entry->toString(), - XMLEntry::class => $entry->toString(), - default => $this->normalizeValue($entry->value()), + UuidEntry::class, + XMLEntry::class, + XMLElementEntry::class, + HTMLEntry::class, + HTMLElementEntry::class => $entry->toString(), + default => throw new InvalidArgumentException('Unknown entry type: ' . $entry::class), }; } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/EnumEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/EnumEntry.php index 18ee6b205..e683cfa08 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/EnumEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/EnumEntry.php @@ -95,6 +95,10 @@ public function toString() : string return ''; } + if ($this->value instanceof \BackedEnum) { + return (string) $this->value->value; + } + return $this->value->name; }