git.iko.soy/typeable/http-api-data
on master help sign in
Add basic FormOptions
7a7b274Nickolay Kudasov
src/Web/Internal/FormUrlEncoded.hs+35−18
@@ -228,7 +228,7 @@ class ToForm a where
228 -- | Convert a value into 'Form'.
228 -- | Convert a value into 'Form'.
229 toForm :: a -> Form
229 toForm :: a -> Form
230 default toForm :: (Generic a, GToForm a (Rep a)) => a -> Form
230 default toForm :: (Generic a, GToForm a (Rep a)) => a -> Form
231− toForm = genericToForm
231+ toForm = genericToForm defaultFormOptions
232
232
233instance ToForm Form where toForm = id
233instance ToForm Form where toForm = id
234
234
@@ -274,25 +274,25 @@ type family NotSupported (cls :: k1) (a :: k2) (reason :: Symbol) :: Constraint
274-- , age :: Int
274-- , age :: Int
275-- } deriving ('Generic')
275-- } deriving ('Generic')
276-- @
276-- @
277−genericToForm :: forall a. (Generic a, GToForm a (Rep a)) => a -> Form
277+genericToForm :: forall a. (Generic a, GToForm a (Rep a)) => FormOptions -> a -> Form
278−genericToForm = gToForm (Proxy :: Proxy a) . from
278+genericToForm opts = gToForm (Proxy :: Proxy a) opts . from
279
279
280class GToForm t (f :: * -> *) where
280class GToForm t (f :: * -> *) where
281− gToForm :: Proxy t -> f x -> Form
281+ gToForm :: Proxy t -> FormOptions -> f x -> Form
282
282
283instance (GToForm t f, GToForm t g) => GToForm t (f :*: g) where
283instance (GToForm t f, GToForm t g) => GToForm t (f :*: g) where
284− gToForm p (a :*: b) = gToForm p a <> gToForm p b
284+ gToForm p opts (a :*: b) = gToForm p opts a <> gToForm p opts b
285
285
286instance (GToForm t f) => GToForm t (M1 D x f) where
286instance (GToForm t f) => GToForm t (M1 D x f) where
287− gToForm p (M1 a) = gToForm p a
287+ gToForm p opts (M1 a) = gToForm p opts a
288
288
289instance (GToForm t f) => GToForm t (M1 C x f) where
289instance (GToForm t f) => GToForm t (M1 C x f) where
290− gToForm p (M1 a) = gToForm p a
290+ gToForm p opts (M1 a) = gToForm p opts a
291
291
292instance (Selector s, ToHttpApiData c) => GToForm t (M1 S s (K1 i c)) where
292instance (Selector s, ToHttpApiData c) => GToForm t (M1 S s (K1 i c)) where
293− gToForm _ (M1 (K1 c)) = fromList [(key, toQueryParam c)]
293+ gToForm _ opts (M1 (K1 c)) = fromList [(key, toQueryParam c)]
294 where
294 where
295− key = Text.pack $ selName (Proxy3 :: Proxy3 s g p)
295+ key = Text.pack $ fieldLabelModifier opts $ selName (Proxy3 :: Proxy3 s g p)
296
296
297instance NotSupported ToForm t "is a sum type" => GToForm t (f :+: g) where gToForm = error "impossible"
297instance NotSupported ToForm t "is a sum type" => GToForm t (f :+: g) where gToForm = error "impossible"
298
298
@@ -335,7 +335,7 @@ class FromForm a where
335 -- | Parse 'Form' into a value.
335 -- | Parse 'Form' into a value.
336 fromForm :: Form -> Either Text a
336 fromForm :: Form -> Either Text a
337 default fromForm :: (Generic a, GFromForm a (Rep a)) => Form -> Either Text a
337 default fromForm :: (Generic a, GFromForm a (Rep a)) => Form -> Either Text a
338− fromForm = genericFromForm
338+ fromForm = genericFromForm defaultFormOptions
339
339
340instance FromForm Form where fromForm = pure
340instance FromForm Form where fromForm = pure
341
341
@@ -371,25 +371,25 @@ toEntriesByKey = traverse parseGroup . HashMap.toList . unForm
371-- , age :: Int
371-- , age :: Int
372-- } deriving ('Generic')
372-- } deriving ('Generic')
373-- @
373-- @
374−genericFromForm :: forall a. (Generic a, GFromForm a (Rep a)) => Form -> Either Text a
374+genericFromForm :: forall a. (Generic a, GFromForm a (Rep a)) => FormOptions -> Form -> Either Text a
375−genericFromForm f = to <$> gFromForm (Proxy :: Proxy a) f
375+genericFromForm opts f = to <$> gFromForm (Proxy :: Proxy a) opts f
376
376
377class GFromForm t (f :: * -> *) where
377class GFromForm t (f :: * -> *) where
378− gFromForm :: Proxy t -> Form -> Either Text (f x)
378+ gFromForm :: Proxy t -> FormOptions -> Form -> Either Text (f x)
379
379
380instance (GFromForm t f, GFromForm t g) => GFromForm t (f :*: g) where
380instance (GFromForm t f, GFromForm t g) => GFromForm t (f :*: g) where
381− gFromForm p f = (:*:) <$> gFromForm p f <*> gFromForm p f
381+ gFromForm p opts f = (:*:) <$> gFromForm p opts f <*> gFromForm p opts f
382
382
383instance (Selector s, FromHttpApiData f) => GFromForm t (M1 S s (K1 i f)) where
383instance (Selector s, FromHttpApiData f) => GFromForm t (M1 S s (K1 i f)) where
384− gFromForm _ form = M1 . K1 <$> parseUnique key form
384+ gFromForm _ opts form = M1 . K1 <$> parseUnique key form
385 where
385 where
386− key = Text.pack $ selName (Proxy3 :: Proxy3 s g p)
386+ key = Text.pack $ fieldLabelModifier opts $ selName (Proxy3 :: Proxy3 s g p)
387
387
388instance GFromForm t f => GFromForm t (M1 D x f) where
388instance GFromForm t f => GFromForm t (M1 D x f) where
389− gFromForm p f = M1 <$> gFromForm p f
389+ gFromForm p opts f = M1 <$> gFromForm p opts f
390
390
391instance GFromForm t f => GFromForm t (M1 C x f) where
391instance GFromForm t f => GFromForm t (M1 C x f) where
392− gFromForm p f = M1 <$> gFromForm p f
392+ gFromForm p opts f = M1 <$> gFromForm p opts f
393
393
394instance NotSupported FromForm t "is a sum type" => GFromForm t (f :+: g) where gFromForm = error "impossible"
394instance NotSupported FromForm t "is a sum type" => GFromForm t (f :+: g) where gFromForm = error "impossible"
395
395
@@ -551,3 +551,20 @@ parseAll key = parseQueryParams . lookupAll key
551parseUnique :: FromHttpApiData v => Text -> Form -> Either Text v
551parseUnique :: FromHttpApiData v => Text -> Form -> Either Text v
552parseUnique key form = lookupUnique key form >>= parseQueryParam
552parseUnique key form = lookupUnique key form >>= parseQueryParam
553
553
554+-- | 'Generic'-based deriving options for 'ToForm' and 'FromForm'.
555+data FormOptions = FormOptions
556+ { -- | Function applied to field labels. Handy for removing common record prefixes for example.
557+ fieldLabelModifier :: String -> String
558+ }
559+
560+-- | Default encoding 'FormOptions'.
561+--
562+-- @
563+-- 'FormOptions'
564+-- { 'fieldLabelModifier' = id
565+-- }
566+-- @
567+defaultFormOptions :: FormOptions
568+defaultFormOptions = FormOptions
569+ { fieldLabelModifier = id
570+ }