{-# LANGUAGE UndecidableInstances #-}

module Operations.ToYaml (ToYaml(..)) where

import SyntaxTrees.Yaml  (YamlExpression(..), CollectionType(..))
import SyntaxTrees.Json (JsExpression(..))
import Operations.ToJson (ToJson(..))
import Parsers.Number (intLike)
import Parser (runParser)


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
$ Double -> Input
forall a. Show a => a -> Input
show Double
n
    JsBool Bool
bool  -> Bool -> YamlExpression
YamlBool Bool
bool
    JsString Input
str -> Input -> YamlExpression
YamlString Input
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 Input JsExpression
obj -> CollectionType -> Map Input YamlExpression -> YamlExpression
YamlMap  CollectionType
Standard (Map Input YamlExpression -> YamlExpression)
-> Map Input YamlExpression -> YamlExpression
forall a b. (a -> b) -> a -> b
$ JsExpression -> YamlExpression
forall a. ToYaml a => a -> YamlExpression
toYaml (JsExpression -> YamlExpression)
-> Map Input JsExpression -> Map Input YamlExpression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Input JsExpression
obj