module Bookhound.Format.Parsers.Json (json, nil, number, bool, string, array, object) where

import Bookhound.Parser              (Parser, withError)
import Bookhound.ParserCombinators   (IsMatch (..), maybeWithin, (<|>), (|*))
import Bookhound.Parsers.Char        (colon, doubleQuote)
import Bookhound.Parsers.Collections (listOf, mapOf)
import Bookhound.Parsers.Number      (double)
import Bookhound.Parsers.String      (spacing, withinDoubleQuotes)

import Bookhound.Format.SyntaxTrees.Json    (JsExpression (..))


json :: Parser JsExpression
json :: Parser JsExpression
json = Parser String -> Parser JsExpression -> Parser JsExpression
forall a b. Parser a -> Parser b -> Parser b
maybeWithin Parser String
spacing Parser JsExpression
jsValue
  where
    jsValue :: Parser JsExpression
jsValue = Parser JsExpression
element Parser JsExpression -> Parser JsExpression -> Parser JsExpression
forall a. Parser a -> Parser a -> Parser a
<|> Parser JsExpression
container


nil :: Parser JsExpression
nil :: Parser JsExpression
nil = String -> Parser JsExpression -> Parser JsExpression
forall a. String -> Parser a -> Parser a
withError String
"Json Null"
  (Parser JsExpression -> Parser JsExpression)
-> Parser JsExpression -> Parser JsExpression
forall a b. (a -> b) -> a -> b
$ JsExpression
JsNull JsExpression -> Parser String -> Parser JsExpression
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
forall a. IsMatch a => a -> Parser a
is String
"null"

number :: Parser JsExpression
number :: Parser JsExpression
number = String -> Parser JsExpression -> Parser JsExpression
forall a. String -> Parser a -> Parser a
withError String
"Json Number"
  (Parser JsExpression -> Parser JsExpression)
-> Parser JsExpression -> Parser JsExpression
forall a b. (a -> b) -> a -> b
$ Double -> JsExpression
JsNumber (Double -> JsExpression) -> Parser Double -> Parser JsExpression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Double
double


bool :: Parser JsExpression
bool :: Parser JsExpression
bool = String -> Parser JsExpression -> Parser JsExpression
forall a. String -> Parser a -> Parser a
withError String
"Json Bool"
  (Parser JsExpression -> Parser JsExpression)
-> Parser JsExpression -> Parser JsExpression
forall a b. (a -> b) -> a -> b
$ Bool -> JsExpression
JsBool (Bool -> JsExpression) -> Parser Bool -> Parser JsExpression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Bool
True  Bool -> Parser String -> Parser Bool
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
forall a. IsMatch a => a -> Parser a
is String
"true" Parser Bool -> Parser Bool -> Parser Bool
forall a. Parser a -> Parser a -> Parser a
<|>
                Bool
False Bool -> Parser String -> Parser Bool
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
forall a. IsMatch a => a -> Parser a
is String
"false")


string :: Parser JsExpression
string :: Parser JsExpression
string = String -> Parser JsExpression -> Parser JsExpression
forall a. String -> Parser a -> Parser a
withError String
"Json String"
  (Parser JsExpression -> Parser JsExpression)
-> Parser JsExpression -> Parser JsExpression
forall a b. (a -> b) -> a -> b
$ String -> JsExpression
JsString (String -> JsExpression) -> Parser String -> Parser JsExpression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String
text


array :: Parser JsExpression
array :: Parser JsExpression
array = String -> Parser JsExpression -> Parser JsExpression
forall a. String -> Parser a -> Parser a
withError String
"Json Array"
  (Parser JsExpression -> Parser JsExpression)
-> Parser JsExpression -> Parser JsExpression
forall a b. (a -> b) -> a -> b
$ [JsExpression] -> JsExpression
JsArray ([JsExpression] -> JsExpression)
-> Parser [JsExpression] -> Parser JsExpression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser JsExpression -> Parser [JsExpression]
forall a. Parser a -> Parser [a]
listOf Parser JsExpression
json


object :: Parser JsExpression
object :: Parser JsExpression
object = String -> Parser JsExpression -> Parser JsExpression
forall a. String -> Parser a -> Parser a
withError String
"Json Object"
  (Parser JsExpression -> Parser JsExpression)
-> Parser JsExpression -> Parser JsExpression
forall a b. (a -> b) -> a -> b
$ Map String JsExpression -> JsExpression
JsObject (Map String JsExpression -> JsExpression)
-> Parser (Map String JsExpression) -> Parser JsExpression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Char
-> Parser String
-> Parser JsExpression
-> Parser (Map String JsExpression)
forall b a c.
Ord b =>
Parser a -> Parser b -> Parser c -> Parser (Map b c)
mapOf Parser Char
colon Parser String
text Parser JsExpression
json



element :: Parser JsExpression
element :: Parser JsExpression
element = Parser JsExpression
number Parser JsExpression -> Parser JsExpression -> Parser JsExpression
forall a. Parser a -> Parser a -> Parser a
<|> Parser JsExpression
bool Parser JsExpression -> Parser JsExpression -> Parser JsExpression
forall a. Parser a -> Parser a -> Parser a
<|> Parser JsExpression
nil Parser JsExpression -> Parser JsExpression -> Parser JsExpression
forall a. Parser a -> Parser a -> Parser a
<|> Parser JsExpression
string

container :: Parser JsExpression
container :: Parser JsExpression
container = Parser JsExpression
array Parser JsExpression -> Parser JsExpression -> Parser JsExpression
forall a. Parser a -> Parser a -> Parser a
<|> Parser JsExpression
object



text :: Parser String
text :: Parser String
text = Parser String -> Parser String
forall b. Parser b -> Parser b
withinDoubleQuotes (Parser Char -> Parser Char
forall a. IsMatch a => Parser a -> Parser a
inverse Parser Char
doubleQuote Parser Char -> Parser String
forall a. Parser a -> Parser [a]
|*)