    {-# 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{Object -> Parser v
    Value -> Parser v
    Text -> k
    Text -> Parser (k, v)
    parseString :: forall k v. Parse k v -> Text -> Parser (k, v)
    parseListItem :: forall k v. Parse k v -> Object -> Parser v
    parseDictItem :: forall k v. Parse k v -> Value -> Parser v
    parseName :: forall k v. Parse k v -> Text -> k
    parseString :: Text -> Parser (k, v)
    parseListItem :: Object -> Parser v
    parseDictItem :: Value -> Parser v
    parseName :: Text -> k
    ..} Value
    v = case Value
    v of
      String Text
    s -> (k, v) -> [(k, v)]
    forall a. a -> [a]
    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 a b c. (a -> b) -> (a, c) -> (b, c)
    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 :: forall k v. Parse k v -> Value -> Parser (k, v)
    buildToolFromValue Parse{Object -> Parser v
    Value -> Parser v
    Text -> k
    Text -> Parser (k, v)
    parseString :: forall k v. Parse k v -> Text -> Parser (k, v)
    parseListItem :: forall k v. Parse k v -> Object -> Parser v
    parseDictItem :: forall k v. Parse k v -> Value -> Parser v
    parseName :: forall k v. Parse k v -> Text -> k
    parseString :: Text -> Parser (k, v)
    parseListItem :: Object -> Parser v
    parseDictItem :: Value -> Parser v
    parseName :: Text -> k
    ..} 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 a b. Parser (a -> b) -> Parser a -> Parser b
    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"