Skip to content

Commit 9cd72c0

Browse files
authored
Integration with symfony/string for better strings manipulation (#1782)
* Added scalar function Reverse * Added slice scalar function * Added Truncate Scalar Function * Added Repeat scalar function * Added Chunk and Length scalar functions * Added isEmpty scalar function * Added Width Scalar Function * Added IndexOfLast Scalar Function * Addd EqualsTo ScalarFunction * Added ContainsAny Scalar Function * Added StringMatch Scalar Function * Added StringMatchAll Scalar Function * Added Prepend and Append scalar function * Added Ensure Start/End Scalar Functions * Added Wordwrap scalar function * Added CollapseWhitespace Scalar Function * Added TrimStart and TrimEnd functions * Added BinaryLength, CodePointLength, Normalize, UnicodeLength Scalar Functions * Make function names more consistant * Reduced the scope of unit tests, focus on integration, not symfony string behavior * Reduce scope of integration tests * Simplified Trim Scalar Function logic
1 parent 1017210 commit 9cd72c0

68 files changed

Lines changed: 3322 additions & 16 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Symfony\Component\String\s;
8+
use Flow\ETL\Row;
9+
10+
final class Append extends ScalarFunctionChain
11+
{
12+
public function __construct(
13+
private readonly ScalarFunction|string $value,
14+
private readonly ScalarFunction|string $suffix,
15+
) {
16+
}
17+
18+
public function eval(Row $row) : ?string
19+
{
20+
$value = (new Parameter($this->value))->asString($row);
21+
$suffix = (new Parameter($this->suffix))->asString($row);
22+
23+
if ($value === null) {
24+
return null;
25+
}
26+
27+
if ($suffix === null) {
28+
return $value;
29+
}
30+
31+
return s($value)->append($suffix)->toString();
32+
}
33+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Symfony\Component\String\b;
8+
use Flow\ETL\Row;
9+
10+
final class BinaryLength extends ScalarFunctionChain
11+
{
12+
public function __construct(
13+
private readonly ScalarFunction|string $value,
14+
) {
15+
}
16+
17+
public function eval(Row $row) : ?int
18+
{
19+
$value = (new Parameter($this->value))->asString($row);
20+
21+
if ($value === null) {
22+
return null;
23+
}
24+
25+
return b($value)->length();
26+
}
27+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Symfony\Component\String\s;
8+
use Flow\ETL\Row;
9+
10+
final class Chunk extends ScalarFunctionChain
11+
{
12+
public function __construct(
13+
private readonly ScalarFunction|string $value,
14+
private readonly ScalarFunction|int $size,
15+
) {
16+
}
17+
18+
/**
19+
* @return null|array<int, string>
20+
*/
21+
public function eval(Row $row) : ?array
22+
{
23+
$value = (new Parameter($this->value))->asString($row);
24+
$size = (new Parameter($this->size))->asInt($row);
25+
26+
if ($value === null) {
27+
return null;
28+
}
29+
30+
if ($size === null || $size <= 0) {
31+
return [];
32+
}
33+
34+
$chunks = s($value)->chunk($size);
35+
36+
return array_map(static fn ($chunk) => $chunk->toString(), iterator_to_array($chunks));
37+
}
38+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Symfony\Component\String\s;
8+
use Flow\ETL\Row;
9+
10+
final class CodePointLength extends ScalarFunctionChain
11+
{
12+
public function __construct(
13+
private readonly ScalarFunction|string $value,
14+
) {
15+
}
16+
17+
public function eval(Row $row) : ?int
18+
{
19+
$value = (new Parameter($this->value))->asString($row);
20+
21+
if ($value === null) {
22+
return null;
23+
}
24+
25+
return s($value)->toCodePointString()->length();
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Symfony\Component\String\s;
8+
use Flow\ETL\Row;
9+
10+
final class CollapseWhitespace extends ScalarFunctionChain
11+
{
12+
public function __construct(
13+
private readonly ScalarFunction|string $value,
14+
) {
15+
}
16+
17+
public function eval(Row $row) : ?string
18+
{
19+
$value = (new Parameter($this->value))->asString($row);
20+
21+
if ($value === null) {
22+
return null;
23+
}
24+
25+
return s($value)->collapseWhitespace()->toString();
26+
}
27+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Symfony\Component\String\s;
8+
use Flow\ETL\Row;
9+
10+
final class EnsureEnd extends ScalarFunctionChain
11+
{
12+
public function __construct(
13+
private readonly ScalarFunction|string $value,
14+
private readonly ScalarFunction|string $suffix,
15+
) {
16+
}
17+
18+
public function eval(Row $row) : ?string
19+
{
20+
$value = (new Parameter($this->value))->asString($row);
21+
$suffix = (new Parameter($this->suffix))->asString($row);
22+
23+
if ($value === null) {
24+
return null;
25+
}
26+
27+
if ($suffix === null || $suffix === '') {
28+
return $value;
29+
}
30+
31+
return s($value)->ensureEnd($suffix)->toString();
32+
}
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Symfony\Component\String\s;
8+
use Flow\ETL\Row;
9+
10+
final class EnsureStart extends ScalarFunctionChain
11+
{
12+
public function __construct(
13+
private readonly ScalarFunction|string $value,
14+
private readonly ScalarFunction|string $prefix,
15+
) {
16+
}
17+
18+
public function eval(Row $row) : ?string
19+
{
20+
$value = (new Parameter($this->value))->asString($row);
21+
$prefix = (new Parameter($this->prefix))->asString($row);
22+
23+
if ($value === null) {
24+
return null;
25+
}
26+
27+
if ($prefix === null || $prefix === '') {
28+
return $value;
29+
}
30+
31+
return s($value)->ensureStart($prefix)->toString();
32+
}
33+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Flow\Types\DSL\type_integer;
8+
use function Symfony\Component\String\u;
9+
use Flow\ETL\Row;
10+
11+
final class IndexOfLast extends ScalarFunctionChain
12+
{
13+
public function __construct(
14+
private readonly ScalarFunction|string $string,
15+
private readonly ScalarFunction|string $needle,
16+
private readonly ScalarFunction|bool $ignoreCase = false,
17+
private readonly ScalarFunction|int $offset = 0,
18+
) {
19+
}
20+
21+
public function eval(Row $row) : int|false|null
22+
{
23+
$string = (new Parameter($this->string))->asString($row);
24+
$needle = (new Parameter($this->needle))->asString($row);
25+
$offset = type_integer()->assert((new Parameter($this->offset))->as($row, type_integer()));
26+
$ignoreCase = (new Parameter($this->ignoreCase))->asBoolean($row);
27+
28+
if ($string === null || $needle === null) {
29+
return false;
30+
}
31+
32+
if ($ignoreCase) {
33+
return u($string)->ignoreCase()->indexOfLast($needle, $offset);
34+
}
35+
36+
return u($string)->indexOfLast($needle, $offset);
37+
}
38+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Symfony\Component\String\s;
8+
use Flow\ETL\Row;
9+
10+
final class IsEmpty extends ScalarFunctionChain
11+
{
12+
public function __construct(
13+
private readonly ScalarFunction|string $value,
14+
) {
15+
}
16+
17+
public function eval(Row $row) : ?bool
18+
{
19+
$value = (new Parameter($this->value))->asString($row);
20+
21+
if ($value === null) {
22+
return null;
23+
}
24+
25+
return s($value)->isEmpty();
26+
}
27+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Function;
6+
7+
use function Symfony\Component\String\s;
8+
use Flow\ETL\Row;
9+
10+
final class Prepend extends ScalarFunctionChain
11+
{
12+
public function __construct(
13+
private readonly ScalarFunction|string $value,
14+
private readonly ScalarFunction|string $prefix,
15+
) {
16+
}
17+
18+
public function eval(Row $row) : ?string
19+
{
20+
$value = (new Parameter($this->value))->asString($row);
21+
$prefix = (new Parameter($this->prefix))->asString($row);
22+
23+
if ($value === null) {
24+
return null;
25+
}
26+
27+
if ($prefix === null) {
28+
return $value;
29+
}
30+
31+
return s($value)->prepend($prefix)->toString();
32+
}
33+
}

0 commit comments

Comments
 (0)