git.iko.soy/typeable/http-api-data
on master help sign in
Merge pull request #17 from fizruk/use-text-show
008fff8Nickolay Kudasov
.travis.yml+12−7
@@ -1,12 +1,17 @@
1env:
1env:
2− - GHCVER=7.6.3 CABALVER=1.18
2+ - GHCVER=7.6.3 CABALVER=1.18 CABAL_FLAGS=
3+ - GHCVER=7.8.4 CABALVER=1.18 CABAL_FLAGS=
4+ - GHCVER=7.10.2 CABALVER=1.22 CABAL_FLAGS=
5+ - GHCVER=head CABALVER=head CABAL_FLAGS=
6+ - GHCVER=7.6.3 CABALVER=1.18 CABAL_FLAGS=use-text-show
3− - GHCVER=7.8.4 CABALVER=1.18
7+ - GHCVER=7.8.4 CABALVER=1.18 CABAL_FLAGS=use-text-show
4− - GHCVER=7.10.2 CABALVER=1.22
8+ - GHCVER=7.10.2 CABALVER=1.22 CABAL_FLAGS=use-text-show
5− - GHCVER=head CABALVER=head
9+ - GHCVER=head CABALVER=head CABAL_FLAGS=use-text-show
6
10
7matrix:
11matrix:
8 allow_failures:
12 allow_failures:
9− - env: GHCVER=head CABALVER=head
13+ - env: GHCVER=head CABALVER=head CABAL_FLAGS=
14+ - env: GHCVER=head CABALVER=head CABAL_FLAGS=use-text-show
10
15
11before_install:
16before_install:
12 - travis_retry sudo add-apt-repository -y ppa:hvr/ghc
17 - travis_retry sudo add-apt-repository -y ppa:hvr/ghc
@@ -17,10 +22,10 @@ before_install:
17
22
18install:
23install:
19 - cabal update
24 - cabal update
20− - cabal install --only-dependencies --enable-tests
25+ - cabal install --only-dependencies --enable-tests --flags=$CABAL_FLAGS
21
26
22script:
27script:
23− - cabal configure --enable-tests -v2
28+ - cabal configure --enable-tests -v2 --flags=$CABAL_FLAGS
24 - cabal build
29 - cabal build
25 - cabal test
30 - cabal test
26 - cabal check
31 - cabal check
CHANGELOG.md+3
@@ -1 +1,4 @@
1+0.1.1
2+---
1
3
4+* Add `use-text-show` flag to optionally use more efficient `TextShow` instances
Web/HttpApiData/Internal.hs+69−15
@@ -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)
36
36
37+#if USE_TEXT_SHOW
38+import TextShow (TextShow, showt)
39+#endif
40+
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
98
102
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
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.
101--
126--
@@ -109,7 +134,12 @@ parseMaybeTextData parse input =
109-- >>> toUrlPiece Foo
134-- >>> toUrlPiece Foo
110-- "foo"
135-- "foo"
111showTextData :: Show a => a -> Text
136showTextData :: 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
113
143
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.
115--
145--
@@ -131,6 +161,27 @@ parseUrlPieceWithPrefix pattern input
131 where
161 where
132 (prefix, rest) = T.splitAt (T.length pattern) input
162 (prefix, rest) = T.splitAt (T.length pattern) input
133
163
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
134-- | Parse values case insensitively based on @'Show'@ instance.
185-- | Parse values case insensitively based on @'Show'@ instance.
135--
186--
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
199+#endif
148parseBoundedCaseInsensitiveTextData = parseMaybeTextData (flip lookup values . T.toLower)
200parseBoundedCaseInsensitiveTextData = parseMaybeTextData (flip lookup values . T.toLower)
149 where
201 where
150 values = map (showTextData &&& id) [minBound..maxBound :: a]
202 values = map (showTextData &&& id) [minBound..maxBound :: a]
@@ -201,23 +253,25 @@ instance ToHttpApiData Void where
201
253
202instance ToHttpApiData Bool where toUrlPiece = showTextData
254instance ToHttpApiData Bool where toUrlPiece = showTextData
203instance ToHttpApiData Ordering where toUrlPiece = showTextData
255instance ToHttpApiData Ordering where toUrlPiece = showTextData
256+
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
271+
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
221
275
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
http-api-data.cabal+8−1
@@ -1,5 +1,5 @@
1name: http-api-data
1name: http-api-data
2−version: 0.1.0
2+version: 0.1.1
3license: BSD3
3license: BSD3
4license-file: LICENSE
4license-file: LICENSE
5author: Michael Snoyman <michael@snoyman.com>
5author: Michael Snoyman <michael@snoyman.com>
@@ -16,11 +16,18 @@ extra-source-files:
16 CHANGELOG.md
16 CHANGELOG.md
17 README.md
17 README.md
18
18
19+flag use-text-show
20+ description: Use @text-show@ library for efficient @'ToHttpApiData'@ implementations.
21+ default: False
22+
19library
23library
20 build-depends: base >= 4 && < 5
24 build-depends: base >= 4 && < 5
21 , text >= 0.5
25 , text >= 0.5
22 , bytestring
26 , bytestring
23 , time
27 , time
28+ if flag(use-text-show)
29+ cpp-options: -DUSE_TEXT_SHOW
30+ build-depends: text-show >= 2
24 exposed-modules:
31 exposed-modules:
25 Web.HttpApiData
32 Web.HttpApiData
26 Web.HttpApiData.Internal
33 Web.HttpApiData.Internal