@@ -93,10 +93,10 @@ class ToHttpApiData a where
9393 toUrlPiece = toQueryParam
9494
9595 -- | Convert to a URL path piece, making sure to encode any special chars.
96- -- The default definition uses 'H.encodePathSegmentsRelative',
96+ -- The default definition uses @ 'H.urlEncodeBuilder' 'False'@
9797 -- but this may be overriden with a more efficient version.
9898 toEncodedUrlPiece :: a -> BS. Builder
99- toEncodedUrlPiece = H. encodePathSegmentsRelative . ( : [] ) . toUrlPiece
99+ toEncodedUrlPiece = H. urlEncodeBuilder False . encodeUtf8 . toUrlPiece
100100
101101 -- | Convert to HTTP header value.
102102 toHeader :: a -> ByteString
@@ -106,6 +106,14 @@ class ToHttpApiData a where
106106 toQueryParam :: a -> Text
107107 toQueryParam = toUrlPiece
108108
109+ -- | Convert to URL query param,
110+ -- The default definition uses @'H.urlEncodeBuilder' 'True'@
111+ -- but this may be overriden with a more efficient version.
112+ --
113+ -- @since 0.5.1
114+ toEncodedQueryParam :: a -> BS. Builder
115+ toEncodedQueryParam = H. urlEncodeBuilder True . encodeUtf8 . toQueryParam
116+
109117-- | Parse value from HTTP API data.
110118--
111119-- __WARNING__: Do not derive this using @DeriveAnyClass@ as the generated
@@ -422,12 +430,21 @@ parseBounded reader input = do
422430unsafeToEncodedUrlPiece :: ToHttpApiData a => a -> BS. Builder
423431unsafeToEncodedUrlPiece = BS. byteString . encodeUtf8 . toUrlPiece
424432
433+ -- | Convert to a URL-encoded query param using 'toQueryParam'.
434+ -- /Note/: this function does not check if the result contains unescaped characters!
435+ --
436+ -- @since 0.5.1
437+ unsafeToEncodedQueryParam :: ToHttpApiData a => a -> BS. Builder
438+ unsafeToEncodedQueryParam = BS. byteString . encodeUtf8 . toQueryParam
439+
425440-- |
426441-- >>> toUrlPiece ()
427442-- "_"
428443instance ToHttpApiData () where
429- toUrlPiece () = " _"
430- toEncodedUrlPiece = unsafeToEncodedUrlPiece
444+ toUrlPiece _ = " _"
445+ toHeader _ = " _"
446+ toEncodedUrlPiece _ = " _"
447+ toEncodedQueryParam _ = " _"
431448
432449instance ToHttpApiData Char where
433450 toUrlPiece = T. singleton
@@ -438,36 +455,38 @@ instance ToHttpApiData Char where
438455instance ToHttpApiData Version where
439456 toUrlPiece = T. pack . showVersion
440457 toEncodedUrlPiece = unsafeToEncodedUrlPiece
458+ toEncodedQueryParam = unsafeToEncodedQueryParam
441459
442460instance ToHttpApiData Void where toUrlPiece = absurd
443- instance ToHttpApiData Natural where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
444-
445- instance ToHttpApiData Bool where toUrlPiece = showTextData; toEncodedUrlPiece = unsafeToEncodedUrlPiece
446- instance ToHttpApiData Ordering where toUrlPiece = showTextData; toEncodedUrlPiece = unsafeToEncodedUrlPiece
447-
448- instance ToHttpApiData Double where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
449- instance ToHttpApiData Float where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
450- instance ToHttpApiData Int where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
451- instance ToHttpApiData Int8 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
452- instance ToHttpApiData Int16 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
453- instance ToHttpApiData Int32 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
454- instance ToHttpApiData Int64 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
455- instance ToHttpApiData Integer where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
456- instance ToHttpApiData Word where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
457- instance ToHttpApiData Word8 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
458- instance ToHttpApiData Word16 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
459- instance ToHttpApiData Word32 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
460- instance ToHttpApiData Word64 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
461+ instance ToHttpApiData Natural where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
462+
463+ instance ToHttpApiData Bool where toUrlPiece = showTextData; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
464+ instance ToHttpApiData Ordering where toUrlPiece = showTextData; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
465+
466+ instance ToHttpApiData Double where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
467+ instance ToHttpApiData Float where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
468+ instance ToHttpApiData Int where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
469+ instance ToHttpApiData Int8 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
470+ instance ToHttpApiData Int16 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
471+ instance ToHttpApiData Int32 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
472+ instance ToHttpApiData Int64 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
473+ instance ToHttpApiData Integer where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
474+ instance ToHttpApiData Word where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
475+ instance ToHttpApiData Word8 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
476+ instance ToHttpApiData Word16 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
477+ instance ToHttpApiData Word32 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
478+ instance ToHttpApiData Word64 where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
461479
462480-- | Note: this instance is not polykinded
463- instance F. HasResolution a => ToHttpApiData (F. Fixed (a :: Type )) where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece
481+ instance F. HasResolution a => ToHttpApiData (F. Fixed (a :: Type )) where toUrlPiece = showt; toEncodedUrlPiece = unsafeToEncodedUrlPiece; toEncodedQueryParam = unsafeToEncodedQueryParam
464482
465483-- |
466484-- >>> toUrlPiece (fromGregorian 2015 10 03)
467485-- "2015-10-03"
468486instance ToHttpApiData Day where
469487 toUrlPiece = T. pack . show
470488 toEncodedUrlPiece = unsafeToEncodedUrlPiece
489+ toEncodedQueryParam = unsafeToEncodedQueryParam
471490
472491timeToUrlPiece :: FormatTime t => String -> t -> Text
473492timeToUrlPiece fmt = T. pack . formatTime defaultTimeLocale (iso8601DateFormat (Just fmt))
@@ -478,27 +497,31 @@ timeToUrlPiece fmt = T.pack . formatTime defaultTimeLocale (iso8601DateFormat (J
478497instance ToHttpApiData TimeOfDay where
479498 toUrlPiece = T. pack . formatTime defaultTimeLocale " %H:%M:%S%Q"
480499 toEncodedUrlPiece = unsafeToEncodedUrlPiece
500+ -- no toEncodedQueryParam as : is unsafe char.
481501
482502-- |
483503-- >>> toUrlPiece $ LocalTime (fromGregorian 2015 10 03) (TimeOfDay 14 55 21.687)
484504-- "2015-10-03T14:55:21.687"
485505instance ToHttpApiData LocalTime where
486506 toUrlPiece = timeToUrlPiece " %H:%M:%S%Q"
487507 toEncodedUrlPiece = unsafeToEncodedUrlPiece
508+ -- no toEncodedQueryParam as : is unsafe char.
488509
489510-- |
490511-- >>> toUrlPiece $ ZonedTime (LocalTime (fromGregorian 2015 10 03) (TimeOfDay 14 55 51.001)) utc
491512-- "2015-10-03T14:55:51.001+0000"
492513instance ToHttpApiData ZonedTime where
493514 toUrlPiece = timeToUrlPiece " %H:%M:%S%Q%z"
494515 toEncodedUrlPiece = unsafeToEncodedUrlPiece
516+ -- no toEncodedQueryParam as : is unsafe char.
495517
496518-- |
497519-- >>> toUrlPiece $ UTCTime (fromGregorian 2015 10 03) 864.5
498520-- "2015-10-03T00:14:24.5Z"
499521instance ToHttpApiData UTCTime where
500522 toUrlPiece = timeToUrlPiece " %H:%M:%S%QZ"
501523 toEncodedUrlPiece = unsafeToEncodedUrlPiece
524+ -- no toEncodedQueryParam as : is unsafe char.
502525
503526-- |
504527-- >>> toUrlPiece Monday
@@ -513,8 +536,9 @@ instance ToHttpApiData DayOfWeek where
513536 toUrlPiece Sunday = " sunday"
514537
515538 toEncodedUrlPiece = unsafeToEncodedUrlPiece
539+ toEncodedQueryParam = unsafeToEncodedQueryParam
516540
517- -- |
541+ -- |
518542-- >>> toUrlPiece Q4
519543-- "q4"
520544instance ToHttpApiData QuarterOfYear where
@@ -523,6 +547,9 @@ instance ToHttpApiData QuarterOfYear where
523547 toUrlPiece Q3 = " q3"
524548 toUrlPiece Q4 = " q4"
525549
550+ toEncodedUrlPiece = unsafeToEncodedUrlPiece
551+ toEncodedQueryParam = unsafeToEncodedQueryParam
552+
526553-- |
527554-- >>> import Data.Time.Calendar.Quarter.Compat (Quarter (..))
528555-- >>> MkQuarter 8040
@@ -540,6 +567,9 @@ instance ToHttpApiData Quarter where
540567 f Q3 = " q3"
541568 f Q4 = " q4"
542569
570+ toEncodedUrlPiece = unsafeToEncodedUrlPiece
571+ toEncodedQueryParam = unsafeToEncodedQueryParam
572+
543573-- |
544574-- >>> import Data.Time.Calendar.Month.Compat (Month (..))
545575-- >>> MkMonth 24482
@@ -551,8 +581,13 @@ instance ToHttpApiData Quarter where
551581instance ToHttpApiData Month where
552582 toUrlPiece = T. pack . formatTime defaultTimeLocale " %Y-%m"
553583
584+ toEncodedUrlPiece = unsafeToEncodedUrlPiece
585+ toEncodedQueryParam = unsafeToEncodedQueryParam
586+
554587instance ToHttpApiData NominalDiffTime where
555588 toUrlPiece = toUrlPiece . nominalDiffTimeToSeconds
589+
590+ toEncodedQueryParam = unsafeToEncodedQueryParam
556591 toEncodedUrlPiece = unsafeToEncodedUrlPiece
557592
558593instance ToHttpApiData String where toUrlPiece = T. pack
@@ -562,46 +597,57 @@ instance ToHttpApiData L.Text where toUrlPiece = L.toStrict
562597instance ToHttpApiData All where
563598 toUrlPiece = coerce (toUrlPiece :: Bool -> Text )
564599 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: Bool -> BS. Builder )
600+ toEncodedQueryParam = coerce (toEncodedQueryParam :: Bool -> BS. Builder )
565601
566602instance ToHttpApiData Any where
567603 toUrlPiece = coerce (toUrlPiece :: Bool -> Text )
568604 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: Bool -> BS. Builder )
605+ toEncodedQueryParam = coerce (toEncodedQueryParam :: Bool -> BS. Builder )
569606
570607instance ToHttpApiData a => ToHttpApiData (Dual a ) where
571608 toUrlPiece = coerce (toUrlPiece :: a -> Text )
572609 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
610+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
573611
574612instance ToHttpApiData a => ToHttpApiData (Sum a ) where
575613 toUrlPiece = coerce (toUrlPiece :: a -> Text )
576614 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
615+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
577616
578617instance ToHttpApiData a => ToHttpApiData (Product a ) where
579618 toUrlPiece = coerce (toUrlPiece :: a -> Text )
580619 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
620+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
581621
582622instance ToHttpApiData a => ToHttpApiData (First a ) where
583623 toUrlPiece = coerce (toUrlPiece :: Maybe a -> Text )
584624 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: Maybe a -> BS. Builder )
625+ toEncodedQueryParam = coerce (toEncodedQueryParam :: Maybe a -> BS. Builder )
585626
586627instance ToHttpApiData a => ToHttpApiData (Last a ) where
587628 toUrlPiece = coerce (toUrlPiece :: Maybe a -> Text )
588629 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: Maybe a -> BS. Builder )
630+ toEncodedQueryParam = coerce (toEncodedQueryParam :: Maybe a -> BS. Builder )
589631
590632instance ToHttpApiData a => ToHttpApiData (Semi. Min a ) where
591633 toUrlPiece = coerce (toUrlPiece :: a -> Text )
592634 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
635+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
593636
594637instance ToHttpApiData a => ToHttpApiData (Semi. Max a ) where
595638 toUrlPiece = coerce (toUrlPiece :: a -> Text )
596639 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
640+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
597641
598642instance ToHttpApiData a => ToHttpApiData (Semi. First a ) where
599643 toUrlPiece = coerce (toUrlPiece :: a -> Text )
600644 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
645+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
601646
602647instance ToHttpApiData a => ToHttpApiData (Semi. Last a ) where
603648 toUrlPiece = coerce (toUrlPiece :: a -> Text )
604649 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
650+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
605651
606652-- |
607653-- >>> toUrlPiece (Just "Hello")
@@ -639,20 +685,23 @@ instance ToHttpApiData a => ToHttpApiData (Tagged (b :: Type) a) where
639685 toHeader = coerce (toHeader :: a -> ByteString )
640686 toQueryParam = coerce (toQueryParam :: a -> Text )
641687 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
688+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
642689
643690-- | @since 0.4.2
644691instance ToHttpApiData a => ToHttpApiData (Const a b ) where
645692 toUrlPiece = coerce (toUrlPiece :: a -> Text )
646693 toHeader = coerce (toHeader :: a -> ByteString )
647694 toQueryParam = coerce (toQueryParam :: a -> Text )
648695 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
696+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
649697
650698-- | @since 0.4.2
651699instance ToHttpApiData a => ToHttpApiData (Identity a ) where
652700 toUrlPiece = coerce (toUrlPiece :: a -> Text )
653701 toHeader = coerce (toHeader :: a -> ByteString )
654702 toQueryParam = coerce (toQueryParam :: a -> Text )
655703 toEncodedUrlPiece = coerce (toEncodedUrlPiece :: a -> BS. Builder )
704+ toEncodedQueryParam = coerce (toEncodedQueryParam :: a -> BS. Builder )
656705
657706-- |
658707-- >>> parseUrlPiece "_" :: Either Text ()
0 commit comments