diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml index 105da1a7..e1d15085 100644 --- a/.github/workflows/haskell-ci.yml +++ b/.github/workflows/haskell-ci.yml @@ -8,9 +8,9 @@ # # For more information, see https://github.com/haskell-CI/haskell-ci # -# version: 0.19.20250506 +# version: 0.19.20260331 # -# REGENDATA ("0.19.20250506",["github","cabal.project"]) +# REGENDATA ("0.19.20260331",["github","cabal.project"]) # name: Haskell-CI on: @@ -20,6 +20,11 @@ on: pull_request: branches: - master + merge_group: + branches: + - master + workflow_dispatch: + {} jobs: linux: name: Haskell-CI - Linux - ${{ matrix.compiler }} @@ -27,41 +32,46 @@ jobs: timeout-minutes: 60 container: - image: buildpack-deps:focal + image: buildpack-deps:jammy continue-on-error: ${{ matrix.allow-failure }} strategy: matrix: include: - - compiler: ghc-9.12.1 + - compiler: ghc-9.14.1 compilerKind: ghc - compilerVersion: 9.12.1 + compilerVersion: 9.14.1 setup-method: ghcup allow-failure: true - - compiler: ghc-9.10.2 + - compiler: ghc-9.12.4 compilerKind: ghc - compilerVersion: 9.10.2 + compilerVersion: 9.12.4 setup-method: ghcup - allow-failure: true - - compiler: ghc-9.8.1 + allow-failure: false + - compiler: ghc-9.10.3 compilerKind: ghc - compilerVersion: 9.8.1 + compilerVersion: 9.10.3 setup-method: ghcup - allow-failure: true - - compiler: ghc-9.6.3 + allow-failure: false + - compiler: ghc-9.8.4 compilerKind: ghc - compilerVersion: 9.6.3 + compilerVersion: 9.8.4 setup-method: ghcup - allow-failure: true + allow-failure: false + - compiler: ghc-9.6.7 + compilerKind: ghc + compilerVersion: 9.6.7 + setup-method: ghcup + allow-failure: false - compiler: ghc-9.4.8 compilerKind: ghc compilerVersion: 9.4.8 setup-method: ghcup - allow-failure: true + allow-failure: false - compiler: ghc-9.2.8 compilerKind: ghc compilerVersion: 9.2.8 setup-method: ghcup - allow-failure: true + allow-failure: false - compiler: ghc-9.0.2 compilerKind: ghc compilerVersion: 9.0.2 @@ -82,17 +92,12 @@ jobs: compilerVersion: 8.6.5 setup-method: ghcup allow-failure: false - - compiler: ghc-8.4.4 - compilerKind: ghc - compilerVersion: 8.4.4 - setup-method: ghcup - allow-failure: false fail-fast: false steps: - name: apt-get install run: | apt-get update - apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5 libnuma-dev + apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5 - name: Install GHCup run: | mkdir -p "$HOME/.ghcup/bin" @@ -100,8 +105,8 @@ jobs: chmod a+x "$HOME/.ghcup/bin/ghcup" - name: Install cabal-install run: | - "$HOME/.ghcup/bin/ghcup" install cabal 3.14.2.0 || (cat "$HOME"/.ghcup/logs/*.* && false) - echo "CABAL=$HOME/.ghcup/bin/cabal-3.14.2.0 -vnormal+nowrap" >> "$GITHUB_ENV" + "$HOME/.ghcup/bin/ghcup" install cabal 3.16.0.0 || (cat "$HOME"/.ghcup/logs/*.* && false) + echo "CABAL=$HOME/.ghcup/bin/cabal-3.16.0.0 -vnormal+nowrap" >> "$GITHUB_ENV" - name: Install GHC (GHCup) if: matrix.setup-method == 'ghcup' run: | @@ -177,7 +182,7 @@ jobs: chmod a+x $HOME/.cabal/bin/cabal-plan cabal-plan --version - name: checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: source - name: initial cabal.project for sdist @@ -202,7 +207,9 @@ jobs: touch cabal.project.local echo "packages: ${PKGDIR_openapi3}" >> cabal.project echo "package openapi3" >> cabal.project - echo " ghc-options: -Werror=missing-methods" >> cabal.project + echo " ghc-options: -Werror=missing-methods -Werror=missing-fields" >> cabal.project + if [ $((HCNUMVER >= 90000)) -ne 0 ] ; then echo "package openapi3" >> cabal.project ; fi + if [ $((HCNUMVER >= 90000)) -ne 0 ] ; then echo " ghc-options: -Werror=incomplete-patterns -Werror=incomplete-uni-patterns" >> cabal.project ; fi cat >> cabal.project <> cabal.project.local @@ -245,6 +252,18 @@ jobs: - name: prepare for constraint sets run: | rm -f cabal.project.local + - name: constraint set insert-ordered-containers-0.3 + run: | + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='insert-ordered-containers >=0.3' all --dry-run + cabal-plan topo | sort + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='insert-ordered-containers >=0.3' --dependencies-only -j2 all + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='insert-ordered-containers >=0.3' all + - name: constraint set insert-ordered-containers-0.2 + run: | + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='insert-ordered-containers <0.3' all --dry-run + cabal-plan topo | sort + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='insert-ordered-containers <0.3' --dependencies-only -j2 all + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='insert-ordered-containers <0.3' all - name: constraint set aeson-2 run: | $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='aeson >=2.0' all --dry-run diff --git a/cabal.haskell-ci b/cabal.haskell-ci index ea783c4c..f2053cc8 100644 --- a/cabal.haskell-ci +++ b/cabal.haskell-ci @@ -1,7 +1,6 @@ branches: master -distribution: focal -allow-failures: >=9.2 +allow-failures: >=9.14 -- https://github.com/haskell-CI/haskell-ci/issues/658#issuecomment-1513692337 haddock-components: libs @@ -11,9 +10,18 @@ haddock-components: libs -- and https://github.com/haskell/cabal/issues/8707 haddock: < 9.0 || >= 9.4 +-- Breaks on doctests +error-unused-packages: False + constraint-set aeson-1 constraints: aeson <2.0 ghc: <9.2 constraint-set aeson-2 constraints: aeson >=2.0 + +constraint-set insert-ordered-containers-0.2 + constraints: insert-ordered-containers <0.3 + +constraint-set insert-ordered-containers-0.3 + constraints: insert-ordered-containers >=0.3 diff --git a/openapi3.cabal b/openapi3.cabal index 1185d038..726feaba 100644 --- a/openapi3.cabal +++ b/openapi3.cabal @@ -23,17 +23,17 @@ extra-source-files: , CHANGELOG.md , examples/*.hs tested-with: - GHC ==8.4.4 - || ==8.6.5 + GHC ==8.6.5 || ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 - || ==9.6.3 - || ==9.8.1 - || ==9.10.2 - || ==9.12.1 + || ==9.6.7 + || ==9.8.4 + || ==9.10.3 + || ==9.12.4 + || ==9.14.1 custom-setup setup-depends: @@ -65,14 +65,15 @@ library Data.OpenApi.Internal.TypeShape Data.OpenApi.Aeson.Compat + Data.HashMap.Strict.InsOrd.Compat -- GHC boot libraries build-depends: - base >=4.11.1.0 && <4.22 + base >=4.11.1.0 && <4.23 , bytestring >=0.10.8.2 && <0.13 , containers >=0.5.11.0 && <0.9 - , template-haskell >=2.13.0.0 && <2.24 - , time >=1.8.0.2 && <1.15 + , template-haskell >=2.13.0.0 && <2.25 + , time >=1.8.0.2 && <1.16 , transformers >=0.5.5.0 && <0.7 build-depends: @@ -81,7 +82,7 @@ library -- other dependencies build-depends: - base-compat-batteries >=0.11.1 && <0.15 + base-compat-batteries >=0.11.1 && <0.16 , aeson >=1.4.2.0 && <1.6 || >=2.0.1.0 && < 2.3 , aeson-pretty >=0.8.7 && <0.9 -- cookie 0.4.3 is needed by GHC 7.8 due to time>=1.4 constraint @@ -89,7 +90,7 @@ library , generics-sop >=0.5.1.0 && <0.6 , hashable >=1.2.7.0 && <1.6 , http-media >=0.8.0.0 && <0.9 - , insert-ordered-containers >=0.2.3 && <0.3 + , insert-ordered-containers >=0.2.3 && <0.4 , lens >=4.16.1 && <5.4 , optics-core >=0.2 && <0.5 , optics-th >=0.2 && <0.5 @@ -97,9 +98,43 @@ library , unordered-containers >=0.2.9.0 && <0.3 , uuid-types >=1.0.3 && <1.1 , vector >=0.12.0.1 && <0.14 - , QuickCheck >=2.10.1 && <2.16 + , QuickCheck >=2.10.1 && <2.19 default-language: Haskell2010 + default-extensions: + ConstraintKinds + DataKinds + DefaultSignatures + DeriveDataTypeable + DeriveFunctor + DeriveGeneric + DeriveTraversable + ExplicitForAll + FlexibleContexts + FlexibleInstances + FunctionalDependencies + GADTs + GeneralizedNewtypeDeriving + KindSignatures + LambdaCase + MultiParamTypeClasses + OverloadedLabels + OverloadedStrings + PackageImports + PolyKinds + RankNTypes + RecordWildCards + ScopedTypeVariables + StandaloneDeriving + TemplateHaskell + TupleSections + TypeApplications + TypeFamilies + TypeOperators + TypeSynonymInstances + UndecidableInstances + UndecidableSuperClasses + ViewPatterns test-suite spec type: exitcode-stdio-1.0 @@ -155,6 +190,7 @@ test-suite doctests main-is: doctests.hs type: exitcode-stdio-1.0 build-depends: base, openapi3 + ghc-options: -Wno-unused-packages executable example hs-source-dirs: examples diff --git a/src/Data/HashMap/Strict/InsOrd/Compat.hs b/src/Data/HashMap/Strict/InsOrd/Compat.hs new file mode 100644 index 00000000..e6fabead --- /dev/null +++ b/src/Data/HashMap/Strict/InsOrd/Compat.hs @@ -0,0 +1,438 @@ +-- Ported from GetShopTV/swagger2 (pull request #262) to apply the same +-- insert-ordered-containers-0.3 compatibility fix to openapi3. +-- Credit for the design and implementation belongs to the swagger2 authors. +{-# LANGUAGE CPP #-} +-- | +-- Module: Data.HashMap.Strict.InsOrd.Compat +-- Maintainer: Nickolay Kudasov +-- Stability: experimental +-- +-- Compatibility wrapper around @insert-ordered-containers@ to mitigate the +-- breaking changes introduced in @insert-ordered-containers-0.3.0@: +-- . +-- +-- That change fixed 'Eq' and Aeson instances in the upstream package, but it is +-- a behavioral break for @swagger2@ where we need stable Swagger Schema +-- generation and JSON object-like encoding. +-- +-- This module keeps the old @swagger2@ expectations: +-- +-- * 'InsOrdHashMap' values are encoded as JSON objects (not arrays of key/value +-- tuples), so field names remain first-class object keys. +-- * Equality intentionally ignores insertion order (compares as plain hash +-- maps), which matches how many tests currently assert JSON equality. +-- +-- Simple encoding examples: +-- +-- >>> import Data.Aeson (encode, eitherDecode) +-- >>> import qualified Data.ByteString.Lazy.Char8 as BSL8 +-- >>> import qualified Data.HashMap.Strict as HM +-- >>> import qualified Data.HashMap.Strict.InsOrd.Compat as IOHM +-- >>> let decodeIOHM s = either error id (eitherDecode (BSL8.pack s) :: Either String (IOHM.InsOrdHashMap String Int)) +-- +-- A regular hash map has no insertion order guarantee: +-- +-- >>> encode (HM.fromList [("a", 1 :: Int), ("b", 2)]) +-- "{\"a\":1,\"b\":2}" +-- >>> encode (HM.fromList [("b", 1 :: Int), ("a", 2)]) +-- "{\"a\":2,\"b\":1}" +-- +-- Our compat 'InsOrdHashMap' encodes to a JSON object as well, but preserves insertion order: +-- +-- >>> encode (IOHM.fromList [("a", 1 :: Int), ("b", 2)]) +-- "{\"a\":1,\"b\":2}" +-- >>> encode (IOHM.fromList [("b", 1 :: Int), ("a", 2)]) +-- "{\"b\":1,\"a\":2}" +-- +-- Round-tripping through decode/encode demonstrates the caveat: encoding +-- preserves insertion order, but decoded object key order is not guaranteed. +-- +-- >>> encode (decodeIOHM "{\"a\":1,\"b\":2}") +-- "{\"a\":1,\"b\":2}" +-- >>> encode (decodeIOHM "{\"b\":1,\"a\":2}") +-- "{\"a\":2,\"b\":1}" +-- +-- This object encoding is what @swagger2@ wants for generated Swagger +-- definitions/properties because it keeps emitted schemas easy to consume and +-- stable in practice. +-- +-- Important caveat: decoding cannot be fully stable with respect to insertion +-- order due to @aeson@ limitations. In particular, object parsing goes through +-- structures that do not preserve all ordering guarantees end-to-end. We accept +-- this trade-off for now because the primary requirement is deterministic +-- /encoding/ for generated Swagger Schema artifacts. +-- +-- Many tests rely on @aesonQQ@-style JSON equality, where semantic object +-- equality matters more than insertion order. Comparing via plain hash maps +-- makes those tests robust under benign key-order variation. This is a weaker +-- notion of equality and hopefully will be revisited later. +module Data.HashMap.Strict.InsOrd.Compat ( + InsOrdHashMap, + -- * Construction + empty, + singleton, + -- * Basic interface + null, + size, + member, + lookup, + lookupDefault, + insert, + insertWith, + delete, + adjust, + update, + alter, + -- * Combine + union, + unionWith, + unionWithKey, + unions, + -- * Transformations + map, + mapKeys, + traverseKeys, + mapWithKey, + traverseWithKey, + -- ** Unordered + unorderedTraverse, + unorderedTraverseWithKey, + -- * Difference and intersection + difference, + intersection, + intersectionWith, + intersectionWithKey, + -- * Folds + foldl', + foldlWithKey', + foldr, + foldrWithKey, + foldMapWithKey, + -- ** Unordered + unorderedFoldMap, + unorderedFoldMapWithKey, + -- * Filter + filter, + filterWithKey, + mapMaybe, + mapMaybeWithKey, + -- * Conversions + keys, + elems, + toList, + toRevList, + fromList, + toHashMap, + fromHashMap, + -- * Lenses + hashMap, + unorderedTraversal, + -- * Debugging + valid, + ) where + +#if !MIN_VERSION_insert_ordered_containers(0,3,0) +import Prelude hiding (null, lookup, map, foldl', foldr, filter) +import Data.HashMap.Strict.InsOrd +#else +import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap + +import Prelude hiding (null, size, member, lookup, lookupDefault, map, foldl', filter) +import qualified Prelude + +import qualified Data.Aeson as A +import qualified Data.Aeson.Encoding as E +import Data.HashMap.Strict (HashMap) +import qualified Data.HashMap.Strict as HashMap + +import qualified GHC.Exts as Exts + +import Data.Data (Data) +import Data.Foldable (Foldable (foldMap)) +import Data.Hashable (Hashable (..)) + +import qualified Control.Lens as Lens +import Control.Lens + (At (..), Index, Iso, IxValue, Ixed (..), Traversal, _1, _2, iso, (<&>)) + +import qualified Optics.Core as Optics + +newtype InsOrdHashMap k v = InsOrdHashMap { unCompatInsOrdHashMap :: InsOrdHashMap.InsOrdHashMap k v } + deriving (Show, Read, Data, Functor, Foldable, Traversable, Semigroup, Monoid) + +instance (Eq k, Eq v) => Eq (InsOrdHashMap k v) where + a == b = toHashMap a == toHashMap b + +instance (Eq k, Hashable k) => Exts.IsList (InsOrdHashMap k v) where + type Item (InsOrdHashMap k v) = Exts.Item (InsOrdHashMap.InsOrdHashMap k v) + fromList = InsOrdHashMap . InsOrdHashMap.fromList + toList = InsOrdHashMap.toList . unCompatInsOrdHashMap + +------------------------------------------------------------------------------- +-- Aeson +------------------------------------------------------------------------------- + +instance (A.ToJSONKey k) => A.ToJSON1 (InsOrdHashMap k) where + liftToJSON _ t _ = case A.toJSONKey :: A.ToJSONKeyFunction k of + A.ToJSONKeyText f _ -> A.object . fmap (\(k, v) -> (f k, t v)) . toList + A.ToJSONKeyValue f _ -> A.toJSON . fmap (\(k,v) -> A.toJSON (f k, t v)) . toList + + liftToEncoding o t _ = case A.toJSONKey :: A.ToJSONKeyFunction k of + A.ToJSONKeyText _ f -> E.dict f t foldrWithKey + A.ToJSONKeyValue _ f -> E.list (A.liftToEncoding2 (const False) f (E.list f) o t (E.list t)) . toList + +instance (A.ToJSONKey k, A.ToJSON v) => A.ToJSON (InsOrdHashMap k v) where + toJSON = A.toJSON1 + toEncoding = A.toEncoding1 + +------------------------------------------------------------------------------- + +instance (Eq k, Hashable k, A.FromJSONKey k) => A.FromJSON1 (InsOrdHashMap k) where + liftParseJSON o p pl v = fromList . HashMap.toList <$> A.liftParseJSON o p pl v + +instance (Eq k, Hashable k, A.FromJSONKey k, A.FromJSON v) => A.FromJSON (InsOrdHashMap k v) where + parseJSON = A.parseJSON1 + +------------------------------------------------------------------------------- +-- indexed-traversals +------------------------------------------------------------------------------- + +instance (Eq k, Hashable k) => Optics.FunctorWithIndex k (InsOrdHashMap k) where + imap = mapWithKey +instance (Eq k, Hashable k) => Optics.FoldableWithIndex k (InsOrdHashMap k) where + ifoldMap = foldMapWithKey + ifoldr = foldrWithKey +instance (Eq k, Hashable k) => Optics.TraversableWithIndex k (InsOrdHashMap k) where + itraverse = traverseWithKey + +------------------------------------------------------------------------------- +-- Lens +------------------------------------------------------------------------------- + +type instance Index (InsOrdHashMap k v) = k +type instance IxValue (InsOrdHashMap k v) = v + +instance (Eq k, Hashable k) => Ixed (InsOrdHashMap k v) where + ix k f m = ixImpl k pure f m + {-# INLINABLE ix #-} + +ixImpl + :: (Eq k, Hashable k, Functor f) + => k + -> (InsOrdHashMap k v -> f (InsOrdHashMap k v)) + -> (v -> f v) + -> InsOrdHashMap k v + -> f (InsOrdHashMap k v) +ixImpl k point f m = case lookup k m of + Just v -> f v <&> \v' -> insert k v' m + Nothing -> point m +{-# INLINE ixImpl #-} + +instance (Eq k, Hashable k) => At (InsOrdHashMap k a) where + at k f m = f mv <&> \r -> case r of + Nothing -> maybe m (const (delete k m)) mv + Just v' -> insert k v' m + where mv = lookup k m + {-# INLINABLE at #-} + +------------------------------------------------------------------------------- +-- Optics +------------------------------------------------------------------------------- + +type instance Optics.Index (InsOrdHashMap k v) = k +type instance Optics.IxValue (InsOrdHashMap k v) = v + +instance (Eq k, Hashable k) => Optics.Ixed (InsOrdHashMap k v) where + ix k = Optics.atraversalVL $ \point f m -> ixImpl k point f m + {-# INLINE ix #-} + +instance (Eq k, Hashable k) => Optics.At (InsOrdHashMap k a) where + at k = Optics.lensVL $ \f m -> Lens.at k f m + {-# INLINE at #-} + +------------------------------------------------------------------------------- + +-- | This is a slight lie, as roundtrip doesn't preserve ordering. +hashMap :: Iso (InsOrdHashMap k a) (InsOrdHashMap k b) (HashMap k a) (HashMap k b) +hashMap = iso toHashMap fromHashMap + +unorderedTraversal :: Traversal (InsOrdHashMap k a) (InsOrdHashMap k b) a b +unorderedTraversal = hashMap . traverse + +------------------------------------------------------------------------------- +-- * Construction +------------------------------------------------------------------------------- + +empty :: InsOrdHashMap k v +empty = InsOrdHashMap InsOrdHashMap.empty + +singleton :: Hashable k => k -> v -> InsOrdHashMap k v +singleton k v = InsOrdHashMap (InsOrdHashMap.singleton k v) + +------------------------------------------------------------------------------- +-- * Basic interface +------------------------------------------------------------------------------- + +null :: InsOrdHashMap k v -> Bool +null = InsOrdHashMap.null . unCompatInsOrdHashMap + +size :: InsOrdHashMap k v -> Int +size = InsOrdHashMap.size . unCompatInsOrdHashMap + +insert :: Hashable k => k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v +insert k v = InsOrdHashMap . InsOrdHashMap.insert k v . unCompatInsOrdHashMap + +insertWith :: Hashable k => (v -> v -> v) -> k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v +insertWith f k v = InsOrdHashMap . InsOrdHashMap.insertWith f k v . unCompatInsOrdHashMap + +delete :: Hashable k => k -> InsOrdHashMap k v -> InsOrdHashMap k v +delete k = InsOrdHashMap . InsOrdHashMap.delete k . unCompatInsOrdHashMap + +adjust :: Hashable k => (v -> v) -> k -> InsOrdHashMap k v -> InsOrdHashMap k v +adjust f k = InsOrdHashMap . InsOrdHashMap.adjust f k . unCompatInsOrdHashMap + +update :: Hashable k => (v -> Maybe v) -> k -> InsOrdHashMap k v -> InsOrdHashMap k v +update f k = InsOrdHashMap . InsOrdHashMap.update f k . unCompatInsOrdHashMap + +alter :: Hashable k => (Maybe v -> Maybe v) -> k -> InsOrdHashMap k v -> InsOrdHashMap k v +alter f k = InsOrdHashMap . InsOrdHashMap.alter f k . unCompatInsOrdHashMap + +member :: Hashable k => k -> InsOrdHashMap k v -> Bool +member k = InsOrdHashMap.member k . unCompatInsOrdHashMap + +lookup :: Hashable k => k -> InsOrdHashMap k v -> Maybe v +lookup k = InsOrdHashMap.lookup k . unCompatInsOrdHashMap + +lookupDefault :: Hashable k => v -> k -> InsOrdHashMap k v -> v +lookupDefault k def = InsOrdHashMap.lookupDefault k def . unCompatInsOrdHashMap + +-- * Combine + +union :: Hashable k => InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v +union m1 m2 = InsOrdHashMap (InsOrdHashMap.union (unCompatInsOrdHashMap m1) (unCompatInsOrdHashMap m2)) + +unionWith :: Hashable k => (v -> v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v +unionWith f m1 m2 = InsOrdHashMap (InsOrdHashMap.unionWith f (unCompatInsOrdHashMap m1) (unCompatInsOrdHashMap m2)) + +unionWithKey :: Hashable k => (k -> v -> v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v +unionWithKey f m1 m2 = InsOrdHashMap (InsOrdHashMap.unionWithKey f (unCompatInsOrdHashMap m1) (unCompatInsOrdHashMap m2)) + +unions :: Hashable k => [InsOrdHashMap k v] -> InsOrdHashMap k v +unions = InsOrdHashMap . InsOrdHashMap.unions . Prelude.map unCompatInsOrdHashMap + +------------------------------------------------------------------------------- +-- * Transformations +------------------------------------------------------------------------------- + +map :: (v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v +map f = InsOrdHashMap . InsOrdHashMap.map f . unCompatInsOrdHashMap + +mapKeys :: Hashable k => (k -> k) -> InsOrdHashMap k v -> InsOrdHashMap k v +mapKeys f = InsOrdHashMap . InsOrdHashMap.mapKeys f . unCompatInsOrdHashMap + +traverseKeys :: (Applicative f, Hashable k) => (k -> f k) -> InsOrdHashMap k v -> f (InsOrdHashMap k v) +traverseKeys f = fmap InsOrdHashMap . InsOrdHashMap.traverseKeys f . unCompatInsOrdHashMap + +mapWithKey :: (k -> v1 -> v2) -> InsOrdHashMap k v1 -> InsOrdHashMap k v2 +mapWithKey f = InsOrdHashMap . InsOrdHashMap.mapWithKey f . unCompatInsOrdHashMap + +traverseWithKey :: (Applicative f, Hashable k) => (k -> v1 -> f v2) -> InsOrdHashMap k v1 -> f (InsOrdHashMap k v2) +traverseWithKey f = fmap InsOrdHashMap . InsOrdHashMap.traverseWithKey f . unCompatInsOrdHashMap + +-- ** Unordered + +unorderedTraverse :: (Applicative f, Hashable k) => (v -> f v) -> InsOrdHashMap k v -> f (InsOrdHashMap k v) +unorderedTraverse f = fmap InsOrdHashMap . InsOrdHashMap.unorderedTraverse f . unCompatInsOrdHashMap + +unorderedTraverseWithKey :: (Applicative f, Hashable k) => (k -> v -> f v) -> InsOrdHashMap k v -> f (InsOrdHashMap k v) +unorderedTraverseWithKey f = fmap InsOrdHashMap . InsOrdHashMap.unorderedTraverseWithKey f . unCompatInsOrdHashMap + +------------------------------------------------------------------------------- +-- * Difference and intersection +------------------------------------------------------------------------------- + +difference :: Hashable k => InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v +difference m1 m2 = InsOrdHashMap (InsOrdHashMap.difference (unCompatInsOrdHashMap m1) (unCompatInsOrdHashMap m2)) + +intersection :: Hashable k => InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v +intersection m1 m2 = InsOrdHashMap (InsOrdHashMap.intersection (unCompatInsOrdHashMap m1) (unCompatInsOrdHashMap m2)) + +intersectionWith :: Hashable k => (v -> v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v +intersectionWith f m1 m2 = InsOrdHashMap (InsOrdHashMap.intersectionWith f (unCompatInsOrdHashMap m1) (unCompatInsOrdHashMap m2)) + +intersectionWithKey :: Hashable k => (k -> v -> v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v +intersectionWithKey f m1 m2 = InsOrdHashMap (InsOrdHashMap.intersectionWithKey f (unCompatInsOrdHashMap m1) (unCompatInsOrdHashMap m2)) + +------------------------------------------------------------------------------- +-- * Folds +------------------------------------------------------------------------------- + +foldl' :: (a -> v -> a) -> a -> InsOrdHashMap k v -> a +foldl' f z = InsOrdHashMap.foldl' f z . unCompatInsOrdHashMap + +foldlWithKey' :: (a -> k -> v -> a) -> a -> InsOrdHashMap k v -> a +foldlWithKey' f z = InsOrdHashMap.foldlWithKey' f z . unCompatInsOrdHashMap + +foldMapWithKey :: Monoid m => (k -> v -> m) -> InsOrdHashMap k v -> m +foldMapWithKey f = InsOrdHashMap.foldMapWithKey f . unCompatInsOrdHashMap + +foldrWithKey :: (k -> v -> a -> a) -> a -> InsOrdHashMap k v -> a +foldrWithKey f z = InsOrdHashMap.foldrWithKey f z . unCompatInsOrdHashMap + +-- ** Unordered + +unorderedFoldMap :: Monoid m => (v -> m) -> InsOrdHashMap k v -> m +unorderedFoldMap f = InsOrdHashMap.unorderedFoldMap f . unCompatInsOrdHashMap + +unorderedFoldMapWithKey :: Monoid m => (k -> v -> m) -> InsOrdHashMap k v -> m +unorderedFoldMapWithKey f = InsOrdHashMap.unorderedFoldMapWithKey f . unCompatInsOrdHashMap + +------------------------------------------------------------------------------- +-- * Filter +------------------------------------------------------------------------------- + +filter :: (v -> Bool) -> InsOrdHashMap k v -> InsOrdHashMap k v +filter f = InsOrdHashMap . InsOrdHashMap.filter f . unCompatInsOrdHashMap + +filterWithKey :: (k -> v -> Bool) -> InsOrdHashMap k v -> InsOrdHashMap k v +filterWithKey f = InsOrdHashMap . InsOrdHashMap.filterWithKey f . unCompatInsOrdHashMap + +mapMaybe :: (v -> Maybe v) -> InsOrdHashMap k v -> InsOrdHashMap k v +mapMaybe f = InsOrdHashMap . InsOrdHashMap.mapMaybe f . unCompatInsOrdHashMap + +mapMaybeWithKey :: (k -> v -> Maybe v) -> InsOrdHashMap k v -> InsOrdHashMap k v +mapMaybeWithKey f = InsOrdHashMap . InsOrdHashMap.mapMaybeWithKey f . unCompatInsOrdHashMap + +------------------------------------------------------------------------------- +-- * Conversions +------------------------------------------------------------------------------- + +keys :: InsOrdHashMap k v -> [k] +keys = InsOrdHashMap.keys . unCompatInsOrdHashMap + +elems :: InsOrdHashMap k v -> [v] +elems = InsOrdHashMap.elems . unCompatInsOrdHashMap + +toRevList :: InsOrdHashMap k v -> [(k, v)] +toRevList = InsOrdHashMap.toRevList . unCompatInsOrdHashMap + +fromList :: Hashable k => [(k, v)] -> InsOrdHashMap k v +fromList = InsOrdHashMap . InsOrdHashMap.fromList + +toList :: InsOrdHashMap k v -> [(k, v)] +toList = InsOrdHashMap.toList . unCompatInsOrdHashMap + +toHashMap :: InsOrdHashMap k v -> HashMap k v +toHashMap = InsOrdHashMap.toHashMap . unCompatInsOrdHashMap + +fromHashMap :: HashMap k v -> InsOrdHashMap k v +fromHashMap = InsOrdHashMap . InsOrdHashMap.fromHashMap + +------------------------------------------------------------------------------- +-- * Debugging +------------------------------------------------------------------------------- + +valid :: (Eq k, Hashable k) => InsOrdHashMap k v -> Bool +valid = InsOrdHashMap.valid . unCompatInsOrdHashMap + +#endif diff --git a/src/Data/OpenApi.hs b/src/Data/OpenApi.hs index a9ce8f3d..c4d825cc 100644 --- a/src/Data/OpenApi.hs +++ b/src/Data/OpenApi.hs @@ -139,7 +139,7 @@ import Data.OpenApi.Internal -- >>> import qualified Data.ByteString.Lazy.Char8 as BSL -- >>> import Data.OpenApi.Internal -- >>> import Data.OpenApi.Internal.Schema --- >>> import qualified Data.HashMap.Strict.InsOrd as IOHM +-- >>> import qualified Data.HashMap.Strict.InsOrd.Compat as IOHM -- >>> import Data.OpenApi.Internal.Utils -- >>> import Data.OpenApi.Lens -- >>> :set -XDeriveGeneric diff --git a/src/Data/OpenApi/Aeson/Compat.hs b/src/Data/OpenApi/Aeson/Compat.hs index c516a4e1..21387d27 100644 --- a/src/Data/OpenApi/Aeson/Compat.hs +++ b/src/Data/OpenApi/Aeson/Compat.hs @@ -10,7 +10,7 @@ import qualified Data.Aeson.KeyMap as KeyMap import qualified Data.HashMap.Strict as HM #endif import Data.Bifunctor (first) -import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap +import qualified Data.HashMap.Strict.InsOrd.Compat as InsOrdHashMap import qualified Data.Text as T #if MIN_VERSION_aeson(2,0,0) diff --git a/src/Data/OpenApi/Declare.hs b/src/Data/OpenApi/Declare.hs index a302bb0a..df9ef8d3 100644 --- a/src/Data/OpenApi/Declare.hs +++ b/src/Data/OpenApi/Declare.hs @@ -1,8 +1,3 @@ -{-# LANGUAGE DeriveFunctor #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE FunctionalDependencies #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE UndecidableInstances #-} -- | -- Module: Data.OpenApi.Declare -- Maintainer: Nickolay Kudasov @@ -52,7 +47,6 @@ instance (Applicative m, Monad m, Monoid d) => Applicative (DeclareT d m) where return (mappend d' d'', f x) instance (Applicative m, Monad m, Monoid d) => Monad (DeclareT d m) where - return x = DeclareT (\_ -> pure (mempty, x)) DeclareT dx >>= f = DeclareT $ \d -> do ~(d', x) <- dx d ~(d'', y) <- runDeclareT (f x) (mappend d d') diff --git a/src/Data/OpenApi/Internal.hs b/src/Data/OpenApi/Internal.hs index b9be5292..be77723b 100644 --- a/src/Data/OpenApi/Internal.hs +++ b/src/Data/OpenApi/Internal.hs @@ -1,19 +1,5 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveDataTypeable #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE DeriveTraversable #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE StandaloneDeriving #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wno-orphans #-} module Data.OpenApi.Internal where import Prelude () @@ -45,8 +31,8 @@ import Network.HTTP.Media (MediaType, mainType, parameters, parseAc (/:)) import Text.Read (readMaybe) -import Data.HashMap.Strict.InsOrd (InsOrdHashMap) -import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap +import Data.HashMap.Strict.InsOrd.Compat (InsOrdHashMap) +import qualified Data.HashMap.Strict.InsOrd.Compat as InsOrdHashMap import Data.OpenApi.Aeson.Compat (deleteKey) import Data.OpenApi.Internal.AesonUtils (AesonDefaultValue (..), HasSwaggerAesonOptions (..), @@ -335,7 +321,10 @@ instance Data MediaType where dataTypeOf _ = mediaTypeData +mediaTypeConstr :: Constr mediaTypeConstr = mkConstr mediaTypeData "MediaType" [] Prefix + +mediaTypeData :: DataType mediaTypeData = mkDataType "MediaType" [mediaTypeConstr] instance Hashable MediaType where @@ -1006,12 +995,12 @@ deriveGeneric ''OpenApiSpecVersion -- ======================================================================= instance Semigroup OpenApiSpecVersion where - (<>) (OpenApiSpecVersion a) (OpenApiSpecVersion b) = OpenApiSpecVersion $ max a b - + (<>) (OpenApiSpecVersion a) (OpenApiSpecVersion b) = OpenApiSpecVersion $ max a b + instance Monoid OpenApiSpecVersion where mempty = OpenApiSpecVersion (makeVersion [3,0,0]) mappend = (<>) - + instance Semigroup OpenApi where (<>) = genericMappend instance Monoid OpenApi where @@ -1282,7 +1271,7 @@ instance FromJSON OAuth2AuthorizationCodeFlow where -- Manual ToJSON instances -- ======================================================================= -instance ToJSON OpenApiSpecVersion where +instance ToJSON OpenApiSpecVersion where toJSON (OpenApiSpecVersion v)= toJSON . showVersion $ v instance ToJSON MediaType where @@ -1456,15 +1445,15 @@ instance FromJSON OpenApiSpecVersion where parseJSON = withText "OpenApiSpecVersion" $ \str -> let validatedVersion :: Either String Version validatedVersion = do - parsedVersion <- readVersion str + parsedVersion <- readVersion str unless ((parsedVersion >= lowerOpenApiSpecVersion) && (parsedVersion <= upperOpenApiSpecVersion)) $ Left ("The provided version " <> showVersion parsedVersion <> " is out of the allowed range >=" <> showVersion lowerOpenApiSpecVersion <> " && <=" <> showVersion upperOpenApiSpecVersion) return parsedVersion - in + in either fail (return . OpenApiSpecVersion) validatedVersion where readVersion :: Text -> Either String Version - readVersion v = case readP_to_S parseVersion (Text.unpack v) of + readVersion v = case readP_to_S parseVersion (Text.unpack v) of [] -> Left $ "Failed to parse as a version string " <> Text.unpack v solutions -> Right (fst . last $ solutions) @@ -1649,7 +1638,7 @@ instance HasSwaggerAesonOptions Encoding where instance HasSwaggerAesonOptions Link where swaggerAesonOptions _ = mkSwaggerAesonOptions "link" -instance AesonDefaultValue Version where +instance AesonDefaultValue Version where defaultValue = Just (makeVersion [3,0,0]) instance AesonDefaultValue OpenApiSpecVersion instance AesonDefaultValue Server diff --git a/src/Data/OpenApi/Internal/AesonUtils.hs b/src/Data/OpenApi/Internal/AesonUtils.hs index 3804ab32..2b1e2625 100644 --- a/src/Data/OpenApi/Internal/AesonUtils.hs +++ b/src/Data/OpenApi/Internal/AesonUtils.hs @@ -1,10 +1,3 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE ExplicitForAll #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE UndecidableSuperClasses #-} module Data.OpenApi.Internal.AesonUtils ( -- * Generic functions AesonDefaultValue(..), @@ -37,7 +30,7 @@ import Generics.SOP import qualified Data.Text as T import qualified Data.Set as Set -import qualified Data.HashMap.Strict.InsOrd as InsOrd +import qualified Data.HashMap.Strict.InsOrd.Compat as InsOrd import qualified Data.HashSet.InsOrd as InsOrdHS import Data.OpenApi.Aeson.Compat (keyToString, objectToList, stringToKey) diff --git a/src/Data/OpenApi/Internal/ParamSchema.hs b/src/Data/OpenApi/Internal/ParamSchema.hs index 75b637a2..ae83e0c5 100644 --- a/src/Data/OpenApi/Internal/ParamSchema.hs +++ b/src/Data/OpenApi/Internal/ParamSchema.hs @@ -1,16 +1,3 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DefaultSignatures #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE PackageImports #-} -{-# LANGUAGE PolyKinds #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} -{-# LANGUAGE TypeSynonymInstances #-} -{-# LANGUAGE UndecidableInstances #-} -- Generic a is redundant in ToParamSchema a default imple {-# OPTIONS_GHC -Wno-redundant-constraints #-} -- For TypeErrors @@ -19,6 +6,7 @@ module Data.OpenApi.Internal.ParamSchema where import Control.Lens import Data.Aeson (ToJSON (..)) +import Data.Kind (Type) import Data.Proxy import GHC.Generics @@ -313,7 +301,7 @@ instance ToParamSchema UUID where genericToParamSchema :: forall a t. (Generic a, GToParamSchema (Rep a)) => SchemaOptions -> Proxy a -> Schema genericToParamSchema opts _ = gtoParamSchema opts (Proxy :: Proxy (Rep a)) mempty -class GToParamSchema (f :: * -> *) where +class GToParamSchema (f :: Type -> Type) where gtoParamSchema :: SchemaOptions -> Proxy f -> Schema -> Schema instance GToParamSchema f => GToParamSchema (D1 d f) where @@ -331,7 +319,7 @@ instance ToParamSchema c => GToParamSchema (K1 i c) where instance (GEnumParamSchema f, GEnumParamSchema g) => GToParamSchema (f :+: g) where gtoParamSchema opts _ = genumParamSchema opts (Proxy :: Proxy (f :+: g)) -class GEnumParamSchema (f :: * -> *) where +class GEnumParamSchema (f :: Type -> Type) where genumParamSchema :: SchemaOptions -> Proxy f -> Schema -> Schema instance (GEnumParamSchema f, GEnumParamSchema g) => GEnumParamSchema (f :+: g) where diff --git a/src/Data/OpenApi/Internal/Schema.hs b/src/Data/OpenApi/Internal/Schema.hs index da56acf0..e5fa09d1 100644 --- a/src/Data/OpenApi/Internal/Schema.hs +++ b/src/Data/OpenApi/Internal/Schema.hs @@ -1,21 +1,5 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DefaultSignatures #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE OverloadedLists #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE PackageImports #-} -{-# LANGUAGE PolyKinds #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} -{-# LANGUAGE TypeSynonymInstances #-} -{-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wno-redundant-constraints #-} -- For TypeErrors {-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-} @@ -24,6 +8,8 @@ module Data.OpenApi.Internal.Schema where import Prelude () import Prelude.Compat +import Data.Kind (Type) + import Control.Lens hiding (allOf) import Data.Data.Lens (template) @@ -39,7 +25,7 @@ import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap import "unordered-containers" Data.HashSet (HashSet) import qualified "unordered-containers" Data.HashSet as HashSet -import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap +import qualified Data.HashMap.Strict.InsOrd.Compat as InsOrdHashMap import Data.Int import Data.IntSet (IntSet) import Data.IntMap (IntMap) @@ -587,7 +573,7 @@ sketchStrictSchema = go . toJSON where names = objectKeys o -class GToSchema (f :: * -> *) where +class GToSchema (f :: Type -> Type) where gdeclareNamedSchema :: SchemaOptions -> Proxy f -> Schema -> Declare (Definitions Schema) NamedSchema instance {-# OVERLAPPABLE #-} ToSchema a => ToSchema [a] where @@ -1046,7 +1032,7 @@ gdeclareNamedSumSchema opts proxy _ type AllNullary = All -class GSumToSchema (f :: * -> *) where +class GSumToSchema (f :: Type -> Type) where gsumToSchema :: SchemaOptions -> Proxy f -> WriterT AllNullary (Declare (Definitions Schema)) [(T.Text, Referenced Schema)] instance (GSumToSchema f, GSumToSchema g) => GSumToSchema (f :+: g) where diff --git a/src/Data/OpenApi/Internal/Schema/Validation.hs b/src/Data/OpenApi/Internal/Schema/Validation.hs index 5554ccf8..42340145 100644 --- a/src/Data/OpenApi/Internal/Schema/Validation.hs +++ b/src/Data/OpenApi/Internal/Schema/Validation.hs @@ -1,19 +1,5 @@ {-# OPTIONS_GHC -Wall #-} {-# LANGUAGE CPP #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveFunctor #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE FunctionalDependencies #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE PackageImports #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE UndecidableInstances #-} -{-# LANGUAGE ViewPatterns #-} -- | -- Module: Data.OpenApi.Internal.Schema.Validation -- Copyright: (c) 2015 GetShopTV @@ -40,7 +26,7 @@ import Data.Foldable (for_, sequenceA_, #if !MIN_VERSION_aeson(2,0,0) import Data.HashMap.Strict (HashMap) #endif -import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap +import qualified Data.HashMap.Strict.InsOrd.Compat as InsOrdHashMap import qualified "unordered-containers" Data.HashSet as HashSet import Data.Maybe (fromMaybe) import Data.Proxy diff --git a/src/Data/OpenApi/Internal/TypeShape.hs b/src/Data/OpenApi/Internal/TypeShape.hs index 89230e21..8af73b1b 100644 --- a/src/Data/OpenApi/Internal/TypeShape.hs +++ b/src/Data/OpenApi/Internal/TypeShape.hs @@ -1,11 +1,7 @@ -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} -{-# LANGUAGE UndecidableInstances #-} module Data.OpenApi.Internal.TypeShape where +import Data.Kind (Type) import Data.Proxy import GHC.Generics import GHC.TypeLits @@ -46,7 +42,7 @@ type family GenericHasSimpleShape t (f :: Symbol) (s :: TypeShape) :: Constraint ) -- | Infer a 'TypeShape' for a generic representation of a type. -type family GenericShape (g :: * -> *) :: TypeShape +type family GenericShape (g :: Type -> Type) :: TypeShape type instance GenericShape (f :*: g) = ProdCombine (GenericShape f) (GenericShape g) type instance GenericShape (f :+: g) = SumCombine (GenericShape f) (GenericShape g) diff --git a/src/Data/OpenApi/Internal/Utils.hs b/src/Data/OpenApi/Internal/Utils.hs index 8bcdd3b1..a8aaa3ae 100644 --- a/src/Data/OpenApi/Internal/Utils.hs +++ b/src/Data/OpenApi/Internal/Utils.hs @@ -1,9 +1,3 @@ -{-# LANGUAGE DefaultSignatures #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE TypeOperators #-} module Data.OpenApi.Internal.Utils where import Prelude () @@ -20,8 +14,8 @@ import Data.Data import Data.Hashable (Hashable) import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap -import Data.HashMap.Strict.InsOrd (InsOrdHashMap) -import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap +import Data.HashMap.Strict.InsOrd.Compat (InsOrdHashMap) +import qualified Data.HashMap.Strict.InsOrd.Compat as InsOrdHashMap import Data.Map (Map) import Data.Set (Set) import Data.Text (Text) diff --git a/src/Data/OpenApi/Lens.hs b/src/Data/OpenApi/Lens.hs index b8e23101..f3e6f30f 100644 --- a/src/Data/OpenApi/Lens.hs +++ b/src/Data/OpenApi/Lens.hs @@ -1,13 +1,3 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE FunctionalDependencies #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | -- Module: Data.OpenApi.Lens diff --git a/src/Data/OpenApi/Operation.hs b/src/Data/OpenApi/Operation.hs index cb8a07e0..845271ad 100644 --- a/src/Data/OpenApi/Operation.hs +++ b/src/Data/OpenApi/Operation.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE RankNTypes #-} -- | -- Module: Data.OpenApi.Operation -- Maintainer: Nickolay Kudasov @@ -47,7 +46,7 @@ import Data.OpenApi.Internal import Data.OpenApi.Lens import Data.OpenApi.Schema -import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap +import qualified Data.HashMap.Strict.InsOrd.Compat as InsOrdHashMap import qualified Data.HashSet.InsOrd as InsOrdHS -- $setup @@ -55,7 +54,7 @@ import qualified Data.HashSet.InsOrd as InsOrdHS -- >>> import Data.Proxy -- >>> import Data.Time -- >>> import qualified Data.ByteString.Lazy.Char8 as BSL --- >>> import qualified Data.HashMap.Strict.InsOrd as IOHM +-- >>> import qualified Data.HashMap.Strict.InsOrd.Compat as IOHM -- >>> import Data.OpenApi.Internal.Utils -- | Prepend path piece to all operations of the spec. diff --git a/src/Data/OpenApi/Optics.hs b/src/Data/OpenApi/Optics.hs index 3d0a42e8..8f71454e 100644 --- a/src/Data/OpenApi/Optics.hs +++ b/src/Data/OpenApi/Optics.hs @@ -1,10 +1,3 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE OverloadedLabels #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | -- Module: Data.OpenApi.Optics @@ -18,7 +11,7 @@ -- >>> import Optics.Core -- >>> :set -XOverloadedLabels -- >>> import qualified Data.ByteString.Lazy.Char8 as BSL --- >>> import qualified Data.HashMap.Strict.InsOrd as IOHM +-- >>> import qualified Data.HashMap.Strict.InsOrd.Compat as IOHM -- -- Example from the "Data.OpenApi" module using @optics@: -- diff --git a/src/Data/OpenApi/Schema/Generator.hs b/src/Data/OpenApi/Schema/Generator.hs index 9cb4014f..8ccaf574 100644 --- a/src/Data/OpenApi/Schema/Generator.hs +++ b/src/Data/OpenApi/Schema/Generator.hs @@ -1,6 +1,4 @@ -{-# LANGUAGE GADTs #-} -{-# LANGUAGE OverloadedLists #-} -{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE OverloadedLists #-} module Data.OpenApi.Schema.Generator where @@ -11,7 +9,7 @@ import Control.Lens.Operators import Control.Monad (filterM) import Data.Aeson import Data.Aeson.Types -import qualified Data.HashMap.Strict.InsOrd as M +import qualified Data.HashMap.Strict.InsOrd.Compat as M import Data.Maybe import Data.Proxy import Data.Scientific @@ -70,6 +68,7 @@ schemaGen defns schema = OpenApiItemsArray refs -> let itemGens = schemaGen defns . dereference defns <$> refs in fmap (Array . V.fromList) $ sequence itemGens + | otherwise -> pure $ Array V.empty Just OpenApiString -> do size <- getSize let minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minLength diff --git a/src/Data/OpenApi/SchemaOptions.hs b/src/Data/OpenApi/SchemaOptions.hs index ed95881f..8d920cd3 100644 --- a/src/Data/OpenApi/SchemaOptions.hs +++ b/src/Data/OpenApi/SchemaOptions.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE RecordWildCards #-} -- | -- Module: Data.OpenApi.SchemaOptions -- Maintainer: Nickolay Kudasov diff --git a/test/Data/OpenApi/SchemaSpec.hs b/test/Data/OpenApi/SchemaSpec.hs index 0a3f96e7..a2986921 100644 --- a/test/Data/OpenApi/SchemaSpec.hs +++ b/test/Data/OpenApi/SchemaSpec.hs @@ -9,7 +9,7 @@ import Prelude.Compat import Control.Lens ((^.)) import Data.Aeson (Value) -import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap +import qualified Data.HashMap.Strict.InsOrd.Compat as InsOrdHashMap import Data.Proxy import Data.Set (Set) import qualified Data.Text as Text