{-# LANGUAGE FlexibleInstances #-}

module CabalGild.Unstable.Type.VersionRange where

import qualified CabalGild.Unstable.Extra.CharParsing as Parse
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Set as Set
import qualified Distribution.Compat.CharParsing as Parse
import qualified Distribution.Parsec as Parsec
import qualified Distribution.Pretty as Pretty
import qualified Numeric.Natural as Natural
import qualified Text.PrettyPrint as PrettyPrint
import qualified Text.Read as Read

data Part
  = Numeric Natural.Natural
  | Wildcard
  deriving (Part -> Part -> Bool
(Part -> Part -> Bool) -> (Part -> Part -> Bool) -> Eq Part
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Part -> Part -> Bool
== :: Part -> Part -> Bool
$c/= :: Part -> Part -> Bool
/= :: Part -> Part -> Bool
Eq, Eq Part
Eq Part =>
(Part -> Part -> Ordering)
-> (Part -> Part -> Bool)
-> (Part -> Part -> Bool)
-> (Part -> Part -> Bool)
-> (Part -> Part -> Bool)
-> (Part -> Part -> Part)
-> (Part -> Part -> Part)
-> Ord Part
Part -> Part -> Bool
Part -> Part -> Ordering
Part -> Part -> Part
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Part -> Part -> Ordering
compare :: Part -> Part -> Ordering
$c< :: Part -> Part -> Bool
< :: Part -> Part -> Bool
$c<= :: Part -> Part -> Bool
<= :: Part -> Part -> Bool
$c> :: Part -> Part -> Bool
> :: Part -> Part -> Bool
$c>= :: Part -> Part -> Bool
>= :: Part -> Part -> Bool
$cmax :: Part -> Part -> Part
max :: Part -> Part -> Part
$cmin :: Part -> Part -> Part
min :: Part -> Part -> Part
Ord, Int -> Part -> ShowS
[Part] -> ShowS
Part -> String
(Int -> Part -> ShowS)
-> (Part -> String) -> ([Part] -> ShowS) -> Show Part
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Part -> ShowS
showsPrec :: Int -> Part -> ShowS
$cshow :: Part -> String
show :: Part -> String
$cshowList :: [Part] -> ShowS
showList :: [Part] -> ShowS
Show)

parseNumeric :: (Parsec.CabalParsing m) => m Natural.Natural
parseNumeric :: forall (m :: * -> *). CabalParsing m => m Natural
parseNumeric =
  [m Natural] -> m Natural
forall (m :: * -> *) a. Alternative m => [m a] -> m a
Parse.choice
    [ m Natural
forall (m :: * -> *). CabalParsing m => m Natural
parseZero,
      m Natural
forall (m :: * -> *). CabalParsing m => m Natural
parseNonZero
    ]

parseZero :: (Parsec.CabalParsing m) => m Natural.Natural
parseZero :: forall (m :: * -> *). CabalParsing m => m Natural
parseZero = Natural
0 Natural -> m () -> m Natural
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"0"

parseNonZero :: (Parsec.CabalParsing m) => m Natural.Natural
parseNonZero :: forall (m :: * -> *). CabalParsing m => m Natural
parseNonZero = do
  Char
c <- (Char -> Bool) -> m Char
forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m Char
Parse.satisfy ((Char -> Bool) -> m Char) -> (Char -> Bool) -> m Char
forall a b. (a -> b) -> a -> b
$ \Char
c -> Char
'1' Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9'
  String
cs <- m Char -> m String
forall a. m a -> m [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
Parse.many m Char
forall (m :: * -> *). CharParsing m => m Char
Parse.digit
  let s :: String
s = Char
c Char -> ShowS
forall a. a -> [a] -> [a]
: String
cs
  case String -> Maybe Natural
forall a. Read a => String -> Maybe a
Read.readMaybe String
s of
    Maybe Natural
Nothing -> String -> m Natural
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> m Natural) -> String -> m Natural
forall a b. (a -> b) -> a -> b
$ String
"invalid Natural: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ShowS
forall a. Show a => a -> String
show String
s
    Just Natural
n -> Natural
n Natural -> m () -> m Natural
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ m ()
forall (m :: * -> *). CharParsing m => m ()
Parse.spaces

renderNumeric :: Natural.Natural -> PrettyPrint.Doc
renderNumeric :: Natural -> Doc
renderNumeric = String -> Doc
PrettyPrint.text (String -> Doc) -> (Natural -> String) -> Natural -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> String
forall a. Show a => a -> String
show

parseWildcard :: (Parsec.CabalParsing m) => m ()
parseWildcard :: forall (m :: * -> *). CabalParsing m => m ()
parseWildcard = String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"*"

renderWildcard :: PrettyPrint.Doc
renderWildcard :: Doc
renderWildcard = Char -> Doc
PrettyPrint.char Char
'*'

parsePart :: (Parsec.CabalParsing m) => m Part
parsePart :: forall (m :: * -> *). CabalParsing m => m Part
parsePart =
  [m Part] -> m Part
forall (m :: * -> *) a. Alternative m => [m a] -> m a
Parse.choice
    [ Natural -> Part
Numeric (Natural -> Part) -> m Natural -> m Part
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Natural
forall (m :: * -> *). CabalParsing m => m Natural
parseNumeric,
      Part
Wildcard Part -> m () -> m Part
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ m ()
forall (m :: * -> *). CabalParsing m => m ()
parseWildcard
    ]

renderPart :: Part -> PrettyPrint.Doc
renderPart :: Part -> Doc
renderPart Part
x =
  case Part
x of
    Numeric Natural
n -> Natural -> Doc
renderNumeric Natural
n
    Part
Wildcard -> Doc
renderWildcard

newtype Version
  = MkVersion (NonEmpty.NonEmpty Part)
  deriving (Version -> Version -> Bool
(Version -> Version -> Bool)
-> (Version -> Version -> Bool) -> Eq Version
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Version -> Version -> Bool
== :: Version -> Version -> Bool
$c/= :: Version -> Version -> Bool
/= :: Version -> Version -> Bool
Eq, Eq Version
Eq Version =>
(Version -> Version -> Ordering)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Version)
-> (Version -> Version -> Version)
-> Ord Version
Version -> Version -> Bool
Version -> Version -> Ordering
Version -> Version -> Version
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Version -> Version -> Ordering
compare :: Version -> Version -> Ordering
$c< :: Version -> Version -> Bool
< :: Version -> Version -> Bool
$c<= :: Version -> Version -> Bool
<= :: Version -> Version -> Bool
$c> :: Version -> Version -> Bool
> :: Version -> Version -> Bool
$c>= :: Version -> Version -> Bool
>= :: Version -> Version -> Bool
$cmax :: Version -> Version -> Version
max :: Version -> Version -> Version
$cmin :: Version -> Version -> Version
min :: Version -> Version -> Version
Ord, Int -> Version -> ShowS
[Version] -> ShowS
Version -> String
(Int -> Version -> ShowS)
-> (Version -> String) -> ([Version] -> ShowS) -> Show Version
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Version -> ShowS
showsPrec :: Int -> Version -> ShowS
$cshow :: Version -> String
show :: Version -> String
$cshowList :: [Version] -> ShowS
showList :: [Version] -> ShowS
Show)

