diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml index 8801db3..231a352 100644 --- a/.github/workflows/haskell-ci.yml +++ b/.github/workflows/haskell-ci.yml @@ -268,16 +268,18 @@ jobs: rm -f cabal.project.local - name: constraint set filepath-1.5 run: | - if [ $((HCNUMVER >= 90200)) -ne 0 ] ; then $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='filepath ^>=1.5.2.0' all --dry-run ; fi + if [ $((HCNUMVER >= 90200)) -ne 0 ] ; then $CABAL v2-build $ARG_COMPILER --enable-tests --disable-benchmarks --constraint='filepath ^>=1.5.2.0' all --dry-run ; fi if [ $((HCNUMVER >= 90200)) -ne 0 ] ; then cabal-plan topo | sort ; fi - if [ $((HCNUMVER >= 90200)) -ne 0 ] ; then $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='filepath ^>=1.5.2.0' --dependencies-only -j2 all ; fi - if [ $((HCNUMVER >= 90200)) -ne 0 ] ; then $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='filepath ^>=1.5.2.0' all ; fi + if [ $((HCNUMVER >= 90200)) -ne 0 ] ; then $CABAL v2-build $ARG_COMPILER --enable-tests --disable-benchmarks --constraint='filepath ^>=1.5.2.0' --dependencies-only -j2 all ; fi + if [ $((HCNUMVER >= 90200)) -ne 0 ] ; then $CABAL v2-build $ARG_COMPILER --enable-tests --disable-benchmarks --constraint='filepath ^>=1.5.2.0' all ; fi + if [ $((HCNUMVER >= 90200)) -ne 0 ] ; then $CABAL v2-test $ARG_COMPILER --enable-tests --disable-benchmarks --constraint='filepath ^>=1.5.2.0' all ; fi - name: constraint set filepath-1.4.100.0 run: | - $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='filepath ^>=1.4.100.0' all --dry-run + $CABAL v2-build $ARG_COMPILER --enable-tests --disable-benchmarks --constraint='filepath ^>=1.4.100.0' all --dry-run cabal-plan topo | sort - $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='filepath ^>=1.4.100.0' --dependencies-only -j2 all - $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='filepath ^>=1.4.100.0' all + $CABAL v2-build $ARG_COMPILER --enable-tests --disable-benchmarks --constraint='filepath ^>=1.4.100.0' --dependencies-only -j2 all + $CABAL v2-build $ARG_COMPILER --enable-tests --disable-benchmarks --constraint='filepath ^>=1.4.100.0' all + $CABAL v2-test $ARG_COMPILER --enable-tests --disable-benchmarks --constraint='filepath ^>=1.4.100.0' all - name: constraint set random-initial-seed run: | $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='hashable +random-initial-seed' all --dry-run diff --git a/cabal.haskell-ci b/cabal.haskell-ci index ba2e0be..41cc5e1 100644 --- a/cabal.haskell-ci +++ b/cabal.haskell-ci @@ -8,7 +8,11 @@ constraint-set random-initial-seed constraint-set filepath-1.4.100.0 constraints: filepath ^>=1.4.100.0 + tests: True + run-tests: True constraint-set filepath-1.5 ghc: >=9.2 constraints: filepath ^>=1.5.2.0 + tests: True + run-tests: True diff --git a/hashable.cabal b/hashable.cabal index 7680e31..dbed582 100644 --- a/hashable.cabal +++ b/hashable.cabal @@ -163,6 +163,7 @@ test-suite hashable-tests build-depends: base , bytestring + , filepath , ghc-prim , hashable , HUnit @@ -174,7 +175,7 @@ test-suite hashable-tests , text >=0.11.0.5 if impl(ghc >=9.2) - build-depends: os-string >=2.0.2 + build-depends: os-string if !os(windows) build-depends: unix diff --git a/src/Data/Hashable/Class.hs b/src/Data/Hashable/Class.hs index 4f60d03..fcf9f59 100644 --- a/src/Data/Hashable/Class.hs +++ b/src/Data/Hashable/Class.hs @@ -4,6 +4,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE PackageImports #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE Trustworthy #-} @@ -167,7 +168,25 @@ import Data.Tuple (Solo (..)) import GHC.Tuple (Solo (..)) #endif -#if MIN_VERSION_filepath(1,4,100) +-- filepath >=1.4.100 && <1.5 has System.OsString.Internal.Types module +#if MIN_VERSION_filepath(1,4,100) && !(MIN_VERSION_filepath(1,5,0)) +#define HAS_OS_STRING_filepath 1 +#else +#define HAS_OS_STRING_filepath 0 +#endif + +-- if we depend on os_string module, then it has System.OsString.Internal.Types +-- module as well +#ifdef MIN_VERSION_os_string +#define HAS_OS_STRING_os_string 1 +#else +#define HAS_OS_STRING_os_string 0 +#endif + +#if HAS_OS_STRING_filepath && HAS_OS_STRING_os_string +import "os-string" System.OsString.Internal.Types (OsString (..), PosixString (..), WindowsString (..)) +import qualified "filepath" System.OsString.Internal.Types as FP (OsString (..), PosixString (..), WindowsString (..)) +#elif HAS_OS_STRING_filepath || HAS_OS_STRING_os_string import System.OsString.Internal.Types (OsString (..), PosixString (..), WindowsString (..)) #endif @@ -666,7 +685,7 @@ instance Hashable BSI.ShortByteString where hashWithSalt salt sbs@(BSI.SBS ba) = hashByteArrayWithSalt ba 0 (BSI.length sbs) (hashWithSalt salt (BSI.length sbs)) -#if MIN_VERSION_filepath(1,4,100) +#if HAS_OS_STRING_filepath || HAS_OS_STRING_os_string -- | @since 1.4.2.0 instance Hashable PosixString where hashWithSalt salt (PosixString s) = hashWithSalt salt s @@ -680,6 +699,17 @@ instance Hashable OsString where hashWithSalt salt (OsString s) = hashWithSalt salt s #endif +#if HAS_OS_STRING_filepath && HAS_OS_STRING_os_string +instance Hashable FP.PosixString where + hashWithSalt salt (FP.PosixString s) = hashWithSalt salt s + +instance Hashable FP.WindowsString where + hashWithSalt salt (FP.WindowsString s) = hashWithSalt salt s + +instance Hashable FP.OsString where + hashWithSalt salt (FP.OsString s) = hashWithSalt salt s +#endif + #if MIN_VERSION_text(2,0,0) instance Hashable T.Text where diff --git a/tests/Properties.hs b/tests/Properties.hs index 5ec898f..31271bd 100644 --- a/tests/Properties.hs +++ b/tests/Properties.hs @@ -1,6 +1,6 @@ {-# LANGUAGE BangPatterns, CPP, GeneralizedNewtypeDeriving, MagicHash, Rank2Types, UnboxedTuples #-} -{-# LANGUAGE DeriveGeneric, ScopedTypeVariables #-} +{-# LANGUAGE DeriveGeneric, ScopedTypeVariables, PackageImports #-} -- | QuickCheck tests for the 'Data.Hashable' module. We test -- functions by comparing the C and Haskell implementations. @@ -30,6 +30,14 @@ import GHC.Generics import qualified Data.ByteString.Short as BS +#if MIN_VERSION_filepath(1,4,100) && !(MIN_VERSION_filepath(1,5,0)) +import qualified "filepath" System.OsString.Internal.Types as FP +#endif + +#ifdef MIN_VERSION_os_string +import qualified "os-string" System.OsString.Internal.Types as OS +#endif + ------------------------------------------------------------------------ -- * Properties @@ -252,3 +260,23 @@ properties = fromStrict :: B.ByteString -> BL.ByteString fromStrict = BL.fromStrict + +------------------------------------------------------------------------ +-- test that instances exist + +instanceExists :: Hashable a => a -> () +instanceExists _ = () + +#if MIN_VERSION_filepath(1,4,100) && !(MIN_VERSION_filepath(1,5,0)) +_fp1, _fp2, _fp3 :: () +_fp1 = instanceExists (undefined :: FP.OsString) +_fp2 = instanceExists (undefined :: FP.WindowsString) +_fp3 = instanceExists (undefined :: FP.PosixString) +#endif + +#ifdef MIN_VERSION_os_string +_os1, _os2, _os3 :: () +_os1 = instanceExists (undefined :: OS.OsString) +_os2 = instanceExists (undefined :: OS.WindowsString) +_os3 = instanceExists (undefined :: OS.PosixString) +#endif