{-# OPTIONS_GHC -Wno-missing-export-lists #-}

module Burrito.Internal.Render where

import qualified Burrito.Internal.Type.Case as Case
import qualified Burrito.Internal.Type.Character as Character
import qualified Burrito.Internal.Type.Digit as Digit
import qualified Burrito.Internal.Type.Expression as Expression
import qualified Burrito.Internal.Type.Field as Field
import qualified Burrito.Internal.Type.Literal as Literal
import qualified Burrito.Internal.Type.MaxLength as MaxLength
import qualified Burrito.Internal.Type.Modifier as Modifier
import qualified Burrito.Internal.Type.Name as Name
import qualified Burrito.Internal.Type.Operator as Operator
import qualified Burrito.Internal.Type.Token as Token
import qualified Burrito.Internal.Type.Variable as Variable
import qualified Data.List as List
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Text.Lazy as LazyText
import qualified Data.Text.Lazy.Builder as Builder

builderToString :: Builder.Builder -> String
builderToString :: Builder -> String
builderToString = Text -> String
LazyText.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
Builder.toLazyText

token :: Token.Token -> Builder.Builder
token :: Token -> Builder
token Token
x = case Token
x of
  Token.Expression Expression
y -> Expression -> Builder
expression Expression
y
  Token.Literal Literal
y -> Literal -> Builder
literal Literal
y

expression :: Expression.Expression -> Builder.Builder
expression :: Expression -> Builder
expression Expression
x =
  Char -> Builder
Builder.singleton Char
'{'
    forall a. Semigroup a => a -> a -> a
<> Operator -> Builder
operator (Expression -> Operator
Expression.operator Expression
x)
    forall a. Semigroup a => a -> a -> a
<> forall a. (a -> Builder) -> Builder -> NonEmpty a -> Builder
sepBy1 Variable -> Builder
variable (Char -> Builder
Builder.singleton Char
',') (Expression -> NonEmpty Variable
Expression.variables Expression
x)
    forall a. Semigroup a => a -> a -> a
<> Char -> Builder
Builder.singleton Char
'}'

operator :: Operator.Operator -> Builder.Builder
operator :: Operator -> Builder
operator Operator
x = case Operator
x of
  Operator
Operator.Ampersand -> Char -> Builder
Builder.singleton Char
'&'
  Operator
Operator.FullStop -> Char -> Builder
Builder.singleton Char
'.'
  Operator
Operator.None -> forall a. Monoid a => a
mempty
  Operator
Operator.NumberSign -> Char -> Builder
Builder.singleton Char
'#'
  Operator
Operator.PlusSign -> Char -> Builder
Builder.singleton Char
'+'
  Operator
Operator.QuestionMark -> Char -> Builder
Builder.singleton Char
'?'
  Operator
Operator.Semicolon -> Char -> Builder
Builder.singleton Char
';'
  Operator
Operator.Solidus -> Char -> Builder
Builder.singleton Char
'/'

sepBy1
  :: (a -> Builder.Builder)
  -> Builder.Builder
  -> NonEmpty.NonEmpty a
  -> Builder.Builder
sepBy1 :: forall a. (a -> Builder) -> Builder -> NonEmpty a -> Builder
sepBy1 a -> Builder
f Builder
x = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
List.intersperse Builder
x forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Builder
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. NonEmpty a -> [a]
NonEmpty.toList

variable :: Variable.Variable -> Builder.Builder
variable :: Variable -> Builder
variable Variable
x = Name -> Builder
name (Variable -> Name
Variable.name Variable
x) forall a. Semigroup a => a -> a -> a
<> Modifier -> Builder
modifier (Variable -> Modifier
Variable.modifier Variable
x)

name :: Name.Name -> Builder.Builder
name :: Name -> Builder
name = forall a. (a -> Builder) -> Builder -> NonEmpty a -> Builder
sepBy1 Field -> Builder
field (Char -> Builder
Builder.singleton Char
'.') forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> NonEmpty Field
Name.fields

field :: Field.Field -> Builder.Builder
field :: Field -> Builder
field = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall tag. Character tag -> Builder
character forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field -> NonEmpty (Character Field)
Field.characters

character :: Character.Character tag -> Builder.Builder
character :: forall tag. Character tag -> Builder
character Character tag
x = case Character tag
x of
  Character.Encoded Digit
y Digit
z -> Digit -> Digit -> Builder
encodedCharacter Digit
y Digit
z
  Character.Unencoded Char
y -> Char -> Builder
Builder.singleton Char
y

encodedCharacter :: Digit.Digit -> Digit.Digit -> Builder.Builder
encodedCharacter :: Digit -> Digit -> Builder
encodedCharacter Digit
x Digit
y = Char -> Builder
Builder.singleton Char
'%' forall a. Semigroup a => a -> a -> a
<> Digit -> Builder
digit Digit
x forall a. Semigroup a => a -> a -> a
<> Digit -> Builder
digit Digit
y

digit :: Digit.Digit -> Builder.Builder
digit :: Digit -> Builder
digit Digit
x = Char -> Builder
Builder.singleton forall a b. (a -> b) -> a -> b
$ case Digit
x of
  Digit
Digit.Ox0 -> Char
'0'
  Digit
Digit.Ox1 -> Char
'1'
  Digit
Digit.Ox2 -> Char
'2'
  Digit
Digit.Ox3 -> Char
'3'
  Digit
Digit.Ox4 -> Char
'4'
  Digit
Digit.Ox5 -> Char
'5'
  Digit
Digit.Ox6 -> Char
'6'
  Digit
Digit.Ox7 -> Char
'7'
  Digit
Digit.Ox8 -> Char
'8'
  Digit
Digit.Ox9 -> Char
'9'
  Digit.OxA Case
Case.Upper -> Char
'A'
  Digit.OxB Case
Case.Upper -> Char
'B'
  Digit.OxC Case
Case.Upper -> Char
'C'
  Digit.OxD Case
Case.Upper -> Char
'D'
  Digit.OxE Case
Case.Upper -> Char
'E'
  Digit.OxF Case
Case.Upper -> Char
'F'
  Digit.OxA Case
Case.Lower -> Char
'a'
  Digit.OxB Case
Case.Lower -> Char
'b'
  Digit.OxC Case
Case.Lower -> Char
'c'
  Digit.OxD Case
Case.Lower -> Char
'd'
  Digit.OxE Case
Case.Lower -> Char
'e'
  Digit.OxF Case
Case.Lower -> Char
'f'

modifier :: Modifier.Modifier -> Builder.Builder
modifier :: Modifier -> Builder
modifier Modifier
x = case Modifier
x of
  Modifier
Modifier.Asterisk -> Char -> Builder
Builder.singleton Char
'*'
  Modifier.Colon MaxLength
y -> Char -> Builder
Builder.singleton Char
':' forall a. Semigroup a => a -> a -> a
<> MaxLength -> Builder
maxLength MaxLength
y
  Modifier
Modifier.None -> forall a. Monoid a => a
mempty

maxLength :: MaxLength.MaxLength -> Builder.Builder
maxLength :: MaxLength -> Builder
maxLength = String -> Builder
Builder.fromString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. MaxLength -> Int
MaxLength.count

literal :: Literal.Literal -> Builder.Builder
literal :: Literal -> Builder
literal = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall tag. Character tag -> Builder
character forall b c a. (b -> c) -> (a -> b) -> a -> c
. Literal -> NonEmpty (Character Literal)
Literal.characters