packages feed

salve 0.0.3 → 0.0.4

raw patch · 4 files changed

+406/−359 lines, 4 filesdep +semverdep +semver-rangePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: semver, semver-range

API changes (from Hackage documentation)

- Salve: constraintAnd :: Constraint -> Constraint -> Constraint
- Salve: constraintCaret :: Version -> Constraint
- Salve: constraintEQ :: Version -> Constraint
- Salve: constraintGE :: Version -> Constraint
- Salve: constraintGT :: Version -> Constraint
- Salve: constraintHyphen :: Version -> Version -> Constraint
- Salve: constraintLE :: Version -> Constraint
- Salve: constraintLT :: Version -> Constraint
- Salve: constraintOr :: Constraint -> Constraint -> Constraint
- Salve: constraintTilde :: Version -> Constraint
- Salve.Internal: Parser :: (String -> [(a, String)]) -> Parser a
- Salve.Internal: [runParser] :: Parser a -> String -> [(a, String)]
- Salve.Internal: caretP :: Parser Constraint
- Salve.Internal: charP :: Char -> Parser Char
- Salve.Internal: choiceP :: Parser a -> Parser a -> Parser a
- Salve.Internal: comparing :: Ord b => (a -> b) -> a -> a -> Ordering
- Salve.Internal: eqP :: Parser Operator
- Salve.Internal: failP :: Parser a
- Salve.Internal: geP :: Parser Operator
- Salve.Internal: getP :: Parser Char
- Salve.Internal: gtP :: Parser Operator
- Salve.Internal: instance GHC.Base.Applicative Salve.Internal.Parser
- Salve.Internal: instance GHC.Base.Functor Salve.Internal.Parser
- Salve.Internal: instance GHC.Base.Monad Salve.Internal.Parser
- Salve.Internal: isAsciiAlpha :: Char -> Bool
- Salve.Internal: isAsciiAlphaLower :: Char -> Bool
- Salve.Internal: isAsciiAlphaUpper :: Char -> Bool
- Salve.Internal: isAsciiDigit :: Char -> Bool
- Salve.Internal: join :: Char -> [String] -> String
- Salve.Internal: leP :: Parser Operator
- Salve.Internal: ltP :: Parser Operator
- Salve.Internal: manyP :: Parser a -> Parser [a]
- Salve.Internal: newtype Parser a
- Salve.Internal: oneOfP :: [Parser a] -> Parser a
- Salve.Internal: optionP :: a -> Parser a -> Parser a
- Salve.Internal: safeHead :: [a] -> Maybe a
- Salve.Internal: satisfyP :: (Char -> Bool) -> Parser Char
- Salve.Internal: sepBy1P :: Parser b -> Parser a -> Parser [a]
- Salve.Internal: sepByP :: Parser b -> Parser a -> Parser [a]
- Salve.Internal: someP :: Parser a -> Parser [a]
- Salve.Internal: spaceP :: Parser Char
- Salve.Internal: stringP :: String -> Parser String
- Salve.Internal: tildeP :: Parser Constraint
+ Salve.Internal: ConstraintWildcard :: Wildcard -> Constraint
+ Salve.Internal: WildcardMajor :: Wildcard
+ Salve.Internal: WildcardMinor :: Word -> Wildcard
+ Salve.Internal: WildcardPatch :: Word -> Word -> Wildcard
+ Salve.Internal: data Wildcard
+ Salve.Internal: instance GHC.Classes.Eq Salve.Internal.Wildcard
+ Salve.Internal: instance GHC.Show.Show Salve.Internal.Wildcard
+ Salve.Internal: isWildcard :: Char -> Bool
+ Salve.Internal: spaces1P :: ReadP ()
+ Salve.Internal: spacesP :: ReadP ()
+ Salve.Internal: wildcardConstraintP :: ReadP Constraint
+ Salve.Internal: wildcardMajorP :: ReadP Wildcard
+ Salve.Internal: wildcardMinorP :: ReadP Wildcard
+ Salve.Internal: wildcardP :: ReadP Wildcard
+ Salve.Internal: wildcardPatchP :: ReadP Wildcard
- Salve.Internal: buildP :: Parser Build
+ Salve.Internal: buildP :: ReadP Build
- Salve.Internal: buildsP :: Parser [Build]
+ Salve.Internal: buildsP :: ReadP [Build]
- Salve.Internal: constraintP :: Parser Constraint
+ Salve.Internal: constraintP :: ReadP Constraint
- Salve.Internal: constraintsP :: Parser Constraint
+ Salve.Internal: constraintsP :: ReadP Constraint
- Salve.Internal: hyphenP :: Parser String
+ Salve.Internal: hyphenP :: ReadP ()
- Salve.Internal: hyphenatedP :: Parser Constraint
+ Salve.Internal: hyphenatedP :: ReadP Constraint
- Salve.Internal: nonZeroP :: Parser Word
+ Salve.Internal: nonZeroP :: ReadP Word
- Salve.Internal: numberP :: Parser Word
+ Salve.Internal: numberP :: ReadP Word
- Salve.Internal: operatorP :: Parser Operator
+ Salve.Internal: operatorP :: ReadP Operator
- Salve.Internal: orP :: Parser String
+ Salve.Internal: orP :: ReadP ()
- Salve.Internal: parse :: Parser a -> String -> Maybe a
+ Salve.Internal: parse :: ReadP a -> String -> Maybe a
- Salve.Internal: preReleaseNumberP :: Parser PreRelease
+ Salve.Internal: preReleaseNumberP :: ReadP PreRelease
- Salve.Internal: preReleaseP :: Parser PreRelease
+ Salve.Internal: preReleaseP :: ReadP PreRelease
- Salve.Internal: preReleaseStringP :: Parser PreRelease
+ Salve.Internal: preReleaseStringP :: ReadP PreRelease
- Salve.Internal: preReleasesP :: Parser [PreRelease]
+ Salve.Internal: preReleasesP :: ReadP [PreRelease]
- Salve.Internal: primitiveP :: Parser Constraint
+ Salve.Internal: primitiveP :: ReadP Constraint
- Salve.Internal: simpleP :: Parser Constraint
+ Salve.Internal: simpleP :: ReadP Constraint
- Salve.Internal: versionP :: Parser Version
+ Salve.Internal: versionP :: ReadP Version
- Salve.Internal: zeroP :: Parser Word
+ Salve.Internal: zeroP :: ReadP Word

