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

"stricter" mode for input types? #3

Closed
Ocramius opened this issue Nov 29, 2021 · 6 comments
Closed

"stricter" mode for input types? #3

Ocramius opened this issue Nov 29, 2021 · 6 comments

Comments

@Ocramius
Copy link
Contributor

Currently, the default behavior of this library is to go through automatic casting, similar to what PHP does with implicit type coercion.

This is probably fine for most use-cases, so this issue is just a question: is it possible to force the library to require exact types as input?

The reason is mostly to avoid issues like floating point -> integer conversion (or the opposite) happening by accident: requiring API clients to provide cleaner data, rather than being "lax" about it.

In following example, all is good:

<?php

namespace My\App;

use CuyZ\Valinor\Attribute\StaticMethodConstructor;
use CuyZ\Valinor\Mapper\MappingError;
use CuyZ\Valinor\MapperBuilder;

require_once __DIR__ . '/Valinor/vendor/autoload.php';

class MyIntWrapper
{
    public int $value;
}

$mapper = (new MapperBuilder())
    ->withCacheDir(__DIR__ . '/cache')
    ->mapper();

var_dump($mapper->map(MyIntWrapper::class, ['value' => 1.0]));
php example.php 
object(My\App\MyIntWrapper)#75 (1) {
  ["value"]=>
  int(1)
}

This is fine, but should there be a rounding error outside what PHP's floating point precision can handle, we would likely have an issue here.

@romm
Copy link
Member

romm commented Dec 7, 2021

Hi @Ocramius, from what I see the only possible issue would be float to int conversion (the opposite should never be a problem IMO). My knowledge is quite low on this topic, you think that something like 1.0000001 could be cast to 1? If that's the case we'll find a solution for this case.

For other scalars, I'd like your feedback on how a mixed can be cast to bool, see:

public function canCast($value): bool
{
return is_bool($value)
|| $value === '1'
|| $value === '0'
|| $value === 1
|| $value === 0
|| $value === 'true'
|| $value === 'false';
}

@dvaeversted
Copy link

I would love a way to enforce strictness as well, especially when handling data received as input through an API.

If i have specified an API endpoint to accept integers in a certain field, i would never expect a numeric string to work in such a field.
In case the serializer or similar is changed later on, it would either risk breaking existing consumers of the API or require the same "loose" logic to be implemented.

@romm
Copy link
Member

romm commented Feb 22, 2022

Hi @dvaeversted that's an interesting point indeed. I will definitely think about a solution to this and keep you updated in this issue.

@romm
Copy link
Member

romm commented Jun 17, 2022

Hi @dvaeversted, I finally managed to handle properly strict rules in the mapper. Any chance you take a look at #159, try it out on your side and give feedback?

@romm
Copy link
Member

romm commented Jun 23, 2022

Released as 0.11.0. Enjoy!

@romm romm closed this as completed Jun 23, 2022
@Ocramius
Copy link
Contributor Author

Nice!

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

3 participants