@@ -90,6 +90,7 @@ module Obelisk.Route
90 , Decoder(..)
90 , Decoder(..)
91 , dmapEncoder
91 , dmapEncoder
92 , fieldMapEncoder
92 , fieldMapEncoder
95import Prelude hiding ((.), id)
96import Prelude hiding ((.), id)
@@ -102,6 +103,7 @@ import Control.Category.Associative
102import Control.Category.Monoidal
103import Control.Category.Monoidal
103import Control.Lens (Identity (..), Prism', makePrisms, itraverse, imap, prism, (^.), re, matching, (^?), _Just, _Nothing, Iso', from, view, Wrapped (..))
104import Control.Lens (Identity (..), Prism', makePrisms, itraverse, imap, prism, (^.), re, matching, (^?), _Just, _Nothing, Iso', from, view, Wrapped (..))
104import Control.Monad.Except
105import Control.Monad.Except
106+import qualified Data.ByteString.Lazy as BSL
105import Data.Dependent.Sum (DSum (..))
107import Data.Dependent.Sum (DSum (..))
106import Data.Dependent.Map (DMap)
108import Data.Dependent.Map (DMap)
107import qualified Data.Dependent.Map as DMap
109import qualified Data.Dependent.Map as DMap
@@ -130,6 +132,8 @@ import qualified Numeric.Lens
130import Obelisk.Route.TH
132import Obelisk.Route.TH
131import Text.Read (readMaybe)
133import Text.Read (readMaybe)
132import Data.Tabulation
134import Data.Tabulation
135+import qualified Data.Aeson as Aeson
136+import Data.Aeson (FromJSON, ToJSON)
134-- Design goals:
138-- Design goals:
135-- No start-up time on the frontend (not yet met)
139-- No start-up time on the frontend (not yet met)
@@ -349,7 +353,7 @@ maybeEncoder f g = shadowEncoder f g . maybeToEitherEncoder
349justEncoder :: (Applicative check, MonadError Text parse) => Encoder check parse a (Maybe a)
353justEncoder :: (Applicative check, MonadError Text parse) => Encoder check parse a (Maybe a)
350justEncoder = prismEncoder _Just
354justEncoder = prismEncoder _Just
352−-- |
356+-- | Encode () to 'Nothing'.
353nothingEncoder :: (Applicative check, MonadError Text parse) => Encoder check parse () (Maybe a)
357nothingEncoder :: (Applicative check, MonadError Text parse) => Encoder check parse () (Maybe a)
354nothingEncoder = prismEncoder _Nothing
358nothingEncoder = prismEncoder _Nothing
@@ -933,4 +937,20 @@ fieldMapEncoder = unsafeEncoder $ do
933 Just (Identity v) -> return v
937 Just (Identity v) -> return v
940+-- | Use ToJSON/FromJSON to encode to Text. The correctness of this encoder is dependent on the encoding being injective and round-tripping correctly.
941+jsonEncoder :: forall check parse r.
945+ , MonadError Text parse
947+ => Encoder check parse r Text
948+jsonEncoder = unsafeEncoder $ do
950+ { _encoderImpl_encode = \r -> decodeUtf8 . BSL.toStrict $ Aeson.encode r
951+ , _encoderImpl_decode = \t -> case Aeson.eitherDecodeStrict $ encodeUtf8 t of
952+ Left err -> throwError ("jsonEncoder: " <> T.pack err)
936--TODO: decodeURIComponent as appropriate
956--TODO: decodeURIComponent as appropriate