1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134:
<?php
namespace esperecyan\webidl\lib;
use esperecyan\webidl\Record;
class DictionaryType
{
use Utility;
private static function convertToArrayAccess($value)
{
if ($value instanceof \ArrayAccess) {
$array = $value;
} elseif ($value instanceof \Traversable) {
$array = SequenceType::convertToRewindable($value);
if ($array instanceof \Traversable) {
set_error_handler(function ($severity, $message) {
return $severity === E_WARNING
? $message === 'Illegal offset type'
: preg_match('/^Resource ID#([0-9]+) used as offset, casting to integer \\(\\1\\)$/', $message);
}, E_WARNING | (PHP_MAJOR_VERSION === 5 ? E_STRICT : E_NOTICE));
$array = iterator_to_array($array);
restore_error_handler();
}
} else {
$array = (array)$value;
}
return $array;
}
public static function toDictionary($value, $identifier, $pseudoTypes)
{
$array = self::convertToArrayAccess($value);
$dictionary = [];
foreach ($pseudoTypes[$identifier] as $dictionaryMemberIdentifier => $dictionaryMemberInfo) {
if (isset($array[$dictionaryMemberIdentifier])) {
$dictionaryMember = $array[$dictionaryMemberIdentifier];
try {
$dictionary[$dictionaryMemberIdentifier]
= Type::to($dictionaryMemberInfo['type'], $dictionaryMember, $pseudoTypes);
} catch (\LogicException $exception) {
if ($exception instanceof \InvalidArgumentException || $exception instanceof \DomainException) {
throw new \DomainException(sprintf(
'In "%s" member of %s, expected %s',
$dictionaryMemberIdentifier,
$identifier,
$dictionaryMemberInfo['type']
), 0, $exception);
} else {
throw $exception;
}
}
} elseif (array_key_exists('default', $dictionaryMemberInfo)) {
$dictionary[$dictionaryMemberIdentifier] = $dictionaryMemberInfo['default'];
} elseif (isset($dictionaryMemberInfo['required'])) {
throw new \DomainException(sprintf(
'In "%s" member of %s, expected %s, got none',
$dictionaryMemberIdentifier,
$identifier,
$dictionaryMemberInfo['type']
));
}
}
return $dictionary;
}
public static function toRecord($traversable, $keyType, $valueType, $pseudoTypes = [])
{
$exceptionMessage = ErrorMessageCreator::create(
null,
sprintf('%s (an associative array including only %s)', "record<$keyType, $valueType>", $valueType),
''
);
$entries = [];
foreach (SequenceType::convertToRewindable($traversable) as $key => $value) {
try {
$entry[0] = Type::to($keyType, $key, $pseudoTypes);
} catch (\LogicException $exception) {
if ($exception instanceof \InvalidArgumentException || $exception instanceof \DomainException) {
throw new \DomainException($exceptionMessage, 0, $exception);
} else {
throw $exception;
}
}
try {
$entry[1] = Type::to($valueType, $value, $pseudoTypes);
} catch (\LogicException $exception) {
if ($exception instanceof \InvalidArgumentException || $exception instanceof \DomainException) {
throw new \DomainException($exceptionMessage, 0, $exception);
} else {
throw $exception;
}
}
$entries[] = $entry;
}
return new Record($entries);
}
}