git.iko.soy/deriving-openapi3
on 4315b78 help sign in
.github/workflows/build.yaml+6−2
since splitsnapshots
unifiedsplit
@@ -17,7 +17,7 @@ jobs:
17 - name: Check library version
17 - name: Check library version
18 if: github.event_name == 'release'
18 if: github.event_name == 'release'
19 run: |
19 run: |
20− if [ "$(awk -F":" '{if ($1 == "version") {gsub(/ /, "", $2); print $2}}' *.cabal)" != "${{ github.event.release.tag_name }}" ]; then
20+ if [ "$(yq eval ".version" package.yaml)" != "${{ github.event.release.tag_name }}" ]; then
21 echo "::error file=action.yaml::Library version does not match release version."
21 echo "::error file=action.yaml::Library version does not match release version."
22 exit 1
22 exit 1
23 fi
23 fi
@@ -33,11 +33,15 @@ jobs:
33 path: |
33 path: |
34 ~/.stack
34 ~/.stack
35 .stack-work
35 .stack-work
36− key: ${{ runner.os }}-stack-${{ hashFiles('stack.yaml') }}-${{ hashFiles('**.cabal') }}
36+ key: ${{ runner.os }}-stack-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}
37 restore-keys: |
37 restore-keys: |
38 ${{ runner.os }}-stack-${{ hashFiles('stack.yaml') }}
38 ${{ runner.os }}-stack-${{ hashFiles('stack.yaml') }}
39 ${{ runner.os }}-stack
39 ${{ runner.os }}-stack
40
40
41+ - name: Upgrade stack
42+ shell: bash
43+ run: stack upgrade --git
44+
41 - name: Build
45 - name: Build
42 shell: bash
46 shell: bash
43 run: |
47 run: |
deriving-openapi3.cabal+11−3
@@ -22,6 +22,11 @@ source-repository head
22 type: git
22 type: git
23 location: https://github.com/ilyakooo0/deriving-openapi3
23 location: https://github.com/ilyakooo0/deriving-openapi3
24
24
25+flag servant-description
26+ description: Create instances for the 'Description' type from 'servant'
27+ manual: False
28+ default: True
29+
25library
30library
26 exposed-modules:
31 exposed-modules:
27 Deriving.OpenApi
32 Deriving.OpenApi
@@ -43,13 +48,16 @@ library
43 OverloadedStrings
48 OverloadedStrings
44 DerivingStrategies
49 DerivingStrategies
45 DerivingVia
50 DerivingVia
46− FlexibleContexts
47 ghc-options: -Weverything -Wno-star-is-type -Wno-unsafe -Wno-prepositive-qualified-module -Wno-safe -Wno-missing-safe-haskell-mode -Wno-missing-import-lists -Wno-implicit-prelude
51 ghc-options: -Weverything -Wno-star-is-type -Wno-unsafe -Wno-prepositive-qualified-module -Wno-safe -Wno-missing-safe-haskell-mode -Wno-missing-import-lists -Wno-implicit-prelude
48 build-depends:
52 build-depends:
49 aeson
53 aeson
50− , base >=4.12
54+ , base
51− , deriving-aeson >=0.2.2
55+ , deriving-aeson
52 , lens
56 , lens
53 , openapi3
57 , openapi3
54 , text
58 , text
59+ if flag(servant-description)
60+ cpp-options: -DSERVANT_DESCRIPTION
61+ build-depends:
62+ servant
55 default-language: Haskell2010
63 default-language: Haskell2010
package.yamlnew file+51
@@ -0,0 +1,51 @@
1+name: deriving-openapi3
2+version: 0.1.0.0
3+synopsis: DerivingVia for OpenAPI 3
4+description: DerivingVia for OpenAPI 3
5+maintainer: Ilya Kostyuchenko <ilyakooo0@gmail.com>
6+category: JSON, Generics, OpenAPI
7+license: MIT
8+license-file: LICENSE
9+extra-source-files: Changelog.md
10+github: ilyakooo0/deriving-openapi3
11+ghc-options: -Weverything
12+ -Wno-star-is-type
13+ -Wno-unsafe
14+ -Wno-prepositive-qualified-module
15+ -Wno-safe
16+ -Wno-missing-safe-haskell-mode
17+ -Wno-missing-import-lists
18+ -Wno-implicit-prelude
19+dependencies:
20+ - base
21+ - openapi3
22+ - deriving-aeson
23+ - aeson
24+ - lens
25+ - text
26+when:
27+ - condition: flag(servant-description)
28+ dependencies:
29+ - servant
30+ cpp-options: -DSERVANT_DESCRIPTION
31+library:
32+ source-dirs: src
33+default-extensions:
34+ - AllowAmbiguousTypes
35+ - ScopedTypeVariables
36+ - KindSignatures
37+ - DataKinds
38+ - TypeOperators
39+ - FlexibleInstances
40+ - TypeApplications
41+ - UndecidableInstances
42+ - TypeFamilies
43+ - PolyKinds
44+ - OverloadedStrings
45+ - DerivingStrategies
46+ - DerivingVia
47+flags:
48+ servant-description:
49+ description: Create instances for the 'Description' type from 'servant'
50+ default: true
51+ manual: false
src/Deriving/OpenApi.hs+7−13
@@ -39,17 +39,18 @@ where
39import Control.Lens
39import Control.Lens
40import qualified Data.Aeson.Types as A
40import qualified Data.Aeson.Types as A
41import Data.OpenApi
41import Data.OpenApi
42−import Data.OpenApi.Internal.ParamSchema
43import Data.OpenApi.Internal.Schema
42import Data.OpenApi.Internal.Schema
44import Data.Proxy
43import Data.Proxy
45−import Data.Text (Text)
46−import qualified Data.Text as T
47import Data.Typeable
44import Data.Typeable
48import Deriving.Aeson
45import Deriving.Aeson
49import GHC.Generics
46import GHC.Generics
50import GHC.TypeLits
47import GHC.TypeLits
51
48
52−data Description (desc :: Symbol) = Description
49+#ifdef SERVANT_DESCRIPTION
50+
51+import Servant.API
52+import Data.Text (Text)
53+import qualified Data.Text as T
53
54
54instance (AesonOptions xs) => AesonOptions (Description f ': xs) where
55instance (AesonOptions xs) => AesonOptions (Description f ': xs) where
55 aesonOptions = aesonOptions @xs
56 aesonOptions = aesonOptions @xs
@@ -60,6 +61,8 @@ instance KnownSymbol t => OpenApiOptionModifier (Description t) where
60toTextLine :: forall s. KnownSymbol s => Text
61toTextLine :: forall s. KnownSymbol s => Text
61toTextLine = "\n\n" <> T.pack (symbolVal (Proxy @s))
62toTextLine = "\n\n" <> T.pack (symbolVal (Proxy @s))
62
63
64+#endif
65+
63-- $setup
66-- $setup
64-- >>> import qualified Data.Yaml
67-- >>> import qualified Data.Yaml
65-- >>> import qualified Data.ByteString.Char8
68-- >>> import qualified Data.ByteString.Char8
@@ -74,13 +77,6 @@ instance
74 openApiSchemaModifier @xs
77 openApiSchemaModifier @xs
75 <$> genericDeclareNamedSchema (openApiOptionsModifier @xs defaultSchemaOptions) (Proxy @x)
78 <$> genericDeclareNamedSchema (openApiOptionsModifier @xs defaultSchemaOptions) (Proxy @x)
76
79
77−instance
78− (OpenApiOptionModifier xs, GToParamSchema (Rep x), Generic x) =>
79− ToParamSchema (CustomJSON (xs :: k) x)
80− where
81− toParamSchema Proxy =
82− genericToParamSchema (openApiOptionsModifier @xs defaultSchemaOptions) (Proxy @x)
83−
84class OpenApiOptionModifier x where
80class OpenApiOptionModifier x where
85 openApiOptionsModifier :: SchemaOptions -> SchemaOptions
81 openApiOptionsModifier :: SchemaOptions -> SchemaOptions
86 openApiOptionsModifier = id
82 openApiOptionsModifier = id
@@ -102,10 +98,8 @@ instance OpenApiOptionModifier UnwrapUnaryRecords where
102
98
103instance OpenApiOptionModifier OmitNothingFields
99instance OpenApiOptionModifier OmitNothingFields
104
100
105−#if MIN_VERSION_deriving_aeson(0,2,4)
106instance OpenApiOptionModifier RejectUnknownFields where
101instance OpenApiOptionModifier RejectUnknownFields where
107 openApiSchemaModifier = schema . additionalProperties .~ Just (AdditionalPropertiesAllowed False)
102 openApiSchemaModifier = schema . additionalProperties .~ Just (AdditionalPropertiesAllowed False)
108−#endif
109
103
110instance StringModifier f => OpenApiOptionModifier (FieldLabelModifier f) where
104instance StringModifier f => OpenApiOptionModifier (FieldLabelModifier f) where
111 openApiOptionsModifier o = o {fieldLabelModifier = getStringModifier @f}
105 openApiOptionsModifier o = o {fieldLabelModifier = getStringModifier @f}