Skip to content

Commit 883a8cc

Browse files
Add support for single-argument cast functions (#59)
* Add support for single-argument cast functions * Update docblocks. --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent af1a395 commit 883a8cc

File tree

4 files changed

+107
-10
lines changed

4 files changed

+107
-10
lines changed

src/DataModel.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use ReflectionAttribute;
66
use ReflectionClass;
77
use ReflectionException;
8+
use ReflectionFunction;
9+
use ReflectionMethod;
810
use ReflectionUnionType;
911
use UnitEnum;
1012

@@ -247,7 +249,12 @@ public static function from(array|object|null|string $context = [], mixed $insta
247249

248250
/** Property-level Cast */
249251
if (isset($Describe->cast)) {
250-
$self->{$property_name} = ($Describe->cast)($context[$context_key] ?? null, $context, $Attribute, $ReflectionProperty);
252+
$param_count = (new (is_array($Describe->cast) ? ReflectionMethod::class : ReflectionFunction::class)(...(array)$Describe->cast))
253+
->getNumberOfParameters();
254+
255+
$self->{$property_name} = $param_count === 1
256+
? ($Describe->cast)($context[$context_key] ?? null)
257+
: ($Describe->cast)($context[$context_key] ?? null, $context, $Attribute, $ReflectionProperty);
251258

252259
/** Property-level Post Hook */
253260
if (isset($Describe->post)) {

src/Describe.php

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,33 +102,90 @@
102102
#[Attribute]
103103
class Describe
104104
{
105+
/**
106+
* @link https://github.com/zero-to-prod/data-model
107+
*/
105108
public const missing_as_null = 'missing_as_null';
106-
/** @see $from */
109+
/**
110+
* @see $from
111+
* @link https://github.com/zero-to-prod/data-model
112+
*/
107113
public const from = 'from';
114+
/**
115+
* @link https://github.com/zero-to-prod/data-model
116+
*/
108117
public string $from;
109-
/** @see $cast */
118+
/**
119+
* @see $cast
120+
* @link https://github.com/zero-to-prod/data-model
121+
*/
110122
public const cast = 'cast';
123+
/**
124+
* @link https://github.com/zero-to-prod/data-model
125+
*/
111126
public string|array $cast;
112-
/** @see $required */
127+
/**
128+
* @see $required
129+
* @link https://github.com/zero-to-prod/data-model
130+
*/
113131
public const required = 'required';
132+
/**
133+
* @link https://github.com/zero-to-prod/data-model
134+
*/
114135
public bool $required;
115-
/** @see $default */
136+
/**
137+
* @see $default
138+
* @link https://github.com/zero-to-prod/data-model
139+
*/
116140
public const default = 'default';
141+
/**
142+
* @link https://github.com/zero-to-prod/data-model
143+
*/
117144
public $default;
118-
/** @see $pre */
145+
/**
146+
* @see $pre
147+
* @link https://github.com/zero-to-prod/data-model
148+
*/
119149
public const pre = 'pre';
150+
/**
151+
* @link https://github.com/zero-to-prod/data-model
152+
*/
120153
public $pre;
121-
/** @see $post */
154+
/**
155+
* @see $post
156+
* @link https://github.com/zero-to-prod/data-model
157+
*/
122158
public const post = 'post';
159+
/**
160+
* @link https://github.com/zero-to-prod/data-model
161+
*/
123162
public $post;
124-
/** @see $nullable */
163+
/**
164+
* @see $nullable
165+
* @link https://github.com/zero-to-prod/data-model
166+
*/
125167
public const nullable = 'nullable';
168+
/**
169+
* @link https://github.com/zero-to-prod/data-model
170+
*/
126171
public bool $nullable;
127-
/** @see $ignore */
172+
/**
173+
* @see $ignore
174+
* @link https://github.com/zero-to-prod/data-model
175+
*/
128176
public const ignore = 'ignore';
177+
/**
178+
* @link https://github.com/zero-to-prod/data-model
179+
*/
129180
public bool $ignore;
130-
/** @see $via */
181+
/**
182+
* @see $via
183+
* @link https://github.com/zero-to-prod/data-model
184+
*/
131185
public const via = 'via';
186+
/**
187+
* @link https://github.com/zero-to-prod/data-model
188+
*/
132189
public string|array $via;
133190

134191
/**
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Tests\Unit\Describe\CastSingleArg;
4+
5+
use Zerotoprod\DataModel\DataModel;
6+
use Zerotoprod\DataModel\Describe;
7+
8+
class CastSingleArgModel
9+
{
10+
use DataModel;
11+
12+
#[Describe(['cast' => 'strtolower'])]
13+
public string $name;
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Tests\Unit\Describe\CastSingleArg;
4+
5+
use PHPUnit\Framework\Attributes\Test;
6+
use Tests\TestCase;
7+
8+
class CastSingleArgTest extends TestCase
9+
{
10+
#[Test]
11+
public function cast_with_single_argument_function(): void
12+
{
13+
$model = CastSingleArgModel::from([
14+
'name' => 'HELLO WORLD',
15+
]);
16+
17+
$this->assertEquals('hello world', $model->name);
18+
}
19+
}

0 commit comments

Comments
 (0)