File tree Expand file tree Collapse file tree
tests/Flow/Types/Tests/Unit/Type/Logical Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1212 InstanceOfType ,
1313 JsonType ,
1414 ListType ,
15+ LiteralType ,
1516 MapType ,
1617 NonEmptyStringType ,
1718 NumericStringType ,
@@ -338,6 +339,19 @@ function type_enum(string $class) : EnumType
338339 return new EnumType ($ class );
339340}
340341
342+ /**
343+ * @template T of bool|float|int|string
344+ *
345+ * @param T $value
346+ *
347+ * @return LiteralType<T>
348+ */
349+ #[DocumentationDSL(module: Module::TYPES , type: DSLType::TYPE )]
350+ function type_literal (bool |float |int |string $ value ) : LiteralType
351+ {
352+ return new LiteralType ($ value );
353+ }
354+
341355/**
342356 * @template T
343357 *
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace Flow \Types \Type \Logical ;
6+
7+ use Flow \Types \Exception \{CastingException , InvalidTypeException };
8+ use Flow \Types \Type ;
9+
10+ /**
11+ * @template T of bool|float|int|string
12+ *
13+ * @implements Type<T>
14+ */
15+ final readonly class LiteralType implements Type
16+ {
17+ /**
18+ * @param T $value
19+ */
20+ public function __construct (
21+ private bool |float |int |string $ value ,
22+ ) {
23+ }
24+
25+ public function assert (mixed $ value ) : bool |float |int |string
26+ {
27+ if ($ this ->isValid ($ value )) {
28+ return $ value ;
29+ }
30+
31+ throw InvalidTypeException::value ($ value , $ this );
32+ }
33+
34+ public function cast (mixed $ value ) : bool |float |int |string
35+ {
36+ if ($ this ->isValid ($ value )) {
37+ return $ value ;
38+ }
39+
40+ throw new CastingException ($ value , $ this );
41+ }
42+
43+ public function isValid (mixed $ value ) : bool
44+ {
45+ return $ value === $ this ->value ;
46+ }
47+
48+ public function normalize () : array
49+ {
50+ return [
51+ 'type ' => 'literal ' ,
52+ 'value ' => (string ) $ this ->value ,
53+ ];
54+ }
55+
56+ public function toString () : string
57+ {
58+ if (\is_string ($ this ->value )) {
59+ return "' {$ this ->value }' " ;
60+ }
61+
62+ if (\is_bool ($ this ->value )) {
63+ return $ this ->value ? 'true ' : 'false ' ;
64+ }
65+
66+ return (string ) $ this ->value ;
67+ }
68+ }
Original file line number Diff line number Diff line change 1212 type_float ,
1313 type_integer ,
1414 type_json ,
15+ type_literal ,
1516 type_mixed ,
1617 type_non_empty_string ,
1718 type_null ,
@@ -64,6 +65,7 @@ public static function fromArray(array $data) : Type
6465 'datetime ' => type_datetime (),
6566 'json ' => type_json (),
6667 'uuid ' => type_uuid (),
68+ 'literal ' => self ::createLiteralFromString ($ data ['value ' ]),
6769 /** @phpstan-ignore argument.type */
6870 'list ' => ListType::fromArray ($ data ),
6971 /** @phpstan-ignore argument.type */
@@ -100,4 +102,28 @@ public static function fromString(string $name) : Type
100102 default => self ::fromArray (['type ' => $ name ]),
101103 };
102104 }
105+
106+ /**
107+ * @return Type<mixed>
108+ */
109+ private static function createLiteralFromString (string $ value ) : Type
110+ {
111+ if ($ value === 'true ' ) {
112+ return type_literal (true );
113+ }
114+
115+ if ($ value === 'false ' ) {
116+ return type_literal (false );
117+ }
118+
119+ if (\is_numeric ($ value )) {
120+ if (\str_contains ($ value , '. ' )) {
121+ return type_literal ((float ) $ value );
122+ }
123+
124+ return type_literal ((int ) $ value );
125+ }
126+
127+ return type_literal ($ value );
128+ }
103129}
You can’t perform that action at this time.
0 commit comments