{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeFamilies #-} module Hpack.Syntax.Dependencies ( Dependencies(..) , DependencyInfo(..) , parseDependency ) where import qualified Control.Monad.Fail as Fail import Data.Text (Text) import qualified Data.Text as T import Data.Semigroup (Semigroup(..)) import qualified Distribution.Package as D import Data.Map.Lazy (Map) import qualified Data.Map.Lazy as Map import GHC.Exts import Data.Aeson.Config.FromValue import Data.Aeson.Config.Types import Hpack.Syntax.DependencyVersion import Hpack.Syntax.ParseDependencies newtype Dependencies = Dependencies { Dependencies -> Map String DependencyInfo unDependencies :: Map String DependencyInfo } deriving (Dependencies -> Dependencies -> Bool (Dependencies -> Dependencies -> Bool) -> (Dependencies -> Dependencies -> Bool) -> Eq Dependencies forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Dependencies -> Dependencies -> Bool $c/= :: Dependencies -> Dependencies -> Bool == :: Dependencies -> Dependencies -> Bool $c== :: Dependencies -> Dependencies -> Bool Eq, Int -> Dependencies -> ShowS [Dependencies] -> ShowS Dependencies -> String (Int -> Dependencies -> ShowS) -> (Dependencies -> String) -> ([Dependencies] -> ShowS) -> Show Dependencies forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Dependencies] -> ShowS $cshowList :: [Dependencies] -> ShowS show :: Dependencies -> String $cshow :: Dependencies -> String showsPrec :: Int -> Dependencies -> ShowS $cshowsPrec :: Int -> Dependencies -> ShowS Show, b -> Dependencies -> Dependencies NonEmpty Dependencies -> Dependencies Dependencies -> Dependencies -> Dependencies (Dependencies -> Dependencies -> Dependencies) -> (NonEmpty Dependencies -> Dependencies) -> (forall b. Integral b => b -> Dependencies -> Dependencies) -> Semigroup Dependencies forall b. Integral b => b -> Dependencies -> Dependencies forall a. (a -> a -> a) -> (NonEmpty a -> a) -> (forall b. Integral b => b -> a -> a) -> Semigroup a stimes :: b -> Dependencies -> Dependencies $cstimes :: forall b. Integral b => b -> Dependencies -> Dependencies sconcat :: NonEmpty Dependencies -> Dependencies $csconcat :: NonEmpty Dependencies -> Dependencies <> :: Dependencies -> Dependencies -> Dependencies $c<> :: Dependencies -> Dependencies -> Dependencies Semigroup, Semigroup Dependencies Dependencies Semigroup Dependencies => Dependencies -> (Dependencies -> Dependencies -> Dependencies) -> ([Dependencies] -> Dependencies) -> Monoid Dependencies [Dependencies] -> Dependencies Dependencies -> Dependencies -> Dependencies forall a. Semigroup a => a -> (a -> a -> a) -> ([a] -> a) -> Monoid a mconcat :: [Dependencies] -> Dependencies $cmconcat :: [Dependencies] -> Dependencies mappend :: Dependencies -> Dependencies -> Dependencies $cmappend :: Dependencies -> Dependencies -> Dependencies mempty :: Dependencies $cmempty :: Dependencies $cp1Monoid :: Semigroup Dependencies Monoid) instance IsList Dependencies where type Item Dependencies = (String, DependencyInfo) fromList :: [Item Dependencies] -> Dependencies fromList = Map String DependencyInfo -> Dependencies Dependencies (Map String DependencyInfo -> Dependencies) -> ([(String, DependencyInfo)] -> Map String DependencyInfo) -> [(String, DependencyInfo)] -> Dependencies forall b c a. (b -> c) -> (a -> b) -> a -> c . [(String, DependencyInfo)] -> Map String DependencyInfo forall k a. Ord k => [(k, a)] -> Map k a Map.fromList toList :: Dependencies -> [Item Dependencies] toList = Map String DependencyInfo -> [(String, DependencyInfo)] forall k a. Map k a -> [(k, a)] Map.toList (Map String DependencyInfo -> [(String, DependencyInfo)]) -> (Dependencies -> Map String DependencyInfo) -> Dependencies -> [(String, DependencyInfo)] forall b c a. (b -> c) -> (a -> b) -> a -> c . Dependencies -> Map String DependencyInfo unDependencies instance FromValue Dependencies where fromValue :: Value -> Parser Dependencies fromValue = ([(String, DependencyInfo)] -> Dependencies) -> Parser [(String, DependencyInfo)] -> Parser Dependencies forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Map String DependencyInfo -> Dependencies Dependencies (Map String DependencyInfo -> Dependencies) -> ([(String, DependencyInfo)] -> Map String DependencyInfo) -> [(String, DependencyInfo)] -> Dependencies forall b c a. (b -> c) -> (a -> b) -> a -> c . [(String, DependencyInfo)] -> Map String DependencyInfo forall k a. Ord k => [(k, a)] -> Map k a Map.fromList) (Parser [(String, DependencyInfo)] -> Parser Dependencies) -> (Value -> Parser [(String, DependencyInfo)]) -> Value -> Parser Dependencies forall b c a. (b -> c) -> (a -> b) -> a -> c . Parse String DependencyInfo -> Value -> Parser [(String, DependencyInfo)] forall k v. Parse k v -> Value -> Parser [(k, v)] parseDependencies Parse String DependencyInfo parse where parse :: Parse String DependencyInfo parse :: Parse String DependencyInfo parse = Parse :: forall k v. (Text -> Parser (k, v)) -> (Object -> Parser v) -> (Value -> Parser v) -> (Text -> k) -> Parse k v Parse { parseString :: Text -> Parser (String, DependencyInfo) parseString = \ input :: Text input -> do (name :: String name, version :: DependencyVersion version) <- String -> Text -> Parser (String, DependencyVersion) forall (m :: * -> *). MonadFail m => String -> Text -> m (String, DependencyVersion) parseDependency "dependency" Text input (String, DependencyInfo) -> Parser (String, DependencyInfo) forall (m :: * -> *) a. Monad m => a -> m a return (String name, [String] -> DependencyVersion -> DependencyInfo DependencyInfo [] DependencyVersion version) , parseListItem :: Object -> Parser DependencyInfo parseListItem = Object -> Parser DependencyInfo objectDependencyInfo , parseDictItem :: Value -> Parser DependencyInfo parseDictItem = Value -> Parser DependencyInfo dependencyInfo , parseName :: Text -> String parseName = Text -> String T.unpack } data DependencyInfo = DependencyInfo { DependencyInfo -> [String] dependencyInfoMixins :: [String] , DependencyInfo -> DependencyVersion dependencyInfoVersion :: DependencyVersion } deriving (DependencyInfo -> DependencyInfo -> Bool (DependencyInfo -> DependencyInfo -> Bool) -> (DependencyInfo -> DependencyInfo -> Bool) -> Eq DependencyInfo forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: DependencyInfo -> DependencyInfo -> Bool $c/= :: DependencyInfo -> DependencyInfo -> Bool == :: DependencyInfo -> DependencyInfo -> Bool $c== :: DependencyInfo -> DependencyInfo -> Bool Eq, Int -> DependencyInfo -> ShowS [DependencyInfo] -> ShowS DependencyInfo -> String (Int -> DependencyInfo -> ShowS) -> (DependencyInfo -> String) -> ([DependencyInfo] -> ShowS) -> Show DependencyInfo forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [DependencyInfo] -> ShowS $cshowList :: [DependencyInfo] -> ShowS show :: DependencyInfo -> String $cshow :: DependencyInfo -> String showsPrec :: Int -> DependencyInfo -> ShowS $cshowsPrec :: Int -> DependencyInfo -> ShowS Show) addMixins :: Object -> DependencyVersion -> Parser DependencyInfo addMixins :: Object -> DependencyVersion -> Parser DependencyInfo addMixins o :: Object o version :: DependencyVersion version = do Maybe (List String) mixinsMay <- Object o Object -> Text -> Parser (Maybe (List String)) forall a. FromValue a => Object -> Text -> Parser (Maybe a) .:? "mixin" DependencyInfo -> Parser DependencyInfo forall (m :: * -> *) a. Monad m => a -> m a return (DependencyInfo -> Parser DependencyInfo) -> DependencyInfo -> Parser DependencyInfo forall a b. (a -> b) -> a -> b $ [String] -> DependencyVersion -> DependencyInfo DependencyInfo (Maybe (List String) -> [String] forall a. Maybe (List a) -> [a] fromMaybeList Maybe (List String) mixinsMay) DependencyVersion version objectDependencyInfo :: Object -> Parser DependencyInfo objectDependencyInfo :: Object -> Parser DependencyInfo objectDependencyInfo o :: Object o = Object -> Parser DependencyVersion objectDependency Object o Parser DependencyVersion -> (DependencyVersion -> Parser DependencyInfo) -> Parser DependencyInfo forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= Object -> DependencyVersion -> Parser DependencyInfo addMixins Object o dependencyInfo :: Value -> Parser DependencyInfo dependencyInfo :: Value -> Parser DependencyInfo dependencyInfo = (DependencyVersion -> DependencyInfo) -> (Object -> DependencyVersion -> Parser DependencyInfo) -> Value -> Parser DependencyInfo forall a. (DependencyVersion -> a) -> (Object -> DependencyVersion -> Parser a) -> Value -> Parser a withDependencyVersion ([String] -> DependencyVersion -> DependencyInfo DependencyInfo []) Object -> DependencyVersion -> Parser DependencyInfo addMixins parseDependency :: Fail.MonadFail m => String -> Text -> m (String, DependencyVersion) parseDependency :: String -> Text -> m (String, DependencyVersion) parseDependency subject :: String subject = (Dependency -> (String, DependencyVersion)) -> m Dependency -> m (String, DependencyVersion) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Dependency -> (String, DependencyVersion) fromCabal (m Dependency -> m (String, DependencyVersion)) -> (Text -> m Dependency) -> Text -> m (String, DependencyVersion) forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> String -> m Dependency forall (m :: * -> *) a. (MonadFail m, Parsec a) => String -> String -> m a cabalParse String subject (String -> m Dependency) -> (Text -> String) -> Text -> m Dependency forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> String T.unpack where fromCabal :: D.Dependency -> (String, DependencyVersion) fromCabal :: Dependency -> (String, DependencyVersion) fromCabal d :: Dependency d = (PackageName -> String D.unPackageName (PackageName -> String) -> PackageName -> String forall a b. (a -> b) -> a -> b $ Dependency -> PackageName D.depPkgName Dependency d, Maybe SourceDependency -> VersionConstraint -> DependencyVersion DependencyVersion Maybe SourceDependency forall a. Maybe a Nothing (VersionConstraint -> DependencyVersion) -> (VersionRange -> VersionConstraint) -> VersionRange -> DependencyVersion forall b c a. (b -> c) -> (a -> b) -> a -> c . VersionRange -> VersionConstraint versionConstraintFromCabal (VersionRange -> DependencyVersion) -> VersionRange -> DependencyVersion forall a b. (a -> b) -> a -> b $ Dependency -> VersionRange D.depVerRange Dependency d)