module Data.Text.Extended
  ( ToTxt (..),
    bquote,
    squote,
    dquote,
    dquoteList,
    commaSeparated,
    paren,
    parenB,
    (<~>),
    (<>>),
    (<<>),
  )
where

import Data.Text as DT
import Database.ODBC.SQLServer qualified as ODBC
import Hasura.Prelude
import Language.GraphQL.Draft.Printer qualified as G
import Language.GraphQL.Draft.Syntax qualified as G
import Text.Builder qualified as TB

class ToTxt a where
  toTxt :: a -> Text

instance ToTxt Text where
  toTxt :: Text -> Text
toTxt = Text -> Text
forall a. a -> a
id
  {-# INLINE toTxt #-}

instance ToTxt Char where
  toTxt :: Char -> Text
toTxt = Char -> Text
DT.singleton

instance ToTxt G.Name where
  toTxt :: Name -> Text
toTxt = Name -> Text
G.unName

deriving instance ToTxt G.EnumValue

instance ToTxt () where
  toTxt :: () -> Text
toTxt = () -> Text
forall a. Show a => a -> Text
tshow

instance ToTxt Void where
  toTxt :: Void -> Text
toTxt = Void -> Text
forall a. Void -> a
absurd

instance ToTxt (G.Value Void) where
  toTxt :: Value Void -> Text
toTxt = Builder -> Text
TB.run (Builder -> Text) -> (Value Void -> Builder) -> Value Void -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value Void -> Builder
forall var a. (Print var, Printer a) => Value var -> a
G.value

instance ToTxt ODBC.Query where
  toTxt :: Query -> Text
toTxt = Query -> Text
ODBC.renderQuery

bquote :: ToTxt t => t -> Text
bquote :: t -> Text
bquote t
t = Char -> Text
DT.singleton Char
'`' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> t -> Text
forall a. ToTxt a => a -> Text
toTxt t
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Char -> Text
DT.singleton Char
'`'

squote :: ToTxt t => t -> Text
squote :: t -> Text
squote t
t = Char -> Text
DT.singleton Char
'\'' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> t -> Text
forall a. ToTxt a => a -> Text
toTxt t
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Char -> Text
DT.singleton Char
'\''

dquote :: ToTxt t => t -> Text
dquote :: t -> Text
dquote t
t = Char -> Text
DT.singleton Char
'"' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> t -> Text
forall a. ToTxt a => a -> Text
toTxt t
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Char -> Text
DT.singleton Char
'"'

paren :: ToTxt t => t -> Text
paren :: t -> Text
paren t
t = Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> t -> Text
forall a. ToTxt a => a -> Text
toTxt t
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"

parenB :: TB.Builder -> TB.Builder
parenB :: Builder -> Builder
parenB Builder
t = Char -> Builder
TB.char Char
'(' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
t Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
TB.char Char
')'

dquoteList :: (ToTxt t, Foldable f) => f t -> Text
dquoteList :: f t -> Text
dquoteList = Text -> [Text] -> Text
DT.intercalate Text
", " ([Text] -> Text) -> (f t -> [Text]) -> f t -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t -> Text) -> [t] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap t -> Text
forall a. ToTxt a => a -> Text
dquote ([t] -> [Text]) -> (f t -> [t]) -> f t -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f t -> [t]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList

commaSeparated :: (ToTxt t, Foldable f) => f t -> Text
commaSeparated :: f t -> Text
commaSeparated = Text -> [Text] -> Text
DT.intercalate Text
", " ([Text] -> Text) -> (f t -> [Text]) -> f t -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t -> Text) -> [t] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap t -> Text
forall a. ToTxt a => a -> Text
toTxt ([t] -> [Text]) -> (f t -> [t]) -> f t -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f t -> [t]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList

infixr 6 <>>

(<>>) :: ToTxt t => Text -> t -> Text
<>> :: Text -> t -> Text
(<>>) Text
lTxt t
a = Text
lTxt Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> t -> Text
forall a. ToTxt a => a -> Text
dquote t
a

infixr 6 <<>

(<<>) :: ToTxt t => t -> Text -> Text
<<> :: t -> Text -> Text
(<<>) t
a Text
rTxt = t -> Text
forall a. ToTxt a => a -> Text
dquote t
a Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rTxt

infixr 6 <~>

(<~>) :: TB.Builder -> TB.Builder -> TB.Builder
<~> :: Builder -> Builder -> Builder
(<~>) Builder
l Builder
r = Builder
l Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
TB.char Char
' ' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
r