git.iko.soy/deriving-openapi3
on master help sign in
Merge pull request #2 from ilyakooo0/iko/ci
70c6973iko
.github/workflows/build.yamlnew file+62
@@ -0,0 +1,62 @@
1+name: Build
2+
3+on:
4+ push:
5+ branches: [master]
6+ pull_request:
7+ branches: [master]
8+ release:
9+ types: [prereleased]
10+
11+jobs:
12+ check_versions:
13+ runs-on: ubuntu-latest
14+ steps:
15+ - uses: actions/checkout@v2
16+
17+ - name: Check library version
18+ if: github.event_name == 'release'
19+ run: |
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."
22+ exit 1
23+ fi
24+ Linux:
25+ needs: check_versions
26+ runs-on: ubuntu-latest
27+ steps:
28+ - uses: actions/checkout@v2
29+
30+ - name: Cache
31+ uses: actions/cache@v1
32+ with:
33+ path: |
34+ ~/.stack
35+ .stack-work
36+ key: ${{ runner.os }}-stack-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}
37+ restore-keys: |
38+ ${{ runner.os }}-stack-${{ hashFiles('stack.yaml') }}
39+ ${{ runner.os }}-stack
40+
41+ - name: Upgrade stack
42+ shell: bash
43+ run: stack upgrade --git
44+
45+ - name: Build
46+ shell: bash
47+ run: |
48+ stack build
49+
50+ - name: Check Formatting
51+ shell: bash
52+ run: |
53+ stack install ormolu
54+ ormolu -o -XTypeApplications -o -XCPP -m check $(find src -type f -name "*.hs")
55+
56+ - name: Publish candidate
57+ shell: bash
58+ if: github.event_name == 'release'
59+ env:
60+ HACKAGE_KEY: ${{ secrets.HACKAGE_TOKEN }}
61+ run: |
62+ stack upload --pvp-bounds both --test-tarball --candidate .
Changelog.mdnew file+3
@@ -0,0 +1,3 @@
1+# 0.1.0.0
2+
3+Initial release
package.yaml+24−4
@@ -1,18 +1,33 @@
1name: deriving-openapi3
1name: deriving-openapi3
2−version: 0.1.0
2+version: 0.1.0.0
3synopsis: DerivingVia for OpenAPI 3
3synopsis: DerivingVia for OpenAPI 3
4−# description:
4+description: See <https://github.com/ilyakooo0/deriving-openapi3 GitHub> for more details.
5maintainer: Ilya Kostyuchenko <ilyakooo0@gmail.com>
5maintainer: Ilya Kostyuchenko <ilyakooo0@gmail.com>
6+category: JSON, Generics, OpenAPI
7+license: MIT
8+license-file: LICENSE
9+extra-source-files: Changelog.md
6github: ilyakooo0/deriving-openapi3
10github: ilyakooo0/deriving-openapi3
7−ghc-options: -Wall
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
8dependencies:
19dependencies:
9 - base
20 - base
10 - openapi3
21 - openapi3
11 - deriving-aeson
22 - deriving-aeson
12 - aeson
23 - aeson
13− - servant
14 - lens
24 - lens
15 - text
25 - text
26+when:
27+ - condition: flag(servant-description)
28+ dependencies:
29+ - servant
30+ cpp-options: -DSERVANT_DESCRIPTION
16library:
31library:
17 source-dirs: src
32 source-dirs: src
18default-extensions:
33default-extensions:
@@ -27,3 +42,8 @@ default-extensions:
27 - TypeFamilies
42 - TypeFamilies
28 - PolyKinds
43 - PolyKinds
29 - OverloadedStrings
44 - OverloadedStrings
45+flags:
46+ servant-description:
47+ description: Create instances for the 'Description' type from 'servant'
48+ default: true
49+ manual: false
src/Deriving/OpenApi.hs+18−12
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1{-# OPTIONS_GHC -Wno-orphans #-}
2{-# OPTIONS_GHC -Wno-orphans #-}
2
3
3module Deriving.OpenApi
4module Deriving.OpenApi
@@ -15,13 +16,28 @@ import Data.Kind
15import Data.OpenApi
16import Data.OpenApi
16import Data.OpenApi.Internal.Schema
17import Data.OpenApi.Internal.Schema
17import Data.Proxy
18import Data.Proxy
18−import Data.Text (Text)
19−import qualified Data.Text as T
20import Data.Typeable
19import Data.Typeable
21import Deriving.Aeson
20import Deriving.Aeson
22import GHC.Generics
21import GHC.Generics
23import GHC.TypeLits
22import GHC.TypeLits
23+
24+#ifdef SERVANT_DESCRIPTION
25+
24import Servant.API
26import Servant.API
27+import Data.Text (Text)
28+import qualified Data.Text as T
29+
30+instance (AesonOptions xs) => AesonOptions (Description f ': xs) where
31+ aesonOptions = aesonOptions @xs
32+
33+instance (OpenApiOptions xs, KnownSymbol t) => OpenApiOptions (Description t ': xs) where
34+ openApiOptions = openApiOptions @xs
35+ openApiSchemaModifier = schema . description <>~ Just (toTextLine @t)
36+
37+toTextLine :: forall s. KnownSymbol s => Text
38+toTextLine = "\n\n" <> T.pack (symbolVal (Proxy @s))
39+
40+#endif
25
41
26type CustomOpenApi = CustomJSON
42type CustomOpenApi = CustomJSON
27
43
@@ -37,16 +53,6 @@ instance (StringModifier f, OpenApiOptions xs) => OpenApiOptions (DatatypeNameMo
37instance (AesonOptions xs) => AesonOptions (DatatypeNameModifier f ': xs) where
53instance (AesonOptions xs) => AesonOptions (DatatypeNameModifier f ': xs) where
38 aesonOptions = aesonOptions @xs
54 aesonOptions = aesonOptions @xs
39
55
40−instance (AesonOptions xs) => AesonOptions (Description f ': xs) where
41− aesonOptions = aesonOptions @xs
42−
43−instance (OpenApiOptions xs, KnownSymbol t) => OpenApiOptions (Description t ': xs) where
44− openApiOptions = openApiOptions @xs
45− openApiSchemaModifier = schema . description <>~ Just (toTextLine @t)
46−
47−toTextLine :: forall s. KnownSymbol s => Text
48−toTextLine = "\n\n" <> T.pack (symbolVal (Proxy @s))
49−
50type family (++) (x :: [k]) (y :: [k]) :: [k] where
56type family (++) (x :: [k]) (y :: [k]) :: [k] where
51 (++) '[] ys = ys
57 (++) '[] ys = ys
52 (++) (x ': xs) ys = xs ++ (x ': ys)
58 (++) (x ': xs) ys = xs ++ (x ': ys)