{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Hpack.Syntax.ParseDependencies where

import           Imports

import           Data.Aeson.Config.FromValue
import qualified Data.Aeson.Config.Key as Key

data Parse k v = Parse {
  Parse k v -> Text -> Parser (k, v)
parseString  :: Text -> Parser (k, v)
, Parse k v -> Object -> Parser v
parseListItem :: Object -> Parser v
, Parse k v -> Value -> Parser v
parseDictItem :: Value -> Parser v
, Parse k v -> Text -> k
parseName :: Text -> k
}

parseDependencies :: Parse k v -> Value -> Parser [(k, v)]
parseDependencies :: Parse k v -> Value -> Parser [(k, v)]
parseDependencies parse :: Parse k v
parse@Parse{Text -> k
Text -> Parser (k, v)
Value -> Parser v
Object -> Parser v
parseName :: Text -> k
parseDictItem :: Value -> Parser v
parseListItem :: Object -> Parser v
parseString :: Text -> Parser (k, v)
parseName :: forall k v. Parse k v -> Text -> k
parseDictItem :: forall k v. Parse k v -> Value -> Parser v
parseListItem :: forall k v. Parse k v -> Object -> Parser v
parseString :: forall k v. Parse k v -> Text -> Parser (k, v)
..} Value
v = case Value
v of
  String Text
s -> (k, v) -> [(k, v)]
forall (m :: * -> *) a. Monad m => a -> m a
return ((k, v) -> [(k, v)]) -> Parser (k, v) -> Parser [(k, v)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Parser (k, v)
parseString Text
s
  Array Array
xs -> (Value -> Parser (k, v)) -> Array -> Parser [(k, v)]
forall a. (Value -> Parser a) -> Array -> Parser [a]
parseArray (Parse k v -> Value -> Parser (k, v)
forall k v. Parse k v -> Value -> Parser (k, v)
buildToolFromValue Parse k v
parse) Array
xs
  Object Object
o -> ((Key, v) -> (k, v)) -> [(Key, v)] -> [(k, v)]
forall a b. (a -> b) -> [a] -> [b]
map ((Key -> k) -> (Key, v) -> (k, v)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Text -> k
parseName (Text -> k) -> (Key -> Text) -> Key -> k
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Text
Key.toText)) ([(Key, v)] -> [(k, v)]) -> Parser [(Key, v)] -> Parser [(k, v)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> Parser v) -> Object -> Parser [(Key, v)]
forall a. (Value -> Parser a) -> Object -> Parser [(Key, a)]
traverseObject Value -> Parser v
parseDictItem Object
o
  Value
_ -> String -> Value -> Parser [(k, v)]
forall a. String -> Value -> Parser a
typeMismatch String
"Array, Object, or String" Value
v

buildToolFromValue :: Parse k v -> Value -> Parser (k, v)
buildToolFromValue :: Parse k v -> Value -> Parser (k, v)
buildToolFromValue Parse{Text -> k
Text -> Parser (k, v)
Value -> Parser v
Object -> Parser v
parseName :: Text -> k
parseDictItem :: Value -> Parser v
parseListItem :: Object -> Parser v
parseString :: Text -> Parser (k, v)
parseName :: forall k v. Parse k v -> Text -> k
parseDictItem :: forall k v. Parse k v -> Value -> Parser v
parseListItem :: forall k v. Parse k v -> Object -> Parser v
parseString :: forall k v. Parse k v -> Text -> Parser (k, v)
..} Value
v = case Value
v of
  String Text
s -> Text -> Parser (k, v)
parseString Text
s
  Object Object
o -> Object -> Parser (k, v)
sourceDependency Object
o
  Value
_ -> String -> Value -> Parser (k, v)
forall a. String -> Value -> Parser a
typeMismatch String
"Object or String" Value
v
  where
    sourceDependency :: Object -> Parser (k, v)
sourceDependency Object
o = (,) (k -> v -> (k, v)) -> Parser k -> Parser (v -> (k, v))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Text -> k
parseName (Text -> k) -> Parser Text -> Parser k
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
name) Parser (v -> (k, v)) -> Parser v -> Parser (k, v)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object -> Parser v
parseListItem Object
o
      where
        name :: Parser Text
        name :: Parser Text
name = Object
o Object -> Key -> Parser Text
forall a. FromValue a => Object -> Key -> Parser a
.: Key
"name"