diff --git a/.travis.yml b/.travis.yml index 90a32fa..45bd61e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,7 +49,7 @@ install: if [[ ! -f "$HOME/.pyvenv/bin/activate" ]]; then virtualenv -p "$(which python$PY)" "$HOME/.pyvenv"; fi fi - '"$HOME/.pyvenv/bin/pip" install --upgrade pip setuptools' -- '"$HOME/.pyvenv/bin/pip" install git+git://github.com/spoqa/nirum-python.git' +- '"$HOME/.pyvenv/bin/pip" install --upgrade git+git://github.com/spoqa/nirum-python.git' - if [[ "$PY" = "3.4" ]]; then "$HOME/.pyvenv/bin/pip" install --upgrade typing; fi # FIXME - 'sed -E "s/resolver\s*:\s*.*/resolver: $RESOLVER/" stack.yaml > stack-new.yaml' - mv stack-new.yaml stack.yaml diff --git a/appveyor.yml b/appveyor.yml index 9dd102a..c6d4b24 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -32,7 +32,7 @@ install: - > C:\pyvenv\Scripts\Activate.bat & python -m pip install --upgrade setuptools pip & - pip install git+git://github.com/spoqa/nirum-python.git + pip install --upgrade git+git://github.com/spoqa/nirum-python.git build_script: - stack --no-terminal build --copy-bins after_build: diff --git a/docs/serialization.md b/docs/serialization.md index b697d61..9bf5f17 100644 --- a/docs/serialization.md +++ b/docs/serialization.md @@ -86,13 +86,13 @@ It's represented in JSON to: } -Boxed type ----------- +Unboxed type +------------ -Boxed type is equivalent to 1-member record type in runtime, but it's equivalent -to its internal type in JSON representation. For example: +Unboxed type is equivalent to 1-member record type in runtime, +but it's equivalent to its internal type in JSON representation. For example: - boxed offset (float64); + unboxed offset (float64); record payload ( offset left, @@ -112,7 +112,7 @@ The internal type might be a record type as well: float64 top, ); - boxed coord (point); + unboxed coord (point); record payload ( coord location, @@ -131,14 +131,14 @@ It's represented in JSON as: The internal type also can be a option/set/list/map type: - boxed box-option (text?); + unboxed box-option (text?); enum color = red | green | blue; - boxed box-set ({color}); + unboxed box-set ({color}); - boxed box-list ([float64]); + unboxed box-list ([float64]); - boxed box-map ({uuid: datetime}); + unboxed box-map ({uuid: datetime}); record payload ( box-option a, diff --git a/examples/shapes.nrm b/examples/shapes.nrm index b095cbd..7f37db1 100644 --- a/examples/shapes.nrm +++ b/examples/shapes.nrm @@ -1,11 +1,11 @@ # Module consists zero or more type declarations. -boxed offset (float64); -# The key difference between boxed type and reocrd type consisting of a single +unboxed offset (float64); +# The key difference between unboxed type and reocrd type consisting of a single # field is that the former has the same JSON representation to its target type, # while the latter has thicker JSON representation than its only field. # -# For example, a value of `boxed offset (float);` type is represented +# For example, a value of `unboxed offset (float);` type is represented # in JSON as: # # 120.5 diff --git a/src/Nirum/Constructs/Identifier.hs b/src/Nirum/Constructs/Identifier.hs index 1735b5c..6de86df 100644 --- a/src/Nirum/Constructs/Identifier.hs +++ b/src/Nirum/Constructs/Identifier.hs @@ -52,12 +52,12 @@ import Nirum.Constructs (Construct(toCode)) data Identifier = Identifier T.Text deriving (Show) reservedKeywords :: S.Set Identifier -reservedKeywords = [ "boxed" - , "enum" +reservedKeywords = [ "enum" , "record" , "service" , "throws" , "type" + , "unboxed" , "union" ] diff --git a/src/Nirum/Constructs/TypeDeclaration.hs b/src/Nirum/Constructs/TypeDeclaration.hs index d3bf5ee..3e2598d 100644 --- a/src/Nirum/Constructs/TypeDeclaration.hs +++ b/src/Nirum/Constructs/TypeDeclaration.hs @@ -47,7 +47,7 @@ import Nirum.Constructs.TypeExpression (TypeExpression) data Type = Alias { canonicalType :: TypeExpression } - | BoxedType { innerType :: TypeExpression } + | UnboxedType { innerType :: TypeExpression } | EnumType { members :: DeclarationSet EnumMember } | RecordType { fields :: DeclarationSet Field } | UnionType { tags :: DeclarationSet Tag } @@ -143,9 +143,9 @@ instance Construct TypeDeclaration where , " = ", toCode cname, ";" , toCodeWithPrefix "\n" (A.lookupDocs annotationSet') ] - toCode (TypeDeclaration name' (BoxedType itype) annotationSet') = + toCode (TypeDeclaration name' (UnboxedType itype) annotationSet') = T.concat [ toCode annotationSet' - , "boxed ", toCode name' + , "unboxed ", toCode name' , " (", toCode itype, ");" , toCodeWithPrefix "\n" (A.lookupDocs annotationSet')] toCode (TypeDeclaration name' (EnumType members') annotationSet') = diff --git a/src/Nirum/Parser.hs b/src/Nirum/Parser.hs index 318eb30..f7d6386 100644 --- a/src/Nirum/Parser.hs +++ b/src/Nirum/Parser.hs @@ -5,7 +5,6 @@ module Nirum.Parser ( Parser , aliasTypeDeclaration , annotation , annotationSet - , boxedTypeDeclaration , docs , enumTypeDeclaration , file @@ -28,6 +27,7 @@ module Nirum.Parser ( Parser , typeExpression , typeExpressionWithoutOptionModifier , typeIdentifier + , unboxedTypeDeclaration , unionTypeDeclaration ) where @@ -94,9 +94,9 @@ import Nirum.Constructs.TypeDeclaration ( EnumMember(EnumMember) , Field(Field) , Tag(Tag) , Type( Alias - , BoxedType , EnumType , RecordType + , UnboxedType , UnionType ) , TypeDeclaration( Import @@ -266,24 +266,24 @@ aliasTypeDeclaration = do return $ TypeDeclaration name' (Alias canonicalType) annotationSet'' -boxedTypeDeclaration :: Parser TypeDeclaration -boxedTypeDeclaration = do - annotationSet' <- annotationSet "boxed type annotations" - string' "boxed" "boxed type keyword" +unboxedTypeDeclaration :: Parser TypeDeclaration +unboxedTypeDeclaration = do + annotationSet' <- annotationSet "unboxed type annotations" + string' "unboxed" "unboxed type keyword" spaces - typename <- identifier "boxed type name" + typename <- identifier "unboxed type name" let name' = Name typename typename spaces char '(' spaces - innerType <- typeExpression "inner type of boxed type" + innerType <- typeExpression "inner type of unboxed type" spaces char ')' spaces char ';' - docs' <- optional $ try $ spaces >> (docs "boxed type docs") + docs' <- optional $ try $ spaces >> (docs "unboxed type docs") annotationSet'' <- annotationsWithDocs annotationSet' docs' - return $ TypeDeclaration name' (BoxedType innerType) annotationSet'' + return $ TypeDeclaration name' (UnboxedType innerType) annotationSet'' enumMember :: Parser EnumMember enumMember = do @@ -462,12 +462,12 @@ typeDeclaration = do annotationSet' <- annotationSet "type annotations" spaces typeDecl <- choice - [ unless' ["union", "record", "enum", "boxed"] aliasTypeDeclaration - , unless' ["union", "record", "enum"] boxedTypeDeclaration + [ unless' ["union", "record", "enum", "unboxed"] aliasTypeDeclaration + , unless' ["union", "record", "enum"] unboxedTypeDeclaration , unless' ["union", "record"] enumTypeDeclaration , unless' ["union"] recordTypeDeclaration , unionTypeDeclaration - ] "type declaration (e.g. boxed, enum, record, union)" + ] "type declaration (e.g. enum, record, unboxed, union)" -- In theory, though it preconsumes annotationSet' before parsing typeDecl -- so that typeDecl itself has no annotations, to prepare for an -- unlikely situation (that I bet it'll never happen) diff --git a/src/Nirum/Targets/Python.hs b/src/Nirum/Targets/Python.hs index 49c2671..1df822c 100644 --- a/src/Nirum/Targets/Python.hs +++ b/src/Nirum/Targets/Python.hs @@ -69,10 +69,10 @@ import Nirum.Constructs.TypeDeclaration ( EnumMember(EnumMember) , PrimitiveTypeIdentifier(..) , Tag(Tag) , Type( Alias - , BoxedType , EnumType , PrimitiveType , RecordType + , UnboxedType , UnionType ) , TypeDeclaration(..) @@ -311,22 +311,23 @@ compileTypeDeclaration src TypeDeclaration { typename = typename' {toClassName' typename'} = $ctypeExpr |] compileTypeDeclaration src TypeDeclaration { typename = typename' - , type' = BoxedType itype } = do + , type' = UnboxedType itype } = do let className = toClassName' typename' itypeExpr <- compileTypeExpression src itype insertStandardImport "typing" - insertThirdPartyImports [ ("nirum.validate", ["validate_boxed_type"]) - , ("nirum.serialize", ["serialize_boxed_type"]) - , ("nirum.deserialize", ["deserialize_boxed_type"]) - ] + insertThirdPartyImports + [ ("nirum.validate", ["validate_unboxed_type"]) + , ("nirum.serialize", ["serialize_unboxed_type"]) + , ("nirum.deserialize", ["deserialize_unboxed_type"]) + ] return [qq| class $className: # TODO: docstring - __nirum_boxed_type__ = $itypeExpr + __nirum_inner_type__ = $itypeExpr def __init__(self, value: $itypeExpr) -> None: - validate_boxed_type(value, $itypeExpr) + validate_unboxed_type(value, $itypeExpr) self.value = value # type: $itypeExpr def __eq__(self, other) -> bool: @@ -337,11 +338,11 @@ class $className: return hash(self.value) def __nirum_serialize__(self) -> typing.Any: - return serialize_boxed_type(self) + return serialize_unboxed_type(self) @classmethod def __nirum_deserialize__(cls: type, value: typing.Any) -> '{className}': - return deserialize_boxed_type(cls, value) + return deserialize_unboxed_type(cls, value) def __repr__(self) -> str: return '\{0.__module__\}.\{0.__qualname__\}(\{1!r\})'.format( diff --git a/test/Nirum/Constructs/ModuleSpec.hs b/test/Nirum/Constructs/ModuleSpec.hs index 570c462..bb74368 100644 --- a/test/Nirum/Constructs/ModuleSpec.hs +++ b/test/Nirum/Constructs/ModuleSpec.hs @@ -20,7 +20,7 @@ spec = let docsAnno = A.docs "path string" pathT = TypeDeclaration "path" (Alias "text") (singleton docsAnno) offsetT = - TypeDeclaration "offset" (BoxedType "float64") empty + TypeDeclaration "offset" (UnboxedType "float64") empty decls = [ Import ["foo", "bar"] "baz" empty , Import ["foo", "bar"] "qux" empty , Import ["zzz"] "qqq" empty @@ -45,7 +45,7 @@ import zzz (ppp, qqq); type path = text; # path string -boxed offset (float64); +unboxed offset (float64); |] toCode mod2 `shouldBe` [q|# module level docs... # blahblah @@ -56,5 +56,5 @@ import zzz (ppp, qqq); type path = text; # path string -boxed offset (float64); +unboxed offset (float64); |] diff --git a/test/Nirum/Constructs/TypeDeclarationSpec.hs b/test/Nirum/Constructs/TypeDeclarationSpec.hs index f216a3f..b4b276b 100644 --- a/test/Nirum/Constructs/TypeDeclarationSpec.hs +++ b/test/Nirum/Constructs/TypeDeclarationSpec.hs @@ -46,10 +46,10 @@ spec = do specify "toCode" $ do toCode a `shouldBe` "type path = text;" toCode b `shouldBe` "type path = text;\n# docs" - context "BoxedType" $ do - let boxed = BoxedType "float64" + context "UnboxedType" $ do + let unboxed = UnboxedType "float64" a = TypeDeclaration { typename = "offset" - , type' = boxed + , type' = unboxed , typeAnnotations = empty } b = a { typeAnnotations = singleDocs "docs" } @@ -60,8 +60,8 @@ spec = do docs a `shouldBe` Nothing docs b `shouldBe` Just "docs" specify "toCode" $ do - toCode a `shouldBe` "boxed offset (float64);" - toCode b `shouldBe` "boxed offset (float64);\n# docs" + toCode a `shouldBe` "unboxed offset (float64);" + toCode b `shouldBe` "unboxed offset (float64);\n# docs" context "EnumType" $ do let enumMembers = [ EnumMember "kr" empty , EnumMember "jp" (singleDocs "Japan") diff --git a/test/Nirum/ParserSpec.hs b/test/Nirum/ParserSpec.hs index eccd675..23daf34 100644 --- a/test/Nirum/ParserSpec.hs +++ b/test/Nirum/ParserSpec.hs @@ -120,8 +120,8 @@ spec = do it "fails to parse an identifier containing disallowed chars" $ do expectError "무효한-식별자" 1 1 expectError "invalid-식별자" 1 9 - let keywords = [ "boxed", "enum", "record", "type", "union" - , "BOXED", "Enum", "rEcord", "tyPE", "unioN" + let keywords = [ "enum", "record", "type", "unboxed", "union" + , "Enum", "rEcord", "tyPE", "UNBOXED", "unioN" ] :: [T.Text] it "fails to parse bare identifier if it's a reserved keyword" $ forM_ keywords $ \kwd -> @@ -174,8 +174,8 @@ spec = do parse' "`enum`" `shouldBeRight` Name "enum" "enum" parse' "facial/behind" `shouldBeRight` Name "facial" "behind" parse' "facial / behind" `shouldBeRight` Name "facial" "behind" - parse' "`enum`/`boxed`" `shouldBeRight` Name "enum" "boxed" - parse' "`enum` / `boxed`" `shouldBeRight` Name "enum" "boxed" + parse' "`enum`/`unboxed`" `shouldBeRight` Name "enum" "unboxed" + parse' "`enum` / `unboxed`" `shouldBeRight` Name "enum" "unboxed" describe "annotation" $ do let (parse', expectError) = helperFuncs P.annotation @@ -420,36 +420,37 @@ spec = do it "fails to parse if trailing semicolon is missing" $ do let (_, expectErr) = helperFuncs P.module' expectErr "type a = text;\ntype b = text\ntype c = text;" 3 1 - expectErr "boxed a (text);\ntype b = text\nboxed c (text);" 3 1 - expectErr "type a = text;\nboxed b (text)\ntype c = text;" 3 1 + expectErr "unboxed a (text);\ntype b = text\nunboxed c (text);" 3 1 + expectErr "type a = text;\nunboxed b (text)\ntype c = text;" 3 1 - descTypeDecl "boxedTypeDeclaration" P.boxedTypeDeclaration $ \helpers -> do - let (parse', expectError) = helpers - it "emits (TypeDeclaration (BoxedType ...)) if succeeded to parse" $ do - parse' "boxed offset (float64);" `shouldBeRight` - TypeDeclaration "offset" (BoxedType "float64") empty - parse' "boxed offset (float64);\n# docs" `shouldBeRight` - TypeDeclaration "offset" (BoxedType "float64") + descTypeDecl "unboxedTypeDeclaration" P.unboxedTypeDeclaration $ \funs -> do + let (parse', expectError) = funs + it "emits (TypeDeclaration (UnboxedType ..)) if succeeded to parse" $ do + parse' "unboxed offset (float64);" `shouldBeRight` + TypeDeclaration "offset" (UnboxedType "float64") empty + parse' "unboxed offset (float64);\n# docs" `shouldBeRight` + TypeDeclaration "offset" (UnboxedType "float64") (singleDocs "docs\n") - parse' "boxed offset (float64);\n# docs\n# docs..." `shouldBeRight` - TypeDeclaration "offset" (BoxedType "float64") + parse' "unboxed offset (float64);\n# docs\n# docs..." `shouldBeRight` + TypeDeclaration "offset" (UnboxedType "float64") (singleDocs "docs\ndocs...\n") - parse' "@foo(\"bar\")\nboxed offset (float64);\n# docs\n# docs..." + parse' "@foo(\"bar\")\nunboxed offset (float64);\n# docs\n# docs..." `shouldBeRight` - TypeDeclaration "offset" (BoxedType "float64") + TypeDeclaration "offset" (UnboxedType "float64") (A.union (singleDocs "docs\ndocs...\n") fooAnnotationSet) - parse' "@baz\nboxed offset (float64);\n# docs\n# docs..." + parse' "@baz\nunboxed offset (float64);\n# docs\n# docs..." `shouldBeRight` - TypeDeclaration "offset" (BoxedType "float64") + TypeDeclaration "offset" (UnboxedType "float64") (A.union (singleDocs "docs\ndocs...\n") bazAnnotationSet) - expectError "boxed offset/behind (float64);" 1 13 + expectError "unboxed offset/behind (float64);" 1 15 it "fails to parse if trailing semicolon is missing" $ do let (_, expectErr) = helperFuncs P.module' - expectErr "boxed a (text);\nboxed b (text)\nboxed c (text);" 3 1 - expectErr "type a = text;\nboxed b (text)\ntype c = text;" 3 1 - expectErr "boxed a (text);\ntype b = text\nboxed c (text);" 3 1 + expectErr "unboxed a (text);\nunboxed b (text)\nunboxed c (text);" + 3 1 + expectErr "type a = text;\nunboxed b (text)\ntype c = text;" 3 1 + expectErr "unboxed a (text);\ntype b = text\nunboxed c (text);" 3 1 descTypeDecl "enumTypeDeclaration" P.enumTypeDeclaration $ \helpers -> do let (parse', expectError) = helpers @@ -505,8 +506,8 @@ spec = do it "fails to parse if trailing semicolon is missing" $ do let (_, expectErr) = helperFuncs P.module' expectErr "enum a = x | y;\nenum b = x | y\nenum c = x | y;" 3 1 - expectErr "boxed a (text);\nenum b = x | y\nboxed c (text);" 3 1 - expectErr "enum a = x | y;\nboxed b (text)\nenum c = x | y;" 3 1 + expectErr "unboxed a (text);\nenum b = x | y\nunboxed c (text);" 3 1 + expectErr "enum a = x | y;\nunboxed b (text)\nenum c = x | y;" 3 1 descTypeDecl "recordTypeDeclaration" P.recordTypeDeclaration $ \helpers -> do let (parse', expectError) = helpers @@ -746,8 +747,9 @@ spec = do it "fails to parse if trailing semicolon is missing" $ do let (_, expectErr) = helperFuncs P.module' expectErr "union a = x | y;\nunion b = x | y\nunion c = x | y;" 3 1 - expectErr "boxed a (text);\nunion b = x | y\nboxed c (text);" 3 1 - expectErr "union a = x | y;\nboxed b (text)\nunion c = x | y;" 3 1 + expectErr "unboxed a (text);\nunion b = x | y\nunboxed c (text);" + 3 1 + expectErr "union a = x | y;\nunboxed b (text)\nunion c = x | y;" 3 1 describe "method" $ do let (parse', expectError) = helperFuncs P.method @@ -1009,12 +1011,13 @@ spec = do it "emits Module if succeeded to parse" $ do let decls = [ TypeDeclaration "path" (Alias "text") empty , TypeDeclaration "offset" - (BoxedType "float64") empty + (UnboxedType "float64") empty ] - parse' "type path = text; boxed offset (float64);" + parse' "type path = text; unboxed offset (float64);" `shouldBeRight` Module decls Nothing - parse' "#docs\n#...\ntype path = text; boxed offset (float64);" - `shouldBeRight` Module decls (Just "docs\n...") + parse' + "#docs\n#...\ntype path = text; unboxed offset (float64);" + `shouldBeRight` Module decls (Just "docs\n...") it "may have no type declarations" $ do parse' "" `shouldBeRight` Module [] Nothing parse' "# docs" `shouldBeRight` Module [] (Just "docs") diff --git a/test/Nirum/Targets/PythonSpec.hs b/test/Nirum/Targets/PythonSpec.hs index c7aa317..4260465 100644 --- a/test/Nirum/Targets/PythonSpec.hs +++ b/test/Nirum/Targets/PythonSpec.hs @@ -57,9 +57,9 @@ import Nirum.Constructs.TypeDeclaration ( Field(Field) , PrimitiveTypeIdentifier(..) , Tag(Tag) , Type( Alias - , BoxedType , EnumType , RecordType + , UnboxedType , UnionType ) , TypeDeclaration ( Import @@ -263,8 +263,9 @@ makeDummySource' pathPrefix m = [ (mp ["foo"], m) , ( mp ["foo", "bar"] , Module [ Import (mp ["qux"]) "path" empty - , TypeDeclaration "path-box" (BoxedType "path") empty - , TypeDeclaration "int-box" (BoxedType "bigint") empty + , TypeDeclaration "path-unbox" (UnboxedType "path") empty + , TypeDeclaration "int-unbox" + (UnboxedType "bigint") empty , TypeDeclaration "point" (RecordType [ Field "x" "int64" empty , Field "y" "int64" empty @@ -275,7 +276,7 @@ makeDummySource' pathPrefix m = , ( mp ["qux"] , Module [ TypeDeclaration "path" (Alias "text") empty - , TypeDeclaration "name" (BoxedType "text") empty + , TypeDeclaration "name" (UnboxedType "text") empty ] Nothing ) @@ -300,21 +301,21 @@ compileError cg = either Just (const Nothing) $ fst $ runCodeGen cg emptyContext spec :: Spec spec = parallel $ do describe "CodeGen" $ do - context "Monad" $ - specify "packages and imports" $ do - let c = do - insertStandardImport "sys" - insertThirdPartyImports [("nirum", ["serialize_boxed_type"])] - insertLocalImport ".." "Gender" - insertStandardImport "os" - insertThirdPartyImports [("nirum", ["serialize_enum_type"])] - insertLocalImport ".." "Path" - let (e, ctx) = runCodeGen c emptyContext - e `shouldSatisfy` isRight - standardImports ctx `shouldBe` ["os", "sys"] - thirdPartyImports ctx `shouldBe` - [("nirum", ["serialize_boxed_type", "serialize_enum_type"])] - localImports ctx `shouldBe` [("..", ["Gender", "Path"])] + specify "packages and imports" $ do + let c = do + insertStandardImport "sys" + insertThirdPartyImports + [("nirum", ["serialize_unboxed_type"])] + insertLocalImport ".." "Gender" + insertStandardImport "os" + insertThirdPartyImports [("nirum", ["serialize_enum_type"])] + insertLocalImport ".." "Path" + let (e, ctx) = runCodeGen c emptyContext + e `shouldSatisfy` isRight + standardImports ctx `shouldBe` ["os", "sys"] + thirdPartyImports ctx `shouldBe` + [("nirum", ["serialize_unboxed_type", "serialize_enum_type"])] + localImports ctx `shouldBe` [("..", ["Gender", "Path"])] specify "insertStandardImport" $ do let codeGen1 = insertStandardImport "sys" let (e1, ctx1) = runCodeGen codeGen1 emptyContext @@ -491,73 +492,76 @@ spec = parallel $ do let Just result = out T.strip (T.pack result) `shouldBe` expected test testRunner source T.empty - specify "boxed type" $ do - let decl = TypeDeclaration "float-box" (BoxedType "float64") empty - tT decl "isinstance(FloatBox, type)" - tT decl "FloatBox(3.14).value == 3.14" - tT decl "FloatBox(3.14) == FloatBox(3.14)" - tT decl "FloatBox(3.14) != FloatBox(1.0)" - tT decl [q|{FloatBox(3.14), FloatBox(3.14), FloatBox(1.0)} == - {FloatBox(3.14), FloatBox(1.0)}|] - tT decl "FloatBox(3.14).__nirum_serialize__() == 3.14" - tT decl "FloatBox.__nirum_deserialize__(3.14) == FloatBox(3.14)" - tT decl "FloatBox.__nirum_deserialize__(3.14) == FloatBox(3.14)" - tT decl "hash(FloatBox(3.14))" - tT decl "hash(FloatBox(3.14)) != 3.14" + specify "unboxed type" $ do + let decl = TypeDeclaration "float-unbox" (UnboxedType "float64") + empty + tT decl "isinstance(FloatUnbox, type)" + tT decl "FloatUnbox(3.14).value == 3.14" + tT decl "FloatUnbox(3.14) == FloatUnbox(3.14)" + tT decl "FloatUnbox(3.14) != FloatUnbox(1.0)" + tT decl [q|{FloatUnbox(3.14), FloatUnbox(3.14), FloatUnbox(1.0)} == + {FloatUnbox(3.14), FloatUnbox(1.0)}|] + tT decl "FloatUnbox(3.14).__nirum_serialize__() == 3.14" + tT decl "FloatUnbox.__nirum_deserialize__(3.14) == FloatUnbox(3.14)" + tT decl "FloatUnbox.__nirum_deserialize__(3.14) == FloatUnbox(3.14)" + tT decl "hash(FloatUnbox(3.14))" + tT decl "hash(FloatUnbox(3.14)) != 3.14" -- FIXME: Is TypeError/ValueError is appropriate exception type -- for deserialization error? For such case, json.loads() raises -- JSONDecodeError (which inherits ValueError). tR' decl "(TypeError, ValueError)" - "FloatBox.__nirum_deserialize__('a')" - tR' decl "TypeError" "FloatBox('a')" - let decls = [ Import ["foo", "bar"] "path-box" empty - , TypeDeclaration "imported-type-box" - (BoxedType "path-box") empty + "FloatUnbox.__nirum_deserialize__('a')" + tR' decl "TypeError" "FloatUnbox('a')" + let decls = [ Import ["foo", "bar"] "path-unbox" empty + , TypeDeclaration "imported-type-unbox" + (UnboxedType "path-unbox") empty ] - tT' decls "isinstance(ImportedTypeBox, type)" - tT' decls [q|ImportedTypeBox(PathBox('/path/string')).value.value == - '/path/string'|] - tT' decls [q|ImportedTypeBox(PathBox('/path/string')) == - ImportedTypeBox(PathBox('/path/string'))|] - tT' decls [q|ImportedTypeBox(PathBox('/path/string')) != - ImportedTypeBox(PathBox('/other/path'))|] - tT' decls [q|{ImportedTypeBox(PathBox('/path/string')), - ImportedTypeBox(PathBox('/path/string')), - ImportedTypeBox(PathBox('/other/path')), - ImportedTypeBox(PathBox('/path/string')), - ImportedTypeBox(PathBox('/other/path'))} == - {ImportedTypeBox(PathBox('/path/string')), - ImportedTypeBox(PathBox('/other/path'))}|] + tT' decls "isinstance(ImportedTypeUnbox, type)" tT' decls [q| - ImportedTypeBox(PathBox('/path/string')).__nirum_serialize__() - == '/path/string' + ImportedTypeUnbox(PathUnbox('/path/string')).value.value == + '/path/string' |] + tT' decls [q|ImportedTypeUnbox(PathUnbox('/path/string')) == + ImportedTypeUnbox(PathUnbox('/path/string'))|] + tT' decls [q|ImportedTypeUnbox(PathUnbox('/path/string')) != + ImportedTypeUnbox(PathUnbox('/other/path'))|] + tT' decls [q|{ImportedTypeUnbox(PathUnbox('/path/string')), + ImportedTypeUnbox(PathUnbox('/path/string')), + ImportedTypeUnbox(PathUnbox('/other/path')), + ImportedTypeUnbox(PathUnbox('/path/string')), + ImportedTypeUnbox(PathUnbox('/other/path'))} == + {ImportedTypeUnbox(PathUnbox('/path/string')), + ImportedTypeUnbox(PathUnbox('/other/path'))}|] tT' decls [q| - ImportedTypeBox.__nirum_deserialize__('/path/string') == - ImportedTypeBox(PathBox('/path/string')) + ImportedTypeUnbox(PathUnbox('/path/string') + ).__nirum_serialize__() == '/path/string' + |] + tT' decls [q| + ImportedTypeUnbox.__nirum_deserialize__('/path/string') == + ImportedTypeUnbox(PathUnbox('/path/string')) |] -- FIXME: Is TypeError/ValueError is appropriate exception type -- for deserialization error? For such case, json.loads() raises -- JSONDecodeError (which inherits ValueError). tR'' decls "(TypeError, ValueError)" - "ImportedTypeBox.__nirum_deserialize__(123)" - tR'' decls "TypeError" "ImportedTypeBox(123)" + "ImportedTypeUnbox.__nirum_deserialize__(123)" + tR'' decls "TypeError" "ImportedTypeUnbox(123)" let boxedAlias = [ Import ["qux"] "path" empty , TypeDeclaration "way" - (BoxedType "path") empty + (UnboxedType "path") empty ] tT' boxedAlias "Way('.').value == '.'" tT' boxedAlias "Way(Path('.')).value == '.'" tT' boxedAlias "Way.__nirum_deserialize__('.') == Way('.')" tT' boxedAlias "Way('.').__nirum_serialize__() == '.'" - let aliasBoxed = [ Import ["qux"] "name" empty - , TypeDeclaration "irum" (Alias "name") empty - ] - tT' aliasBoxed "Name('khj') == Irum('khj')" - tT' aliasBoxed "Irum.__nirum_deserialize__('khj') == Irum('khj')" - tT' aliasBoxed "Irum('khj').__nirum_serialize__() == 'khj'" - tT' aliasBoxed "Irum.__nirum_deserialize__('khj') == Name('khj')" - tT' aliasBoxed "Irum.__nirum_deserialize__('khj') == Irum('khj')" + let aliasUnboxed = [ Import ["qux"] "name" empty + , TypeDeclaration "irum" (Alias "name") empty + ] + tT' aliasUnboxed "Name('khj') == Irum('khj')" + tT' aliasUnboxed "Irum.__nirum_deserialize__('khj') == Irum('khj')" + tT' aliasUnboxed "Irum('khj').__nirum_serialize__() == 'khj'" + tT' aliasUnboxed "Irum.__nirum_deserialize__('khj') == Name('khj')" + tT' aliasUnboxed "Irum.__nirum_deserialize__('khj') == Irum('khj')" specify "enum type" $ do let members = [ "male" , EnumMember (Name "female" "yeoseong") empty @@ -618,36 +622,38 @@ spec = parallel $ do tR' decl "TypeError" "Point(left=1, top='a')" tR' decl "TypeError" "Point(left='a', top=1)" tR' decl "TypeError" "Point(left='a', top='b')" - let fields' = [ Field "left" "int-box" empty - , Field "top" "int-box" empty + let fields' = [ Field "left" "int-unbox" empty + , Field "top" "int-unbox" empty ] - decls = [ Import ["foo", "bar"] "int-box" empty + decls = [ Import ["foo", "bar"] "int-unbox" empty , TypeDeclaration "point" (RecordType fields') empty ] payload' = "{'_type': 'point', 'left': 3, 'top': 14}" :: T.Text tT' decls "isinstance(Point, type)" - tT' decls "Point(left=IntBox(3), top=IntBox(14)).left == IntBox(3)" - tT' decls "Point(left=IntBox(3), top=IntBox(14)).top == IntBox(14)" - tT' decls [q|Point(left=IntBox(3), top=IntBox(14)) == - Point(left=IntBox(3), top=IntBox(14))|] - tT' decls [q|Point(left=IntBox(3), top=IntBox(14)) != - Point(left=IntBox(3), top=IntBox(15))|] - tT' decls [q|Point(left=IntBox(3), top=IntBox(14)) != - Point(left=IntBox(4), top=IntBox(14))|] - tT' decls [q|Point(left=IntBox(3), top=IntBox(14)) != - Point(left=IntBox(4), top=IntBox(15))|] - tT' decls "Point(left=IntBox(3), top=IntBox(14)) != 'foo'" - tT' decls [q|Point(left=IntBox(3), - top=IntBox(14)).__nirum_serialize__() == + tT' decls [q|Point(left=IntUnbox(3), top=IntUnbox(14)).left == + IntUnbox(3)|] + tT' decls [q|Point(left=IntUnbox(3), top=IntUnbox(14)).top == + IntUnbox(14)|] + tT' decls [q|Point(left=IntUnbox(3), top=IntUnbox(14)) == + Point(left=IntUnbox(3), top=IntUnbox(14))|] + tT' decls [q|Point(left=IntUnbox(3), top=IntUnbox(14)) != + Point(left=IntUnbox(3), top=IntUnbox(15))|] + tT' decls [q|Point(left=IntUnbox(3), top=IntUnbox(14)) != + Point(left=IntUnbox(4), top=IntUnbox(14))|] + tT' decls [q|Point(left=IntUnbox(3), top=IntUnbox(14)) != + Point(left=IntUnbox(4), top=IntUnbox(15))|] + tT' decls "Point(left=IntUnbox(3), top=IntUnbox(14)) != 'foo'" + tT' decls [q|Point(left=IntUnbox(3), + top=IntUnbox(14)).__nirum_serialize__() == {'_type': 'point', 'left': 3, 'top': 14}|] tT' decls [qq|Point.__nirum_deserialize__($payload') == - Point(left=IntBox(3), top=IntBox(14))|] + Point(left=IntUnbox(3), top=IntUnbox(14))|] tR'' decls "ValueError" "Point.__nirum_deserialize__({'left': 3, 'top': 14})" tR'' decls "ValueError" "Point.__nirum_deserialize__({'_type': 'foo'})" - tR'' decls "TypeError" "Point(left=IntBox(1), top='a')" - tR'' decls "TypeError" "Point(left=IntBox(1), top=2)" + tR'' decls "TypeError" "Point(left=IntUnbox(1), top='a')" + tR'' decls "TypeError" "Point(left=IntUnbox(1), top=2)" let fields'' = [ Field "xy" "point" empty , Field "z" "int64" empty ]