Skip to content

Commit cc193f4

Browse files
committed
Merge branch 'copilot/add-hashable-instances'
2 parents 35ea86b + 1e3cac6 commit cc193f4

40 files changed

+157
-16
lines changed

postgresql-types.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ library
159159
base >=4.11 && <5,
160160
bytestring >=0.10 && <0.13,
161161
containers >=0.6 && <0.9,
162+
hashable >=1.3 && <2,
162163
invariant ^>=0.6.4,
163164
jsonifier ^>=0.2.1.3,
164165
mtl >=2.2 && <3,

src/library/PostgresqlTypes/Bit.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ where
1616
import qualified Data.Attoparsec.Text as Attoparsec
1717
import qualified Data.Bits as Bits
1818
import qualified Data.ByteString as ByteString
19+
import Data.Hashable (Hashable (..))
1920
import qualified Data.Text as Text
2021
import qualified Data.Vector.Generic as Vg
2122
import qualified GHC.TypeLits as TypeLits
@@ -48,6 +49,9 @@ instance (TypeLits.KnownNat numBits) => Arbitrary (Bit numBits) where
4849
Nothing -> error "Arbitrary Bit: Generated bit string has incorrect length"
4950
Just bit -> pure bit
5051

52+
instance Hashable (Bit numBits) where
53+
hashWithSalt salt (Bit bytes) = hashWithSalt salt bytes
54+
5155
instance (TypeLits.KnownNat numBits) => IsScalar (Bit numBits) where
5256
schemaName = Tagged Nothing
5357
typeName = Tagged "bit"

src/library/PostgresqlTypes/Bool.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ where
1111

1212
import qualified Data.Attoparsec.Text as Attoparsec
1313
import qualified Data.Bool
14+
import Data.Hashable (Hashable)
1415
import PostgresqlTypes.Algebra
1516
import PostgresqlTypes.Prelude hiding (Bool)
1617
import PostgresqlTypes.Via
@@ -21,7 +22,7 @@ import qualified PtrPoker.Write as Write
2122
--
2223
-- [PostgreSQL docs](https://www.postgresql.org/docs/18/datatype-boolean.html).
2324
newtype Bool = Bool Data.Bool.Bool
24-
deriving newtype (Eq, Ord, Arbitrary)
25+
deriving newtype (Eq, Ord, Hashable, Arbitrary)
2526
deriving (Show, Read, IsString) via (ViaIsScalar Bool)
2627

2728
instance IsScalar Bool where

src/library/PostgresqlTypes/Box.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module PostgresqlTypes.Box
1414
where
1515

1616
import qualified Data.Attoparsec.Text as Attoparsec
17+
import Data.Hashable (Hashable (..))
1718
import GHC.Float (castDoubleToWord64, castWord64ToDouble)
1819
import PostgresqlTypes.Algebra
1920
import PostgresqlTypes.Prelude
@@ -55,6 +56,13 @@ instance Arbitrary Box where
5556
| (x1', y1', x2', y2') <- shrink (x1, y1, x2, y2)
5657
]
5758

59+
instance Hashable Box where
60+
hashWithSalt salt (Box x1 y1 x2 y2) =
61+
salt `hashWithSalt` castDoubleToWord64 x1
62+
`hashWithSalt` castDoubleToWord64 y1
63+
`hashWithSalt` castDoubleToWord64 x2
64+
`hashWithSalt` castDoubleToWord64 y2
65+
5866
instance IsScalar Box where
5967
schemaName = Tagged Nothing
6068
typeName = Tagged "box"

src/library/PostgresqlTypes/Bpchar.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module PostgresqlTypes.Bpchar
1414
where
1515

1616
import qualified Data.Attoparsec.Text as Attoparsec
17+
import Data.Hashable (Hashable (..))
1718
import Data.String
1819
import qualified Data.Text as Text
1920
import qualified Data.Text.Encoding as Text.Encoding
@@ -55,6 +56,9 @@ instance (TypeLits.KnownNat numChars) => Arbitrary (Bpchar numChars) where
5556
Nothing -> error "Arbitrary Bpchar: Generated string has incorrect length"
5657
Just char -> pure char
5758

59+
instance Hashable (Bpchar numChars) where
60+
hashWithSalt salt (Bpchar txt) = hashWithSalt salt txt
61+
5862
instance (TypeLits.KnownNat numChars) => IsScalar (Bpchar numChars) where
5963
schemaName = Tagged Nothing
6064
typeName = Tagged "bpchar"

src/library/PostgresqlTypes/Bytea.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ where
1111

