@@ -34,6 +34,10 @@ import Data.Void
34import Text.Read (readMaybe)
34import Text.Read (readMaybe)
35import Text.ParserCombinators.ReadP (readP_to_S)
35import Text.ParserCombinators.ReadP (readP_to_S)
38+import TextShow (TextShow, showt)
37-- | Convert value to HTTP API data.
41-- | Convert value to HTTP API data.
38class ToHttpApiData a where
42class ToHttpApiData a where
39 {-# MINIMAL toUrlPiece | toQueryParam #-}
43 {-# MINIMAL toUrlPiece | toQueryParam #-}
@@ -96,6 +100,27 @@ parseMaybeTextData parse input =
96 Nothing -> defaultParseError input
100 Nothing -> defaultParseError input
97 Just val -> Right val
101 Just val -> Right val
104+-- | Convert to URL piece using @'TextShow'@ instance.
105+-- The result is always lower cased.
107+-- >>> showTextData True
110+-- This can be used as a default implementation for enumeration types:
113+-- data MyData = Foo | Bar | Baz deriving (Generic)
115+-- instance TextShow MyData where
116+-- showt = genericShowt
118+-- instance ToHttpApiData MyData where
119+-- toUrlPiece = showTextData
121+showTextData :: TextShow a => a -> Text
122+showTextData = T.toLower . showt
99-- | Convert to URL piece using @'Show'@ instance.
124-- | Convert to URL piece using @'Show'@ instance.
100-- The result is always lower cased.
125-- The result is always lower cased.
@@ -109,7 +134,12 @@ parseMaybeTextData parse input =
109-- >>> toUrlPiece Foo
134-- >>> toUrlPiece Foo
111showTextData :: Show a => a -> Text
136showTextData :: Show a => a -> Text
112−showTextData = T.toLower . T.pack . show
137+showTextData = T.toLower . showt
139+-- | Like @'show'@, but returns @'Text'@.
140+showt :: Show a => a -> Text
141+showt = T.pack . show
114-- | Parse given text case insensitive and return the rest of the input.
144-- | Parse given text case insensitive and return the rest of the input.
@@ -131,6 +161,27 @@ parseUrlPieceWithPrefix pattern input
132 (prefix, rest) = T.splitAt (T.length pattern) input
162 (prefix, rest) = T.splitAt (T.length pattern) input
165+-- | Parse values case insensitively based on @'TextShow'@ instance.
167+-- >>> parseBoundedCaseInsensitiveTextData "true" :: Either Text Bool
169+-- >>> parseBoundedCaseInsensitiveTextData "FALSE" :: Either Text Bool
172+-- This can be used as a default implementation for enumeration types:
175+-- data MyData = Foo | Bar | Baz deriving (Show, Bounded, Enum, Generic)
177+-- instance TextShow MyData where
178+-- showt = genericShowt
180+-- instance FromHttpApiData MyData where
181+-- parseUrlPiece = parseBoundedCaseInsensitiveTextData
183+parseBoundedCaseInsensitiveTextData :: forall a. (TextShow a, Bounded a, Enum a) => Text -> Either Text a
134-- | Parse values case insensitively based on @'Show'@ instance.
185-- | Parse values case insensitively based on @'Show'@ instance.
136-- >>> parseBoundedCaseInsensitiveTextData "true" :: Either Text Bool
187-- >>> parseBoundedCaseInsensitiveTextData "true" :: Either Text Bool
@@ -145,6 +196,7 @@ parseUrlPieceWithPrefix pattern input
145-- >>> parseUrlPiece "foo" :: Either Text MyData
196-- >>> parseUrlPiece "foo" :: Either Text MyData
146-- Right Foo
197-- Right Foo
147parseBoundedCaseInsensitiveTextData :: forall a. (Show a, Bounded a, Enum a) => Text -> Either Text a
198parseBoundedCaseInsensitiveTextData :: forall a. (Show a, Bounded a, Enum a) => Text -> Either Text a
148parseBoundedCaseInsensitiveTextData = parseMaybeTextData (flip lookup values . T.toLower)
200parseBoundedCaseInsensitiveTextData = parseMaybeTextData (flip lookup values . T.toLower)
150 values = map (showTextData &&& id) [minBound..maxBound :: a]
202 values = map (showTextData &&& id) [minBound..maxBound :: a]
@@ -201,23 +253,25 @@ instance ToHttpApiData Void where
202instance ToHttpApiData Bool where toUrlPiece = showTextData
254instance ToHttpApiData Bool where toUrlPiece = showTextData
203instance ToHttpApiData Ordering where toUrlPiece = showTextData
255instance ToHttpApiData Ordering where toUrlPiece = showTextData
204−instance ToHttpApiData Double where toUrlPiece = showTextData
257+instance ToHttpApiData Double where toUrlPiece = showt
205−instance ToHttpApiData Float where toUrlPiece = showTextData
258+instance ToHttpApiData Float where toUrlPiece = showt
206−instance ToHttpApiData Int where toUrlPiece = showTextData
259+instance ToHttpApiData Int where toUrlPiece = showt
207−instance ToHttpApiData Int8 where toUrlPiece = showTextData
260+instance ToHttpApiData Int8 where toUrlPiece = showt
208−instance ToHttpApiData Int16 where toUrlPiece = showTextData
261+instance ToHttpApiData Int16 where toUrlPiece = showt
209−instance ToHttpApiData Int32 where toUrlPiece = showTextData
262+instance ToHttpApiData Int32 where toUrlPiece = showt
210−instance ToHttpApiData Int64 where toUrlPiece = showTextData
263+instance ToHttpApiData Int64 where toUrlPiece = showt
211−instance ToHttpApiData Integer where toUrlPiece = showTextData
264+instance ToHttpApiData Integer where toUrlPiece = showt
212−instance ToHttpApiData Word where toUrlPiece = showTextData
265+instance ToHttpApiData Word where toUrlPiece = showt
213−instance ToHttpApiData Word8 where toUrlPiece = showTextData
266+instance ToHttpApiData Word8 where toUrlPiece = showt
214−instance ToHttpApiData Word16 where toUrlPiece = showTextData
267+instance ToHttpApiData Word16 where toUrlPiece = showt
215−instance ToHttpApiData Word32 where toUrlPiece = showTextData
268+instance ToHttpApiData Word32 where toUrlPiece = showt
216−instance ToHttpApiData Word64 where toUrlPiece = showTextData
269+instance ToHttpApiData Word64 where toUrlPiece = showt
270+instance ToHttpApiData Day where toUrlPiece = T.pack . show
217instance ToHttpApiData String where toUrlPiece = T.pack
272instance ToHttpApiData String where toUrlPiece = T.pack
218instance ToHttpApiData Text where toUrlPiece = id
273instance ToHttpApiData Text where toUrlPiece = id
219instance ToHttpApiData L.Text where toUrlPiece = L.toStrict
274instance ToHttpApiData L.Text where toUrlPiece = L.toStrict
220−instance ToHttpApiData Day where toUrlPiece = showTextData
222instance ToHttpApiData All where toUrlPiece = toUrlPiece . getAll
276instance ToHttpApiData All where toUrlPiece = toUrlPiece . getAll
223instance ToHttpApiData Any where toUrlPiece = toUrlPiece . getAny
277instance ToHttpApiData Any where toUrlPiece = toUrlPiece . getAny