@@ -4,9 +4,12 @@
4{-# OPTIONS_GHC -Wno-orphans #-}
4{-# OPTIONS_GHC -Wno-orphans #-}
6module Data.Id
6module Data.Id
7− ( Id, mkId, unId, randomId, unsafeIdTagConvert, coerceId, _Id, nilId
7+ ( Id, mkId, unId, unsafeIdTagConvert, coerceId, _Id, nilId
8 , IntId, mkIntId, unIntId, unsafeIntIdTagConvert, coerceIntId, _IntId
8 , IntId, mkIntId, unIntId, unsafeIntIdTagConvert, coerceIntId, _IntId
9 , Name, mkName, unName, unsafeNameTagConvert, coerceName, _Name
9 , Name, mkName, unName, unsafeNameTagConvert, coerceName, _Name
@@ -18,33 +21,52 @@ import Data.Binary (Binary)
18import Data.Coerce (coerce)
21import Data.Coerce (coerce)
19import Data.Data
22import Data.Data
20import Data.Hashable (Hashable)
23import Data.Hashable (Hashable)
22import Data.String
24import Data.String
23import Data.Text as T
25import Data.Text as T
24−import Data.UUID (UUID)
26+import Data.UUID.Types (UUID)
25−import qualified Data.UUID as UUID
27+import qualified Data.UUID.Types as UUID
30+import Text.ParserCombinators.ReadP
31+import Web.HttpApiData
32+import Web.PathPieces (PathPiece(..))
26import qualified Data.UUID.V4 as UUID.V4
35import qualified Data.UUID.V4 as UUID.V4
27−#ifndef ghcjs_HOST_OS
36+#endif
39+import Test.QuickCheck
41+import Data.Csv as Csv hiding(Name)
28import Database.PostgreSQL.Simple.FromField as PG (FromField)
44import Database.PostgreSQL.Simple.FromField as PG (FromField)
29import Database.PostgreSQL.Simple.ToField as PG (ToField)
45import Database.PostgreSQL.Simple.ToField as PG (ToField)
30−import Data.Csv as Csv hiding(Name)
32import Flat as F
50import Flat as F
33−import GHC.TypeLits
51+#endif
34−import Test.QuickCheck
52+#ifdef USE_STORE
35−import Text.ParserCombinators.ReadP
53+import qualified Data.Store
36−import Web.HttpApiData
54+#endif
37−import Web.PathPieces (PathPiece(..))
39newtype Id t = Id { unId :: UUID }
56newtype Id t = Id { unId :: UUID }
40 deriving stock Data
57 deriving stock Data
41 deriving newtype
58 deriving newtype
42 ( Eq, Ord, Binary
59 ( Eq, Ord, Binary
43#ifndef ghcjs_HOST_OS
60#ifndef ghcjs_HOST_OS
44 , PG.ToField, PG.FromField
62 , PG.ToField, PG.FromField
46− , FromJSON, ToJSON, NFData, Hashable, FromJSONKey, ToJSONKey, ToSchema
65+ , FromJSON, ToJSON, NFData, Hashable, FromJSONKey, ToJSONKey
67+ , ToSchema, ToParamSchema
47− , ToParamSchema, FromHttpApiData, ToHttpApiData )
69+ , FromHttpApiData, ToHttpApiData )
49type role Id nominal
71type role Id nominal
@@ -54,29 +76,42 @@ mkId :: forall s. UUID -> Id s
54mkId = coerce
76mkId = coerce
55{-# INLINE mkId #-}
77{-# INLINE mkId #-}
57randomId :: forall s. IO (Id s)
80randomId :: forall s. IO (Id s)
58randomId = coerce <$> UUID.V4.nextRandom
81randomId = coerce <$> UUID.V4.nextRandom
59{-# INLINE randomId #-}
82{-# INLINE randomId #-}
61instance KnownSymbol s => Show (Id s) where
85instance KnownSymbol s => Show (Id s) where
62− show (Id v) = "Id-" <> symbolVal (Proxy @s) <> "-" <> show v
86+ show (Id v) = "Id-" <> symbolVal (Proxy @s) <> "-" <> P.show v
64instance KnownSymbol s => Read (Id s) where
88instance KnownSymbol s => Read (Id s) where
65 readsPrec _ = readP_to_S $ do
89 readsPrec _ = readP_to_S $ do
66 _ <- string ("Id-" <> symbolVal (Proxy @s) <> "-")
90 _ <- string ("Id-" <> symbolVal (Proxy @s) <> "-")
67 mkId <$> readS_to_P reads
91 mkId <$> readS_to_P reads
69instance Flat (Id s) where
94instance Flat (Id s) where
70 encode = F.encode . UUID.toWords . coerce
95 encode = F.encode . UUID.toWords . coerce
71 decode = coerce . (\(a,b,c,d) -> UUID.fromWords a b c d) <$> F.decode
96 decode = coerce . (\(a,b,c,d) -> UUID.fromWords a b c d) <$> F.decode
72 size = F.size . UUID.toWords . coerce
97 size = F.size . UUID.toWords . coerce
101+instance Data.Store.Store (Id s) where
102+ poke = Data.Store.poke . UUID.toWords . coerce
103+ peek = coerce . (\(a,b,c,d) -> UUID.fromWords a b c d) <$> Data.Store.peek
104+ size = Data.Store.ConstSize 16
74instance Arbitrary (Id t) where
108instance Arbitrary (Id t) where
75 arbitrary = fmap Id $ UUID.fromWords
109 arbitrary = fmap Id $ UUID.fromWords
76 <$> arbitrary
110 <$> arbitrary
77 <*> arbitrary
111 <*> arbitrary
78 <*> arbitrary
112 <*> arbitrary
79 <*> arbitrary
113 <*> arbitrary
81instance PathPiece (Id t) where
116instance PathPiece (Id t) where
82 fromPathPiece = coerce . UUID.fromText
117 fromPathPiece = coerce . UUID.fromText
@@ -84,12 +119,14 @@ instance PathPiece (Id t) where
85#ifndef ghcjs_HOST_OS
120#ifndef ghcjs_HOST_OS
87instance Csv.FromField (Id tag) where
123instance Csv.FromField (Id tag) where
88 parseField = parseField
124 parseField = parseField
89 >=> fmap mkId . maybe (fail "invalid UUID in CSV") pure . UUID.fromText
125 >=> fmap mkId . maybe (fail "invalid UUID in CSV") pure . UUID.fromText
91instance Csv.ToField (Id tag) where
127instance Csv.ToField (Id tag) where
92 toField = Csv.toField . UUID.toText . coerce
128 toField = Csv.toField . UUID.toText . coerce
@@ -116,11 +153,24 @@ newtype IntId t = IntId { unIntId :: Integer }
116 deriving newtype
153 deriving newtype
117 ( Eq, Ord, Binary
154 ( Eq, Ord, Binary
118#ifndef ghcjs_HOST_OS
155#ifndef ghcjs_HOST_OS
157+ , PG.ToField, PG.FromField
119− , PG.ToField, PG.FromField, Csv.ToField, Csv.FromField
160+ , Csv.ToField, Csv.FromField
170+ , ToSchema, ToParamSchema, Arbitrary
121− , FromJSON, ToJSON, NFData, Hashable, FromJSONKey, ToJSONKey, ToSchema
172+ , FromJSON, ToJSON, NFData, Hashable, FromJSONKey, ToJSONKey, FromHttpApiData
122− , ToParamSchema, FromHttpApiData, ToHttpApiData, PathPiece, Flat, Arbitrary
123− , Num, Integral, Real, Enum )
173+ , ToHttpApiData, PathPiece, Num, Integral, Real, Enum )
125type role IntId nominal
175type role IntId nominal
@@ -131,7 +181,7 @@ mkIntId = coerce
131{-# INLINE mkIntId #-}
181{-# INLINE mkIntId #-}
133instance KnownSymbol s => Show (IntId s) where
183instance KnownSymbol s => Show (IntId s) where
134− show (IntId v) = "IntId-" <> symbolVal (Proxy @s) <> "-" <> show v
184+ show (IntId v) = "IntId-" <> symbolVal (Proxy @s) <> "-" <> P.show v
136instance KnownSymbol s => Read (IntId s) where
186instance KnownSymbol s => Read (IntId s) where
137 readsPrec _ = readP_to_S $ do
187 readsPrec _ = readP_to_S $ do
@@ -154,11 +204,24 @@ newtype Name t = Name { unName :: Text }
154 deriving newtype
204 deriving newtype
155 ( Eq, Ord, Binary
205 ( Eq, Ord, Binary
156#ifndef ghcjs_HOST_OS
206#ifndef ghcjs_HOST_OS
208+ , PG.ToField, PG.FromField
157− , PG.ToField, PG.FromField, Csv.ToField, Csv.FromField
211+ , Csv.ToField, Csv.FromField
221+ , ToSchema, ToParamSchema
159− , FromJSON, ToJSON, NFData, Hashable, FromJSONKey, ToJSONKey, ToSchema
223+ , FromJSON, ToJSON, NFData, Hashable, FromJSONKey, ToJSONKey, FromHttpApiData
160− , ToParamSchema, FromHttpApiData, ToHttpApiData, PathPiece, Flat
161− , IsString, Semigroup, Monoid )
224+ , ToHttpApiData, PathPiece, IsString, Semigroup, Monoid )
163type role Name nominal
226type role Name nominal
@@ -169,15 +232,17 @@ mkName = coerce
169{-# INLINE mkName #-}
232{-# INLINE mkName #-}
171instance KnownSymbol s => Show (Name s) where
234instance KnownSymbol s => Show (Name s) where
172− show (Name v) = "Name-" <> symbolVal (Proxy @s) <> "-" <> show v
235+ show (Name v) = "Name-" <> symbolVal (Proxy @s) <> "-" <> P.show v
174instance KnownSymbol s => Read (Name s) where
237instance KnownSymbol s => Read (Name s) where
175 readsPrec _ = readP_to_S $ do
238 readsPrec _ = readP_to_S $ do
176 _ <- string ("Name-" <> symbolVal (Proxy @s) <> "-")
239 _ <- string ("Name-" <> symbolVal (Proxy @s) <> "-")
177 mkName <$> readS_to_P reads
240 mkName <$> readS_to_P reads
179instance Arbitrary (Name s) where
243instance Arbitrary (Name s) where
180 arbitrary = coerce . T.pack . getPrintableString <$> arbitrary
244 arbitrary = coerce . T.pack . getPrintableString <$> arbitrary
182-- | This is a more \"explicit\" 'coerce' specifically for 'Name'.
247-- | This is a more \"explicit\" 'coerce' specifically for 'Name'.
183-- You are forced to explicitly specify the phantom types you are converting
248-- You are forced to explicitly specify the phantom types you are converting