Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do you supports default property value for readonly properties? #70

Open
roquie opened this issue Jan 31, 2022 · 5 comments
Open

Do you supports default property value for readonly properties? #70

roquie opened this issue Jan 31, 2022 · 5 comments

Comments

@roquie
Copy link

roquie commented Jan 31, 2022

Example:

class Acme {
  public function __construct(
      #[DefaultValue('bar')]
      private readonly string $foo,
      private readonly string $baz,
  ) {}
}

Let's map it:

map(Acme::class, [
    'baz' => 'test'
]);

Expected result:

[
  'foo' => 'bar',
  'baz' => 'test'
]

m?

@romm
Copy link
Member

romm commented Jan 31, 2022

Default value is an existing PHP feature, if you want to take advantage of it just use it as below, the mapper will handle it properly.

class Acme {
  public function __construct(
      private readonly string $baz,
      private readonly string $foo = 'bar',
  ) {}
}

@roquie
Copy link
Author

roquie commented Feb 1, 2022

Your example will be successful for non read only properties. Attempting to hydration read only property with field who has default value will throw an PHP error (should be declared once).

My question is about opportunity to have filled read only property after hydration if it presented or to set default value it from attribute.

@romm
Copy link
Member

romm commented Feb 1, 2022

Ok I see the issue here, you're talking about properties that are not promoted.

Indeed the following code fails hard:

class Acme {
    private readonly string $foo = 'bar';
    private readonly string $baz;
}

I'll think about a solution, but you're probably right: an attribute looks like the best way to do it.

@roquie
Copy link
Author

roquie commented Feb 2, 2022

Thanks! I hope to see this feature :)

Attributes also can help convert source value to typed property (interface or object).

For example:

class Acme {
  public function __construct(
      #[FieldMapper\RamseyUuid] 
      private readonly UuidInterface $foo,
      private readonly string $baz,
  ) {}
}
// ...
map(Acme::class, [
     'foo' => '58054f1d-fbfc-4349-9c4a-4d7f22b63369',
    'baz' => 'test'
]);

It real use case from my application.

@romm
Copy link
Member

romm commented Feb 2, 2022

Attributes also can help convert source value to typed property (interface or object).

This is actually an existing feature, not documented yet because there are chances the API will soon change.

You can use the following:

(new \CuyZ\Valinor\MapperBuilder())
    ->infer(UuidInterface::class, fn () => RamseyUuid::class)
    ->map(SomeClass::class, [/* … */];

But once again, be aware that this API may change soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants