{-# LANGUAGE UndecidableInstances #-}

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

import Bookhound.Format.Operations.ToJson (ToJson (..))
import Bookhound.Format.SyntaxTrees.Json  (JsonExpression (..))
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 = forall a. ToYaml a => a -> YamlExpression
toYaml forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToJson a => a -> JsonExpression
toJson

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

instance ToYaml JsonExpression where

  toYaml :: JsonExpression -> YamlExpression
toYaml = \case
    JsonExpression
JsNull       -> YamlExpression
YamlNull
    JsNumber Double
n   -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const (Double -> YamlExpression
YamlFloat Double
n)) Integer -> YamlExpression
YamlInteger forall a b. (a -> b) -> a -> b
$
      forall a. Parser a -> Input -> Either [ParseError] a
runParser Parser Integer
intLike forall a b. (a -> b) -> a -> b
$ String -> Input
pack forall a b. (a -> b) -> a -> b
$ 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 [JsonExpression]
arr  -> CollectionType -> [YamlExpression] -> YamlExpression
YamlList CollectionType
Standard forall a b. (a -> b) -> a -> b
$ forall a. ToYaml a => a -> YamlExpression
toYaml forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [JsonExpression]
arr
    JsObject Map String JsonExpression
obj -> CollectionType -> Map String YamlExpression -> YamlExpression
YamlMap  CollectionType
Standard forall a b. (a -> b) -> a -> b
$ forall a. ToYaml a => a -> YamlExpression
toYaml forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map String JsonExpression
obj