From b4ff9efeb85d467556c633a0b4fdd5947b664065 Mon Sep 17 00:00:00 2001 From: Jonathan Oddy Date: Wed, 30 Apr 2014 17:45:50 +0100 Subject: [PATCH 1/2] Configuration now contains parsed type data. This avoids type parsing at mapping time. --- .../Config/ClassAnnotationDriver.php | 11 +- lib/Weasel/JsonMarshaller/JsonMapper.php | 103 ++++++++---------- .../JsonMarshaller/Utils/TypeParser.php | 43 ++++++++ .../Config/ClassAnnotationDriverTest.php | 10 +- .../Weasel/JsonMarshaller/JsonMapperTest.php | 3 + tests/bootstrap.php | 2 + 6 files changed, 103 insertions(+), 69 deletions(-) create mode 100644 lib/Weasel/JsonMarshaller/Utils/TypeParser.php diff --git a/lib/Weasel/JsonMarshaller/Config/ClassAnnotationDriver.php b/lib/Weasel/JsonMarshaller/Config/ClassAnnotationDriver.php index ddc5b3f..89eaf3d 100644 --- a/lib/Weasel/JsonMarshaller/Config/ClassAnnotationDriver.php +++ b/lib/Weasel/JsonMarshaller/Config/ClassAnnotationDriver.php @@ -16,6 +16,7 @@ use Weasel\JsonMarshaller\Config\IAnnotations\IJsonAnyGetter; use Weasel\JsonMarshaller\Config\IAnnotations\IJsonAnySetter; use Weasel\JsonMarshaller\Config\IAnnotations\IJsonTypeInfo; +use Weasel\JsonMarshaller\Utils\TypeParser; /** * Load the configuration for a given class from annotations @@ -137,7 +138,7 @@ protected function _configureGetter(\ReflectionMethod $method, IJsonProperty $pr throw new \Exception("Serialization for property of name $property has already been configured."); } $getterConfig->method = $name; - $getterConfig->type = $propertyConfig->getType(); + $getterConfig->type = TypeParser::parseType($propertyConfig->getType(), true); $this->config->serialization->properties[$property] = $getterConfig; } @@ -169,7 +170,7 @@ protected function _configureSetter(\ReflectionMethod $method, IJsonProperty $pr } $setterConfig = new Deserialization\SetterDeserialization(); $setterConfig->method = $name; - $setterConfig->type = $propertyConfig->getType(); + $setterConfig->type = TypeParser::parseType($propertyConfig->getType(), true); $setterConfig->typeInfo = $this->_getDeserializationTypeInfo($typeInfo, $subTypes); $setterConfig->strict = $propertyConfig->getStrict(); @@ -213,7 +214,7 @@ protected function _configureCreator(\ReflectionMethod $method, IJsonCreator $cr foreach ($creatorConfig->getParams() as $paramConfig) { $param = new Deserialization\Param(); $param->name = $paramConfig->getName(); - $param->type = $paramConfig->getType(); + $param->type = TypeParser::parseType($paramConfig->getType(), true); $param->strict = $paramConfig->getStrict(); if (!isset($param->name)) { if (!isset($paramNames[$i])) { @@ -284,7 +285,7 @@ protected function _configureProperty(\ReflectionProperty $property) if (!isset($this->config->deserialization->properties[$propertyName])) { $setterConfig = new Deserialization\DirectDeserialization(); $setterConfig->property = $name; - $setterConfig->type = $propertyConfig->getType(); + $setterConfig->type = TypeParser::parseType($propertyConfig->getType(), true); $setterConfig->typeInfo = $this->_getDeserializationTypeInfo($typeInfo, $subTypes); $this->config->deserialization->properties[$propertyName] = $setterConfig; @@ -294,7 +295,7 @@ protected function _configureProperty(\ReflectionProperty $property) if (!isset($this->config->serialization->properties[$propertyName])) { $getterConfig = new Serialization\DirectSerialization(); $getterConfig->property = $name; - $getterConfig->type = $propertyConfig->getType(); + $getterConfig->type = TypeParser::parseType($propertyConfig->getType(), true); /** * @var Annotations\JsonInclude $includer diff --git a/lib/Weasel/JsonMarshaller/JsonMapper.php b/lib/Weasel/JsonMarshaller/JsonMapper.php index b0cff38..94c887c 100644 --- a/lib/Weasel/JsonMarshaller/JsonMapper.php +++ b/lib/Weasel/JsonMarshaller/JsonMapper.php @@ -13,6 +13,7 @@ use Weasel\JsonMarshaller\Types\OldTypeWrapper; use Weasel\JsonMarshaller\Exception\JsonMarshallerException; use Weasel\JsonMarshaller\Config\JsonConfigProvider; +use Weasel\JsonMarshaller\Utils\TypeParser; class JsonMapper { @@ -76,7 +77,7 @@ public function readString($string, $type, $strict = null) if ($strict === null) { $strict = $this->strict; } - return $this->_decodeValue($decoded, $type, $strict); + return $this->_decodeValue($decoded, TypeParser::parseType($type, true), $strict); } /** @@ -128,7 +129,7 @@ public function writeString($data, $type = null) if (!isset($type)) { $type = $this->_guessType($data); } - return $this->_encodeValue($data, $type); + return $this->_encodeValue($data, TypeParser::parseType($type, true)); } /** @@ -276,7 +277,7 @@ protected function _encodeObject($object, $typeInfo = null, $type = null) break; } $property = $typeInfo->typeInfoProperty; - $properties[$property] = $this->_encodeValue($classId, "string"); + $properties[$property] = $this->_encodeValue($classId, array(TypeParser::TYPE_SCALAR, "string")); break; case Config\Serialization\TypeInfo::TI_AS_WRAPPER_ARRAY: // We're actually going to encase this encoded object in an array containing the classId. @@ -284,7 +285,7 @@ protected function _encodeObject($object, $typeInfo = null, $type = null) break; } return '[' . $this->_encodeValue($classId, - 'string') . ', ' . $this->_objectToJson($properties) . ']'; + array(TypeParser::TYPE_SCALAR, 'string')) . ', ' . $this->_objectToJson($properties) . ']'; break; case Config\Serialization\TypeInfo::TI_AS_WRAPPER_OBJECT: // Very similar yo the wrapper array case, but this time it's a map from the classId to the object. @@ -292,7 +293,7 @@ protected function _encodeObject($object, $typeInfo = null, $type = null) break; } return '{' . $this->_encodeValue($classId, - 'string') . ': ' . $this->_objectToJson($properties) . '}'; + array(TypeParser::TYPE_SCALAR, 'string')) . ': ' . $this->_objectToJson($properties) . '}'; break; default: throw new \Exception("Unsupported type info storage at class level"); @@ -307,7 +308,7 @@ protected function _objectToJson($properties) { $elements = array(); foreach ($properties as $key => $property) { - $elements[] = $this->_encodeValue($key, 'string') . ': ' . $property; + $elements[] = $this->_encodeValue($key, array(TypeParser::TYPE_SCALAR, 'string')) . ': ' . $property; } return '{' . implode(', ', $elements) . '}'; } @@ -472,37 +473,24 @@ protected function _decodeClass($array, $class, $strict) } - protected function _parseType($type) - { - if (isset($this->typeHandlers[$type])) { - // Assumption: if there's a type handler for this type string, then it's the right thing to use. - return array($type, $this->typeHandlers[$type]); - } - - // Assume type strings are well formed: look for the last [ to see if it's an array or map. - // Note that this might be an array of arrays, and we're after the outermost type, so we're after the last [! - $pos = strrpos($type, '['); - if ($pos === false) { - // If there wasn't a [ then this must be an object. - return array("complex"); + protected function _parseType($type) { + if (!is_array($type)) { + if (defined('E_USER_DEPRECATED')) { + // TODO: need to handle serialized configs before we can properly deprecate this. +// trigger_error("Use of unexpanded types is deprecated", E_USER_DEPRECATED); + } + // This is the really slow path. + $type = TypeParser::parseType($type, false); } - - // Extract the base type, and whatever's between the [...] as the index type. - // Potentially the type string is actually badly formed: - // e.g. this code will accept string[int! as being an array of string with index int. - // Bah. I'll ignore that case for now. This bit of code gets called a lot, I'd rather not add another substr. - $elementType = substr($type, 0, $pos); - $indexType = substr($type, $pos + 1, -1); - - if ($indexType === "") { - // The [...] were empty. It's an array. - return array("array", $elementType); + if ($type[0] == TypeParser::TYPE_SCALAR) { + if (isset($this->typeHandlers[$type[1]])) { + // Assumption: if there's a type handler for this type string, then it's the right thing to use. + return array(TypeParser::TYPE_SCALAR, $type[1], $this->typeHandlers[$type[1]]); + } else { + return array(TypeParser::TYPE_OBJECT, $type[1]); + } } - // Must be a map then. - return array("map", - $indexType, - $elementType - ); + return $type; } protected function _decodeKey($value, $type) @@ -511,13 +499,12 @@ protected function _decodeKey($value, $type) throw new JsonMarshallerException("Key values cannot be null"); } $typeData = $this->_parseType($type); - switch (array_shift($typeData)) { - case "complex": - case "array": - throw new JsonMarshallerException("Keys must be of type int or string, not " . $type); - default: + switch ($typeData[0]) { + case TypeParser::TYPE_SCALAR: // Keys are always strings, however we will allow other types, and disable strict type checking. - return $this->_decodeValue($value, $type, false); + return $this->_decodeValue($value, $typeData, false); + default: + throw new JsonMarshallerException("Keys must be of type int or string, not " . $type); } } @@ -528,16 +515,15 @@ protected function _decodeValue($value, $type, $strict) } $typeData = $this->_parseType($type); switch (array_shift($typeData)) { - case "complex": + case TypeParser::TYPE_OBJECT: if (!is_array($value)) { - throw new InvalidTypeException($type, $value); + throw new InvalidTypeException($typeData[0], $value); } - return $this->_decodeClass($value, $type, $strict); + return $this->_decodeClass($value, $typeData[0], $strict); break; /** @noinspection PhpMissingBreakStatementInspection */ - case "array": - array_unshift($typeData, 'int'); - case "map": + case TypeParser::TYPE_LIST: + case TypeParser::TYPE_MAP: list ($indexType, $elementType) = $typeData; $result = array(); if (!is_array($value)) { @@ -552,7 +538,7 @@ protected function _decodeValue($value, $type, $strict) /** * @var $typeHandler Types\JsonType */ - list ($typeHandler) = $typeData; + list ($typeName, $typeHandler) = $typeData; return $typeHandler->decodeValue($value, $this, $strict); } @@ -566,11 +552,10 @@ protected function _encodeKey($value, $type) $typeData = $this->_parseType($type); switch (array_shift($typeData)) { /** @noinspection PhpMissingBreakStatementInspection */ - case "complex": - case "array": - throw new JsonMarshallerException("Keys must be of type int or string, not " . $type); + case TypeParser::TYPE_SCALAR: + return $this->_encodeValue($value, array(TypeParser::TYPE_SCALAR, "string")); default: - return $this->_encodeValue($value, "string"); + throw new JsonMarshallerException("Keys must be of type int or string, not " . $type); } } @@ -588,14 +573,14 @@ protected function _encodeValue($value, $type, $typeInfo = null) } $typeData = $this->_parseType($type); switch (array_shift($typeData)) { - case "complex": + case TypeParser::TYPE_OBJECT: if (!is_object($value)) { - throw new InvalidTypeException($type, $value); + throw new InvalidTypeException($typeData[0], $value); } - return $this->_encodeObject($value, $typeInfo, $type); + return $this->_encodeObject($value, $typeInfo, $typeData[0]); break; - case "array": - list ($elementType) = $typeData; + case TypeParser::TYPE_LIST: + list ($indexType, $elementType) = $typeData; if (!is_array($value)) { $value = array($value); } @@ -604,7 +589,7 @@ protected function _encodeValue($value, $type, $typeInfo = null) $elements[] = $this->_encodeValue($element, $elementType); } return '[' . implode(', ', $elements) . ']'; - case "map": + case TypeParser::TYPE_MAP: list ($indexType, $elementType) = $typeData; if (!is_array($value)) { $value = array($value); @@ -619,7 +604,7 @@ protected function _encodeValue($value, $type, $typeInfo = null) /** * @var $typeHandler Types\JsonType */ - list ($typeHandler) = $typeData; + list ($typeName, $typeHandler) = $typeData; return $typeHandler->encodeValue($value, $this); } diff --git a/lib/Weasel/JsonMarshaller/Utils/TypeParser.php b/lib/Weasel/JsonMarshaller/Utils/TypeParser.php new file mode 100644 index 0000000..aa24284 --- /dev/null +++ b/lib/Weasel/JsonMarshaller/Utils/TypeParser.php @@ -0,0 +1,43 @@ +getConfig(); $eProperties = array( - "stuff" => new GetterSerialization("getStuff", "string", 1), - "good" => new GetterSerialization("isGood", "bool", 1), + "stuff" => new GetterSerialization("getStuff", array("scalar", "string"), 1), + "good" => new GetterSerialization("isGood", array("scalar", "bool"), 1), ); $this->assertEquals($eProperties, $config->serialization->properties); @@ -65,7 +65,7 @@ public function testGetterNameIsNoBool() ); $mockReader->shouldReceive('getSingleMethodAnnotation')->with('isGood', '\Weasel\JsonMarshaller\Config\Annotations\JsonProperty')->andReturn( - new JsonProperty(null, "string", null) + new JsonProperty(null, "string[]", null) ); $mockReader->shouldReceive('getSingleMethodAnnotation')->withAnyArgs()->andReturnNull(); @@ -80,8 +80,8 @@ public function testGetterNameIsNoBool() $config = $driver->getConfig(); $eProperties = array( - "stuff" => new GetterSerialization("getStuff", "string", 1), - "isGood" => new GetterSerialization("isGood", "string", 1), + "stuff" => new GetterSerialization("getStuff", array("scalar", "string"), 1), + "isGood" => new GetterSerialization("isGood", array("array", array("scalar", "int"), array("scalar", "string")), 1), ); $this->assertEquals($eProperties, $config->serialization->properties); diff --git a/tests/Weasel/JsonMarshaller/JsonMapperTest.php b/tests/Weasel/JsonMarshaller/JsonMapperTest.php index 8e0c752..a2604b3 100644 --- a/tests/Weasel/JsonMarshaller/JsonMapperTest.php +++ b/tests/Weasel/JsonMarshaller/JsonMapperTest.php @@ -7,6 +7,7 @@ namespace Weasel\JsonMarshaller; use Weasel\JsonMarshaller\Config\JsonConfigProvider; +use Weasel\JsonMarshaller\Utils\TypeParser; class JsonMapperTest extends \PHPUnit_Framework_TestCase { @@ -440,6 +441,8 @@ public function testAnyGetter() protected function addPropConfig(Config\ClassMarshaller $config, $name, $type) { + $type = TypeParser::parseType($type, true); + $prop = new Config\Serialization\DirectSerialization(); $prop->type = $type; $prop->property = $name; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 92213d3..8f05f89 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,6 +1,8 @@ Date: Thu, 1 May 2014 15:15:41 +0100 Subject: [PATCH 2/2] Classes for type configuration. --- .../JsonMarshaller/Config/Type/ListType.php | 19 +++ .../JsonMarshaller/Config/Type/MapType.php | 20 +++ .../JsonMarshaller/Config/Type/ObjectType.php | 19 +++ .../JsonMarshaller/Config/Type/ScalarType.php | 25 ++++ .../JsonMarshaller/Config/Type/Type.php | 20 +++ lib/Weasel/JsonMarshaller/JsonMapper.php | 134 ++++++++++-------- .../JsonMarshaller/Utils/TypeParser.php | 21 ++- .../Config/ClassAnnotationDriverTest.php | 13 +- 8 files changed, 194 insertions(+), 77 deletions(-) create mode 100644 lib/Weasel/JsonMarshaller/Config/Type/ListType.php create mode 100644 lib/Weasel/JsonMarshaller/Config/Type/MapType.php create mode 100644 lib/Weasel/JsonMarshaller/Config/Type/ObjectType.php create mode 100644 lib/Weasel/JsonMarshaller/Config/Type/ScalarType.php create mode 100644 lib/Weasel/JsonMarshaller/Config/Type/Type.php diff --git a/lib/Weasel/JsonMarshaller/Config/Type/ListType.php b/lib/Weasel/JsonMarshaller/Config/Type/ListType.php new file mode 100644 index 0000000..d0b4441 --- /dev/null +++ b/lib/Weasel/JsonMarshaller/Config/Type/ListType.php @@ -0,0 +1,19 @@ +valueType = $valueType; + } + +} \ No newline at end of file diff --git a/lib/Weasel/JsonMarshaller/Config/Type/MapType.php b/lib/Weasel/JsonMarshaller/Config/Type/MapType.php new file mode 100644 index 0000000..1c84b81 --- /dev/null +++ b/lib/Weasel/JsonMarshaller/Config/Type/MapType.php @@ -0,0 +1,20 @@ +keyType = $keyType; + parent::__construct($valueType); + } + +} \ No newline at end of file diff --git a/lib/Weasel/JsonMarshaller/Config/Type/ObjectType.php b/lib/Weasel/JsonMarshaller/Config/Type/ObjectType.php new file mode 100644 index 0000000..867b76e --- /dev/null +++ b/lib/Weasel/JsonMarshaller/Config/Type/ObjectType.php @@ -0,0 +1,19 @@ +class = $class; + } + +} \ No newline at end of file diff --git a/lib/Weasel/JsonMarshaller/Config/Type/ScalarType.php b/lib/Weasel/JsonMarshaller/Config/Type/ScalarType.php new file mode 100644 index 0000000..81cb8eb --- /dev/null +++ b/lib/Weasel/JsonMarshaller/Config/Type/ScalarType.php @@ -0,0 +1,25 @@ +typeName = $typeName; + } + + /** + * @var string + * @JsonProperty(type="string") + */ + public $typeName; + + /** + * This is a bit of a dirty hack... + * @var JsonType + */ + public $jsonType; + +} \ No newline at end of file diff --git a/lib/Weasel/JsonMarshaller/Config/Type/Type.php b/lib/Weasel/JsonMarshaller/Config/Type/Type.php new file mode 100644 index 0000000..fdfbce9 --- /dev/null +++ b/lib/Weasel/JsonMarshaller/Config/Type/Type.php @@ -0,0 +1,20 @@ +typeInfoProperty; - $properties[$property] = $this->_encodeValue($classId, array(TypeParser::TYPE_SCALAR, "string")); + $properties[$property] = $this->_encodeValue($classId, new ScalarType("string")); break; case Config\Serialization\TypeInfo::TI_AS_WRAPPER_ARRAY: // We're actually going to encase this encoded object in an array containing the classId. @@ -285,7 +290,7 @@ protected function _encodeObject($object, $typeInfo = null, $type = null) break; } return '[' . $this->_encodeValue($classId, - array(TypeParser::TYPE_SCALAR, 'string')) . ', ' . $this->_objectToJson($properties) . ']'; + new ScalarType('string')) . ', ' . $this->_objectToJson($properties) . ']'; break; case Config\Serialization\TypeInfo::TI_AS_WRAPPER_OBJECT: // Very similar yo the wrapper array case, but this time it's a map from the classId to the object. @@ -293,7 +298,7 @@ protected function _encodeObject($object, $typeInfo = null, $type = null) break; } return '{' . $this->_encodeValue($classId, - array(TypeParser::TYPE_SCALAR, 'string')) . ': ' . $this->_objectToJson($properties) . '}'; + new ScalarType('string')) . ': ' . $this->_objectToJson($properties) . '}'; break; default: throw new \Exception("Unsupported type info storage at class level"); @@ -308,7 +313,7 @@ protected function _objectToJson($properties) { $elements = array(); foreach ($properties as $key => $property) { - $elements[] = $this->_encodeValue($key, array(TypeParser::TYPE_SCALAR, 'string')) . ': ' . $property; + $elements[] = $this->_encodeValue($key, new ScalarType('string')) . ': ' . $property; } return '{' . implode(', ', $elements) . '}'; } @@ -473,8 +478,12 @@ protected function _decodeClass($array, $class, $strict) } + /** + * @param Type $type + * @return Type + */ protected function _parseType($type) { - if (!is_array($type)) { + if (!$type instanceof Type) { if (defined('E_USER_DEPRECATED')) { // TODO: need to handle serialized configs before we can properly deprecate this. // trigger_error("Use of unexpanded types is deprecated", E_USER_DEPRECATED); @@ -482,49 +491,69 @@ protected function _parseType($type) { // This is the really slow path. $type = TypeParser::parseType($type, false); } - if ($type[0] == TypeParser::TYPE_SCALAR) { - if (isset($this->typeHandlers[$type[1]])) { + if ($type instanceof ScalarType) { + if (isset($this->typeHandlers[$type->typeName])) { // Assumption: if there's a type handler for this type string, then it's the right thing to use. - return array(TypeParser::TYPE_SCALAR, $type[1], $this->typeHandlers[$type[1]]); + $type->jsonType = $this->typeHandlers[$type->typeName]; } else { - return array(TypeParser::TYPE_OBJECT, $type[1]); + $type = new ObjectType($type->typeName); } } return $type; } + /** + * @param $value + * @param $type + * @throws Exception\InvalidTypeException + * @throws Exception\JsonMarshallerException + * @throws \Exception + * @return mixed + */ protected function _decodeKey($value, $type) { if (!isset($value)) { throw new JsonMarshallerException("Key values cannot be null"); } $typeData = $this->_parseType($type); - switch ($typeData[0]) { - case TypeParser::TYPE_SCALAR: - // Keys are always strings, however we will allow other types, and disable strict type checking. - return $this->_decodeValue($value, $typeData, false); - default: - throw new JsonMarshallerException("Keys must be of type int or string, not " . $type); + if ($typeData instanceof ScalarType) { + // Keys are always strings, however we will allow other types, and disable strict type checking. + return $this->_decodeValue($value, $typeData, false); + } else { + throw new JsonMarshallerException("Keys must be of type int or string, not " . $type); } } + /** + * @param $value + * @param $type + * @param $strict + * @return mixed + * @throws Exception\InvalidTypeException + * @throws Exception\JsonMarshallerException + * @throws \Exception + */ protected function _decodeValue($value, $type, $strict) { if (!isset($value)) { return null; } $typeData = $this->_parseType($type); - switch (array_shift($typeData)) { - case TypeParser::TYPE_OBJECT: + switch (true) { + case ($typeData instanceof ObjectType): if (!is_array($value)) { - throw new InvalidTypeException($typeData[0], $value); + throw new InvalidTypeException($typeData->class, $value); } - return $this->_decodeClass($value, $typeData[0], $strict); + return $this->_decodeClass($value, $typeData->class, $strict); break; /** @noinspection PhpMissingBreakStatementInspection */ - case TypeParser::TYPE_LIST: - case TypeParser::TYPE_MAP: - list ($indexType, $elementType) = $typeData; + case ($typeData instanceof MapType): + $indexType = $typeData->keyType; + case ($typeData instanceof ListType): + if (!isset($indexType)) { + $indexType = new ScalarType("int"); + } + $elementType = $typeData->valueType; $result = array(); if (!is_array($value)) { $value = array($value); @@ -533,13 +562,10 @@ protected function _decodeValue($value, $type, $strict) $result[$this->_decodeKey($key, $indexType)] = $this->_decodeValue($element, $elementType, $strict); } return $result; - break; + case ($typeData instanceof ScalarType): + return $typeData->jsonType->decodeValue($value, $this, $strict); default: - /** - * @var $typeHandler Types\JsonType - */ - list ($typeName, $typeHandler) = $typeData; - return $typeHandler->decodeValue($value, $this, $strict); + throw new \Exception("Invalid config for type"); } } @@ -550,12 +576,10 @@ protected function _encodeKey($value, $type) throw new JsonMarshallerException("Key values cannot be null"); } $typeData = $this->_parseType($type); - switch (array_shift($typeData)) { - /** @noinspection PhpMissingBreakStatementInspection */ - case TypeParser::TYPE_SCALAR: - return $this->_encodeValue($value, array(TypeParser::TYPE_SCALAR, "string")); - default: - throw new JsonMarshallerException("Keys must be of type int or string, not " . $type); + if ($typeData instanceof ScalarType) { + return $this->_encodeValue($value, new ScalarType("string")); + } else { + throw new JsonMarshallerException("Keys must be of type int or string, not " . $type); } } @@ -572,43 +596,39 @@ protected function _encodeValue($value, $type, $typeInfo = null) return json_encode(null); } $typeData = $this->_parseType($type); - switch (array_shift($typeData)) { - case TypeParser::TYPE_OBJECT: + switch (true) { + case ($typeData instanceof ObjectType): if (!is_object($value)) { - throw new InvalidTypeException($typeData[0], $value); + throw new InvalidTypeException($typeData->class, $value); } - return $this->_encodeObject($value, $typeInfo, $typeData[0]); - break; - case TypeParser::TYPE_LIST: - list ($indexType, $elementType) = $typeData; + return $this->_encodeObject($value, $typeInfo, $typeData->class); + case ($typeData instanceof MapType): + $indexType = $typeData->keyType; + $elementType = $typeData->valueType; if (!is_array($value)) { $value = array($value); } $elements = array(); - foreach ($value as $element) { - $elements[] = $this->_encodeValue($element, $elementType); + foreach ($value as $key => $element) { + $elements[] = $this->_encodeKey($key, $indexType) . ': ' . $this->_encodeValue($element, + $elementType); } - return '[' . implode(', ', $elements) . ']'; - case TypeParser::TYPE_MAP: - list ($indexType, $elementType) = $typeData; + return '{' . implode(', ', $elements) . '}'; + case ($typeData instanceof ListType): + $elementType = $typeData->valueType; if (!is_array($value)) { $value = array($value); } $elements = array(); - foreach ($value as $key => $element) { - $elements[] = $this->_encodeKey($key, $indexType) . ': ' . $this->_encodeValue($element, - $elementType); + foreach ($value as $element) { + $elements[] = $this->_encodeValue($element, $elementType); } - return '{' . implode(', ', $elements) . '}'; + return '[' . implode(', ', $elements) . ']'; + case ($typeData instanceof ScalarType): + return $typeData->jsonType->encodeValue($value, $this); default: - /** - * @var $typeHandler Types\JsonType - */ - list ($typeName, $typeHandler) = $typeData; - return $typeHandler->encodeValue($value, $this); - + throw new \Exception("Unable to work out what to do with type"); } - } diff --git a/lib/Weasel/JsonMarshaller/Utils/TypeParser.php b/lib/Weasel/JsonMarshaller/Utils/TypeParser.php index aa24284..fa41055 100644 --- a/lib/Weasel/JsonMarshaller/Utils/TypeParser.php +++ b/lib/Weasel/JsonMarshaller/Utils/TypeParser.php @@ -1,12 +1,11 @@ getConfig(); $eProperties = array( - "stuff" => new GetterSerialization("getStuff", array("scalar", "string"), 1), - "good" => new GetterSerialization("isGood", array("scalar", "bool"), 1), + "stuff" => new GetterSerialization("getStuff", new ScalarType("string"), 1), + "good" => new GetterSerialization("isGood", new ScalarType("bool"), 1), ); $this->assertEquals($eProperties, $config->serialization->properties); @@ -80,8 +79,8 @@ public function testGetterNameIsNoBool() $config = $driver->getConfig(); $eProperties = array( - "stuff" => new GetterSerialization("getStuff", array("scalar", "string"), 1), - "isGood" => new GetterSerialization("isGood", array("array", array("scalar", "int"), array("scalar", "string")), 1), + "stuff" => new GetterSerialization("getStuff", new ScalarType("string"), 1), + "isGood" => new GetterSerialization("isGood", new ListType(new ScalarType("string")), 1), ); $this->assertEquals($eProperties, $config->serialization->properties);