parseVersion :: (Parsec.CabalParsing m) => m Version
parseVersion :: forall (m :: * -> *). CabalParsing m => m Version
parseVersion =
  NonEmpty Part -> Version
MkVersion
    (NonEmpty Part -> Version) -> m (NonEmpty Part) -> m Version
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Part -> m Char -> m (NonEmpty Part)
forall (m :: * -> *) a sep.
Alternative m =>
m a -> m sep -> m (NonEmpty a)
Parse.sepByNonEmpty m Part
forall (m :: * -> *). CabalParsing m => m Part
parsePart (Char -> m Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Parse.char Char
'.')
    m Version -> m () -> m Version
forall a b. m a -> m b -> m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* m ()
forall (m :: * -> *). CharParsing m => m ()
Parse.spaces

renderVersion :: Version -> PrettyPrint.Doc
renderVersion :: Version -> Doc
renderVersion (MkVersion NonEmpty Part
parts) =
  [Doc] -> Doc
forall a. Monoid a => [a] -> a
mconcat
    ([Doc] -> Doc) -> ([Part] -> [Doc]) -> [Part] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> [Doc] -> [Doc]
PrettyPrint.punctuate (Char -> Doc
PrettyPrint.char Char
'.')
    ([Doc] -> [Doc]) -> ([Part] -> [Doc]) -> [Part] -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Part -> Doc) -> [Part] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Part -> Doc
