Parse and validate AT Protocol Lexicons with DTO generation for Laravel
at dev 3.1 kB view raw
1<?php 2 3namespace SocialDept\AtpSchema\Data\Types; 4 5use SocialDept\AtpSchema\Data\TypeDefinition; 6use SocialDept\AtpSchema\Exceptions\RecordValidationException; 7 8class IntegerType extends TypeDefinition 9{ 10 /** 11 * Minimum value. 12 */ 13 public readonly ?int $minimum; 14 15 /** 16 * Maximum value. 17 */ 18 public readonly ?int $maximum; 19 20 /** 21 * Allowed enum values. 22 * 23 * @var array<int>|null 24 */ 25 public readonly ?array $enum; 26 27 /** 28 * Constant value. 29 */ 30 public readonly ?int $const; 31 32 /** 33 * Create a new IntegerType. 34 * 35 * @param array<int>|null $enum 36 */ 37 public function __construct( 38 ?string $description = null, 39 ?int $minimum = null, 40 ?int $maximum = null, 41 ?array $enum = null, 42 ?int $const = null 43 ) { 44 parent::__construct('integer', $description); 45 46 $this->minimum = $minimum; 47 $this->maximum = $maximum; 48 $this->enum = $enum; 49 $this->const = $const; 50 } 51 52 /** 53 * Create from array data. 54 */ 55 public static function fromArray(array $data): self 56 { 57 return new self( 58 description: $data['description'] ?? null, 59 minimum: $data['minimum'] ?? null, 60 maximum: $data['maximum'] ?? null, 61 enum: $data['enum'] ?? null, 62 const: $data['const'] ?? null 63 ); 64 } 65 66 /** 67 * Convert to array. 68 */ 69 public function toArray(): array 70 { 71 $array = ['type' => $this->type]; 72 73 if ($this->description !== null) { 74 $array['description'] = $this->description; 75 } 76 77 if ($this->minimum !== null) { 78 $array['minimum'] = $this->minimum; 79 } 80 81 if ($this->maximum !== null) { 82 $array['maximum'] = $this->maximum; 83 } 84 85 if ($this->enum !== null) { 86 $array['enum'] = $this->enum; 87 } 88 89 if ($this->const !== null) { 90 $array['const'] = $this->const; 91 } 92 93 return $array; 94 } 95 96 /** 97 * Validate a value against this type definition. 98 */ 99 public function validate(mixed $value, string $path = ''): void 100 { 101 if (! is_int($value)) { 102 throw RecordValidationException::invalidType($path, 'integer', gettype($value)); 103 } 104 105 // Const validation 106 if ($this->const !== null && $value !== $this->const) { 107 throw RecordValidationException::invalidValue($path, "must equal {$this->const}"); 108 } 109 110 // Enum validation 111 if ($this->enum !== null && ! in_array($value, $this->enum, true)) { 112 throw RecordValidationException::invalidValue($path, 'must be one of: '.implode(', ', $this->enum)); 113 } 114 115 // Range validation 116 if ($this->minimum !== null && $value < $this->minimum) { 117 throw RecordValidationException::invalidValue($path, "must be at least {$this->minimum}"); 118 } 119 120 if ($this->maximum !== null && $value > $this->maximum) { 121 throw RecordValidationException::invalidValue($path, "must be at most {$this->maximum}"); 122 } 123 } 124}