-
Notifications
You must be signed in to change notification settings - Fork 9
Add enum support #57
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
Add enum support #57
Changes from all commits
a3dc02b
f1a2f7b
1659734
cf16661
68da7cb
bfdd9ae
b2ea31f
6ee4ff8
b9b6ca3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,5 +4,3 @@ parameters: | |
| - PHP_VERSION_ID | ||
| paths: | ||
| - src/ | ||
| excludePaths: | ||
| - src/ModelParser/JMSParserLegacy.php | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,6 +48,7 @@ final class ClassMetadata implements \JsonSerializable | |
| public function __construct(string $className, array $properties, array $constructorParameters = [], array $postDeserializeMethods = [], ?ClassDiscriminatorMetadata $discriminatorMetadata = null) | ||
| { | ||
| \assert(array_reduce($constructorParameters, static function (bool $carry, $parameter): bool { | ||
| /* @phpstan-ignore instanceof.alwaysTrue */ | ||
| return $carry && $parameter instanceof ParameterMetadata; | ||
| }, true)); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this can only be removed if we trust phpdoc (aka phpstan is running). as this class is not
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually it will also work fine without phpstan running, as the constructor itself does a foreach over the properties and then calls Do you still want me to change it back?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is about the $constructorParameters, not about the $properties. the $constructorParameters are assigned to an array 2 lines after this. i think we should add the check back to make sure the error is reported in the constructor.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added it back, but I also had to add a |
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Liip\MetadataParser\Metadata; | ||
|
|
||
| use Liip\MetadataParser\Exception\InvalidTypeException; | ||
|
|
||
| final class PropertyTypeEnum extends AbstractPropertyType | ||
| { | ||
| private string $className; | ||
| private ?string $backingType; | ||
|
|
||
| private ?SerializationMode $serializationMode; | ||
|
|
||
| public function __construct(string $className, bool $nullable, ?SerializationMode $serializationMode = null) | ||
| { | ||
| parent::__construct($nullable); | ||
| if (!enum_exists($className)) { | ||
| throw new InvalidTypeException(\sprintf('Given type "%s" is not a PHP 8.1 enum', $className)); | ||
| } | ||
|
|
||
| $this->className = $className; | ||
| $this->backingType = null; | ||
| $this->serializationMode = $serializationMode; | ||
|
|
||
| $reflEnum = new \ReflectionEnum($className); | ||
| $backingType = $reflEnum->getBackingType(); | ||
| if ($backingType instanceof \ReflectionNamedType) { | ||
| $this->backingType = $backingType->getName(); | ||
| } | ||
| } | ||
|
|
||
| public function __toString(): string | ||
| { | ||
| return $this->className.parent::__toString(); | ||
| } | ||
|
|
||
| public function getClassName(): string | ||
| { | ||
| return $this->className; | ||
| } | ||
|
|
||
| public function getBackingType(): ?string | ||
| { | ||
| return $this->backingType; | ||
| } | ||
|
|
||
| public function isBackedEnum(): bool | ||
| { | ||
| return null !== $this->backingType; | ||
| } | ||
|
|
||
| public function getSerializationMode(): ?SerializationMode | ||
| { | ||
| return $this->serializationMode; | ||
| } | ||
|
|
||
| public function shouldSerializeAsValue(): bool | ||
| { | ||
| return $this->isBackedEnum() && SerializationMode::Name !== $this->serializationMode; | ||
| } | ||
|
|
||
| public function merge(PropertyType $other): PropertyType | ||
| { | ||
| $nullable = $this->isNullable() && $other->isNullable(); | ||
|
|
||
| if ($other instanceof PropertyTypeUnknown) { | ||
| return new self($this->className, $nullable, $this->serializationMode); | ||
| } | ||
|
|
||
| if (!$other instanceof self) { | ||
| throw new \UnexpectedValueException(\sprintf('Can\'t merge type %s with %s, they must be the same or unknown', self::class, \get_class($other))); | ||
| } | ||
|
|
||
| if ($this->getClassName() !== $other->getClassName()) { | ||
| throw new \UnexpectedValueException(\sprintf('Can\'t merge type %s with %s, they must be equal', self::class, \get_class($other))); | ||
| } | ||
|
|
||
| if (null !== $this->serializationMode && null !== $other->getSerializationMode() && $this->serializationMode !== $other->getSerializationMode()) { | ||
| throw new \UnexpectedValueException(\sprintf('Can\'t merge type %s with conflicting serialization modes "%s" and "%s"', self::class, $this->serializationMode->value, $other->getSerializationMode()->value)); | ||
| } | ||
|
|
||
| $serializationMode = $this->serializationMode ?? $other->getSerializationMode(); | ||
|
|
||
| return new self($this->className, $nullable, $serializationMode); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Liip\MetadataParser\Metadata; | ||
|
|
||
| enum SerializationMode: string | ||
| { | ||
| case Value = 'value'; | ||
| case Name = 'name'; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to exclude these files?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
UnionDiscriminatorfrom JMS exists since version3.31.0, but this library supports^2.3 || ^3of thejms/serializerdepencency. So when installing the composer dependencies in the CI workflow with the options--prefer-stable --prefer-lowest, it will install version3.19.0, which does not include theUnionDiscriminatorand thus phpstan would complain about it.Since those fixture files are not really critical, I thought to just exclude them, but maybe it could also make sense to adjust the minimum required version for
jms/serializer?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, thanks. can you add a comment that we exclude these until only a new enough version of jms serializer is supported. thats good enough imho. the comment will be useful to know when we can stop excluding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done - I amended the change to the original commit bfdd9ae