renderPart
    ([Part] -> Doc) -> [Part] -> Doc
forall a b. (a -> b) -> a -> b
$ NonEmpty Part -> [Part]
forall a. NonEmpty a -> [a]
NonEmpty.toList NonEmpty Part
parts

data Versions
  = One Version
  | Set (Set.Set Version)
  deriving (Versions -> Versions -> Bool
(Versions -> Versions -> Bool)
-> (Versions -> Versions -> Bool) -> Eq Versions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Versions -> Versions -> Bool
== :: Versions -> Versions -> Bool
$c/= :: Versions -> Versions -> Bool
/= :: Versions -> Versions -> Bool
Eq, Eq Versions
Eq Versions =>
(Versions -> Versions -> Ordering)
-> (Versions -> Versions -> Bool)
-> (Versions -> Versions -> Bool)
-> (Versions -> Versions -> Bool)
-> (Versions -> Versions -> Bool)
-> (Versions -> Versions -> Versions)
-> (Versions -> Versions -> Versions)
-> Ord Versions
Versions -> Versions -> Bool
Versions -> Versions -> Ordering
Versions -> Versions -> Versions
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Versions -> Versions -> Ordering
compare :: Versions -> Versions -> Ordering
$c< :: Versions -> Versions -> Bool
< :: Versions -> Versions -> Bool
$c<= :: Versions -> Versions -> Bool
<= :: Versions -> Versions -> Bool
$c> :: Versions -> Versions -> Bool
> :: Versions -> Versions -> Bool
$c>= :: Versions -> Versions -> Bool
>= :: Versions -> Versions -> Bool
$cmax :: Versions -> Versions -> Versions
max :: Versions -> Versions -> Versions
$cmin :: Versions -> Versions -> Versions
min :: Versions -> Versions -> Versions
Ord, Int -> Versions -> ShowS
[Versions] -> ShowS
Versions -> String
(Int -> Versions -> ShowS)
-> (Versions -> String) -> ([Versions] -> ShowS) -> Show Versions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Versions -> ShowS
showsPrec :: Int -> Versions -> ShowS
$cshow :: Versions -> String
show :: Versions -> String
$cshowList :: [Versions] -> ShowS
showList :: [Versions] -> ShowS
Show)

parseVersions :: (Parsec.CabalParsing m) => m Versions
parseVersions :: forall (m :: * -> *). CabalParsing m => m Versions
parseVersions =
  [m Versions] -> m Versions
forall (m :: * -> *) a. Alternative m => [m a] -> m a
Parse.choice
    [ Version -> Versions
One (Version -> Versions) -> m Version -> m Versions
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Version
forall (m :: * -> *). CabalParsing m => m Version
parseVersion,
      Set Version -> Versions
Set (Set Version -> Versions)
-> ([Version] -> Set Version) -> [Version] -> Versions
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Version] -> Set Version
forall a. Ord a => [a] -> Set a
Set.fromList ([Version] -> Versions) -> m [Version] -> m Versions
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m [Version] -> m [Version]
forall (m :: * -> *) a. CabalParsing m => m a -> m a
Parse.braces (m Version -> m () -> m [Version]
forall (m :: * -> *) a sep. Alternative m => m a -> m sep -> m [a]
Parse.sepBy m Version
forall (m :: * -> *). CabalParsing m => m Version
parseVersion (m () -> m [Version]) -> m () -> m [Version]
forall a b. (a -> b) -> a -> b
$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
",")
    ]

