Something went wrong. Try again.
Parse and validate AT Protocol Lexicons with DTO generation for Laravel
Something went wrong. Try again.
3.9 kB · 150 lines
PHP
at dev
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151<?php
namespace SocialDept\AtpSchema\Parser;
use SocialDept\AtpSchema\Data\TypeDefinition;use SocialDept\AtpSchema\Data\Types\ArrayType;use SocialDept\AtpSchema\Data\Types\BlobType;use SocialDept\AtpSchema\Data\Types\ObjectType;use SocialDept\AtpSchema\Data\Types\RefType;use SocialDept\AtpSchema\Data\Types\UnionType;use SocialDept\AtpSchema\Exceptions\TypeResolutionException;
class ComplexTypeParser{ /** * Primitive parser for nested types. */ protected PrimitiveParser $primitiveParser;
/** * Type parser for resolving references. */ protected ?object $typeParser = null;
/** * Create a new ComplexTypeParser. */ public function __construct(?PrimitiveParser $primitiveParser = null) { $this->primitiveParser = $primitiveParser ?? new PrimitiveParser(); }
/** * Set the type parser for reference resolution. */ public function setTypeParser(object $typeParser): void { $this->typeParser = $typeParser; }
/** * Parse a complex type definition from array data. * * @throws TypeResolutionException */ public function parse(array $data): TypeDefinition { $type = $data['type'] ?? null;
if ($type === null) { throw TypeResolutionException::unknownType('(missing type field)'); }
return match ($type) { 'object' => $this->parseObject($data), 'array' => $this->parseArray($data), 'union' => UnionType::fromArray($data), 'ref' => RefType::fromArray($data), 'blob' => BlobType::fromArray($data), default => throw TypeResolutionException::unknownType($type), }; }
/** * Parse an object type with nested properties. */ protected function parseObject(array $data): ObjectType { $object = ObjectType::fromArray($data);
// Parse properties if present if (isset($data['properties']) && is_array($data['properties'])) { $properties = [];
foreach ($data['properties'] as $key => $propertyData) { $properties[$key] = $this->parseNestedType($propertyData); }
$object = $object->withProperties($properties); }
return $object; }
/** * Parse an array type with nested items. */ protected function parseArray(array $data): ArrayType { $array = ArrayType::fromArray($data);
// Parse items if present if (isset($data['items']) && is_array($data['items'])) { $items = $this->parseNestedType($data['items']); $array = $array->withItems($items); }
return $array; }
/** * Parse a nested type definition (can be primitive or complex). */ protected function parseNestedType(array $data): TypeDefinition { $type = $data['type'] ?? null;
if ($type === null) { throw TypeResolutionException::unknownType('(missing type field)'); }
// Try primitive types first if ($this->primitiveParser->isPrimitive($type)) { return $this->primitiveParser->parse($data); }
// Try complex types return $this->parse($data); }
/** * Check if a type is a complex type. */ public function isComplex(string $type): bool { return in_array($type, [ 'object', 'array', 'union', 'ref', 'blob', ]); }
/** * Get all supported complex types. * * @return array<string> */ public function getSupportedTypes(): array { return [ 'object', 'array', 'union', 'ref', 'blob', ]; }}