99
1010class StringType implements TypeInterface
1111{
12+ protected const NULL_TO_STRING = '' ;
13+ protected const TRUE_TO_STRING = 'true ' ;
14+ protected const FALSE_TO_STRING = 'false ' ;
15+ protected const NAN_TO_STRING = 'nan ' ;
16+ protected const INF_TO_STRING = 'inf ' ;
17+
1218 public function match (mixed $ value , Context $ context ): bool
1319 {
1420 return \is_string ($ value );
@@ -21,14 +27,42 @@ public function match(mixed $value, Context $context): bool
2127 */
2228 public function cast (mixed $ value , Context $ context ): string
2329 {
24- if ($ this -> match ($ value, $ context )) {
30+ if (\is_string ($ value )) {
2531 /** @var string */
2632 return $ value ;
2733 }
2834
35+ if (!$ context ->isStrictTypesEnabled ()) {
36+ return $ this ->tryCast ($ value , $ context );
37+ }
38+
2939 throw InvalidValueException::createFromContext (
3040 value: $ value ,
3141 context: $ context ,
3242 );
3343 }
44+
45+ /**
46+ * @throws InvalidValueException
47+ */
48+ private function tryCast (mixed $ value , Context $ context ): string
49+ {
50+ return match (true ) {
51+ $ value === null => static ::NULL_TO_STRING ,
52+ $ value === true => static ::TRUE_TO_STRING ,
53+ $ value === false => static ::FALSE_TO_STRING ,
54+ \is_float ($ value ) => match (true ) {
55+ \is_nan ($ value ) => static ::NAN_TO_STRING ,
56+ \is_infinite ($ value ) => ($ value >= 0 ? '' : '- ' ) . static ::INF_TO_STRING ,
57+ default => (string ) $ value ,
58+ },
59+ \is_int ($ value ),
60+ $ value instanceof \Stringable => (string ) $ value ,
61+ $ value instanceof \BackedEnum => (string ) $ value ->value ,
62+ default => throw InvalidValueException::createFromContext (
63+ value: $ value ,
64+ context: $ context ,
65+ ),
66+ };
67+ }
3468}
0 commit comments