renderVersions :: Versions -> PrettyPrint.Doc
renderVersions :: Versions -> Doc
renderVersions Versions
x =
  case Versions
x of
    One Version
v -> Version -> Doc
renderVersion Version
v
    Set Set Version
vs ->
      Doc -> Doc
PrettyPrint.braces
        (Doc -> Doc) -> ([Version] -> Doc) -> [Version] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc] -> Doc
PrettyPrint.hsep
        ([Doc] -> Doc) -> ([Version] -> [Doc]) -> [Version] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> [Doc] -> [Doc]
PrettyPrint.punctuate Doc
PrettyPrint.comma
        ([Doc] -> [Doc]) -> ([Version] -> [Doc]) -> [Version] -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Version -> Doc) -> [Version] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Version -> Doc
renderVersion
        ([Version] -> Doc) -> [Version] -> Doc
forall a b. (a -> b) -> a -> b
$ Set Version -> [Version]
forall a. Set a -> [a]
Set.toAscList Set Version
vs

data Operator
  = Caret
  | Ge
  | Gt
  | Le
  | Lt
  | Eq
  deriving (Operator -> Operator -> Bool
(Operator -> Operator -> Bool)
-> (Operator -> Operator -> Bool) -> Eq Operator
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Operator -> Operator -> Bool
== :: Operator -> Operator -> Bool
$c/= :: Operator -> Operator -> Bool
/= :: Operator -> Operator -> Bool
Eq, Eq Operator
Eq Operator =>
(Operator -> Operator -> Ordering)
-> (Operator -> Operator -> Bool)
-> (Operator -> Operator -> Bool)
-> (Operator -> Operator -> Bool)
-> (Operator -> Operator -> Bool)
-> (Operator -> Operator -> Operator)
-> (Operator -> Operator -> Operator)
-> Ord Operator
Operator -> Operator -> Bool
Operator -> Operator -> Ordering
Operator -> Operator -> Operator
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Operator -> Operator -> Ordering
compare :: Operator -> Operator -> Ordering
$c< :: Operator -> Operator -> Bool
< :: Operator -> Operator -> Bool
$c<= :: Operator -> Operator -> Bool
<= :: Operator -> Operator -> Bool
$c> :: Operator -> Operator -> Bool
> :: Operator -> Operator -> Bool
$c>= :: Operator -> Operator -> Bool
>= :: Operator -> Operator -> Bool
$cmax :: Operator -> Operator -> Operator
max :: Operator -> Operator -> Operator
$cmin :: Operator -> Operator -> Operator
min :: Operator -> Operator -> Operator
Ord, Int -> Operator -> ShowS
[Operator] -> ShowS
Operator -> String
(Int -> Operator -> ShowS)
-> (Operator -> String) -> ([Operator] -> ShowS) -> Show Operator
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Operator -> ShowS
showsPrec :: Int -> Operator -> ShowS
$cshow :: Operator -> String
show :: Operator -> String
$cshowList :: [Operator] -> ShowS
showList :: [Operator] -> ShowS
Show)

parseOperator :: (Parsec.CabalParsing m) => m Operator
parseOperator :: forall (m :: * -> *). CabalParsing m => m Operator
parseOperator =
  [m Operator] -> m Operator
forall (m :: * -> *) a. Alternative m => [m a] -> m a
Parse.choice
    [ Operator
Caret Operator -> m () -> m Operator
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"^>=",
      m Operator -> m Operator
forall a. m a -> m a
forall (m :: * -> *) a. Parsing m => m a -> m a
Parse.try (m Operator -> m Operator) -> m Operator -> m Operator
forall a b. (a -> b) -> a -> b
$ Operator
Ge Operator -> m () -> m Operator
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
">=",
      Operator
Gt Operator -> m () -> m Operator
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
">",
      m Operator -> m Operator
forall a. m a -> m a
forall (m :: * -> *) a. Parsing m => m a -> m a
Parse.try (m Operator -> m Operator) -> m Operator -> m Operator
forall a b. (a -> b) -> a -> b
$ Operator
Le Operator -> m () -> m Operator
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"<=",
      Operator
Lt Operator -> m () -> m Operator
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"<",
      Operator
Eq Operator -> m () -> m Operator
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"=="
    ]

