{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module CabalGild.Type.Set where
import qualified CabalGild.Extra.List as List
import qualified Data.Proxy as Proxy
import qualified Data.Set as Set
import qualified Distribution.CabalSpecVersion as CabalSpecVersion
import qualified Distribution.Compat.Newtype as Newtype
import qualified Distribution.FieldGrammar.Newtypes as Newtypes
import qualified Distribution.Parsec as Parsec
import qualified Distribution.Pretty as Pretty
import qualified Text.PrettyPrint as PrettyPrint
newtype Set s b a = Set
{ forall s b a. Set s b a -> Set' s b a
unwrap :: Newtypes.Set' s b a
}
instance Newtype.Newtype (Set.Set a) (Set s b a) where
pack :: Set a -> Set s b a
pack = Set' s b a -> Set s b a
forall s b a. Set' s b a -> Set s b a
Set (Set' s b a -> Set s b a)
-> (Set a -> Set' s b a) -> Set a -> Set s b a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set a -> Set' s b a
forall o n. Newtype o n => o -> n
Newtype.pack
unpack :: Set s b a -> Set a
unpack = Set' s b a -> Set a
forall o n. Newtype o n => n -> o
Newtype.unpack (Set' s b a -> Set a)
-> (Set s b a -> Set' s b a) -> Set s b a -> Set a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set s b a -> Set' s b a
forall s b a. Set s b a -> Set' s b a
unwrap
instance
( Newtype.Newtype a b,
Ord a,
Parsec.Parsec b,
Newtypes.Sep s
) =>
Parsec.Parsec (Set s b a)
where
parsec :: forall (m :: * -> *). CabalParsing m => m (Set s b a)
parsec = Set' s b a -> Set s b a
forall s b a. Set' s b a -> Set s b a
Set (Set' s b a -> Set s b a) -> m (Set' s b a) -> m (Set s b a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (Set' s b a)
forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
forall (m :: * -> *). CabalParsing m => m (Set' s b a)
Parsec.parsec
instance
( Newtype.Newtype a b,
Pretty.Pretty b,
Newtypes.Sep s
) =>
Pretty.Pretty (Set s b a)
where
pretty :: Set s b a -> Doc
pretty = CabalSpecVersion -> Set s b a -> Doc
forall a. Pretty a => CabalSpecVersion -> a -> Doc
Pretty.prettyVersioned CabalSpecVersion
CabalSpecVersion.CabalSpecV1_0
prettyVersioned :: CabalSpecVersion -> Set s b a -> Doc
prettyVersioned CabalSpecVersion
v =
Proxy s -> [Doc] -> Doc
forall sep. Sep sep => Proxy sep -> [Doc] -> Doc
Newtypes.prettySep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy.Proxy @s)
([Doc] -> Doc) -> (Set s b a -> [Doc]) -> Set s b a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc) -> [a] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Pretty a => CabalSpecVersion -> a -> Doc
Pretty.prettyVersioned @b CabalSpecVersion
v (b -> Doc) -> (a -> b) -> a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
forall o n. Newtype o n => o -> n
Newtype.pack)
([a] -> [Doc]) -> (Set s b a -> [a]) -> Set s b a -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set a -> [a]
forall a. Set a -> [a]
Set.toAscList
(Set a -> [a]) -> (Set s b a -> Set a) -> Set s b a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set s b a -> Set a
forall o n. Newtype o n => n -> o
Newtype.unpack
instance
{-# OVERLAPPING #-}
( Newtype.Newtype a b,
Pretty.Pretty b
) =>
Pretty.Pretty (Set Newtypes.CommaFSep b a)
where
pretty :: Set CommaFSep b a -> Doc
pretty = CabalSpecVersion -> Set CommaFSep b a -> Doc
forall a. Pretty a => CabalSpecVersion -> a -> Doc
Pretty.prettyVersioned CabalSpecVersion
CabalSpecVersion.CabalSpecV1_0
prettyVersioned :: CabalSpecVersion -> Set CommaFSep b a -> Doc
prettyVersioned CabalSpecVersion
v =
( \[Doc]
xs ->
if [Doc] -> Int -> Ordering
forall a. [a] -> Int -> Ordering
List.compareLength [Doc]
xs Int
1 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT Bool -> Bool -> Bool
&& CabalSpecVersion
v CabalSpecVersion -> CabalSpecVersion -> Bool
forall a. Ord a => a -> a -> Bool
>= CabalSpecVersion
CabalSpecVersion.CabalSpecV2_2
then [Doc] -> Doc
PrettyPrint.fsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (Doc -> Doc) -> [Doc] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
PrettyPrint.comma) [Doc]
xs
else Proxy CommaFSep -> [Doc] -> Doc
forall sep. Sep sep => Proxy sep -> [Doc] -> Doc
Newtypes.prettySep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy.Proxy @Newtypes.CommaFSep) [Doc]
xs
)
([Doc] -> Doc)
-> (Set CommaFSep b a -> [Doc]) -> Set CommaFSep b a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc) -> [a] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Pretty a => CabalSpecVersion -> a -> Doc
Pretty.prettyVersioned @b CabalSpecVersion
v (b -> Doc) -> (a -> b) -> a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
forall o n. Newtype o n => o -> n
Newtype.pack)
([a] -> [Doc])
-> (Set CommaFSep b a -> [a]) -> Set CommaFSep b a -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set a -> [a]
forall a. Set a -> [a]
Set.toAscList
(Set a -> [a])
-> (Set CommaFSep b a -> Set a) -> Set CommaFSep b a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set CommaFSep b a -> Set a
forall o n. Newtype o n => n -> o
Newtype.unpack
instance
{-# OVERLAPPING #-}
( Newtype.Newtype a b,
Pretty.Pretty b
) =>
Pretty.Pretty (Set Newtypes.CommaVCat b a)
where
pretty :: Set CommaVCat b a -> Doc
pretty = CabalSpecVersion -> Set CommaVCat b a -> Doc
forall a. Pretty a => CabalSpecVersion -> a -> Doc
Pretty.prettyVersioned CabalSpecVersion
CabalSpecVersion.CabalSpecV1_0
prettyVersioned :: CabalSpecVersion -> Set CommaVCat b a -> Doc
prettyVersioned CabalSpecVersion
v =
( \[Doc]
xs ->
if [Doc] -> Int -> Ordering
forall a. [a] -> Int -> Ordering
List.compareLength [Doc]
xs Int
1 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT Bool -> Bool -> Bool
&& CabalSpecVersion
v CabalSpecVersion -> CabalSpecVersion -> Bool
forall a. Ord a => a -> a -> Bool
>= CabalSpecVersion
CabalSpecVersion.CabalSpecV2_2
then [Doc] -> Doc
PrettyPrint.vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (Doc -> Doc) -> [Doc] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
PrettyPrint.comma) [Doc]
xs
else Proxy CommaVCat -> [Doc] -> Doc
forall sep. Sep sep => Proxy sep -> [Doc] -> Doc
Newtypes.prettySep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy.Proxy @Newtypes.CommaVCat) [Doc]
xs
)
([Doc] -> Doc)
-> (Set CommaVCat b a -> [Doc]) -> Set CommaVCat b a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc) -> [a] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Pretty a => CabalSpecVersion -> a -> Doc
Pretty.prettyVersioned @b CabalSpecVersion
v (b -> Doc) -> (a -> b) -> a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
forall o n. Newtype o n => o -> n
Newtype.pack)
([a] -> [Doc])
-> (Set CommaVCat b a -> [a]) -> Set CommaVCat b a -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set a -> [a]
forall a. Set a -> [a]
Set.toAscList
(Set a -> [a])
-> (Set CommaVCat b a -> Set a) -> Set CommaVCat b a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set CommaVCat b a -> Set a
forall o n. Newtype o n => n -> o
Newtype.unpack