mirror of
https://github.com/NorfairKing/autodocodec.git
synced 2024-11-22 13:07:39 +03:00
Added boundedEnumCodec
This commit is contained in:
parent
f19887d136
commit
be4aba9ef1
@ -78,6 +78,7 @@ extra-source-files:
|
|||||||
test_resources/json-schema/semigroup-first.json
|
test_resources/json-schema/semigroup-first.json
|
||||||
test_resources/json-schema/semigroup-last.json
|
test_resources/json-schema/semigroup-last.json
|
||||||
test_resources/json-schema/set-text.json
|
test_resources/json-schema/set-text.json
|
||||||
|
test_resources/json-schema/shape.json
|
||||||
test_resources/json-schema/string.json
|
test_resources/json-schema/string.json
|
||||||
test_resources/json-schema/text.json
|
test_resources/json-schema/text.json
|
||||||
test_resources/json-schema/these.json
|
test_resources/json-schema/these.json
|
||||||
@ -144,6 +145,7 @@ extra-source-files:
|
|||||||
test_resources/nix/semigroup-first-type.nix
|
test_resources/nix/semigroup-first-type.nix
|
||||||
test_resources/nix/semigroup-last-type.nix
|
test_resources/nix/semigroup-last-type.nix
|
||||||
test_resources/nix/set-text-type.nix
|
test_resources/nix/set-text-type.nix
|
||||||
|
test_resources/nix/shape-type.nix
|
||||||
test_resources/nix/string-type.nix
|
test_resources/nix/string-type.nix
|
||||||
test_resources/nix/text-type.nix
|
test_resources/nix/text-type.nix
|
||||||
test_resources/nix/these-options.nix
|
test_resources/nix/these-options.nix
|
||||||
@ -183,6 +185,7 @@ extra-source-files:
|
|||||||
test_resources/openapi-schema/declareSchemaRef/recursive.json
|
test_resources/openapi-schema/declareSchemaRef/recursive.json
|
||||||
test_resources/openapi-schema/declareSchemaRef/semigroup-first.json
|
test_resources/openapi-schema/declareSchemaRef/semigroup-first.json
|
||||||
test_resources/openapi-schema/declareSchemaRef/semigroup-last.json
|
test_resources/openapi-schema/declareSchemaRef/semigroup-last.json
|
||||||
|
test_resources/openapi-schema/declareSchemaRef/shape.json
|
||||||
test_resources/openapi-schema/declareSchemaRef/these.json
|
test_resources/openapi-schema/declareSchemaRef/these.json
|
||||||
test_resources/openapi-schema/declareSchemaRef/very-comment.json
|
test_resources/openapi-schema/declareSchemaRef/very-comment.json
|
||||||
test_resources/openapi-schema/declareSchemaRef/via.json
|
test_resources/openapi-schema/declareSchemaRef/via.json
|
||||||
@ -227,6 +230,7 @@ extra-source-files:
|
|||||||
test_resources/openapi-schema/semigroup-first.json
|
test_resources/openapi-schema/semigroup-first.json
|
||||||
test_resources/openapi-schema/semigroup-last.json
|
test_resources/openapi-schema/semigroup-last.json
|
||||||
test_resources/openapi-schema/set-text.json
|
test_resources/openapi-schema/set-text.json
|
||||||
|
test_resources/openapi-schema/shape.json
|
||||||
test_resources/openapi-schema/string.json
|
test_resources/openapi-schema/string.json
|
||||||
test_resources/openapi-schema/text.json
|
test_resources/openapi-schema/text.json
|
||||||
test_resources/openapi-schema/these.json
|
test_resources/openapi-schema/these.json
|
||||||
@ -285,6 +289,7 @@ extra-source-files:
|
|||||||
test_resources/show-codec/semigroup-first.txt
|
test_resources/show-codec/semigroup-first.txt
|
||||||
test_resources/show-codec/semigroup-last.txt
|
test_resources/show-codec/semigroup-last.txt
|
||||||
test_resources/show-codec/set-text.txt
|
test_resources/show-codec/set-text.txt
|
||||||
|
test_resources/show-codec/shape.txt
|
||||||
test_resources/show-codec/string.txt
|
test_resources/show-codec/string.txt
|
||||||
test_resources/show-codec/text.txt
|
test_resources/show-codec/text.txt
|
||||||
test_resources/show-codec/these.txt
|
test_resources/show-codec/these.txt
|
||||||
@ -346,6 +351,7 @@ extra-source-files:
|
|||||||
test_resources/swagger-schema/semigroup-first.json
|
test_resources/swagger-schema/semigroup-first.json
|
||||||
test_resources/swagger-schema/semigroup-last.json
|
test_resources/swagger-schema/semigroup-last.json
|
||||||
test_resources/swagger-schema/set-text.json
|
test_resources/swagger-schema/set-text.json
|
||||||
|
test_resources/swagger-schema/shape.json
|
||||||
test_resources/swagger-schema/string.json
|
test_resources/swagger-schema/string.json
|
||||||
test_resources/swagger-schema/text.json
|
test_resources/swagger-schema/text.json
|
||||||
test_resources/swagger-schema/these.json
|
test_resources/swagger-schema/these.json
|
||||||
@ -399,6 +405,7 @@ extra-source-files:
|
|||||||
test_resources/yaml-schema/recursive.txt
|
test_resources/yaml-schema/recursive.txt
|
||||||
test_resources/yaml-schema/scientific.txt
|
test_resources/yaml-schema/scientific.txt
|
||||||
test_resources/yaml-schema/set-text.txt
|
test_resources/yaml-schema/set-text.txt
|
||||||
|
test_resources/yaml-schema/shape.txt
|
||||||
test_resources/yaml-schema/string.txt
|
test_resources/yaml-schema/string.txt
|
||||||
test_resources/yaml-schema/text.txt
|
test_resources/yaml-schema/text.txt
|
||||||
test_resources/yaml-schema/these.txt
|
test_resources/yaml-schema/these.txt
|
||||||
|
@ -74,6 +74,7 @@ main =
|
|||||||
comparisonBench @DiffTime,
|
comparisonBench @DiffTime,
|
||||||
comparisonBench @NominalDiffTime,
|
comparisonBench @NominalDiffTime,
|
||||||
comparisonBench @Fruit,
|
comparisonBench @Fruit,
|
||||||
|
comparisonBench @Shape,
|
||||||
comparisonBench @Example,
|
comparisonBench @Example,
|
||||||
comparisonBench @Recursive,
|
comparisonBench @Recursive,
|
||||||
comparisonBench @Via,
|
comparisonBench @Via,
|
||||||
|
@ -94,6 +94,28 @@ instance FromJSON Fruit
|
|||||||
|
|
||||||
instance ToJSON Fruit
|
instance ToJSON Fruit
|
||||||
|
|
||||||
|
data Shape
|
||||||
|
= ShapeCircle
|
||||||
|
| ShapeSquare
|
||||||
|
| ShapeRectangle
|
||||||
|
deriving (Show, Eq, Generic, Enum, Bounded)
|
||||||
|
deriving (FromJSON, ToJSON) via Autodocodec Shape
|
||||||
|
deriving (OpenAPI.ToSchema) via AutodocodecOpenApi Shape
|
||||||
|
|
||||||
|
instance Validity Shape
|
||||||
|
|
||||||
|
instance NFData Shape
|
||||||
|
|
||||||
|
instance GenValid Shape where
|
||||||
|
genValid = genValidStructurallyWithoutExtraChecking
|
||||||
|
shrinkValid = shrinkValidStructurallyWithoutExtraFiltering
|
||||||
|
|
||||||
|
instance HasCodec Shape where
|
||||||
|
codec = boundedEnumCodec $ \case
|
||||||
|
ShapeCircle -> "circle"
|
||||||
|
ShapeSquare -> "square"
|
||||||
|
ShapeRectangle -> "rectangle"
|
||||||
|
|
||||||
-- | A complex example type
|
-- | A complex example type
|
||||||
data Example = Example
|
data Example = Example
|
||||||
{ exampleText :: !Text,
|
{ exampleText :: !Text,
|
||||||
@ -104,7 +126,8 @@ data Example = Example
|
|||||||
exampleOptionalWithDefault :: !Text,
|
exampleOptionalWithDefault :: !Text,
|
||||||
exampleOptionalWithNullDefault :: ![Text],
|
exampleOptionalWithNullDefault :: ![Text],
|
||||||
exampleSingleOrList :: ![Text],
|
exampleSingleOrList :: ![Text],
|
||||||
exampleFruit :: !Fruit
|
exampleFruit :: !Fruit,
|
||||||
|
exampleShape :: !Shape
|
||||||
}
|
}
|
||||||
deriving (Show, Eq, Generic)
|
deriving (Show, Eq, Generic)
|
||||||
deriving (OpenAPI.ToSchema) via (AutodocodecOpenApi Example)
|
deriving (OpenAPI.ToSchema) via (AutodocodecOpenApi Example)
|
||||||
@ -132,6 +155,7 @@ instance HasObjectCodec Example where
|
|||||||
<*> optionalFieldWithOmittedDefault "optional-with-null-default" [] "an optional list of texts with a default empty list where the empty list would be omitted" .= exampleOptionalWithNullDefault
|
<*> optionalFieldWithOmittedDefault "optional-with-null-default" [] "an optional list of texts with a default empty list where the empty list would be omitted" .= exampleOptionalWithNullDefault
|
||||||
<*> optionalFieldWithOmittedDefaultWith "single-or-list" (singleOrListCodec codec) [] "an optional list that can also be specified as a single element" .= exampleSingleOrList
|
<*> optionalFieldWithOmittedDefaultWith "single-or-list" (singleOrListCodec codec) [] "an optional list that can also be specified as a single element" .= exampleSingleOrList
|
||||||
<*> requiredField "fruit" "fruit!!" .= exampleFruit
|
<*> requiredField "fruit" "fruit!!" .= exampleFruit
|
||||||
|
<*> requiredField "shape" "shape!?" .= exampleShape
|
||||||
|
|
||||||
instance ToJSON Example where
|
instance ToJSON Example where
|
||||||
toJSON Example {..} =
|
toJSON Example {..} =
|
||||||
@ -141,6 +165,7 @@ instance ToJSON Example where
|
|||||||
"bool" JSON..= exampleBool,
|
"bool" JSON..= exampleBool,
|
||||||
"maybe" JSON..= exampleRequiredMaybe,
|
"maybe" JSON..= exampleRequiredMaybe,
|
||||||
"fruit" JSON..= exampleFruit,
|
"fruit" JSON..= exampleFruit,
|
||||||
|
"shape" JSON..= exampleShape,
|
||||||
"optional-with-default" JSON..= exampleOptionalWithDefault
|
"optional-with-default" JSON..= exampleOptionalWithDefault
|
||||||
],
|
],
|
||||||
[ "optional" JSON..= opt
|
[ "optional" JSON..= opt
|
||||||
@ -173,6 +198,7 @@ instance FromJSON Example where
|
|||||||
<|> (o JSON..:? "single-or-list" JSON..!= [])
|
<|> (o JSON..:? "single-or-list" JSON..!= [])
|
||||||
)
|
)
|
||||||
<*> o JSON..: "fruit"
|
<*> o JSON..: "fruit"
|
||||||
|
<*> o JSON..: "shape"
|
||||||
|
|
||||||
instance FromMultipart tag Example where
|
instance FromMultipart tag Example where
|
||||||
fromMultipart form =
|
fromMultipart form =
|
||||||
@ -203,6 +229,12 @@ instance FromMultipart tag Example where
|
|||||||
"Melon" -> Right Melon
|
"Melon" -> Right Melon
|
||||||
_ -> Left "unknown fruit"
|
_ -> Left "unknown fruit"
|
||||||
)
|
)
|
||||||
|
<*> ( lookupInput "shape" form >>= \case
|
||||||
|
"circle" -> Right ShapeCircle
|
||||||
|
"square" -> Right ShapeSquare
|
||||||
|
"rectangle" -> Right ShapeRectangle
|
||||||
|
_ -> Left "unknown shape"
|
||||||
|
)
|
||||||
|
|
||||||
instance ToMultipart tag Example where
|
instance ToMultipart tag Example where
|
||||||
toMultipart Example {..} =
|
toMultipart Example {..} =
|
||||||
@ -217,7 +249,12 @@ instance ToMultipart tag Example where
|
|||||||
[Input "optional-with-default" exampleOptionalWithDefault],
|
[Input "optional-with-default" exampleOptionalWithDefault],
|
||||||
map (Input "optional-with-null-default") exampleOptionalWithNullDefault,
|
map (Input "optional-with-null-default") exampleOptionalWithNullDefault,
|
||||||
map (Input "single-or-list") exampleSingleOrList,
|
map (Input "single-or-list") exampleSingleOrList,
|
||||||
[Input "fruit" $ T.pack $ show exampleFruit]
|
[Input "fruit" $ T.pack $ show exampleFruit],
|
||||||
|
[ Input "shape" $ case exampleShape of
|
||||||
|
ShapeCircle -> "circle"
|
||||||
|
ShapeSquare -> "square"
|
||||||
|
ShapeRectangle -> "rectangle"
|
||||||
|
]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
[]
|
[]
|
||||||
|
@ -85,6 +85,7 @@ spec = do
|
|||||||
jsonSchemaSpec @NominalDiffTime "nominal-difftime"
|
jsonSchemaSpec @NominalDiffTime "nominal-difftime"
|
||||||
jsonSchemaSpec @DiffTime "difftime"
|
jsonSchemaSpec @DiffTime "difftime"
|
||||||
jsonSchemaSpec @Fruit "fruit"
|
jsonSchemaSpec @Fruit "fruit"
|
||||||
|
jsonSchemaSpec @Shape "shape"
|
||||||
jsonSchemaSpec @Example "example"
|
jsonSchemaSpec @Example "example"
|
||||||
jsonSchemaSpec @Recursive "recursive"
|
jsonSchemaSpec @Recursive "recursive"
|
||||||
jsonSchemaSpec @ListsExample "lists-example"
|
jsonSchemaSpec @ListsExample "lists-example"
|
||||||
|
@ -100,6 +100,7 @@ spec = do
|
|||||||
aesonCodecSpec @DiffTime
|
aesonCodecSpec @DiffTime
|
||||||
aesonCodecSpec @NominalDiffTime
|
aesonCodecSpec @NominalDiffTime
|
||||||
aesonCodecSpec @Fruit
|
aesonCodecSpec @Fruit
|
||||||
|
aesonCodecSpec @Shape
|
||||||
aesonCodecSpec @Example
|
aesonCodecSpec @Example
|
||||||
aesonCodecErrorSpec @Example "example-error-bool-number" "{\"text\": \"hello\", \"bool\": 5}"
|
aesonCodecErrorSpec @Example "example-error-bool-number" "{\"text\": \"hello\", \"bool\": 5}"
|
||||||
aesonCodecErrorSpec @Example "example-error-fruit-number" "{\"text\": \"hello\", \"bool\": true, \"maybe\": null, \"fruit\": 5}"
|
aesonCodecErrorSpec @Example "example-error-fruit-number" "{\"text\": \"hello\", \"bool\": true, \"maybe\": null, \"fruit\": 5}"
|
||||||
|
@ -75,6 +75,7 @@ spec = do
|
|||||||
nixOptionTypeSpec @NominalDiffTime "nominal-difftime"
|
nixOptionTypeSpec @NominalDiffTime "nominal-difftime"
|
||||||
nixOptionTypeSpec @DiffTime "difftime"
|
nixOptionTypeSpec @DiffTime "difftime"
|
||||||
nixOptionTypeSpec @Fruit "fruit"
|
nixOptionTypeSpec @Fruit "fruit"
|
||||||
|
nixOptionTypeSpec @Shape "shape"
|
||||||
nixOptionTypeSpec @Example "example"
|
nixOptionTypeSpec @Example "example"
|
||||||
nixOptionsSpec @Example "example"
|
nixOptionsSpec @Example "example"
|
||||||
nixOptionTypeSpec @Recursive "recursive"
|
nixOptionTypeSpec @Recursive "recursive"
|
||||||
|
@ -97,6 +97,8 @@ spec = do
|
|||||||
openAPISchemaSpec @NominalDiffTime "nominal-difftime"
|
openAPISchemaSpec @NominalDiffTime "nominal-difftime"
|
||||||
openAPISchemaSpec @Fruit "fruit"
|
openAPISchemaSpec @Fruit "fruit"
|
||||||
openAPISchemaSpecViaDeclareSchemaRef @Fruit "fruit"
|
openAPISchemaSpecViaDeclareSchemaRef @Fruit "fruit"
|
||||||
|
openAPISchemaSpec @Shape "shape"
|
||||||
|
openAPISchemaSpecViaDeclareSchemaRef @Shape "shape"
|
||||||
openAPISchemaSpec @Example "example"
|
openAPISchemaSpec @Example "example"
|
||||||
openAPISchemaSpecViaDeclareSchemaRef @Example "example"
|
openAPISchemaSpecViaDeclareSchemaRef @Example "example"
|
||||||
openAPISchemaSpec @ListsExample "lists-example"
|
openAPISchemaSpec @ListsExample "lists-example"
|
||||||
|
@ -74,6 +74,7 @@ spec = do
|
|||||||
showCodecSpec @TimeOfDay "time-of-day"
|
showCodecSpec @TimeOfDay "time-of-day"
|
||||||
showCodecSpec @ZonedTime "zoned-time"
|
showCodecSpec @ZonedTime "zoned-time"
|
||||||
showCodecSpec @Fruit "fruit"
|
showCodecSpec @Fruit "fruit"
|
||||||
|
showCodecSpec @Shape "shape"
|
||||||
showCodecSpec @Example "example"
|
showCodecSpec @Example "example"
|
||||||
showCodecSpec @Recursive "recursive"
|
showCodecSpec @Recursive "recursive"
|
||||||
showCodecSpec @ListsExample "lists-example"
|
showCodecSpec @ListsExample "lists-example"
|
||||||
|
@ -92,6 +92,7 @@ spec = do
|
|||||||
swaggerSchemaSpec @DiffTime "difftime"
|
swaggerSchemaSpec @DiffTime "difftime"
|
||||||
swaggerSchemaSpec @NominalDiffTime "nominal-difftime"
|
swaggerSchemaSpec @NominalDiffTime "nominal-difftime"
|
||||||
swaggerSchemaSpec @Fruit "fruit"
|
swaggerSchemaSpec @Fruit "fruit"
|
||||||
|
swaggerSchemaSpec @Shape "shape"
|
||||||
swaggerSchemaSpec @Example "example"
|
swaggerSchemaSpec @Example "example"
|
||||||
swaggerSchemaSpec @Recursive "recursive"
|
swaggerSchemaSpec @Recursive "recursive"
|
||||||
swaggerSchemaSpec @ListsExample "lists-example"
|
swaggerSchemaSpec @ListsExample "lists-example"
|
||||||
|
@ -66,6 +66,7 @@ spec = do
|
|||||||
yamlSchemaSpec @DiffTime "difftime"
|
yamlSchemaSpec @DiffTime "difftime"
|
||||||
yamlSchemaSpec @NominalDiffTime "nominal-difftime"
|
yamlSchemaSpec @NominalDiffTime "nominal-difftime"
|
||||||
yamlSchemaSpec @Fruit "fruit"
|
yamlSchemaSpec @Fruit "fruit"
|
||||||
|
yamlSchemaSpec @Shape "shape"
|
||||||
yamlSchemaSpec @Example "example"
|
yamlSchemaSpec @Example "example"
|
||||||
yamlSchemaSpec @Recursive "recursive"
|
yamlSchemaSpec @Recursive "recursive"
|
||||||
yamlSchemaSpec @ListsExample "lists-example"
|
yamlSchemaSpec @ListsExample "lists-example"
|
||||||
|
@ -84,6 +84,7 @@ spec = do
|
|||||||
yamlCodecSpec @DiffTime
|
yamlCodecSpec @DiffTime
|
||||||
yamlCodecSpec @NominalDiffTime
|
yamlCodecSpec @NominalDiffTime
|
||||||
yamlCodecSpec @Fruit
|
yamlCodecSpec @Fruit
|
||||||
|
yamlCodecSpec @Shape
|
||||||
yamlCodecSpec @Example
|
yamlCodecSpec @Example
|
||||||
yamlCodecSpec @Recursive
|
yamlCodecSpec @Recursive
|
||||||
yamlCodecSpec @MutuallyRecursiveA
|
yamlCodecSpec @MutuallyRecursiveA
|
||||||
|
@ -59,6 +59,20 @@
|
|||||||
},
|
},
|
||||||
"type": "array"
|
"type": "array"
|
||||||
},
|
},
|
||||||
|
"shape": {
|
||||||
|
"$comment": "shape!?",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"const": "circle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"const": "square"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"const": "rectangle"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"single-or-list": {
|
"single-or-list": {
|
||||||
"$comment": "an optional list that can also be specified as a single element",
|
"$comment": "an optional list that can also be specified as a single element",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
@ -79,6 +93,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
"shape",
|
||||||
"fruit",
|
"fruit",
|
||||||
"maybe",
|
"maybe",
|
||||||
"bool",
|
"bool",
|
||||||
|
13
autodocodec-api-usage/test_resources/json-schema/shape.json
Normal file
13
autodocodec-api-usage/test_resources/json-schema/shape.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"const": "circle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"const": "square"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"const": "rectangle"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -37,6 +37,14 @@
|
|||||||
description = "an optional list of texts with a default empty list where the empty list would be omitted";
|
description = "an optional list of texts with a default empty list where the empty list would be omitted";
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
};
|
};
|
||||||
|
shape = lib.mkOption {
|
||||||
|
description = "shape!?";
|
||||||
|
type = lib.types.enum [
|
||||||
|
"circle"
|
||||||
|
"square"
|
||||||
|
"rectangle"
|
||||||
|
];
|
||||||
|
};
|
||||||
single-or-list = lib.mkOption {
|
single-or-list = lib.mkOption {
|
||||||
default = [];
|
default = [];
|
||||||
description = "an optional list that can also be specified as a single element";
|
description = "an optional list that can also be specified as a single element";
|
||||||
|
@ -38,6 +38,14 @@ lib.types.submodule {
|
|||||||
description = "an optional list of texts with a default empty list where the empty list would be omitted";
|
description = "an optional list of texts with a default empty list where the empty list would be omitted";
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
};
|
};
|
||||||
|
shape = lib.mkOption {
|
||||||
|
description = "shape!?";
|
||||||
|
type = lib.types.enum [
|
||||||
|
"circle"
|
||||||
|
"square"
|
||||||
|
"rectangle"
|
||||||
|
];
|
||||||
|
};
|
||||||
single-or-list = lib.mkOption {
|
single-or-list = lib.mkOption {
|
||||||
default = [];
|
default = [];
|
||||||
description = "an optional list that can also be specified as a single element";
|
description = "an optional list that can also be specified as a single element";
|
||||||
|
6
autodocodec-api-usage/test_resources/nix/shape-type.nix
Normal file
6
autodocodec-api-usage/test_resources/nix/shape-type.nix
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{ lib }:
|
||||||
|
lib.types.enum [
|
||||||
|
"circle"
|
||||||
|
"square"
|
||||||
|
"rectangle"
|
||||||
|
]
|
@ -43,6 +43,15 @@
|
|||||||
},
|
},
|
||||||
"type": "array"
|
"type": "array"
|
||||||
},
|
},
|
||||||
|
"shape": {
|
||||||
|
"description": "shape!?",
|
||||||
|
"enum": [
|
||||||
|
"circle",
|
||||||
|
"square",
|
||||||
|
"rectangle"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"single-or-list": {
|
"single-or-list": {
|
||||||
"additionalProperties": true,
|
"additionalProperties": true,
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
@ -68,7 +77,8 @@
|
|||||||
"text",
|
"text",
|
||||||
"bool",
|
"bool",
|
||||||
"maybe",
|
"maybe",
|
||||||
"fruit"
|
"fruit",
|
||||||
|
"shape"
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"definitions": {},
|
||||||
|
"reference": {
|
||||||
|
"enum": [
|
||||||
|
"circle",
|
||||||
|
"square",
|
||||||
|
"rectangle"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
@ -44,6 +44,15 @@
|
|||||||
},
|
},
|
||||||
"type": "array"
|
"type": "array"
|
||||||
},
|
},
|
||||||
|
"shape": {
|
||||||
|
"description": "shape!?",
|
||||||
|
"enum": [
|
||||||
|
"circle",
|
||||||
|
"square",
|
||||||
|
"rectangle"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"single-or-list": {
|
"single-or-list": {
|
||||||
"additionalProperties": true,
|
"additionalProperties": true,
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
@ -69,7 +78,8 @@
|
|||||||
"text",
|
"text",
|
||||||
"bool",
|
"bool",
|
||||||
"maybe",
|
"maybe",
|
||||||
"fruit"
|
"fruit",
|
||||||
|
"shape"
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Shape": {
|
||||||
|
"enum": [
|
||||||
|
"circle",
|
||||||
|
"square",
|
||||||
|
"rectangle"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"title": "",
|
||||||
|
"version": ""
|
||||||
|
},
|
||||||
|
"openapi": "3.0.0",
|
||||||
|
"paths": {}
|
||||||
|
}
|
@ -8,93 +8,113 @@ ObjectOfCodec
|
|||||||
(ApCodec
|
(ApCodec
|
||||||
(ApCodec
|
(ApCodec
|
||||||
(ApCodec
|
(ApCodec
|
||||||
(BimapCodec
|
(ApCodec
|
||||||
_
|
|
||||||
_
|
|
||||||
(RequiredKeyCodec "text" (Just "a text") (StringCodec Nothing)))
|
|
||||||
(BimapCodec
|
|
||||||
_ _ (RequiredKeyCodec "bool" (Just "a bool") (BoolCodec Nothing))))
|
|
||||||
(BimapCodec
|
|
||||||
_
|
|
||||||
_
|
|
||||||
(RequiredKeyCodec
|
|
||||||
"maybe"
|
|
||||||
(Just "a maybe text")
|
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(EitherCodec
|
(RequiredKeyCodec "text" (Just "a text") (StringCodec Nothing)))
|
||||||
PossiblyJointUnion NullCodec (StringCodec Nothing))))))
|
(BimapCodec
|
||||||
|
_ _ (RequiredKeyCodec "bool" (Just "a bool") (BoolCodec Nothing))))
|
||||||
|
(BimapCodec
|
||||||
|
_
|
||||||
|
_
|
||||||
|
(RequiredKeyCodec
|
||||||
|
"maybe"
|
||||||
|
(Just "a maybe text")
|
||||||
|
(BimapCodec
|
||||||
|
_
|
||||||
|
_
|
||||||
|
(EitherCodec
|
||||||
|
PossiblyJointUnion NullCodec (StringCodec Nothing))))))
|
||||||
|
(BimapCodec
|
||||||
|
_
|
||||||
|
_
|
||||||
|
(OptionalKeyCodec
|
||||||
|
"optional" (Just "an optional text") (StringCodec Nothing))))
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(OptionalKeyCodec
|
(OptionalKeyCodec
|
||||||
"optional" (Just "an optional text") (StringCodec Nothing))))
|
"optional-or-null"
|
||||||
|
(Just "an optional-or-null text")
|
||||||
|
(BimapCodec
|
||||||
|
_
|
||||||
|
_
|
||||||
|
(EitherCodec
|
||||||
|
PossiblyJointUnion NullCodec (StringCodec Nothing))))))
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(OptionalKeyCodec
|
(OptionalKeyWithDefaultCodec
|
||||||
"optional-or-null"
|
"optional-with-default"
|
||||||
(Just "an optional-or-null text")
|
(StringCodec Nothing)
|
||||||
(BimapCodec
|
_
|
||||||
_
|
(Just "an optional text with a default"))))
|
||||||
_
|
|
||||||
(EitherCodec
|
|
||||||
PossiblyJointUnion NullCodec (StringCodec Nothing))))))
|
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(OptionalKeyWithDefaultCodec
|
(OptionalKeyWithOmittedDefaultCodec
|
||||||
"optional-with-default"
|
"optional-with-null-default"
|
||||||
(StringCodec Nothing)
|
(BimapCodec _ _ (ArrayOfCodec Nothing (StringCodec Nothing)))
|
||||||
_
|
_
|
||||||
(Just "an optional text with a default"))))
|
(Just
|
||||||
|
"an optional list of texts with a default empty list where the empty list would be omitted"))))
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(OptionalKeyWithOmittedDefaultCodec
|
(OptionalKeyWithOmittedDefaultCodec
|
||||||
"optional-with-null-default"
|
"single-or-list"
|
||||||
(BimapCodec _ _ (ArrayOfCodec Nothing (StringCodec Nothing)))
|
(BimapCodec
|
||||||
|
_
|
||||||
|
_
|
||||||
|
(EitherCodec
|
||||||
|
PossiblyJointUnion
|
||||||
|
(StringCodec Nothing)
|
||||||
|
(BimapCodec _ _ (ArrayOfCodec Nothing (StringCodec Nothing)))))
|
||||||
_
|
_
|
||||||
(Just
|
(Just
|
||||||
"an optional list of texts with a default empty list where the empty list would be omitted"))))
|
"an optional list that can also be specified as a single element"))))
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(OptionalKeyWithOmittedDefaultCodec
|
(RequiredKeyCodec
|
||||||
"single-or-list"
|
"fruit"
|
||||||
|
(Just "fruit!!")
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(EitherCodec
|
(EitherCodec
|
||||||
PossiblyJointUnion
|
DisjointUnion
|
||||||
(StringCodec Nothing)
|
(BimapCodec _ _ (EqCodec "Apple" (StringCodec Nothing)))
|
||||||
(BimapCodec _ _ (ArrayOfCodec Nothing (StringCodec Nothing)))))
|
(BimapCodec
|
||||||
_
|
_
|
||||||
(Just
|
_
|
||||||
"an optional list that can also be specified as a single element"))))
|
(EitherCodec
|
||||||
|
DisjointUnion
|
||||||
|
(BimapCodec _ _ (EqCodec "Orange" (StringCodec Nothing)))
|
||||||
|
(BimapCodec
|
||||||
|
_
|
||||||
|
_
|
||||||
|
(EitherCodec
|
||||||
|
DisjointUnion
|
||||||
|
(BimapCodec _ _ (EqCodec "Banana" (StringCodec Nothing)))
|
||||||
|
(BimapCodec _ _ (EqCodec "Melon" (StringCodec Nothing))))))))))))
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(RequiredKeyCodec
|
(RequiredKeyCodec
|
||||||
"fruit"
|
"shape"
|
||||||
(Just "fruit!!")
|
(Just "shape!?")
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(EitherCodec
|
(EitherCodec
|
||||||
DisjointUnion
|
DisjointUnion
|
||||||
(BimapCodec _ _ (EqCodec "Apple" (StringCodec Nothing)))
|
(BimapCodec _ _ (EqCodec "circle" (StringCodec Nothing)))
|
||||||
(BimapCodec
|
(BimapCodec
|
||||||
_
|
_
|
||||||
_
|
_
|
||||||
(EitherCodec
|
(EitherCodec
|
||||||
DisjointUnion
|
DisjointUnion
|
||||||
(BimapCodec _ _ (EqCodec "Orange" (StringCodec Nothing)))
|
(BimapCodec _ _ (EqCodec "square" (StringCodec Nothing)))
|
||||||
(BimapCodec
|
(BimapCodec _ _ (EqCodec "rectangle" (StringCodec Nothing))))))))))
|
||||||
_
|
|
||||||
_
|
|
||||||
(EitherCodec
|
|
||||||
DisjointUnion
|
|
||||||
(BimapCodec _ _ (EqCodec "Banana" (StringCodec Nothing)))
|
|
||||||
(BimapCodec _ _ (EqCodec "Melon" (StringCodec Nothing))))))))))))
|
|
13
autodocodec-api-usage/test_resources/show-codec/shape.txt
Normal file
13
autodocodec-api-usage/test_resources/show-codec/shape.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
BimapCodec
|
||||||
|
_
|
||||||
|
_
|
||||||
|
(EitherCodec
|
||||||
|
DisjointUnion
|
||||||
|
(BimapCodec _ _ (EqCodec "circle" (StringCodec Nothing)))
|
||||||
|
(BimapCodec
|
||||||
|
_
|
||||||
|
_
|
||||||
|
(EitherCodec
|
||||||
|
DisjointUnion
|
||||||
|
(BimapCodec _ _ (EqCodec "square" (StringCodec Nothing)))
|
||||||
|
(BimapCodec _ _ (EqCodec "rectangle" (StringCodec Nothing))))))
|
@ -39,6 +39,14 @@
|
|||||||
},
|
},
|
||||||
"type": "array"
|
"type": "array"
|
||||||
},
|
},
|
||||||
|
"shape": {
|
||||||
|
"description": "shape!?",
|
||||||
|
"enum": [
|
||||||
|
"circle",
|
||||||
|
"square",
|
||||||
|
"rectangle"
|
||||||
|
]
|
||||||
|
},
|
||||||
"single-or-list": {
|
"single-or-list": {
|
||||||
"additionalProperties": true,
|
"additionalProperties": true,
|
||||||
"description": "an optional list that can also be specified as a single element"
|
"description": "an optional list that can also be specified as a single element"
|
||||||
@ -52,7 +60,8 @@
|
|||||||
"text",
|
"text",
|
||||||
"bool",
|
"bool",
|
||||||
"maybe",
|
"maybe",
|
||||||
"fruit"
|
"fruit",
|
||||||
|
"shape"
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"definitions": {
|
||||||
|
"Shape": {
|
||||||
|
"enum": [
|
||||||
|
"circle",
|
||||||
|
"square",
|
||||||
|
"rectangle"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"title": "",
|
||||||
|
"version": ""
|
||||||
|
},
|
||||||
|
"paths": {},
|
||||||
|
"swagger": "2.0"
|
||||||
|
}
|
@ -39,3 +39,10 @@
|
|||||||
, Banana
|
, Banana
|
||||||
, Melon
|
, Melon
|
||||||
]
|
]
|
||||||
|
[37mshape[m: # [31mrequired[m
|
||||||
|
# shape!?
|
||||||
|
# [32mone of[m
|
||||||
|
[ circle
|
||||||
|
, square
|
||||||
|
, rectangle
|
||||||
|
]
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
# [32mone of[m
|
||||||
|
[ circle
|
||||||
|
, square
|
||||||
|
, rectangle
|
||||||
|
]
|
@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [0.4.2.2] - 2024-09-01
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* `boundedEnumCodec`
|
||||||
|
|
||||||
## [0.4.2.1] - 2024-08-21
|
## [0.4.2.1] - 2024-08-21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -5,7 +5,7 @@ cabal-version: 1.12
|
|||||||
-- see: https://github.com/sol/hpack
|
-- see: https://github.com/sol/hpack
|
||||||
|
|
||||||
name: autodocodec
|
name: autodocodec
|
||||||
version: 0.4.2.1
|
version: 0.4.2.2
|
||||||
synopsis: Self-documenting encoder and decoder
|
synopsis: Self-documenting encoder and decoder
|
||||||
homepage: https://github.com/NorfairKing/autodocodec#readme
|
homepage: https://github.com/NorfairKing/autodocodec#readme
|
||||||
bug-reports: https://github.com/NorfairKing/autodocodec/issues
|
bug-reports: https://github.com/NorfairKing/autodocodec/issues
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
}:
|
}:
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
pname = "autodocodec";
|
pname = "autodocodec";
|
||||||
version = "0.4.2.1";
|
version = "0.4.2.2";
|
||||||
src = ./.;
|
src = ./.;
|
||||||
libraryHaskellDepends = [
|
libraryHaskellDepends = [
|
||||||
aeson base bytestring containers dlist hashable mtl scientific text
|
aeson base bytestring containers dlist hashable mtl scientific text
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name: autodocodec
|
name: autodocodec
|
||||||
version: 0.4.2.1
|
version: 0.4.2.2
|
||||||
github: "NorfairKing/autodocodec"
|
github: "NorfairKing/autodocodec"
|
||||||
license: MIT
|
license: MIT
|
||||||
author: "Tom Sydney Kerckhove"
|
author: "Tom Sydney Kerckhove"
|
||||||
|
@ -102,6 +102,7 @@ module Autodocodec
|
|||||||
|
|
||||||
-- *** Enums
|
-- *** Enums
|
||||||
shownBoundedEnumCodec,
|
shownBoundedEnumCodec,
|
||||||
|
boundedEnumCodec,
|
||||||
stringConstCodec,
|
stringConstCodec,
|
||||||
enumCodec,
|
enumCodec,
|
||||||
|
|
||||||
|
@ -1907,6 +1907,33 @@ stringConstCodec =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- | A codec for a 'Bounded' 'Enum' that uses the provided function to have the values correspond to literal 'Text' values.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- === Example usage
|
||||||
|
--
|
||||||
|
-- >>> data Fruit = Apple | Orange deriving (Show, Eq, Enum, Bounded)
|
||||||
|
-- >>> :{
|
||||||
|
-- let c = boundedEnumCodec $ \case
|
||||||
|
-- Apple -> "foo"
|
||||||
|
-- Orange -> "bar"
|
||||||
|
-- :}
|
||||||
|
--
|
||||||
|
-- >>> toJSONVia c Apple
|
||||||
|
-- String "foo"
|
||||||
|
-- >>> JSON.parseMaybe (parseJSONVia c) (String "bar") :: Maybe Fruit
|
||||||
|
-- Just Orange
|
||||||
|
boundedEnumCodec ::
|
||||||
|
forall enum.
|
||||||
|
(Eq enum, Enum enum, Bounded enum) =>
|
||||||
|
(enum -> T.Text) ->
|
||||||
|
JSONCodec enum
|
||||||
|
boundedEnumCodec showFunc =
|
||||||
|
let ls = [minBound .. maxBound]
|
||||||
|
in case NE.nonEmpty ls of
|
||||||
|
Nothing -> error "0 enum values ?!"
|
||||||
|
Just ne -> stringConstCodec (NE.map (\v -> (v, showFunc v)) ne)
|
||||||
|
|
||||||
-- | A codec for a 'Bounded' 'Enum' that uses its 'Show' instance to have the values correspond to literal 'Text' values.
|
-- | A codec for a 'Bounded' 'Enum' that uses its 'Show' instance to have the values correspond to literal 'Text' values.
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
@ -1922,11 +1949,7 @@ shownBoundedEnumCodec ::
|
|||||||
forall enum.
|
forall enum.
|
||||||
(Show enum, Eq enum, Enum enum, Bounded enum) =>
|
(Show enum, Eq enum, Enum enum, Bounded enum) =>
|
||||||
JSONCodec enum
|
JSONCodec enum
|
||||||
shownBoundedEnumCodec =
|
shownBoundedEnumCodec = boundedEnumCodec (T.pack . show)
|
||||||
let ls = [minBound .. maxBound]
|
|
||||||
in case NE.nonEmpty ls of
|
|
||||||
Nothing -> error "0 enum values ?!"
|
|
||||||
Just ne -> stringConstCodec (NE.map (\v -> (v, T.pack (show v))) ne)
|
|
||||||
|
|
||||||
-- | Helper function for 'optionalFieldOrNullWith' and 'optionalFieldOrNull'.
|
-- | Helper function for 'optionalFieldOrNullWith' and 'optionalFieldOrNull'.
|
||||||
--
|
--
|
||||||
|
Loading…
Reference in New Issue
Block a user