renderOperator :: Operator -> PrettyPrint.Doc
renderOperator :: Operator -> Doc
renderOperator Operator
x =
  case Operator
x of
    Operator
Caret -> String -> Doc
PrettyPrint.text String
"^>="
    Operator
Ge -> String -> Doc
PrettyPrint.text String
">="
    Operator
Gt -> Char -> Doc
PrettyPrint.char Char
'>'
    Operator
Le -> String -> Doc
PrettyPrint.text String
"<="
    Operator
Lt -> Char -> Doc
PrettyPrint.char Char
'<'
    Operator
Eq -> String -> Doc
PrettyPrint.text String
"=="

data Simple
  = Any
  | None
  | Op Operator Versions
  deriving (Simple -> Simple -> Bool
(Simple -> Simple -> Bool)
-> (Simple -> Simple -> Bool) -> Eq Simple
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Simple -> Simple -> Bool
== :: Simple -> Simple -> Bool
$c/= :: Simple -> Simple -> Bool
/= :: Simple -> Simple -> Bool
Eq, Eq Simple
Eq Simple =>
(Simple -> Simple -> Ordering)
-> (Simple -> Simple -> Bool)
-> (Simple -> Simple -> Bool)
-> (Simple -> Simple -> Bool)
-> (Simple -> Simple -> Bool)
-> (Simple -> Simple -> Simple)
-> (Simple -> Simple -> Simple)
-> Ord Simple
Simple -> Simple -> Bool
Simple -> Simple -> Ordering
Simple -> Simple -> Simple
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Simple -> Simple -> Ordering
compare :: Simple -> Simple -> Ordering
$c< :: Simple -> Simple -> Bool
< :: Simple -> Simple -> Bool
$c<= :: Simple -> Simple -> Bool
<= :: Simple -> Simple -> Bool
$c> :: Simple -> Simple -> Bool
> :: Simple -> Simple -> Bool
$c>= :: Simple -> Simple -> Bool
>= :: Simple -> Simple -> Bool
$cmax :: Simple -> Simple -> Simple
max :: Simple -> Simple -> Simple
$cmin :: Simple -> Simple -> Simple
min :: Simple -> Simple -> Simple
Ord, Int -> Simple -> ShowS
[Simple] -> ShowS
Simple -> String
(Int -> Simple -> ShowS)
-> (Simple -> String) -> ([Simple] -> ShowS) -> Show Simple
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Simple -> ShowS
showsPrec :: Int -> Simple -> ShowS
$cshow :: Simple -> String
show :: Simple -> String
$cshowList :: [Simple] -> ShowS
showList :: [Simple] -> ShowS
Show)

parseSimple :: (Parsec.CabalParsing m) => m Simple
parseSimple :: forall (m :: * -> *). CabalParsing m => m Simple
parseSimple =
  [m Simple] -> m Simple
forall (m :: * -> *) a. Alternative m => [m a] -> m a
Parse.choice
    [ m Simple -> m Simple
forall a. m a -> m a
forall (m :: * -> *) a. Parsing m => m a -> m a
Parse.try (m Simple -> m Simple) -> m Simple -> m Simple
forall a b. (a -> b) -> a -> b
$ Simple
Any Simple -> m () -> m Simple
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"-any",
      Simple
None Simple -> m () -> m Simple
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"-none",
      Operator -> Versions -> Simple
Op (Operator -> Versions -> Simple)
-> m Operator -> m (Versions -> Simple)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Operator
forall (m :: * -> *). CabalParsing m => m Operator
parseOperator m (Versions -> Simple) -> m Versions -> m Simple
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m Versions
forall (m :: * -> *). CabalParsing m => m Versions
parseVersions
    ]

