{-# 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 {
  forall k v. Parse k v -> Text -> Parser (k, v)
parseString  :: Text -> Parser (k, v)
, forall k v. Parse k v -> Object -> Parser v
parseListItem :: Object -> Parser v
, forall k v. Parse k v -> Value -> Parser v
parseDictItem :: Value -> Parser v
, forall k v. Parse k v -> Text -> k
parseName :: Text -> k
}

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

buildToolFromValue :: Parse k v -> Value -> Parser (k, v)
buildToolFromValue :: forall k v. 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
_ -> forall a. String -> Value -> Parser a
typeMismatch String
"Object or String" Value
v
  where
    sourceDependency :: Object -> Parser (k, v)
sourceDependency Object
o = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Text -> k
parseName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
name) 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 forall a. FromValue a => Object -> Key -> Parser a
.: Key
"name"