Lines
100.00%
37 / 37
Methods
100.00%
3 / 3
Classes
100.00%
1 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| supportsDomain | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| emitFile | 100.00% | 35 / 35 | 100.00% | 1 / 1 | 5 | ||
| listReservedMemberNames | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 2 | ||
| 15 | final readonly class EntityStateEmitter implements DomainFileEmitter, ReservesMemberNames | |
| 16 | { | |
| 17 | private const array RESERVED_MEMBER_NAMES = ['raw', 'value', 'fromNullableState', 'isOn', 'isOff', 'getStateAsFloat', 'isUnavailable', 'getFriendlyName']; | |
| 18 | ||
| 19 | public function supportsDomain(DomainModel $domain): bool | |
| 20 | { | |
| 21 | return $domain->hasEntities(); | |
| 22 | } | |
| 23 | ||
| 24 | public function emitFile(DomainModel $domain, EmitContext $context): GeneratedFile | |
| 25 | { | |
| 26 | $namespace = $context->createNamespace(); | |
| 27 | $context->importClass($namespace, EntityState::class, $domain->getStateClass()); | |
| 28 | ||
| 29 | $class = $namespace->addClass($domain->getStateClass()) | |
| 30 | ->setFinal() | |
| 31 | ->setReadOnly() | |
| 32 | ->addComment(\sprintf('What a `%s` entity is doing.', $domain->domain)); | |
| 33 | ||
| 34 | $class->addProperty('value')->setType('string'); | |
| 35 | ||
| 36 | $constructor = $class->addMethod('__construct'); | |
| 37 | $constructor->addPromotedParameter('raw')->setType(EntityState::class)->setPublic(); | |
| 38 | $constructor->setBody('$this->value = $raw->state;'); | |
| 39 | ||
| 40 | $class->addMethod('fromNullableState') | |
| 41 | ->setStatic() | |
| 42 | ->setReturnType('?self') | |
| 43 | ->setBody('return $raw === null ? null : new self($raw);') | |
| 44 | ->addParameter('raw') | |
| 45 | ->setType('?' . EntityState::class); | |
| 46 | ||
| 47 | if ($domain->isOnOff()) { | |
| 48 | $class->addMethod('isOn')->setReturnType('bool')->setBody("return \$this->value === 'on';"); | |
| 49 | $class->addMethod('isOff')->setReturnType('bool')->setBody("return \$this->value === 'off';"); | |
| 50 | } | |
| 51 | ||
| 52 | if ($domain->isNumeric()) { | |
| 53 | $class->addMethod('getStateAsFloat')->setReturnType('?float')->setBody('return $this->raw->getStateAsFloat();'); | |
| 54 | } | |
| 55 | ||
| 56 | $class->addMethod('isUnavailable')->setReturnType('bool')->setBody('return $this->raw->isUnavailable();'); | |
| 57 | $class->addMethod('getFriendlyName')->setReturnType('string')->setBody('return $this->raw->getFriendlyName();'); | |
| 58 | ||
| 59 | foreach ($domain->attributes as $attribute) { | |
| 60 | $type = $attribute->kind->getPhpType(); | |
| 61 | $method = $class->addMethod($attribute->accessor) | |
| 62 | ->setReturnType($type->native) | |
| 63 | ->setBody(\sprintf( | |
| 64 | 'return $this->raw->%s(%s);', | |
| 65 | $attribute->kind->getReaderMethodName(), | |
| 66 | var_export($attribute->name, true), | |
| 67 | )); | |
| 68 | ||
| 69 | if ($type->needsDocblock()) { | |
| 70 | $method->addComment('@return ' . $type->docblock); | |
| 71 | } | |
| 72 | } | |
| 73 | ||
| 74 | return $context->printFile($namespace, $domain->getStateClass()); | |
| 75 | } | |
| 76 | ||
| 77 | public function listReservedMemberNames(MemberScope $scope): array | |
| 78 | { | |
| 79 | return $scope === MemberScope::StateView ? self::RESERVED_MEMBER_NAMES : []; | |
| 80 | } | |
| 81 | } |