renderSimple :: Simple -> PrettyPrint.Doc
renderSimple :: Simple -> Doc
renderSimple Simple
x =
  case Simple
x of
    Simple
Any -> String -> Doc
PrettyPrint.text String
"-any"
    Simple
None -> String -> Doc
PrettyPrint.text String
"-none"
    Op Operator
o Versions
vs -> Operator -> Doc
renderOperator Operator
o Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Versions -> Doc
renderVersions Versions
vs

data Complex a
  = Par (Complex a)
  | And a (Complex a)
  | Or a (Complex a)
  | Simple a
  deriving (Complex a -> Complex a -> Bool
(Complex a -> Complex a -> Bool)
-> (Complex a -> Complex a -> Bool) -> Eq (Complex a)
forall a. Eq a => Complex a -> Complex a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Complex a -> Complex a -> Bool
== :: Complex a -> Complex a -> Bool
$c/= :: forall a. Eq a => Complex a -> Complex a -> Bool
/= :: Complex a -> Complex a -> Bool
Eq, Eq (Complex a)
Eq (Complex a) =>
(Complex a -> Complex a -> Ordering)
-> (Complex a -> Complex a -> Bool)
-> (Complex a -> Complex a -> Bool)
-> (Complex a -> Complex a -> Bool)
-> (Complex a -> Complex a -> Bool)
-> (Complex a -> Complex a -> Complex a)
-> (Complex a -> Complex a -> Complex a)
-> Ord (Complex a)
Complex a -> Complex a -> Bool
Complex a -> Complex a -> Ordering
Complex a -> Complex a -> Complex a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Complex a)
forall a. Ord a => Complex a -> Complex a -> Bool
forall a. Ord a => Complex a -> Complex a -> Ordering
forall a. Ord a => Complex a -> Complex a -> Complex a
$ccompare :: forall a. Ord a => Complex a -> Complex a -> Ordering
compare :: Complex a -> Complex a -> Ordering
$c< :: forall a. Ord a => Complex a -> Complex a -> Bool
< :: Complex a -> Complex a -> Bool
$c<= :: forall a. Ord a => Complex a -> Complex a -> Bool
<= :: Complex a -> Complex a -> Bool
$c> :: forall a. Ord a => Complex a -> Complex a -> Bool
> :: Complex a -> Complex a -> Bool
$c>= :: forall a. Ord a => Complex a -> Complex a -> Bool
>= :: Complex a -> Complex a -> Bool
$cmax :: forall a. Ord a => Complex a -> Complex a -> Complex a
max :: Complex a -> Complex a -> Complex a
$cmin :: forall a. Ord a => Complex a -> Complex a -> Complex a
min :: Complex a -> Complex a -> Complex a
Ord, Int -> Complex a -> ShowS
[Complex a] -> ShowS
Complex a -> String
(Int -> Complex a -> ShowS)
-> (Complex a -> String)
-> ([Complex a] -> ShowS)
-> Show (Complex a)
forall a. Show a => Int -> Complex a -> ShowS
forall a. Show a => [Complex a] -> ShowS
forall a. Show a => Complex a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Complex a -> ShowS
showsPrec :: Int -> Complex a -> ShowS
$cshow :: forall a. Show a => Complex a -> String
show :: Complex a -> String
$cshowList :: forall a. Show a => [Complex a] -> ShowS
showList :: [Complex a] -> ShowS
Show)

parseComplex :: (Parsec.CabalParsing m) => m a -> m (Complex a)
parseComplex :: forall (m :: * -> *) a. CabalParsing m => m a -> m (Complex a)
parseComplex m a
p =
  [m (Complex a)] -> m (Complex a)
