@@ -34,6 +34,10 @@ import Data.Void
3434import Text.Read (readMaybe)
3535import Text.ParserCombinators.ReadP (readP_to_S)
3636
37+#if USE_TEXT_SHOW
38+import TextShow (TextShow, showt)
39+#endif
40+
3741-- | Convert value to HTTP API data.
3842class ToHttpApiData a where
3943 {-# MINIMAL toUrlPiece | toQueryParam #-}
@@ -96,6 +100,27 @@ parseMaybeTextData parse input =
96100 Nothing -> defaultParseError input
97101 Just val -> Right val
98102
103+#if USE_TEXT_SHOW
104+-- | Convert to URL piece using @'TextShow'@ instance.
105+-- The result is always lower cased.
106+--
107+-- >>> showTextData True
108+-- "true"
109+--
110+-- This can be used as a default implementation for enumeration types:
111+--
112+-- @
113+-- data MyData = Foo | Bar | Baz deriving (Generic)
114+--
115+-- instance TextShow MyData where
116+-- showt = genericShowt
117+--
118+-- instance ToHttpApiData MyData where
119+-- toUrlPiece = showTextData
120+-- @
121+showTextData :: TextShow a => a -> Text
122+showTextData = T.toLower . showt
123+#else
99124-- | Convert to URL piece using @'Show'@ instance.
100125-- The result is always lower cased.
101126--
@@ -109,7 +134,12 @@ parseMaybeTextData parse input =
109134-- >>> toUrlPiece Foo
110135-- "foo"
111136showTextData :: Show a => a -> Text
112−showTextData = T.toLower . T.pack . show
137+showTextData = T.toLower . showt
138+
139+-- | Like @'show'@, but returns @'Text'@.
140+showt :: Show a => a -> Text
141+showt = T.pack . show
142+#endif
113143
114144-- | Parse given text case insensitive and return the rest of the input.
115145--
@@ -131,6 +161,27 @@ parseUrlPieceWithPrefix pattern input
131161 where
132162 (prefix, rest) = T.splitAt (T.length pattern) input
133163
164+#if USE_TEXT_SHOW
165+-- | Parse values case insensitively based on @'TextShow'@ instance.
166+--
167+-- >>> parseBoundedCaseInsensitiveTextData "true" :: Either Text Bool
168+-- Right True
169+-- >>> parseBoundedCaseInsensitiveTextData "FALSE" :: Either Text Bool
170+-- Right False
171+--
172+-- This can be used as a default implementation for enumeration types:
173+--
174+-- @
175+-- data MyData = Foo | Bar | Baz deriving (Show, Bounded, Enum, Generic)
176+--
177+-- instance TextShow MyData where
178+-- showt = genericShowt
179+--
180+-- instance FromHttpApiData MyData where
181+-- parseUrlPiece = parseBoundedCaseInsensitiveTextData
182+-- @
183+parseBoundedCaseInsensitiveTextData :: forall a. (TextShow a, Bounded a, Enum a) => Text -> Either Text a
184+#else
134185-- | Parse values case insensitively based on @'Show'@ instance.
135186--
136187-- >>> parseBoundedCaseInsensitiveTextData "true" :: Either Text Bool
@@ -145,6 +196,7 @@ parseUrlPieceWithPrefix pattern input
145196-- >>> parseUrlPiece "foo" :: Either Text MyData
146197-- Right Foo
147198parseBoundedCaseInsensitiveTextData :: forall a. (Show a, Bounded a, Enum a) => Text -> Either Text a
199+#endif
148200parseBoundedCaseInsensitiveTextData = parseMaybeTextData (flip lookup values . T.toLower)
149201 where
150202 values = map (showTextData &&& id) [minBound..maxBound :: a]
@@ -201,23 +253,25 @@ instance ToHttpApiData Void where
201253
202254instance ToHttpApiData Bool where toUrlPiece = showTextData
203255instance ToHttpApiData Ordering where toUrlPiece = showTextData
204−instance ToHttpApiData Double where toUrlPiece = showTextData
205−instance ToHttpApiData Float where toUrlPiece = showTextData
206−instance ToHttpApiData Int where toUrlPiece = showTextData
207−instance ToHttpApiData Int8 where toUrlPiece = showTextData
208−instance ToHttpApiData Int16 where toUrlPiece = showTextData
209−instance ToHttpApiData Int32 where toUrlPiece = showTextData
210−instance ToHttpApiData Int64 where toUrlPiece = showTextData
211−instance ToHttpApiData Integer where toUrlPiece = showTextData
212−instance ToHttpApiData Word where toUrlPiece = showTextData
213−instance ToHttpApiData Word8 where toUrlPiece = showTextData
214−instance ToHttpApiData Word16 where toUrlPiece = showTextData
215−instance ToHttpApiData Word32 where toUrlPiece = showTextData
216−instance ToHttpApiData Word64 where toUrlPiece = showTextData
256+
257+instance ToHttpApiData Double where toUrlPiece = showt
258+instance ToHttpApiData Float where toUrlPiece = showt
259+instance ToHttpApiData Int where toUrlPiece = showt
260+instance ToHttpApiData Int8 where toUrlPiece = showt
261+instance ToHttpApiData Int16 where toUrlPiece = showt
262+instance ToHttpApiData Int32 where toUrlPiece = showt
263+instance ToHttpApiData Int64 where toUrlPiece = showt
264+instance ToHttpApiData Integer where toUrlPiece = showt
265+instance ToHttpApiData Word where toUrlPiece = showt
266+instance ToHttpApiData Word8 where toUrlPiece = showt
267+instance ToHttpApiData Word16 where toUrlPiece = showt
268+instance ToHttpApiData Word32 where toUrlPiece = showt
269+instance ToHttpApiData Word64 where toUrlPiece = showt
270+instance ToHttpApiData Day where toUrlPiece = T.pack . show
271+
217272instance ToHttpApiData String where toUrlPiece = T.pack
218273instance ToHttpApiData Text where toUrlPiece = id
219274instance ToHttpApiData L.Text where toUrlPiece = L.toStrict
220−instance ToHttpApiData Day where toUrlPiece = showTextData
221275
222276instance ToHttpApiData All where toUrlPiece = toUrlPiece . getAll
223277instance ToHttpApiData Any where toUrlPiece = toUrlPiece . getAny