Files

benchmarks/benchmark.hs view
@@ -2,67 +2,96 @@  {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE PackageImports #-} {-# LANGUAGE StandaloneDeriving #-}  import qualified Control.DeepSeq as DeepSeq import qualified Criterion.Main as Criterion import qualified Data.Maybe as Maybe+import qualified "semver" Data.SemVer as SemVer+import qualified "semver-range" Data.SemVer as SemVerRange import qualified Data.Version as Version import qualified GHC.Generics as Ghc import qualified Salve.Internal as Salve import qualified Text.ParserCombinators.ReadP as ReadP -deriving instance Ghc.Generic Salve.Build-deriving instance Ghc.Generic Salve.Constraint-deriving instance Ghc.Generic Salve.Operator-deriving instance Ghc.Generic Salve.PreRelease-deriving instance Ghc.Generic Salve.Version- deriving instance DeepSeq.NFData Salve.Build deriving instance DeepSeq.NFData Salve.Constraint deriving instance DeepSeq.NFData Salve.Operator deriving instance DeepSeq.NFData Salve.PreRelease deriving instance DeepSeq.NFData Salve.Version+deriving instance DeepSeq.NFData Salve.Wildcard+deriving instance DeepSeq.NFData SemVerRange.PrereleaseTag+deriving instance DeepSeq.NFData SemVerRange.PrereleaseTags+deriving instance DeepSeq.NFData SemVerRange.SemVer+deriving instance DeepSeq.NFData SemVerRange.SemVerRange+deriving instance Ghc.Generic Salve.Build+deriving instance Ghc.Generic Salve.Constraint+deriving instance Ghc.Generic Salve.Operator+deriving instance Ghc.Generic Salve.PreRelease+deriving instance Ghc.Generic Salve.Version+deriving instance Ghc.Generic Salve.Wildcard+deriving instance Ghc.Generic SemVerRange.SemVerRange  main :: IO () main = Criterion.defaultMain-  [ Criterion.bgroup "Data.Version.parseVersion" (map-    (\ x -> Criterion.bench x (Criterion.nf (runReadP Version.parseVersion) x))-    [ "0.0.0"-    , "123.456.789-pre-release-build-metadata"-    ])-  , Criterion.bgroup "parseVersion" (map-    (\ x -> Criterion.bench x (Criterion.nf Salve.parseVersion x))-    [ "0.0.0"-    , "123.456.789-pre.release+build.metadata"-    ])-  , Criterion.bgroup "parseConstraint" (map-    (\ x -> Criterion.bench x (Criterion.nf Salve.parseConstraint x))-    [ ">=0.0.0"-    , ">1.2.3 || =1.2.3 >=1.2.3 <1.2.3 || 1.2.3 <=1.2.3 ~1.2.3 ^1.2.3 1.2.3 - 1.2.3"-    ])-  , Criterion.bgroup "Data.Version.showVersion" (map-    (\ x ->-      let y = Maybe.fromJust (runReadP Version.parseVersion x)-      in Criterion.bench x (Criterion.nf Version.showVersion y))-    [ "0.0.0"-    , "123.456.789-pre-release-build-metadata"-    ])-  , Criterion.bgroup "renderVersion" (map-    (\ x ->-      let y = Salve.unsafeParseVersion x-      in Criterion.bench x (Criterion.nf Salve.renderVersion y))-    [ "0.0.0"-    , "123.456.789-pre.release+build.metadata"-    ])-  , Criterion.bgroup "renderConstraint" (map-    (\ x ->-      let y = Salve.unsafeParseConstraint x-      in Criterion.bench x (Criterion.nf Salve.renderConstraint y))-    [ ">=0.0.0"-    , ">1.2.3 || =1.2.3 >=1.2.3 <1.2.3 || 1.2.3 <=1.2.3 ~1.2.3 ^1.2.3"-    ])+  [ Criterion.bgroup "version"+    [ Criterion.bgroup "parse"+      [ Criterion.bgroup "simple"+        [ Criterion.bench "base" $ Criterion.nf (runReadP Version.parseVersion) "0.0.0"+        , Criterion.bench "salve" $ Criterion.nf Salve.parseVersion "0.0.0"+        , Criterion.bench "semver" $ Criterion.nf (fromRight . SemVer.fromText) "0.0.0"+        , Criterion.bench "semver-range" $ Criterion.nf (fromRight . SemVerRange.parseSemVer) "0.0.0"+        ]+      , Criterion.bgroup "complex"+        [ Criterion.bench "base" $ Criterion.nf (runReadP Version.parseVersion) "1.22.333-pre-build"+        , Criterion.bench "salve" $ Criterion.nf Salve.parseVersion "1.22.333-pre+build"+        , Criterion.bench "semver" $ Criterion.nf (fromRight . SemVer.fromText) "1.22.333-pre+build"+        , Criterion.bench "semver-range" $ Criterion.nf (fromRight . SemVerRange.parseSemVer) "1.22.333-pre+build"+        ]+      ]+    , Criterion.bgroup "render"+      [ Criterion.bgroup "simple"+        [ let Just v = runReadP Version.parseVersion "0.0.0" in Criterion.bench "base" $ Criterion.nf Version.showVersion v+        , let v = Salve.unsafeParseVersion "0.0.0" in Criterion.bench "salve" $ Criterion.nf Salve.renderVersion v+        , let Right v = SemVer.fromText "0.0.0" in Criterion.bench "semver" $ Criterion.nf SemVer.toText v+        , let Right v = SemVerRange.parseSemVer "0.0.0" in Criterion.bench "semver-range" $ Criterion.nf SemVerRange.renderSV v+        ]+      , Criterion.bgroup "complex"+        [ let Just v = runReadP Version.parseVersion "1.22.333-pre-build" in Criterion.bench "base" $ Criterion.nf Version.showVersion v+        , let v = Salve.unsafeParseVersion "1.22.333-pre+build" in Criterion.bench "salve" $ Criterion.nf Salve.renderVersion v+        , let Right v = SemVer.fromText "1.22.333-pre+build" in Criterion.bench "semver" $ Criterion.nf SemVer.toText v+        , let Right v = SemVerRange.parseSemVer "1.22.333-pre+build" in Criterion.bench "semver-range" $ Criterion.nf SemVerRange.renderSV v+        ]+      ]+    ]+  , Criterion.bgroup "constraint"+    [ Criterion.bgroup "parse"+      [ Criterion.bgroup "simple"+        [ Criterion.bench "salve" $ Criterion.nf Salve.parseConstraint "0.0.0"+        , Criterion.bench "semver-range" $ Criterion.nf (fromRight . SemVerRange.parseSemVerRange) "0.0.0"+        ]+      , Criterion.bgroup "complex"+        [ Criterion.bench "salve" $ Criterion.nf Salve.parseConstraint "<1.2.0 <=1.2.1 || =1.2.2 >=1.2.3 || >1.2.4 1.2.5 || 1.2.6 - 1.2.7 ~1.2.8 || ^1.2.9"+        , Criterion.bench "semver-range" $ Criterion.nf (fromRight . SemVerRange.parseSemVerRange) "<1.2.0 <=1.2.1 || =1.2.2 >=1.2.3 || >1.2.4 1.2.5 || 1.2.6 - 1.2.7 ~1.2.8 || ^1.2.9"+        ]+      ]+    , Criterion.bgroup "render"+      [ Criterion.bgroup "simple"+        [ let c = Salve.unsafeParseConstraint "0.0.0" in Criterion.bench "salve" $ Criterion.nf Salve.renderConstraint c+        ]+      , Criterion.bgroup "complex"+        [ let c = Salve.unsafeParseConstraint "<1.2.0 <=1.2.1 || =1.2.2 >=1.2.3 || >1.2.4 1.2.5 || 1.2.6 - 1.2.7 ~1.2.8 || ^1.2.9" in Criterion.bench "salve" $ Criterion.nf Salve.renderConstraint c+        ]+      ]+    ]   ]++fromRight :: Either a b -> Maybe b+fromRight e = case e of+  Left _ -> Nothing+  Right r -> Just r  runReadP :: ReadP.ReadP a -> String -> Maybe a runReadP parser string = Maybe.listToMaybe (do
library/Salve.hs view
@@ -38,16 +38,6 @@ -- * Constructors makeVersion, initialVersion,-constraintLT,-constraintLE,-constraintEQ,-constraintGE,-constraintGT,-constraintAnd,-constraintOr,-constraintHyphen,-constraintTilde,-constraintCaret,  -- * Parsing parseVersion,@@ -152,28 +142,77 @@ -- >>> parseConstraint "1.2" -- Nothing ----- Wildcards (also known as "x-ranges") are not allowed.+-- Wildcards (also known as "x-ranges") are allowed. The exact character used+-- for the wildcard is not round-tripped. ----- >>> parseConstraint "1.2.x"+-- >>> renderConstraint <$> parseConstraint "1.2.x"+-- Just "1.2.x"+-- >>> renderConstraint <$> parseConstraint "1.2.X"+-- Just "1.2.x"+-- >>> renderConstraint <$> parseConstraint "1.2.*"+-- Just "1.2.x"+--+-- Wildcards can be combined with other constraints.+--+-- >>> renderConstraint <$> parseConstraint "1.2.x 2.3.4"+-- Just "1.2.x 2.3.4"+-- >>> renderConstraint <$> parseConstraint "1.2.x || 2.3.4"+-- Just "1.2.x || 2.3.4"+--+-- Wildcards are allowed at any position.+--+-- >>> renderConstraint <$> parseConstraint "1.2.x"+-- Just "1.2.x"+-- >>> renderConstraint <$> parseConstraint "1.x.x"+-- Just "1.x.x"+-- >>> renderConstraint <$> parseConstraint "x.x.x"+-- Just "x.x.x"+--+-- Non-wildcards cannot come after wildcards.+--+-- >>> parseConstraint "1.x.3" -- Nothing--- >>> parseConstraint "1.2.X"+-- >>> parseConstraint "x.2.3" -- Nothing--- >>> parseConstraint "1.2.*"+-- >>> parseConstraint "x.x.3" -- Nothing+-- >>> parseConstraint "x.2.x"+-- Nothing ----- Extra spaces are not allowed.+-- Wildcards cannot be used with other operators. ----- >>> parseConstraint " 1.2.3 "+-- >>> parseConstraint "<1.2.x" -- Nothing--- >>> parseConstraint "> 1.2.3"+-- >>> parseConstraint "<=1.2.x" -- Nothing--- >>> parseConstraint "1.2.3  -  2.3.4"+-- >>> parseConstraint "=1.2.x" -- Nothing--- >>> parseConstraint "1.2.3  2.3.4"+-- >>> parseConstraint ">=1.2.x" -- Nothing--- >>> parseConstraint "1.2.3  ||  2.3.4"+-- >>> parseConstraint ">1.2.x" -- Nothing+-- >>> parseConstraint "~1.2.x"+-- Nothing+-- >>> parseConstraint "^1.2.x"+-- Nothing+-- >>> parseConstraint "1.2.x - 2.3.4"+-- Nothing+-- >>> parseConstraint "1.2.3 - 2.3.x"+-- Nothing --+-- Spaces are allowed in most places. Extra spaces are not round-tripped.+--+-- >>> renderConstraint <$> parseConstraint " 1.2.3 "+-- Just "1.2.3"+-- >>> renderConstraint <$> parseConstraint "> 1.2.3"+-- Just ">1.2.3"+-- >>> renderConstraint <$> parseConstraint "1.2.3  -  2.3.4"+-- Just "1.2.3 - 2.3.4"+-- >>> renderConstraint <$> parseConstraint "1.2.3  2.3.4"+-- Just "1.2.3 2.3.4"+-- >>> renderConstraint <$> parseConstraint "1.2.3  ||  2.3.4"+-- Just "1.2.3 || 2.3.4"+-- -- Parentheses are not allowed. Note that combining two constraints with a -- space (and) has higher precedence than combining them with pipes (or). In -- other words, @"a b || c"@ parses as @"(a b) || c"@, not @"a (b || c)"@.@@ -213,7 +252,7 @@ -- >>> renderConstraint <$> parseConstraint "=1.2.3" -- Just "1.2.3" ----- Pre-releases and builds are allowed on any constraints.+-- Pre-releases and builds are allowed on any constraints except wildcards. -- -- >>> renderConstraint <$> parseConstraint "1.2.3-p+b" -- Just "1.2.3-p+b"@@ -226,16 +265,19 @@ -- >>> renderConstraint <$> parseConstraint "^1.2.3-p+b" -- Just "^1.2.3-p+b" --+-- >>> parseConstraint "1.2.x-p+b"+-- Nothing+-- -- These examples show every type of constraint in a single expression. ----- >>> renderConstraint <$> parseConstraint "<1.2.0 <=1.2.1 =1.2.2 >=1.2.3 >1.2.4 1.2.5 1.2.6 - 1.2.7 ~1.2.8 ^1.2.9"--- Just "<1.2.0 <=1.2.1 1.2.2 >=1.2.3 >1.2.4 1.2.5 1.2.6 - 1.2.7 ~1.2.8 ^1.2.9"--- >>> renderConstraint <$> parseConstraint "<1.2.0 <=1.2.1 || =1.2.2 >=1.2.3 || >1.2.4 1.2.5 || 1.2.6 - 1.2.7 ~1.2.8 || ^1.2.9"--- Just "<1.2.0 <=1.2.1 || 1.2.2 >=1.2.3 || >1.2.4 1.2.5 || 1.2.6 - 1.2.7 ~1.2.8 || ^1.2.9"--- >>> renderConstraint <$> parseConstraint "<1.2.0 || <=1.2.1 =1.2.2 || >=1.2.3 >1.2.4 || 1.2.5 1.2.6 - 1.2.7 || ~1.2.8 ^1.2.9"--- Just "<1.2.0 || <=1.2.1 1.2.2 || >=1.2.3 >1.2.4 || 1.2.5 1.2.6 - 1.2.7 || ~1.2.8 ^1.2.9"--- >>> renderConstraint <$> parseConstraint "<1.2.0 || <=1.2.1 || =1.2.2 || >=1.2.3 || >1.2.4 || 1.2.5 || 1.2.6 - 1.2.7 || ~1.2.8 || ^1.2.9"--- Just "<1.2.0 || <=1.2.1 || 1.2.2 || >=1.2.3 || >1.2.4 || 1.2.5 || 1.2.6 - 1.2.7 || ~1.2.8 || ^1.2.9"+-- >>> renderConstraint <$> parseConstraint "<1.2.0 <=1.2.1 =1.2.2 >=1.2.3 >1.2.4 1.2.5 1.2.6 - 1.2.7 ~1.2.8 ^1.2.9 1.2.x"+-- Just "<1.2.0 <=1.2.1 1.2.2 >=1.2.3 >1.2.4 1.2.5 1.2.6 - 1.2.7 ~1.2.8 ^1.2.9 1.2.x"+-- >>> renderConstraint <$> parseConstraint "<1.2.0 <=1.2.1 || =1.2.2 >=1.2.3 || >1.2.4 1.2.5 || 1.2.6 - 1.2.7 ~1.2.8 || ^1.2.9 1.2.x"+-- Just "<1.2.0 <=1.2.1 || 1.2.2 >=1.2.3 || >1.2.4 1.2.5 || 1.2.6 - 1.2.7 ~1.2.8 || ^1.2.9 1.2.x"+-- >>> renderConstraint <$> parseConstraint "<1.2.0 || <=1.2.1 =1.2.2 || >=1.2.3 >1.2.4 || 1.2.5 1.2.6 - 1.2.7 || ~1.2.8 ^1.2.9 || 1.2.x"+-- Just "<1.2.0 || <=1.2.1 1.2.2 || >=1.2.3 >1.2.4 || 1.2.5 1.2.6 - 1.2.7 || ~1.2.8 ^1.2.9 || 1.2.x"+-- >>> renderConstraint <$> parseConstraint "<1.2.0 || <=1.2.1 || =1.2.2 || >=1.2.3 || >1.2.4 || 1.2.5 || 1.2.6 - 1.2.7 || ~1.2.8 || ^1.2.9 || 1.2.x"+-- Just "<1.2.0 || <=1.2.1 || 1.2.2 || >=1.2.3 || >1.2.4 || 1.2.5 || 1.2.6 - 1.2.7 || ~1.2.8 || ^1.2.9 || 1.2.x"  -- ** Satisfying constraints -- | Although in general you should use 'satisfies', 'parseVersion', and@@ -385,6 +427,31 @@ --     True --     >>> "0.0.4" ? "^0.0.3" --     False+--+-- -   Wildcard:+--+--     >>> "1.1.0" ? "1.2.x"+--     False+--     >>> "1.2.3" ? "1.2.x"+--     True+--     >>> "1.3.0" ? "1.2.x"+--     False+--+--     >>> "0.1.0" ? "1.x.x"+--     False+--     >>> "1.0.0" ? "1.x.x"+--     True+--     >>> "1.2.3" ? "1.x.x"+--     True+--     >>> "2.0.0" ? "1.x.x"+--     False+--+--     >>> "0.0.0" ? "x.x.x"+--     True+--     >>> "1.2.3" ? "x.x.x"+--     True+--     >>> "2.0.0" ? "x.x.x"+--     True ) where  import Salve.Internal
library/Salve/Internal.hs view
@@ -3,6 +3,14 @@ -- that thing exported from "Salve". module Salve.Internal where +import qualified Control.Monad as Monad+import qualified Data.Char as Char+import qualified Data.List as List+import qualified Data.Maybe as Maybe+import qualified Data.Ord as Ord+import qualified Text.ParserCombinators.ReadP as ReadP+import qualified Text.Read as Read+ -- $setup -- >>> import Lens.Micro -- >>> import Lens.Micro.Extras@@ -62,9 +70,9 @@ -- Just False instance Ord Version where   compare x y = mconcat-    [ comparing versionMajor x y-    , comparing versionMinor x y-    , comparing versionPatch x y+    [ Ord.comparing versionMajor x y+    , Ord.comparing versionMinor x y+    , Ord.comparing versionPatch x y     , case both versionPreReleases (x, y) of       ([], []) -> EQ       ([], _) -> GT@@ -128,6 +136,7 @@ data Constraint   = ConstraintOperator Operator Version   | ConstraintHyphen Version Version+  | ConstraintWildcard Wildcard   | ConstraintAnd Constraint Constraint   | ConstraintOr Constraint Constraint   deriving (Eq, Show)@@ -155,99 +164,6 @@ initialVersion :: Version initialVersion = makeVersion 0 0 0 [] [] --- | Makes a new constraint that must be less than the version number.------ >>> constraintLT <$> parseVersion "1.2.3"--- Just (ConstraintOperator OperatorLT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))--- >>> parseConstraint "<1.2.3"--- Just (ConstraintOperator OperatorLT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))-constraintLT :: Version -> Constraint-constraintLT v = ConstraintOperator OperatorLT v---- | Makes a new constraint that must be less than or euqal to the version--- number.------ >>> constraintLE <$> parseVersion "1.2.3"--- Just (ConstraintOperator OperatorLE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))--- >>> parseConstraint "<=1.2.3"--- Just (ConstraintOperator OperatorLE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))-constraintLE :: Version -> Constraint-constraintLE v = ConstraintOperator OperatorLE v---- | Makes a new constraint that must be equal to the version number.------ >>> constraintEQ <$> parseVersion "1.2.3"--- Just (ConstraintOperator OperatorEQ (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))--- >>> parseConstraint "=1.2.3"--- Just (ConstraintOperator OperatorEQ (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))-constraintEQ :: Version -> Constraint-constraintEQ v = ConstraintOperator OperatorEQ v---- | Makes a new constraint that must be greater than or equal to the version--- number.------ >>> constraintGE <$> parseVersion "1.2.3"--- Just (ConstraintOperator OperatorGE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))--- >>> parseConstraint ">=1.2.3"--- Just (ConstraintOperator OperatorGE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))-constraintGE :: Version -> Constraint-constraintGE v = ConstraintOperator OperatorGE v---- | Makes a new constraint that must be greater than the version number.------ >>> constraintGT <$> parseVersion "1.2.3"--- Just (ConstraintOperator OperatorGT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))--- >>> parseConstraint ">1.2.3"--- Just (ConstraintOperator OperatorGT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))-constraintGT :: Version -> Constraint-constraintGT v = ConstraintOperator OperatorGT v---- | Makes a new constraint that must satisfy both constraints.------ >>> constraintAnd <$> (constraintGE <$> parseVersion "1.2.3") <*> (constraintLT <$> parseVersion "2.0.0")--- Just (ConstraintAnd (ConstraintOperator OperatorGE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})) (ConstraintOperator OperatorLT (Version {versionMajor = 2, versionMinor = 0, versionPatch = 0, versionPreReleases = [], versionBuilds = []})))--- >>> parseConstraint ">=1.2.3 <2.0.0"--- Just (ConstraintAnd (ConstraintOperator OperatorGE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})) (ConstraintOperator OperatorLT (Version {versionMajor = 2, versionMinor = 0, versionPatch = 0, versionPreReleases = [], versionBuilds = []})))-constraintAnd :: Constraint -> Constraint -> Constraint-constraintAnd l r = ConstraintAnd l r---- | Makes a new constraint that must satisfy either constraint.------ >>> constraintOr <$> (constraintEQ <$> parseVersion "1.2.3") <*> (constraintGT <$> parseVersion "1.2.3")--- Just (ConstraintOr (ConstraintOperator OperatorEQ (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})) (ConstraintOperator OperatorGT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})))--- >>> parseConstraint "=1.2.3 || >1.2.3"--- Just (ConstraintOr (ConstraintOperator OperatorEQ (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})) (ConstraintOperator OperatorGT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})))-constraintOr :: Constraint -> Constraint -> Constraint-constraintOr l r = ConstraintOr l r---- | Makes a new constraint that must be between the versions, inclusive.------ >>> constraintHyphen <$> parseVersion "1.2.3" <*> parseVersion "2.3.4"--- Just (ConstraintHyphen (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}) (Version {versionMajor = 2, versionMinor = 3, versionPatch = 4, versionPreReleases = [], versionBuilds = []}))--- >>> parseConstraint "1.2.3 - 2.3.4"--- Just (ConstraintHyphen (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}) (Version {versionMajor = 2, versionMinor = 3, versionPatch = 4, versionPreReleases = [], versionBuilds = []}))-constraintHyphen :: Version -> Version -> Constraint-constraintHyphen v w = ConstraintHyphen v w---- | Makes a new constraint that allows changes to the patch version number.------ >>> constraintTilde <$> parseVersion "1.2.3"--- Just (ConstraintOperator OperatorTilde (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))--- >>> parseConstraint "~1.2.3"--- Just (ConstraintOperator OperatorTilde (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))-constraintTilde :: Version -> Constraint-constraintTilde v = ConstraintOperator OperatorTilde v---- | Makes a new constraint that allows changes that do not modify the--- left-most non-zero version number.------ >>> constraintCaret <$> parseVersion "1.2.3"--- Just (ConstraintOperator OperatorCaret (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))--- >>> parseConstraint "^1.2.3"--- Just (ConstraintOperator OperatorCaret (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))-constraintCaret :: Version -> Constraint-constraintCaret v = ConstraintOperator OperatorCaret v- -- | Attempts to parse a version. This parser follows [SemVer's -- BNF](https://github.com/mojombo/semver/blob/eb9aac5/semver.md#backusnaur-form-grammar-for-valid-semver-versions). --@@ -444,9 +360,13 @@       OperatorGT -> '>' : s       OperatorTilde -> '~' : s       OperatorCaret -> '^' : s-  ConstraintHyphen l r -> join ' ' [renderVersion l, "-", renderVersion r]-  ConstraintAnd l r -> join ' ' (map renderConstraint [l, r])-  ConstraintOr l r -> join ' ' [renderConstraint l, "||", renderConstraint r]+  ConstraintHyphen l r -> unwords [renderVersion l, "-", renderVersion r]+  ConstraintWildcard w -> case w of+    WildcardMajor -> "x.x.x"+    WildcardMinor m -> show m ++ ".x.x"+    WildcardPatch m n -> List.intercalate "." [show m, show n, "x"]+  ConstraintAnd l r -> unwords (map renderConstraint [l, r])+  ConstraintOr l r -> unwords [renderConstraint l, "||", renderConstraint r]  -- | Returns 'True' if the major version number is zero, 'False' otherwise. --@@ -549,6 +469,10 @@             else makeVersion (versionMajor w + 1) 0 0 [] []       in (v >= w) && (v < u)   ConstraintHyphen l r -> (l <= v) && (v <= r)+  ConstraintWildcard w -> case w of+    WildcardMajor -> True+    WildcardMinor m -> (makeVersion m 0 0 [] [] <= v) && (v < makeVersion (m + 1) 0 0 [] [])+    WildcardPatch m n -> (makeVersion m n 0 [] [] <= v) && (v < makeVersion m (n + 1) 0 [] [])   ConstraintAnd l r -> satisfies v l && satisfies v r   ConstraintOr l r -> satisfies v l || satisfies v r @@ -621,266 +545,291 @@   | OperatorCaret   deriving (Eq, Show) +data Wildcard+  = WildcardMajor+  | WildcardMinor Word+  | WildcardPatch Word Word+  deriving (Eq, Show)++-- ** Constructors++-- | Makes a new constraint that must be less than the version number.+--+-- >>> constraintLT <$> parseVersion "1.2.3"+-- Just (ConstraintOperator OperatorLT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+-- >>> parseConstraint "<1.2.3"+-- Just (ConstraintOperator OperatorLT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+constraintLT :: Version -> Constraint+constraintLT v = ConstraintOperator OperatorLT v++-- | Makes a new constraint that must be less than or euqal to the version+-- number.+--+-- >>> constraintLE <$> parseVersion "1.2.3"+-- Just (ConstraintOperator OperatorLE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+-- >>> parseConstraint "<=1.2.3"+-- Just (ConstraintOperator OperatorLE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+constraintLE :: Version -> Constraint+constraintLE v = ConstraintOperator OperatorLE v++-- | Makes a new constraint that must be equal to the version number.+--+-- >>> constraintEQ <$> parseVersion "1.2.3"+-- Just (ConstraintOperator OperatorEQ (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+-- >>> parseConstraint "=1.2.3"+-- Just (ConstraintOperator OperatorEQ (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+constraintEQ :: Version -> Constraint+constraintEQ v = ConstraintOperator OperatorEQ v++-- | Makes a new constraint that must be greater than or equal to the version+-- number.+--+-- >>> constraintGE <$> parseVersion "1.2.3"+-- Just (ConstraintOperator OperatorGE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+-- >>> parseConstraint ">=1.2.3"+-- Just (ConstraintOperator OperatorGE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+constraintGE :: Version -> Constraint+constraintGE v = ConstraintOperator OperatorGE v++-- | Makes a new constraint that must be greater than the version number.+--+-- >>> constraintGT <$> parseVersion "1.2.3"+-- Just (ConstraintOperator OperatorGT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+-- >>> parseConstraint ">1.2.3"+-- Just (ConstraintOperator OperatorGT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+constraintGT :: Version -> Constraint+constraintGT v = ConstraintOperator OperatorGT v++-- | Makes a new constraint that must satisfy both constraints.+--+-- >>> constraintAnd <$> (constraintGE <$> parseVersion "1.2.3") <*> (constraintLT <$> parseVersion "2.0.0")+-- Just (ConstraintAnd (ConstraintOperator OperatorGE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})) (ConstraintOperator OperatorLT (Version {versionMajor = 2, versionMinor = 0, versionPatch = 0, versionPreReleases = [], versionBuilds = []})))+-- >>> parseConstraint ">=1.2.3 <2.0.0"+-- Just (ConstraintAnd (ConstraintOperator OperatorGE (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})) (ConstraintOperator OperatorLT (Version {versionMajor = 2, versionMinor = 0, versionPatch = 0, versionPreReleases = [], versionBuilds = []})))+constraintAnd :: Constraint -> Constraint -> Constraint+constraintAnd l r = ConstraintAnd l r++-- | Makes a new constraint that must satisfy either constraint.+--+-- >>> constraintOr <$> (constraintEQ <$> parseVersion "1.2.3") <*> (constraintGT <$> parseVersion "1.2.3")+-- Just (ConstraintOr (ConstraintOperator OperatorEQ (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})) (ConstraintOperator OperatorGT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})))+-- >>> parseConstraint "=1.2.3 || >1.2.3"+-- Just (ConstraintOr (ConstraintOperator OperatorEQ (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})) (ConstraintOperator OperatorGT (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []})))+constraintOr :: Constraint -> Constraint -> Constraint+constraintOr l r = ConstraintOr l r++-- | Makes a new constraint that must be between the versions, inclusive.+--+-- >>> constraintHyphen <$> parseVersion "1.2.3" <*> parseVersion "2.3.4"+-- Just (ConstraintHyphen (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}) (Version {versionMajor = 2, versionMinor = 3, versionPatch = 4, versionPreReleases = [], versionBuilds = []}))+-- >>> parseConstraint "1.2.3 - 2.3.4"+-- Just (ConstraintHyphen (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}) (Version {versionMajor = 2, versionMinor = 3, versionPatch = 4, versionPreReleases = [], versionBuilds = []}))+constraintHyphen :: Version -> Version -> Constraint+constraintHyphen v w = ConstraintHyphen v w++-- | Makes a new constraint that allows changes to the patch version number.+--+-- >>> constraintTilde <$> parseVersion "1.2.3"+-- Just (ConstraintOperator OperatorTilde (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+-- >>> parseConstraint "~1.2.3"+-- Just (ConstraintOperator OperatorTilde (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+constraintTilde :: Version -> Constraint+constraintTilde v = ConstraintOperator OperatorTilde v++-- | Makes a new constraint that allows changes that do not modify the+-- left-most non-zero version number.+--+-- >>> constraintCaret <$> parseVersion "1.2.3"+-- Just (ConstraintOperator OperatorCaret (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+-- >>> parseConstraint "^1.2.3"+-- Just (ConstraintOperator OperatorCaret (Version {versionMajor = 1, versionMinor = 2, versionPatch = 3, versionPreReleases = [], versionBuilds = []}))+constraintCaret :: Version -> Constraint+constraintCaret v = ConstraintOperator OperatorCaret v+ -- ** Parsing -versionP :: Parser Version+versionP :: ReadP.ReadP Version versionP = do   major <- numberP-  _ <- charP '.'+  Monad.void (ReadP.char '.')   minor <- numberP-  _ <- charP '.'+  Monad.void (ReadP.char '.')   patch <- numberP   preReleases <- preReleasesP   builds <- buildsP   pure (makeVersion major minor patch preReleases builds) -preReleasesP :: Parser [PreRelease]-preReleasesP = optionP [] (do-  _ <- charP '-'-  sepBy1P (charP '.') preReleaseP)+preReleasesP :: ReadP.ReadP [PreRelease]+preReleasesP = ReadP.option [] (do+  Monad.void (ReadP.char '-')+  ReadP.sepBy1 preReleaseP (ReadP.char '.')) -preReleaseP :: Parser PreRelease-preReleaseP = choiceP preReleaseStringP preReleaseNumberP+preReleaseP :: ReadP.ReadP PreRelease+preReleaseP = preReleaseNumberP ReadP.<++ preReleaseStringP -preReleaseNumberP :: Parser PreRelease+preReleaseNumberP :: ReadP.ReadP PreRelease preReleaseNumberP = do   n <- numberP   pure (PreReleaseNumeric n) -preReleaseStringP :: Parser PreRelease+preReleaseStringP :: ReadP.ReadP PreRelease preReleaseStringP = do-  s <- someP (satisfyP isIdentifier)-  if all isAsciiDigit s-    then failP+  s <- ReadP.munch1 isIdentifier+  if all Char.isDigit s+    then ReadP.pfail     else pure (PreReleaseTextual s) -buildsP :: Parser [Build]-buildsP = optionP [] (do-  _ <- charP '+'-  sepBy1P (charP '.') buildP)+buildsP :: ReadP.ReadP [Build]+buildsP = ReadP.option [] (do+  Monad.void (ReadP.char '+')+  ReadP.sepBy1 buildP (ReadP.char '.')) -buildP :: Parser Build+buildP :: ReadP.ReadP Build buildP = do-  b <- someP (satisfyP isIdentifier)+  b <- ReadP.munch1 isIdentifier   pure (Build b) -numberP :: Parser Word-numberP = choiceP zeroP nonZeroP+numberP :: ReadP.ReadP Word+numberP = nonZeroP ReadP.<++ zeroP -zeroP :: Parser Word+zeroP :: ReadP.ReadP Word zeroP = do-  _ <- charP '0'+  Monad.void (ReadP.char '0')   pure 0 -nonZeroP :: Parser Word+nonZeroP :: ReadP.ReadP Word nonZeroP = do-  x <- satisfyP isAsciiDigitNonZero-  ys <- manyP (satisfyP isAsciiDigit)-  pure (read (x : ys))+  x <- ReadP.satisfy isAsciiDigitNonZero+  ys <- ReadP.munch Char.isDigit+  case Read.readMaybe (x : ys) of+    Nothing -> ReadP.pfail+    Just n -> pure n -constraintsP :: Parser Constraint+constraintsP :: ReadP.ReadP Constraint constraintsP = do-  cs <- sepBy1P orP constraintP+  spacesP+  cs <- ReadP.sepBy1 constraintP orP+  spacesP   pure (foldr1 constraintOr cs) -constraintP :: Parser Constraint+constraintP :: ReadP.ReadP Constraint constraintP = do-  cs <- sepBy1P spaceP simpleP+  cs <- ReadP.sepBy1 simpleP spaces1P   pure (foldr1 constraintAnd cs) -hyphenatedP :: Parser Constraint+hyphenatedP :: ReadP.ReadP Constraint hyphenatedP = do   v <- versionP-  _ <- hyphenP+  hyphenP   w <- versionP   pure (constraintHyphen v w) -simpleP :: Parser Constraint-simpleP = oneOfP [hyphenatedP, caretP, tildeP, primitiveP]+simpleP :: ReadP.ReadP Constraint+simpleP = ReadP.choice [hyphenatedP, wildcardConstraintP, primitiveP] -caretP :: Parser Constraint-caretP = do-  _ <- charP '^'-  v <- versionP-  pure (constraintCaret v)+wildcardConstraintP :: ReadP.ReadP Constraint+wildcardConstraintP = do+  w <- wildcardP+  pure (ConstraintWildcard w) -tildeP :: Parser Constraint-tildeP = do-  _ <- charP '~'-  v <- versionP-  pure (constraintTilde v)+wildcardP :: ReadP.ReadP Wildcard+wildcardP = ReadP.choice [wildcardPatchP, wildcardMinorP, wildcardMajorP] -primitiveP :: Parser Constraint+wildcardPatchP :: ReadP.ReadP Wildcard+wildcardPatchP = do+  m <- numberP+  Monad.void (ReadP.char '.')+  n <- numberP+  Monad.void (ReadP.char '.')+  Monad.void (ReadP.satisfy isWildcard)+  pure (WildcardPatch m n)++wildcardMinorP :: ReadP.ReadP Wildcard+wildcardMinorP = do+  m <- numberP+  Monad.void (ReadP.char '.')+  Monad.void (ReadP.satisfy isWildcard)+  Monad.void (ReadP.char '.')+  Monad.void (ReadP.satisfy isWildcard)+  pure (WildcardMinor m)++wildcardMajorP :: ReadP.ReadP Wildcard+wildcardMajorP = do+  Monad.void (ReadP.satisfy isWildcard)+  Monad.void (ReadP.char '.')+  Monad.void (ReadP.satisfy isWildcard)+  Monad.void (ReadP.char '.')+  Monad.void (ReadP.satisfy isWildcard)+  pure WildcardMajor++primitiveP :: ReadP.ReadP Constraint primitiveP = do   o <- operatorP+  spacesP   v <- versionP   pure (ConstraintOperator o v) -operatorP :: Parser Operator-operatorP = oneOfP [leP, geP, ltP, gtP, eqP, pure OperatorEQ]--leP :: Parser Operator-leP = do-  _ <- stringP "<="-  pure OperatorLE--geP :: Parser Operator-geP = do-  _ <- stringP ">="-  pure OperatorGE--ltP :: Parser Operator-ltP = do-  _ <- charP '<'-  pure OperatorLT--gtP :: Parser Operator-gtP = do-  _ <- charP '>'-  pure OperatorGT+operatorP :: ReadP.ReadP Operator+operatorP = ReadP.choice+  [ ReadP.string "<=" *> pure OperatorLE+  , ReadP.string ">=" *> pure OperatorGE+  , ReadP.char '<' *> pure OperatorLT+  , ReadP.char '>' *> pure OperatorGT+  , ReadP.char '=' *> pure OperatorEQ+  , ReadP.char '^' *> pure OperatorCaret+  , ReadP.char '~' *> pure OperatorTilde+  , pure OperatorEQ+  ] -eqP :: Parser Operator-eqP = do-  _ <- charP '='-  pure OperatorEQ+hyphenP :: ReadP.ReadP ()+hyphenP = do+  spaces1P+  Monad.void (ReadP.char '-')+  spaces1P -hyphenP :: Parser String-hyphenP = stringP " - "+orP :: ReadP.ReadP ()+orP = do+  spaces1P+  Monad.void (ReadP.string "||")+  spaces1P -orP :: Parser String-orP = stringP " || "+spaces1P :: ReadP.ReadP ()+spaces1P = Monad.void (ReadP.munch1 (== ' ')) -spaceP :: Parser Char-spaceP = charP ' '+spacesP :: ReadP.ReadP ()+spacesP = Monad.void (ReadP.munch (== ' '))  -- *** Helpers -parse :: Parser a -> String -> Maybe a-parse p s = safeHead (do-  (x, "") <- runParser p s-  pure x)--newtype Parser a = Parser { runParser :: String -> [(a, String)] }--instance Functor Parser where-  fmap f p = Parser (\s -> do-    (x, t) <- runParser p s-    pure (f x, t))--instance Applicative Parser where-  pure x = Parser (\ s -> pure (x, s))--  p <*> q = Parser (\ s -> do-    (f, t) <- runParser p s-    (x, u) <- runParser q t-    pure (f x, u))--instance Monad Parser where-  fail x = Parser (\ _ -> fail x)--  p >>= f = Parser (\ s -> do-    (x, t) <- runParser p s-    runParser (f x) t)--charP :: Char -> Parser Char-charP c = satisfyP (\ d -> d == c)--choiceP :: Parser a -> Parser a -> Parser a-choiceP p q = Parser (\ s -> case runParser p s of-  [] -> runParser q s-  xs -> xs)--failP :: Parser a-failP = fail undefined--getP :: Parser Char-getP = Parser (\ s -> case s of-  "" -> []-  c : t -> pure (c, t))--manyP :: Parser a -> Parser [a]-manyP p = choiceP (someP p) (pure [])--oneOfP :: [Parser a] -> Parser a-oneOfP ps = foldr choiceP failP ps--optionP :: a -> Parser a -> Parser a-optionP x p = choiceP p (pure x)--satisfyP :: (Char -> Bool) -> Parser Char-satisfyP f = do-  c <- getP-  if f c then pure c else failP--sepByP :: Parser b -> Parser a -> Parser [a]-sepByP q p = choiceP (sepBy1P q p) (pure [])--sepBy1P :: Parser b -> Parser a -> Parser [a]-sepBy1P q p = do-  x <- p-  xs <- optionP [] (do-    _ <- q-    sepBy1P q p)-  pure (x : xs)--someP :: Parser a -> Parser [a]-someP p = do-  x <- p-  xs <- manyP p-  pure (x : xs)--stringP :: String -> Parser String-stringP s = case s of-  "" -> pure s-  c : t -> do-    _ <- charP c-    _ <- stringP t-    pure s+parse :: ReadP.ReadP a -> String -> Maybe a+parse p s =+  let p' = ReadP.readP_to_S p+  in Maybe.listToMaybe (do+    (x, "") <- p' s+    pure x)  -- ** Rendering  renderPreReleases :: [PreRelease] -> String renderPreReleases ps = if null ps   then ""-  else '-' : join '.' (map renderPreRelease ps)+  else '-' : List.intercalate "." (map renderPreRelease ps)  renderBuilds :: [Build] -> String renderBuilds bs = if null bs   then ""-  else '+' : join '.' (map renderBuild bs)+  else '+' : List.intercalate "." (map renderBuild bs)  -- ** Helpers  both :: (a -> b) -> (a, a) -> (b, b) both f (x, y) = (f x, f y) -comparing :: Ord b => (a -> b) -> a -> a -> Ordering-comparing f x y = compare (f x) (f y)--isAsciiAlpha :: Char -> Bool-isAsciiAlpha c = (isAsciiAlphaUpper c) || (isAsciiAlphaLower c)--isAsciiAlphaLower :: Char -> Bool-isAsciiAlphaLower c = ('a' <= c) && (c <= 'z')--isAsciiAlphaUpper :: Char -> Bool-isAsciiAlphaUpper c = ('A' <= c) && (c <= 'Z')--isAsciiDigit :: Char -> Bool-isAsciiDigit c = ('0' <= c) && (c <= '9')- isAsciiDigitNonZero :: Char -> Bool-isAsciiDigitNonZero c = isAsciiDigit c && (c /= '0')+isAsciiDigitNonZero c = Char.isDigit c && (c /= '0')  isIdentifier :: Char -> Bool-isIdentifier c = (c == '-') || isAsciiDigit c || isAsciiAlpha c--join :: Char -> [String] -> String-join c ss = case ss of-  [] -> ""-  s : ts -> mconcat (s : map (\ t -> c : t) ts)+isIdentifier c = (Char.isAscii c && Char.isAlphaNum c) || (c == '-') -safeHead :: [a] -> Maybe a-safeHead xs = case xs of-  [] -> Nothing-  x : _ -> Just x+isWildcard :: Char -> Bool+isWildcard c = (c == 'x') || (c == '*') || (c == 'X')
salve.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           salve-version:        0.0.3+version:        0.0.4 synopsis:       Semantic version numbers and constraints. description:    Salve provides semantic version numbers and constraints. category:       Distribution@@ -57,4 +57,6 @@     , criterion >=1.1.0 && <1.3     , deepseq >=1.4.1 && <1.5     , salve+    , semver >=0.3.3 && <0.4+    , semver-range >=0.2.2 && <0.3   default-language: Haskell2010