{-# LANGUAGE UndecidableInstances #-}

module Bookhound.Format.Operations.ToYaml (ToYaml(..)) where

import Bookhound.Format.Operations.ToJson (ToJson (..))
import Bookhound.Format.SyntaxTrees.Json  (JsExpression (..))
import Bookhound.Format.SyntaxTrees.Yaml  (CollectionType (..), YamlExpression (..))

import Bookhound.Parser            (runParser)
import Bookhound.Parsers.Number    (intLike)

import Data.Text                   (pack)



class ToYaml a where
  toYaml :: a -> YamlExpression

instance {-# OVERLAPPABLE #-} ToJson a => ToYaml a where
  toYaml :: a -> YamlExpression
toYaml = JsExpression -> YamlExpression
forall a. ToYaml a => a -> YamlExpression
toYaml (JsExpression -> YamlExpression)
-> (a -> JsExpression) -> a -> YamlExpression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> JsExpression
forall a. ToJson a => a -> JsExpression
toJson

instance ToYaml YamlExpression where
  toYaml :: YamlExpression -> YamlExpression
toYaml = YamlExpression -> YamlExpression
forall a. a -> a
id

instance ToYaml JsExpression where

  toYaml :: JsExpression -> YamlExpression
toYaml = \case
    JsExpression
JsNull       -> YamlExpression
YamlNull
    JsNumber Double
n   -> (ParseError -> YamlExpression)
-> (Integer -> YamlExpression)
-> Either ParseError Integer
-> YamlExpression
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (YamlExpression -> ParseError -> YamlExpression
forall a b. a -> b -> a
const (Double -> YamlExpression
YamlFloat Double
n)) Integer -> YamlExpression
YamlInteger (Either ParseError Integer -> YamlExpression)
-> Either ParseError Integer -> YamlExpression
forall a b. (a -> b) -> a -> b
$
      Parser Integer -> Input -> Either ParseError Integer
forall a. Parser a -> Input -> Either ParseError a
runParser Parser Integer
intLike (Input -> Either ParseError Integer)
-> Input -> Either ParseError Integer
forall a b. (a -> b) -> a -> b
$ String -> Input
pack (String -> Input) -> String -> Input
forall a b. (a -> b) -> a -> b
$ Double -> String
forall a. Show a => a -> String
show Double
n
    JsBool Bool
bool  -> Bool -> YamlExpression
YamlBool Bool
bool
    JsString String
str -> String -> YamlExpression
YamlString String
str
    JsArray [JsExpression]
arr  -> CollectionType -> [YamlExpression] -> YamlExpression
YamlList CollectionType
Standard ([YamlExpression] -> YamlExpression)
-> [YamlExpression] -> YamlExpression
forall a b. (a -> b) -> a -> b
$ JsExpression -> YamlExpression
forall a. ToYaml a => a -> YamlExpression
toYaml (JsExpression -> YamlExpression)
-> [JsExpression] -> [YamlExpression]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [JsExpression]
arr
    JsObject Map String JsExpression
obj -> CollectionType -> Map String YamlExpression -> YamlExpression
YamlMap  CollectionType
Standard (Map String YamlExpression -> YamlExpression)
-> Map String YamlExpression -> YamlExpression
forall a b. (a -> b) -> a -> b
$ JsExpression -> YamlExpression
forall a. ToYaml a => a -> YamlExpression
toYaml (JsExpression -> YamlExpression)
-> Map String JsExpression -> Map String YamlExpression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map String JsExpression
obj