module Ecluse.Core.Version.Semver (
SemverKey (..),
parseSemver,
isSemverStable,
) where
import Data.Char (isDigit)
import Data.Text qualified as T
import Data.Versions (SemVer (..))
import Data.Versions qualified as V
import Ecluse.Core.Version.Token (maxVersionLength)
newtype SemverKey = SemverKey SemVer
deriving stock (Int -> SemverKey -> ShowS
[SemverKey] -> ShowS
SemverKey -> String
(Int -> SemverKey -> ShowS)
-> (SemverKey -> String)
-> ([SemverKey] -> ShowS)
-> Show SemverKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SemverKey -> ShowS
showsPrec :: Int -> SemverKey -> ShowS
$cshow :: SemverKey -> String
show :: SemverKey -> String
$cshowList :: [SemverKey] -> ShowS
showList :: [SemverKey] -> ShowS
Show)
deriving newtype (SemverKey -> SemverKey -> Bool
(SemverKey -> SemverKey -> Bool)
-> (SemverKey -> SemverKey -> Bool) -> Eq SemverKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SemverKey -> SemverKey -> Bool
== :: SemverKey -> SemverKey -> Bool
$c/= :: SemverKey -> SemverKey -> Bool
/= :: SemverKey -> SemverKey -> Bool
Eq, Eq SemverKey
Eq SemverKey =>
(SemverKey -> SemverKey -> Ordering)
-> (SemverKey -> SemverKey -> Bool)
-> (SemverKey -> SemverKey -> Bool)
-> (SemverKey -> SemverKey -> Bool)
-> (SemverKey -> SemverKey -> Bool)
-> (SemverKey -> SemverKey -> SemverKey)
-> (SemverKey -> SemverKey -> SemverKey)
-> Ord SemverKey
SemverKey -> SemverKey -> Bool
SemverKey -> SemverKey -> Ordering
SemverKey -> SemverKey -> SemverKey
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 :: SemverKey -> SemverKey -> Ordering
compare :: SemverKey -> SemverKey -> Ordering
$c< :: SemverKey -> SemverKey -> Bool
< :: SemverKey -> SemverKey -> Bool
$c<= :: SemverKey -> SemverKey -> Bool
<= :: SemverKey -> SemverKey -> Bool
$c> :: SemverKey -> SemverKey -> Bool
> :: SemverKey -> SemverKey -> Bool
$c>= :: SemverKey -> SemverKey -> Bool
>= :: SemverKey -> SemverKey -> Bool
$cmax :: SemverKey -> SemverKey -> SemverKey
max :: SemverKey -> SemverKey -> SemverKey
$cmin :: SemverKey -> SemverKey -> SemverKey
min :: SemverKey -> SemverKey -> SemverKey
Ord)
parseSemver :: Text -> Maybe SemverKey
parseSemver :: Text -> Maybe SemverKey
parseSemver Text
raw = do
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Text -> Int -> Ordering
T.compareLength Text
raw Int
maxVersionLength Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
GT)
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not (Text -> Bool
hasOverlongNumericRun Text
raw))
SemVer -> SemverKey
SemverKey (SemVer -> SemverKey) -> Maybe SemVer -> Maybe SemverKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either ParsingError SemVer -> Maybe SemVer
forall l r. Either l r -> Maybe r
rightToMaybe (Text -> Either ParsingError SemVer
V.semver Text
raw)
maxNumericRun :: Int
maxNumericRun :: Int
maxNumericRun = Int
18
hasOverlongNumericRun :: Text -> Bool
hasOverlongNumericRun :: Text -> Bool
hasOverlongNumericRun = (Text -> Bool) -> [Text] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Text -> Bool
overlong ([Text] -> Bool) -> (Text -> [Text]) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char -> Bool) -> Text -> [Text]
T.groupBy Char -> Char -> Bool
sameClass
where
sameClass :: Char -> Char -> Bool
sameClass Char
a Char
b = Char -> Bool
isDigit Char
a Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Char -> Bool
isDigit Char
b
overlong :: Text -> Bool
overlong Text
run = (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isDigit Text
run Bool -> Bool -> Bool
&& Text -> Int -> Ordering
T.compareLength Text
run Int
maxNumericRun Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT
isSemverStable :: SemverKey -> Bool
isSemverStable :: SemverKey -> Bool
isSemverStable (SemverKey SemVer
sv) = Maybe Release -> Bool
forall a. Maybe a -> Bool
isNothing (SemVer -> Maybe Release
_svPreRel SemVer
sv)