module Argo.QuasiQuoter where

import qualified Argo.Decode as Decode
import qualified Argo.Json.Value as Value
import qualified Argo.Result as Result
import qualified Argo.Vendor.TemplateHaskell as TH
import qualified Argo.Vendor.Text as Text

value :: TH.QuasiQuoter
value :: QuasiQuoter
value = QuasiQuoter :: (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
TH.QuasiQuoter
    { quoteDec :: String -> Q [Dec]
TH.quoteDec = Q [Dec] -> String -> Q [Dec]
forall a b. a -> b -> a
const (Q [Dec] -> String -> Q [Dec]) -> Q [Dec] -> String -> Q [Dec]
forall a b. (a -> b) -> a -> b
$ String -> Q [Dec]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"cannot be used as a declaration"
    , quoteExp :: String -> Q Exp
TH.quoteExp = String -> Q Exp
quoteExp
    , quotePat :: String -> Q Pat
TH.quotePat = Q Pat -> String -> Q Pat
forall a b. a -> b -> a
const (Q Pat -> String -> Q Pat) -> Q Pat -> String -> Q Pat
forall a b. (a -> b) -> a -> b
$ String -> Q Pat
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"cannot be used as a pattern"
    , quoteType :: String -> Q Type
TH.quoteType = Q Type -> String -> Q Type
forall a b. a -> b -> a
const (Q Type -> String -> Q Type) -> Q Type -> String -> Q Type
forall a b. (a -> b) -> a -> b
$ String -> Q Type
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"cannot be used as a type"
    }

quoteExp :: String -> TH.Q TH.Exp
quoteExp :: String -> Q Exp
quoteExp String
x = case ByteString -> Result Value
forall a. FromValue a => ByteString -> Result a
Decode.decode (ByteString -> Result Value)
-> (Text -> ByteString) -> Text -> Result Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
Text.encodeUtf8 (Text -> Result Value) -> Text -> Result Value
forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack String
x of
    Result.Failure String
e -> String -> Q Exp
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
e
    Result.Success Value
y -> Value -> Q Exp
forall t. Lift t => t -> Q Exp
TH.lift (Value
y :: Value.Value)