1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus MCP SDK package.
7: *
8: * (c) 2026 John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Mcp\Core\Schema\Elicitation;
15:
16: use Nexus\Assert\Assert;
17:
18: /**
19: * Use `TitledSingleSelectEnumSchema` instead. This interface will be removed in a future version.
20: *
21: * @implements EnumSchema<array{
22: * type: 'string',
23: * enum: list<non-empty-string>,
24: * title?: non-empty-string,
25: * description?: non-empty-string,
26: * enumNames?: list<non-empty-string>,
27: * default?: string,
28: * }>
29: *
30: * @see https://modelcontextprotocol.io/specification/2026-07-28/schema#legacytitledenumschema
31: */
32: final readonly class LegacyTitledEnumSchema implements EnumSchema
33: {
34: public const string TYPE = 'string';
35:
36: /**
37: * @param list<non-empty-string> $enum
38: * @param null|non-empty-string $title
39: * @param null|non-empty-string $description
40: * @param null|list<non-empty-string> $enumNames
41: */
42: public function __construct(
43: public array $enum,
44: public ?string $title = null,
45: public ?string $description = null,
46: public ?array $enumNames = null,
47: public ?string $default = null,
48: ) {
49: Assert::that($enum)
50: ->isList('legacy titled enum schema "enum" must be a list, non-list array given.')
51: ->values()->isNonEmptyString('each legacy titled enum schema "enum" must be a non-empty string.')
52: ;
53: Assert::that($title)->nullOr()->isNonEmptyString('legacy titled enum schema "title" must be a non-empty string or null.');
54: Assert::that($description)->nullOr()->isNonEmptyString('legacy titled enum schema "description" must be a non-empty string or null.');
55:
56: if (null !== $enumNames) {
57: Assert::that($enumNames)
58: ->isList('legacy titled enum schema "enumNames" must be a list, non-list array given.')
59: ->values()->isNonEmptyString('each legacy titled enum schema "enumNames" must be a non-empty string.')
60: ;
61: }
62: }
63:
64: #[\Override]
65: public static function fromArray(array $data): static
66: {
67: Assert::that($data)->hasOffset('type', 'legacy titled enum schema is missing the required "type" key.');
68: $type = $data['type'];
69: Assert::that($type)->isIdentical(self::TYPE, 'legacy titled enum schema "type" must be {other}, {value} given.');
70:
71: Assert::that($data)->hasOffset('enum', 'legacy titled enum schema is missing the required "enum" key.');
72: Assert::that($data['enum'])
73: ->isList('legacy titled enum schema "enum" must be a list, non-list array given.')
74: ->values()->isNonEmptyString('each legacy titled enum schema "enum" must be a non-empty string, {type} given.')
75: ;
76: $enum = $data['enum'];
77:
78: $title = $data['title'] ?? null;
79: Assert::that($title)->nullOr()->isNonEmptyString('legacy titled enum schema "title" must be a non-empty string or null, {type} given.');
80:
81: $description = $data['description'] ?? null;
82: Assert::that($description)->nullOr()->isNonEmptyString('legacy titled enum schema "description" must be a non-empty string or null, {type} given.');
83:
84: $enumNames = null;
85:
86: if (isset($data['enumNames'])) {
87: Assert::that($data['enumNames'])
88: ->isList('legacy titled enum schema "enumNames" must be a list, non-list array given.')
89: ->values()->isNonEmptyString('each legacy titled enum schema "enumNames" must be a non-empty string, {type} given.')
90: ;
91: $enumNames = $data['enumNames'];
92: }
93:
94: $default = $data['default'] ?? null;
95: Assert::that($default)->nullOr()->isString('legacy titled enum schema "default" must be a string or null, {type} given.');
96:
97: return new self(
98: enum: $enum,
99: title: $title,
100: description: $description,
101: enumNames: $enumNames,
102: default: $default,
103: );
104: }
105:
106: #[\Override]
107: public function toArray(): array
108: {
109: $data = [
110: 'type' => self::TYPE,
111: 'enum' => $this->enum,
112: ];
113:
114: if (null !== $this->title) {
115: $data['title'] = $this->title;
116: }
117:
118: if (null !== $this->description) {
119: $data['description'] = $this->description;
120: }
121:
122: if (null !== $this->enumNames) {
123: $data['enumNames'] = $this->enumNames;
124: }
125:
126: if (null !== $this->default) {
127: $data['default'] = $this->default;
128: }
129:
130: return $data;
131: }
132:
133: #[\Override]
134: public function jsonSerialize(): array
135: {
136: return $this->toArray();
137: }
138: }
139: