parsica-php / parsica

Parsica - PHP Parser Combinators - The easiest way to build robust parsers.
https://parsica-php.github.io/
MIT License
405 stars 18 forks source link

Float should not parse to string but to a custom float object #13

Open mathiasverraes opened 4 years ago

mallardduck commented 3 years ago

@mathiasverraes - Wondering what your thoughts were on this one? I'd be happy to contribute a PR for this feature and update tests too. Doing a quick implementation of things while it can work, one short coming I found is mapping a custom object to a float becomes harder.

Currently floatval can be used with map, but with a custom object that callback breaks. Seems like a short coming of PHP as it doesn't provide a Floatable contract similar to Stringable. Certainly not something I've considered until now, but it would be pretty cool if PHP added similar *able interfaces for other primitives. Seems like a neat half-way between not having them (now) and past suggestions for class like primitives that failed.

Anyway, like I said I'm really interested in supporting parisca and helping out here. So I'm curious if you have some more input here. This would be the gist of the concept I have so far:

class FloatObject implements \Stringable
{
    /**
     * @var float
     */
    private float $value;

    /**
     * @param float $value
     */
    private function __construct(float $value)
    {
        $this->value = $value;
    }

    /**
     * @param string|int|float $value
     *
     * @return FloatObject
     */
    public static function make($value): FloatObject
    {
        if (false === filter_var($value, FILTER_VALIDATE_FLOAT)) {
            throw new \RuntimeException("The input value cannot be properly parsed to a float.");
        }
        return new static((float) $value);
    }

    public function toFloat(): float
    {
        return $this->value;
    }

    public function toInteger(): int
    {
        return (int) round($this->value);
    }

    public function __toString(): string
    {
        return (string) $this->value;
    }
}