{-# LANGUAGE Safe #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Data.Version (
Version(..),
showVersion, parseVersion,
makeVersion
) where
import Data.Functor ( Functor(..) )
import Control.Applicative ( Applicative(..) )
import Data.Bool ( (&&) )
import Data.Char ( isDigit, isAlphaNum )
import Data.Eq
import Data.Int ( Int )
import Data.List ( map, sort, concat, concatMap, intersperse, (++) )
import Data.Ord
import Data.String ( String )
import GHC.Generics
import GHC.Read
import GHC.Show
import Text.ParserCombinators.ReadP
import Text.Read ( read )
data Version =
Version { Version -> [Int]
versionBranch :: [Int],
Version -> [String]
versionTags :: [String]
}
deriving ( ReadPrec [Version]
ReadPrec Version
Int -> ReadS Version
ReadS [Version]
(Int -> ReadS Version)
-> ReadS [Version]
-> ReadPrec Version
-> ReadPrec [Version]
-> Read Version
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Version]
$creadListPrec :: ReadPrec [Version]
readPrec :: ReadPrec Version
$creadPrec :: ReadPrec Version
readList :: ReadS [Version]
$creadList :: ReadS [Version]
readsPrec :: Int -> ReadS Version
$creadsPrec :: Int -> ReadS Version
Read
, 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
showList :: [Version] -> ShowS
$cshowList :: [Version] -> ShowS
show :: Version -> String
$cshow :: Version -> String
showsPrec :: Int -> Version -> ShowS
$cshowsPrec :: Int -> Version -> ShowS
Show
, (forall x. Version -> Rep Version x)
-> (forall x. Rep Version x -> Version) -> Generic Version
forall x. Rep Version x -> Version
forall x. Version -> Rep Version x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Version x -> Version
$cfrom :: forall x. Version -> Rep Version x
Generic
)
{-# DEPRECATED versionTags "See GHC ticket #2496" #-}
instance Eq Version where
Version
v1 == :: Version -> Version -> Bool
== Version
v2 = Version -> [Int]
versionBranch Version
v1 [Int] -> [Int] -> Bool
forall a. Eq a => a -> a -> Bool
== Version -> [Int]
versionBranch Version
v2
Bool -> Bool -> Bool
&& [String] -> [String]
forall a. Ord a => [a] -> [a]
sort (Version -> [String]
versionTags Version
v1) [String] -> [String] -> Bool
forall a. Eq a => a -> a -> Bool
== [String] -> [String]
forall a. Ord a => [a] -> [a]
sort (Version -> [String]
versionTags Version
v2)
instance Ord Version where
Version
v1 compare :: Version -> Version -> Ordering
`compare` Version
v2 = Version -> [Int]
versionBranch Version
v1 [Int] -> [Int] -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Version -> [Int]
versionBranch Version
v2
showVersion :: Version -> String
showVersion :: Version -> String
showVersion (Version [Int]
branch [String]
tags)
= [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse String
"." ((Int -> String) -> [Int] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Int -> String
forall a. Show a => a -> String
show [Int]
branch)) String -> ShowS
forall a. [a] -> [a] -> [a]
++
ShowS -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Char
'-'Char -> ShowS
forall a. a -> [a] -> [a]
:) [String]
tags
parseVersion :: ReadP Version
parseVersion :: ReadP Version
parseVersion = do [Int]
branch <- ReadP Int -> ReadP Char -> ReadP [Int]
forall a sep. ReadP a -> ReadP sep -> ReadP [a]
sepBy1 ((String -> Int) -> ReadP String -> ReadP Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Int
forall a. Read a => String -> a
read ((Char -> Bool) -> ReadP String
munch1 Char -> Bool
isDigit)) (Char -> ReadP Char
char Char
'.')
[String]
tags <- ReadP String -> ReadP [String]
forall a. ReadP a -> ReadP [a]
many (Char -> ReadP Char
char Char
'-' ReadP Char -> ReadP String -> ReadP String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> ReadP String
munch1 Char -> Bool
isAlphaNum)
Version -> ReadP Version
forall (f :: * -> *) a. Applicative f => a -> f a
pure Version{versionBranch :: [Int]
versionBranch=[Int]
branch, versionTags :: [String]
versionTags=[String]
tags}
makeVersion :: [Int] -> Version
makeVersion :: [Int] -> Version
makeVersion [Int]
b = [Int] -> [String] -> Version
Version [Int]
b []