1212
import qualified Data.Attoparsec.Text as Attoparsec
1313
import qualified Data.ByteString as ByteString
14+
import Data.Hashable (Hashable)
1415
import qualified Data.Text as Text
1516
import PostgresqlTypes.Algebra
1617
import PostgresqlTypes.Prelude
@@ -23,7 +24,7 @@ import qualified TextBuilder
2324
--
2425
-- [PostgreSQL docs](https://www.postgresql.org/docs/18/datatype-binary.html).
2526
newtype Bytea = Bytea ByteString
26-
deriving newtype (Eq, Ord, Arbitrary)
27+
deriving newtype (Eq, Ord, Hashable, Arbitrary)
2728
deriving (Show, Read, IsString) via (ViaIsScalar Bytea)
2829

2930
instance IsScalar Bytea where

src/library/PostgresqlTypes/Char.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ where
1515

1616
import qualified Data.Attoparsec.Text as Attoparsec
1717
import qualified Data.Char
18+
import Data.Hashable (Hashable)
1819
import PostgresqlTypes.Algebra
1920
import PostgresqlTypes.Prelude hiding (Char)
2021
import PostgresqlTypes.Via
@@ -41,7 +42,7 @@ import qualified TextBuilder
4142
-- @'PostgresqlTypes.Bpchar.Bpchar' 1@ in Haskell. Despite the similar names,
4243
-- these are entirely different types in PostgreSQL.
4344
newtype Char = Char Word8
44-
deriving newtype (Eq, Ord)
45+
deriving newtype (Eq, Ord, Hashable)
4546
deriving (Show, Read, IsString) via (ViaIsScalar Char)
4647

4748
instance Arbitrary Char where

src/library/PostgresqlTypes/Cidr.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ where
1616

1717
import qualified Data.Attoparsec.Text as Attoparsec
1818
import Data.Bits
19+
import Data.Hashable (Hashable (..))
1920
import PostgresqlTypes.Algebra
2021
import PostgresqlTypes.Prelude hiding (fold)
2122
import PostgresqlTypes.Via
@@ -82,6 +83,11 @@ instance Arbitrary Cidr where
8283
netmask' <= 128
8384
]
8485

86+
instance Hashable Cidr where
87+
hashWithSalt salt = \case
88+
V4Cidr addr netmask -> salt `hashWithSalt` (0 :: Int) `hashWithSalt` addr `hashWithSalt` netmask
89+
V6Cidr w1 w2 w3 w4 netmask -> salt `hashWithSalt` (1 :: Int) `hashWithSalt` w1 `hashWithSalt` w2 `hashWithSalt` w3 `hashWithSalt` w4 `hashWithSalt` netmask
90+
8591
instance IsScalar Cidr where
8692
schemaName = Tagged Nothing
8793
typeName = Tagged "cidr"

src/library/PostgresqlTypes/Circle.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module PostgresqlTypes.Circle
1313
where
1414

1515
import qualified Data.Attoparsec.Text as Attoparsec
16+
import Data.Hashable (Hashable (..))
1617
import GHC.Float (castDoubleToWord64, castWord64ToDouble)
1718
import PostgresqlTypes.Algebra
1819
import PostgresqlTypes.Prelude
@@ -51,6 +52,12 @@ instance Arbitrary Circle where
5152
r' <- abs <$> shrink r
5253
pure (Circle x' y' r')
5354

55+
instance Hashable Circle where
56+
hashWithSalt salt (Circle x y r) =
57+
salt `hashWithSalt` castDoubleToWord64 x
58+
`hashWithSalt` castDoubleToWord64 y
59+
`hashWithSalt` castDoubleToWord64 r
60+
5461
instance IsScalar Circle where
5562
schemaName = Tagged Nothing
5663
typeName = Tagged "circle"

src/library/PostgresqlTypes/Date.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module PostgresqlTypes.Date
1111
where
1212

1313
import qualified Data.Attoparsec.Text as Attoparsec
14+
import Data.Hashable (Hashable)
1415
import qualified Data.Time as Time
1516
import PostgresqlTypes.Algebra
1617
import PostgresqlTypes.Prelude
@@ -28,7 +29,7 @@ import qualified TextBuilder
2829
newtype Date
2930
= -- | Days since PostgreSQL epoch (2000-01-01).
3031
Date Int32
31-
deriving newtype (Eq, Ord)
32+
deriving newtype (Eq, Ord, Hashable)
3233
deriving (Show, Read, IsString) via (ViaIsScalar Date)
3334

3435
-- | PostgreSQL date range: 4713 BC to 5874897 AD.

0 commit comments

Comments
 (0)