{-# OPTIONS_GHC -Wall #-} {-# LANGUAGE LambdaCase #-} module Data.SemanticVersion.SemanticVersion where import Control.Lens import Data.SemanticVersion.BuildIdentifiers import Data.SemanticVersion.PreReleaseIdentifiers import Data.SemanticVersion.Version import Text.Parser.Char import Text.Parser.Combinators -- $setup -- >>> import Text.Parsec(parse) -- >>> import Data.Either(isLeft) -- <valid semver> ::= <version core> -- | <version core> "-" <pre-release> -- | <version core> "+" <build> -- | <version core> "-" <pre-release> "+" <build> data SemanticVersion = SemanticVersionOnly Version | SemanticVersionPreRelease Version PreReleaseIdentifiers | SemanticVersionBuild Version BuildIdentifiers | SemanticVersionPreReleaseBuild Version PreReleaseIdentifiers BuildIdentifiers deriving (SemanticVersion -> SemanticVersion -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: SemanticVersion -> SemanticVersion -> Bool $c/= :: SemanticVersion -> SemanticVersion -> Bool == :: SemanticVersion -> SemanticVersion -> Bool $c== :: SemanticVersion -> SemanticVersion -> Bool Eq, Int -> SemanticVersion -> ShowS [SemanticVersion] -> ShowS SemanticVersion -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [SemanticVersion] -> ShowS $cshowList :: [SemanticVersion] -> ShowS show :: SemanticVersion -> String $cshow :: SemanticVersion -> String showsPrec :: Int -> SemanticVersion -> ShowS $cshowsPrec :: Int -> SemanticVersion -> ShowS Show) class HasSemanticVersion a where semanticVersion :: Lens' a SemanticVersion instance HasSemanticVersion SemanticVersion where semanticVersion :: Lens' SemanticVersion SemanticVersion semanticVersion = forall a. a -> a id class AsSemanticVersion a where _SemanticVersion :: Prism' a SemanticVersion _SemanticVersionOnly :: Prism' a Version _SemanticVersionOnly = forall a. AsSemanticVersion a => Prism' a SemanticVersion _SemanticVersion forall b c a. (b -> c) -> (a -> b) -> a -> c . forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b prism' Version -> SemanticVersion SemanticVersionOnly (\case SemanticVersionOnly Version a -> forall a. a -> Maybe a Just Version a SemanticVersion _ -> forall a. Maybe a Nothing) _SemanticVersionPreRelease :: Prism' a (Version, PreReleaseIdentifiers) _SemanticVersionPreRelease = forall a. AsSemanticVersion a => Prism' a SemanticVersion _SemanticVersion forall b c a. (b -> c) -> (a -> b) -> a -> c . forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b prism' (forall a b c. (a -> b -> c) -> (a, b) -> c uncurry Version -> PreReleaseIdentifiers -> SemanticVersion SemanticVersionPreRelease) (\case SemanticVersionPreRelease Version v PreReleaseIdentifiers pri -> forall a. a -> Maybe a Just (Version v, PreReleaseIdentifiers pri) SemanticVersion _ -> forall a. Maybe a Nothing) _SemanticVersionBuild :: Prism' a (Version, BuildIdentifiers) _SemanticVersionBuild = forall a. AsSemanticVersion a => Prism' a SemanticVersion _SemanticVersion forall b c a. (b -> c) -> (a -> b) -> a -> c . forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b prism' (forall a b c. (a -> b -> c) -> (a, b) -> c uncurry Version -> BuildIdentifiers -> SemanticVersion SemanticVersionBuild) (\case SemanticVersionBuild Version v BuildIdentifiers bi -> forall a. a -> Maybe a Just (Version v, BuildIdentifiers bi) SemanticVersion _ -> forall a. Maybe a Nothing) _SemanticVersionPreReleaseBuild :: Prism' a (Version, PreReleaseIdentifiers, BuildIdentifiers) _SemanticVersionPreReleaseBuild = forall a. AsSemanticVersion a => Prism' a SemanticVersion _SemanticVersion forall b c a. (b -> c) -> (a -> b) -> a -> c . forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b prism' (\(Version v, PreReleaseIdentifiers pri, BuildIdentifiers bi) -> Version -> PreReleaseIdentifiers -> BuildIdentifiers -> SemanticVersion SemanticVersionPreReleaseBuild Version v PreReleaseIdentifiers pri BuildIdentifiers bi) (\case SemanticVersionPreReleaseBuild Version v PreReleaseIdentifiers pri BuildIdentifiers bi -> forall a. a -> Maybe a Just (Version v, PreReleaseIdentifiers pri, BuildIdentifiers bi) SemanticVersion _ -> forall a. Maybe a Nothing) instance AsSemanticVersion SemanticVersion where _SemanticVersion :: Prism' SemanticVersion SemanticVersion _SemanticVersion = forall a. a -> a id instance HasVersion SemanticVersion where version :: Lens' SemanticVersion Version version Version -> f Version f (SemanticVersionOnly Version v) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Version -> SemanticVersion SemanticVersionOnly (Version -> f Version f Version v) version Version -> f Version f (SemanticVersionPreRelease Version v PreReleaseIdentifiers pri) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Version -> PreReleaseIdentifiers -> SemanticVersion `SemanticVersionPreRelease` PreReleaseIdentifiers pri) (Version -> f Version f Version v) version Version -> f Version f (SemanticVersionBuild Version v BuildIdentifiers bi) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Version -> BuildIdentifiers -> SemanticVersion `SemanticVersionBuild` BuildIdentifiers bi) (Version -> f Version f Version v) version Version -> f Version f (SemanticVersionPreReleaseBuild Version v PreReleaseIdentifiers pri BuildIdentifiers bi) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (\Version v' -> Version -> PreReleaseIdentifiers -> BuildIdentifiers -> SemanticVersion SemanticVersionPreReleaseBuild Version v' PreReleaseIdentifiers pri BuildIdentifiers bi) (Version -> f Version f Version v) -- | -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "0.0.0" -- Right (SemanticVersion (Version NumericIdentifierZero NumericIdentifierZero NumericIdentifierZero)) -- -- >>> isLeft (parse parseSemanticVersion "parseSemanticVersion" "") -- True -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.2.3" -- Right (SemanticVersion (Version (NumericIdentifierDigits DecDigitNoZero1 []) (NumericIdentifierDigits DecDigitNoZero2 []) (NumericIdentifierDigits DecDigitNoZero3 []))) -- -- >>> isLeft(parse parseSemanticVersion "parseSemanticVersion" "01.2.3") -- True -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "10.2.3" -- Right (SemanticVersion (Version (NumericIdentifierDigits DecDigitNoZero1 [DecDigit0]) (NumericIdentifierDigits DecDigitNoZero2 []) (NumericIdentifierDigits DecDigitNoZero3 []))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "38012.5.6" -- Right (SemanticVersion (Version (NumericIdentifierDigits DecDigitNoZero3 [DecDigit8,DecDigit0,DecDigit1,DecDigit2]) (NumericIdentifierDigits DecDigitNoZero5 []) (NumericIdentifierDigits DecDigitNoZero6 []))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "38012.5.5432" -- Right (SemanticVersion (Version (NumericIdentifierDigits DecDigitNoZero3 [DecDigit8,DecDigit0,DecDigit1,DecDigit2]) (NumericIdentifierDigits DecDigitNoZero5 []) (NumericIdentifierDigits DecDigitNoZero5 [DecDigit4,DecDigit3,DecDigit2]))) -- -- >>> isLeft (parse (parseSemanticVersion <* eof) "parseSemanticVersion" "38012.05.5432") -- True -- -- >>> isLeft (parse (parseSemanticVersion <* eof) "parseSemanticVersion" "38012.5.05432") -- True -- -- >>> isLeft (parse parseSemanticVersion "parseSemanticVersion" "a") -- True -- -- >>> isLeft (parse parseSemanticVersion "parseSemanticVersion" "-") -- True -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.0.0-alpha" -- Right (SemanticVersionPreRelease (Version (NumericIdentifierDigits DecDigitNoZero1 []) NumericIdentifierZero NumericIdentifierZero) (PreReleaseIdentifiers (PreReleaseIdentifierAlphanumeric (AlphanumericIdentifierNonDigits (NonDigitLetter (AlphaLower Lower_a)) (IdentifierCharacters (IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_l)) :| [IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_p)),IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_h)),IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_a))]))) :| []))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.0.0-alpha.1" -- Right (SemanticVersionPreRelease (Version (NumericIdentifierDigits DecDigitNoZero1 []) NumericIdentifierZero NumericIdentifierZero) (PreReleaseIdentifiers (PreReleaseIdentifierAlphanumeric (AlphanumericIdentifierNonDigits (NonDigitLetter (AlphaLower Lower_a)) (IdentifierCharacters (IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_l)) :| [IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_p)),IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_h)),IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_a))]))) :| [PreReleaseIdentifierNumeric (NumericIdentifierDigits DecDigitNoZero1 [])]))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.0.0-0.3.7" -- Right (SemanticVersionPreRelease (Version (NumericIdentifierDigits DecDigitNoZero1 []) NumericIdentifierZero NumericIdentifierZero) (PreReleaseIdentifiers (PreReleaseIdentifierNumeric NumericIdentifierZero :| [PreReleaseIdentifierNumeric (NumericIdentifierDigits DecDigitNoZero3 []),PreReleaseIdentifierNumeric (NumericIdentifierDigits DecDigitNoZero7 [])]))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.0.0-x.7.z.92" -- Right (SemanticVersionPreRelease (Version (NumericIdentifierDigits DecDigitNoZero1 []) NumericIdentifierZero NumericIdentifierZero) (PreReleaseIdentifiers (PreReleaseIdentifierAlphanumeric (AlphanumericIdentifierNonDigit (NonDigitLetter (AlphaLower Lower_x))) :| [PreReleaseIdentifierNumeric (NumericIdentifierDigits DecDigitNoZero7 []),PreReleaseIdentifierAlphanumeric (AlphanumericIdentifierNonDigit (NonDigitLetter (AlphaLower Lower_z))),PreReleaseIdentifierNumeric (NumericIdentifierDigits DecDigitNoZero9 [DecDigit2])]))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.0.0-x-y-z.--" -- Right (SemanticVersionPreRelease (Version (NumericIdentifierDigits DecDigitNoZero1 []) NumericIdentifierZero NumericIdentifierZero) (PreReleaseIdentifiers (PreReleaseIdentifierAlphanumeric (AlphanumericIdentifierNonDigits (NonDigitLetter (AlphaLower Lower_x)) (IdentifierCharacters (IdentifierCharacterNonDigit NonDigitHyphen :| [IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_y)),IdentifierCharacterNonDigit NonDigitHyphen,IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_z))]))) :| [PreReleaseIdentifierAlphanumeric (AlphanumericIdentifierNonDigits NonDigitHyphen (IdentifierCharacters (IdentifierCharacterNonDigit NonDigitHyphen :| [])))]))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.0.0-alpha+001" -- Right (SemanticVersionPreReleaseBuild (Version (NumericIdentifierDigits DecDigitNoZero1 []) NumericIdentifierZero NumericIdentifierZero) (PreReleaseIdentifiers (PreReleaseIdentifierAlphanumeric (AlphanumericIdentifierNonDigits (NonDigitLetter (AlphaLower Lower_a)) (IdentifierCharacters (IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_l)) :| [IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_p)),IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_h)),IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_a))]))) :| [])) (BuildIdentifiers (BuildIdentifierDigits (DecDigit0 :| [DecDigit0,DecDigit1]) :| []))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.0.0+20130313144700" -- Right (SemanticVersionBuild (Version (NumericIdentifierDigits DecDigitNoZero1 []) NumericIdentifierZero NumericIdentifierZero) (BuildIdentifiers (BuildIdentifierDigits (DecDigit2 :| [DecDigit0,DecDigit1,DecDigit3,DecDigit0,DecDigit3,DecDigit1,DecDigit3,DecDigit1,DecDigit4,DecDigit4,DecDigit7,DecDigit0,DecDigit0]) :| []))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.0.0-beta+exp.sha.5114f85" -- Right (SemanticVersionPreReleaseBuild (Version (NumericIdentifierDigits DecDigitNoZero1 []) NumericIdentifierZero NumericIdentifierZero) (PreReleaseIdentifiers (PreReleaseIdentifierAlphanumeric (AlphanumericIdentifierNonDigits (NonDigitLetter (AlphaLower Lower_b)) (IdentifierCharacters (IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_e)) :| [IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_t)),IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_a))]))) :| [])) (BuildIdentifiers (BuildIdentifierAlphanumeric (AlphanumericIdentifierNonDigits (NonDigitLetter (AlphaLower Lower_e)) (IdentifierCharacters (IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_x)) :| [IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_p))]))) :| [BuildIdentifierAlphanumeric (AlphanumericIdentifierNonDigits (NonDigitLetter (AlphaLower Lower_s)) (IdentifierCharacters (IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_h)) :| [IdentifierCharacterNonDigit (NonDigitLetter (AlphaLower Lower_a))]))),BuildIdentifierAlphanumeric (AlphanumericIdentifierCharacters2 (IdentifierCharacters (IdentifierCharacterDigit DecDigit5 :| [IdentifierCharacterDigit DecDigit1,IdentifierCharacterDigit DecDigit1,IdentifierCharacterDigit DecDigit4])) (NonDigitLetter (AlphaLower Lower_f)) (IdentifierCharacters (IdentifierCharacterDigit DecDigit8 :| [IdentifierCharacterDigit DecDigit5])))]))) -- -- >>> parse (parseSemanticVersion <* eof) "parseSemanticVersion" "1.0.0+21AF26D3----117B344092BD" -- Right (SemanticVersionBuild (Version (NumericIdentifierDigits DecDigitNoZero1 []) NumericIdentifierZero NumericIdentifierZero) (BuildIdentifiers (BuildIdentifierAlphanumeric (AlphanumericIdentifierCharacters2 (IdentifierCharacters (IdentifierCharacterDigit DecDigit2 :| [IdentifierCharacterDigit DecDigit1])) (NonDigitLetter (AlphaUpper Upper_A)) (IdentifierCharacters (IdentifierCharacterNonDigit (NonDigitLetter (AlphaUpper Upper_F)) :| [IdentifierCharacterDigit DecDigit2,IdentifierCharacterDigit DecDigit6,IdentifierCharacterNonDigit (NonDigitLetter (AlphaUpper Upper_D)),IdentifierCharacterDigit DecDigit3,IdentifierCharacterNonDigit NonDigitHyphen,IdentifierCharacterNonDigit NonDigitHyphen,IdentifierCharacterNonDigit NonDigitHyphen,IdentifierCharacterNonDigit NonDigitHyphen,IdentifierCharacterDigit DecDigit1,IdentifierCharacterDigit DecDigit1,IdentifierCharacterDigit DecDigit7,IdentifierCharacterNonDigit (NonDigitLetter (AlphaUpper Upper_B)),IdentifierCharacterDigit DecDigit3,IdentifierCharacterDigit DecDigit4,IdentifierCharacterDigit DecDigit4,IdentifierCharacterDigit DecDigit0,IdentifierCharacterDigit DecDigit9,IdentifierCharacterDigit DecDigit2,IdentifierCharacterNonDigit (NonDigitLetter (AlphaUpper Upper_B)),IdentifierCharacterNonDigit (NonDigitLetter (AlphaUpper Upper_D))]))) :| []))) parseSemanticVersion :: CharParsing p => p SemanticVersion parseSemanticVersion :: forall (p :: * -> *). CharParsing p => p SemanticVersion parseSemanticVersion = let parsePreRelease :: p PreReleaseIdentifiers parsePreRelease = forall (m :: * -> *). CharParsing m => Char -> m Char char Char '-' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> forall (p :: * -> *). CharParsing p => p PreReleaseIdentifiers parsePreReleaseIdentifiers parseBuild :: p BuildIdentifiers parseBuild = forall (m :: * -> *). CharParsing m => Char -> m Char char Char '+' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> forall (p :: * -> *). CharParsing p => p BuildIdentifiers parseBuildIdentifiers mkVersion :: Version -> Maybe PreReleaseIdentifiers -> Maybe BuildIdentifiers -> SemanticVersion mkVersion Version v Maybe PreReleaseIdentifiers Nothing Maybe BuildIdentifiers Nothing = Version -> SemanticVersion SemanticVersionOnly Version v mkVersion Version v (Just PreReleaseIdentifiers pri) Maybe BuildIdentifiers Nothing = Version -> PreReleaseIdentifiers -> SemanticVersion SemanticVersionPreRelease Version v PreReleaseIdentifiers pri mkVersion Version v Maybe PreReleaseIdentifiers Nothing (Just BuildIdentifiers bld) = Version -> BuildIdentifiers -> SemanticVersion SemanticVersionBuild Version v BuildIdentifiers bld mkVersion Version v (Just PreReleaseIdentifiers pri) (Just BuildIdentifiers bld) = Version -> PreReleaseIdentifiers -> BuildIdentifiers -> SemanticVersion SemanticVersionPreReleaseBuild Version v PreReleaseIdentifiers pri BuildIdentifiers bld in Version -> Maybe PreReleaseIdentifiers -> Maybe BuildIdentifiers -> SemanticVersion mkVersion forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall (p :: * -> *). CharParsing p => p Version parseVersion forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> forall (m :: * -> *) a. Parsing m => m a -> m a try (forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional p PreReleaseIdentifiers parsePreRelease) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> forall (m :: * -> *) a. Parsing m => m a -> m a try (forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional p BuildIdentifiers parseBuild)