跳至正文

更新日志 1.13.0 — 2024 年 9 月 2 日

重要变更

时间戳格式的微秒支持

在此补丁之前,这需要一个以下形式的自定义构造函数:

static fn(float | int $timestamp): DateTimeImmutable => new
    DateTimeImmutable(sprintf("@%d", $timestamp)),

这完全绕过了 Valinor 的日期时间格式支持。这是必需的,因为该库不支持浮点数作为有效的DateTimeInterface输入值。

此提交添加了对浮点数的支持,并将timestamp.microseconds ( U.u ) 注册为有效的默认格式。

支持value-of<BackedEnum>类型

该类型可以如下使用:

enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

$suit = (new \CuyZ\Valinor\MapperBuilder())
    ->mapper()
    ->map('value-of<Suit>', 'D');

// $suit === 'D'

对象构造函数参数类型推断改进

检查对象构造函数参数类型的碰撞系统现在更加聪明,因为它不再仅检查参数名称。现在还检查类型,并且仅检测真正的冲突,例如当两个构造函数共享具有相同名称和类型的参数时。

请注意,当两个参数共享相同名称时,将执行以下类型优先级:

  1. 非标量类型
  2. 整数类型
  3. 浮子式
  4. 字符串类型
  5. 布尔类型

经过此更改,下面的代码现在有效:

final readonly class Money
{
    private function __construct(
        public int $value,
    ) {}

    #[\CuyZ\Valinor\Mapper\Object\Constructor]
    public static function fromInt(int $value): self
    {
        return new self($value);
    }

    #[\CuyZ\Valinor\Mapper\Object\Constructor]
    public static function fromString(string $value): self
    {
        if (! preg_match('/^\d+€$/', $value)) {
            throw new \InvalidArgumentException('Invalid money format');
        }

        return new self((int)rtrim($value, '€'));
    }
}

$mapper = (new \CuyZ\Valinor\MapperBuilder())->mapper();

$mapper->map(Money::class, 42); // ✅
$mapper->map(Money::class, '42€'); // ✅

新功能

  • 为时间戳格式添加微秒支持 ( 02bd2e )
  • 添加对value-of<BackedEnum>类型的支持 ( b1017c )
  • 改进对象构造函数参数类型推断( 2150dc )

错误修复

  • 允许类常量类型中的任何常量 ( 694275 )
  • 允许变换器可调用类型的文档块( 69e0e3 )
  • 不要覆盖无效的可变参数类型( c5860f )
  • 处理接口泛型( 40e6fa )
  • 在规范化期间将可迭代对象处理为可迭代 ( 436e3c )
  • 使用 JSON 规范化器正确格式化空对象 ( ba22b5 )
  • 正确处理嵌套的本地类型别名( 127839 )

其他

  • 排除类/函数定义中不需要的特性( 1803d0 )
  • 提高可为空联合类型的映射性能 ( 6fad94 )
  • 在Shell中移动“接受整数值的浮点类型”逻辑 ( 047953 )
  • 在 shell 中移动设置值 ( 84b1ff )
  • 重新组织类型解析器服务 ( 86fb7b )