forall (m :: * -> *) a. Alternative m => [m a] -> m a
Parse.choice
    [ Complex a -> Complex a
forall a. Complex a -> Complex a
Par (Complex a -> Complex a) -> m (Complex a) -> m (Complex a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (Complex a) -> m (Complex a)
forall (m :: * -> *) a. CabalParsing m => m a -> m a
Parse.parens (m a -> m (Complex a)
forall (m :: * -> *) a. CabalParsing m => m a -> m (Complex a)
parseComplex m a
p),
      m (Complex a) -> m (Complex a)
forall a. m a -> m a
forall (m :: * -> *) a. Parsing m => m a -> m a
Parse.try (m (Complex a) -> m (Complex a)) -> m (Complex a) -> m (Complex a)
forall a b. (a -> b) -> a -> b
$ a -> Complex a -> Complex a
forall a. a -> Complex a -> Complex a
And (a -> Complex a -> Complex a) -> m a -> m (Complex a -> Complex a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
p m (Complex a -> Complex a) -> m () -> m (Complex a -> Complex a)
forall a b. m a -> m b -> m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"&&" m (Complex a -> Complex a) -> m (Complex a) -> m (Complex a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a -> m (Complex a)
forall (m :: * -> *) a. CabalParsing m => m a -> m (Complex a)
parseComplex m a
p,
      m (Complex a) -> m (Complex a)
forall a. m a -> m a
forall (m :: * -> *) a. Parsing m => m a -> m a
Parse.try (m (Complex a) -> m (Complex a)) -> m (Complex a) -> m (Complex a)
forall a b. (a -> b) -> a -> b
$ a -> Complex a -> Complex a
forall a. a -> Complex a -> Complex a
Or (a -> Complex a -> Complex a) -> m a -> m (Complex a -> Complex a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
p m (Complex a -> Complex a) -> m () -> m (Complex a -> Complex a)
forall a b. m a -> m b -> m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> m ()
forall (m :: * -> *). CabalParsing m => String -> m ()
Parse.token String
"||" m (Complex a -> Complex a) -> m (Complex a) -> m (Complex a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a -> m (Complex a)
forall (m :: * -> *) a. CabalParsing m => m a -> m (Complex a)
parseComplex m a
p,
      a -> Complex a
forall a. a -> Complex a
Simple (a -> Complex a) -> m a -> m (Complex a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
p
    ]

renderComplex :: (a -> PrettyPrint.Doc) -> Complex a -> PrettyPrint.Doc
renderComplex :: forall a. (a -> Doc) -> Complex a -> Doc
renderComplex a -> Doc
f Complex a
x =
  case Complex a
x of
    Par Complex a
y -> Doc -> Doc
PrettyPrint.parens (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ (a -> Doc) -> Complex a -> Doc
forall a. (a -> Doc) -> Complex a -> Doc
renderComplex a -> Doc
f Complex a
y
    And a
l Complex a
r -> [Doc] -> Doc
PrettyPrint.hsep [a -> Doc
f a
l, String -> Doc
PrettyPrint.text String
"&&", (a -> Doc) -> Complex a -> Doc
forall a. (a -> Doc) -> Complex a -> Doc
renderComplex a -> Doc
f Complex a
r]
    Or a
l Complex a
r -> [Doc] -> Doc
PrettyPrint.hsep [a -> Doc
f a
l, String -> Doc
PrettyPrint.text String
"||", (a -> Doc) -> Complex a -> Doc
forall a. (a -> Doc) -> Complex a -> Doc
renderComplex a -> Doc
f Complex a
r]
    Simple a
y -> a -> Doc
f a
y

type VersionRange = Complex Simple

instance Parsec.Parsec VersionRange where
  parsec :: forall (m :: * -> *). CabalParsing m => m VersionRange
parsec = m Simple -> m VersionRange
forall (m :: * -> *) a. CabalParsing m => m a -> m (Complex a)
parseComplex m Simple
forall (m :: * -> *). CabalParsing m => m Simple
parseSimple

instance Pretty.Pretty VersionRange where
  pretty :: VersionRange -> Doc
pretty = (Simple -> Doc) -> VersionRange -> Doc
forall a. (a -> Doc) -> Complex a -> Doc
renderComplex Simple -> Doc
renderSimple