    {-# LANGUAGE CPP                #-}
    {-# LANGUAGE DeriveAnyClass     #-}
    {-# LANGUAGE DeriveGeneric      #-}
    {-# LANGUAGE DeriveLift         #-}
    {-# LANGUAGE DerivingStrategies #-}
    {-# LANGUAGE OverloadedStrings  #-}
    {-# LANGUAGE Rank2Types         #-}

    -- |
    -- Module    : Data.Versions
    -- Copyright : (c) Colin Woodbury, 2015 - 2023
    -- License   : BSD3
    -- Maintainer: Colin Woodbury <colin@fosskers.ca>
    --
    -- A library for parsing and comparing software version numbers.
    --
    -- We like to give version numbers to our software in a myriad of different
    -- ways. Some ways follow strict guidelines for incrementing and comparison.
    -- Some follow conventional wisdom and are generally self-consistent. Some are
    -- just plain asinine. This library provides a means of parsing and comparing
    -- /any/ style of versioning, be it a nice Semantic Version like this:
    --
    -- > 1.2.3-r1+git123
    --
    -- ...or a monstrosity like this:
    --
    -- > 2:10.2+0.0093r3+1-1
    --
    -- Please switch to <http://semver.org Semantic Versioning> if you aren't
    -- currently using it. It provides consistency in version incrementing and has
    -- the best constraints on comparisons.
    --
    -- __This library implements version @2.0.0@ of the SemVer spec.__
    --
    -- == Using the Parsers
    -- In general, `versioning` is the function you want. It attempts to parse a
    -- given `Text` using the three individual parsers, `semver`, `version` and
    -- `mess`. If one fails, it tries the next. If you know you only want to parse
    -- one specific version type, use that parser directly (e.g. `semver`).

    module Data.Versions
      ( -- * Types
        Versioning(..), isIdeal, isGeneral, isComplex
      , SemVer(..)
      , PVP(..)
      , Version(..)
      , Mess(..), messMajor, messMinor, messPatch, messPatchChunk
      , Release(..)
      , Chunks(..)
      , Chunk(..)
      , MChunk(..)
      , VSep(..)
        -- * Parsing Versions
      , ParsingError
      , versioning, semver, pvp, version, mess
        -- ** Megaparsec Parsers
        -- | For when you'd like to mix version parsing into some larger parser.
      , versioning', semver', pvp', version', mess'
        -- * Pretty Printing
      , prettyV, prettySemVer, prettyPVP, prettyVer, prettyMess, errorBundlePretty
        -- * Lenses
      , Lens'
      , Traversal'
      , Semantic(..)
        -- ** Traversing Text
        -- | When traversing `Text`, leveraging its `Semantic` instance will
        -- likely benefit you more than using these Traversals directly.
      , _Versioning, _SemVer, _Version, _Mess
        -- ** Versioning Traversals
      , _Ideal, _General, _Complex
        -- ** (General) Version Lenses
      , epoch
      ) where

    import qualified Control.Applicative.Combinators.NonEmpty as PC
    import           Control.DeepSeq
    import           Control.Monad (unless, void)
    import           Data.Char (isAlpha, isAlphaNum)
    import           Data.Foldable (fold)
    import           Data.Hashable (Hashable)
    import           Data.List (intersperse)
    import           Data.List.NonEmpty (NonEmpty(..))
    import qualified Data.List.NonEmpty as NEL
    import           Data.Maybe (fromMaybe, listToMaybe, mapMaybe)
    import           Data.Text (Text)
    import qualified Data.Text as T
    import           Data.Void (Void)
    import           GHC.Generics (Generic)
    import           Language.Haskell.TH.Syntax (Lift)
    import           Text.Megaparsec hiding (chunk)
    import           Text.Megaparsec.Char
    import qualified Text.Megaparsec.Char.Lexer as L
    import           Text.Megaparsec.Char.Lexer (decimal)

    ---

    -- | A top-level Versioning type. Acts as a wrapper for the more specific types.
    -- This allows each subtype to have its own parser, and for said parsers to be
    -- composed. This is useful for specifying custom behaviour for when a certain
    -- parser fails.
    data Versioning = Ideal SemVer | General Version | Complex Mess
      deriving (Versioning -> Versioning -> Bool
    (Versioning -> Versioning -> Bool)
    -> (Versioning -> Versioning -> Bool) -> Eq Versioning
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Versioning -> Versioning -> Bool
    == :: Versioning -> Versioning -> Bool
    $c/= :: Versioning -> Versioning -> Bool
    /= :: Versioning -> Versioning -> Bool
    Eq, Int -> Versioning -> ShowS
    [Versioning] -> ShowS
    Versioning -> String
    (Int -> Versioning -> ShowS)
    -> (Versioning -> String)
    -> ([Versioning] -> ShowS)
    -> Show Versioning
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Versioning -> ShowS
    showsPrec :: Int -> Versioning -> ShowS
    $cshow :: Versioning -> String
    show :: Versioning -> String
    $cshowList :: [Versioning] -> ShowS
    showList :: [Versioning] -> ShowS
    Show, (forall x. Versioning -> Rep Versioning x)
    -> (forall x. Rep Versioning x -> Versioning) -> Generic Versioning
    forall x. Rep Versioning x -> Versioning
    forall x. Versioning -> Rep Versioning x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Versioning -> Rep Versioning x
    from :: forall x. Versioning -> Rep Versioning x
    $cto :: forall x. Rep Versioning x -> Versioning
    to :: forall x. Rep Versioning x -> Versioning
    Generic, Versioning -> ()
    (Versioning -> ()) -> NFData Versioning
    forall a. (a -> ()) -> NFData a
    $crnf :: Versioning -> ()
    rnf :: Versioning -> ()
    NFData, Eq Versioning
    Eq Versioning
    -> (Int -> Versioning -> Int)
    -> (Versioning -> Int)
    -> Hashable Versioning
    Int -> Versioning -> Int
    Versioning -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> Versioning -> Int
    hashWithSalt :: Int -> Versioning -> Int
    $chash :: Versioning -> Int
    hash :: Versioning -> Int
    Hashable, (forall (m :: * -> *). Quote m => Versioning -> m Exp)
    -> (forall (m :: * -> *).
        Quote m =>
        Versioning -> Code m Versioning)
    -> Lift Versioning
    forall t.
    (forall (m :: * -> *). Quote m => t -> m Exp)
    -> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
    forall (m :: * -> *). Quote m => Versioning -> m Exp
    forall (m :: * -> *). Quote m => Versioning -> Code m Versioning
    $clift :: forall (m :: * -> *). Quote m => Versioning -> m Exp
    lift :: forall (m :: * -> *). Quote m => Versioning -> m Exp
    $cliftTyped :: forall (m :: * -> *). Quote m => Versioning -> Code m Versioning
    liftTyped :: forall (m :: * -> *). Quote m => Versioning -> Code m Versioning
    Lift)

    -- | Short-hand for detecting a `SemVer`.
    isIdeal :: Versioning -> Bool
    isIdeal :: Versioning -> Bool
    isIdeal (Ideal SemVer
    _) = Bool
    True
    isIdeal Versioning
    _         = Bool
    False

    -- | Short-hand for detecting a `Version`.
    isGeneral :: Versioning -> Bool
    isGeneral :: Versioning -> Bool
    isGeneral (General Version
    _) = Bool
    True
    isGeneral Versioning
    _           = Bool
    False

    -- | Short-hand for detecting a `Mess`.
    isComplex :: Versioning -> Bool
    isComplex :: Versioning -> Bool
    isComplex (Complex Mess
    _) = Bool
    True
    isComplex Versioning
    _           = Bool
    False

    -- | Comparison of @Ideal@s is always well defined.
    --
    -- If comparison of @General@s is well-defined, then comparison of @Ideal@ and
    -- @General@ is well-defined, as there exists a perfect mapping from @Ideal@ to
    -- @General@.
    --
    -- If comparison of @Complex@es is well-defined, then comparison of @General@
    -- and @Complex@ is well defined for the same reason. This implies comparison of
    -- @Ideal@ and @Complex@ is also well-defined.
    instance Ord Versioning where
      compare :: Versioning -> Versioning -> Ordering
    compare (Ideal SemVer
    s)     (Ideal SemVer
    s')   = SemVer -> SemVer -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare SemVer
    s SemVer
    s'
      compare (General Version
    v)   (General Version
    v') = Version -> Version -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Version
    v Version
    v'
      compare (Complex Mess
    m)   (Complex Mess
    m') = Mess -> Mess -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Mess
    m Mess
    m'
      compare (Ideal SemVer
    s)     (General Version
    v)  = SemVer -> Version -> Ordering
    semverAndVer SemVer
    s Version
    v
      compare (General Version
    v)   (Ideal SemVer
    s)    = Ordering -> Ordering
    opposite (Ordering -> Ordering) -> Ordering -> Ordering
    forall a b. (a -> b) -> a -> b
    $ SemVer -> Version -> Ordering
    semverAndVer SemVer
    s Version
    v
      compare (General Version
    v)   (Complex Mess
    m)  = Mess -> Mess -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare (Version -> Mess
    mFromV Version
    v) Mess
    m
      compare (Complex Mess
    m)   (General Version
    v)  = Ordering -> Ordering
    opposite (Ordering -> Ordering) -> Ordering -> Ordering
    forall a b. (a -> b) -> a -> b
    $ Mess -> Mess -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare (Version -> Mess
    mFromV Version
    v) Mess
    m
      compare (Ideal SemVer
    s)     (Complex Mess
    m)  = SemVer -> Mess -> Ordering
    semverAndMess SemVer
    s Mess
    m
      compare (Complex Mess
    m)   (Ideal SemVer
    s)    = Ordering -> Ordering
    opposite (Ordering -> Ordering) -> Ordering -> Ordering
    forall a b. (a -> b) -> a -> b
    $ SemVer -> Mess -> Ordering
    semverAndMess SemVer
    s Mess
    m

    -- | Convert a `SemVer` to a `Version`.
    vFromS :: SemVer -> Version
    vFromS :: SemVer -> Version
    vFromS (SemVer Word
    ma Word
    mi Word
    pa Maybe Release
    re Maybe Text
    me) =
      Version
      { _vEpoch :: Maybe Word
    _vEpoch = Maybe Word
    forall a. Maybe a
    Nothing
      , _vChunks :: Chunks
    _vChunks = NonEmpty Chunk -> Chunks
    Chunks (NonEmpty Chunk -> Chunks) -> NonEmpty Chunk -> Chunks
    forall a b. (a -> b) -> a -> b
    $ Word -> Chunk
    Numeric Word
    ma Chunk -> [Chunk] -> NonEmpty Chunk
    forall a. a -> [a] -> NonEmpty a
    :| [Word -> Chunk
    Numeric Word
    mi, Word -> Chunk
    Numeric Word
    pa]
      , _vMeta :: Maybe Text
    _vMeta = Maybe Text
    me
      , _vRel :: Maybe Release
    _vRel = Maybe Release
    re }

    -- | Convert a `Version` to a `Mess`.
    mFromV :: Version -> Mess
    mFromV :: Version -> Mess
    mFromV (Version Maybe Word
    me (Chunks NonEmpty Chunk
    v) Maybe Release
    r Maybe Text
    _) = case Maybe Word
    me of
      Maybe Word
    Nothing -> Mess
    f
      Just Word
    e  ->
        let cs :: NonEmpty MChunk
    cs = (MChunk -> [MChunk] -> NonEmpty MChunk
    forall a. a -> [a] -> NonEmpty a
    :| []) (MChunk -> NonEmpty MChunk)
    -> (Text -> MChunk) -> Text -> NonEmpty MChunk
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word -> Text -> MChunk
    MDigit Word
    e (Text -> NonEmpty MChunk) -> Text -> NonEmpty MChunk
    forall a b. (a -> b) -> a -> b
    $ Word -> Text
    forall a. Show a => a -> Text
    showt Word
    e
        in NonEmpty MChunk -> Maybe (VSep, Mess) -> Mess
    Mess NonEmpty MChunk
    cs (Maybe (VSep, Mess) -> Mess) -> Maybe (VSep, Mess) -> Mess
    forall a b. (a -> b) -> a -> b
    $ (VSep, Mess) -> Maybe (VSep, Mess)
    forall a. a -> Maybe a
    Just (VSep
    VColon, Mess
    f)
      where
        f :: Mess
        f :: Mess
    f = NonEmpty MChunk -> Maybe (VSep, Mess) -> Mess
    Mess NonEmpty MChunk
    cs (Maybe (VSep, Mess) -> Mess) -> Maybe (VSep, Mess) -> Mess
    forall a b. (a -> b) -> a -> b
    $ (Release -> (VSep, Mess)) -> Maybe Release -> Maybe (VSep, Mess)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Release -> (VSep, Mess)
    g Maybe Release
    r
          where
            cs :: NonEmpty MChunk
    cs = (Chunk -> MChunk) -> NonEmpty Chunk -> NonEmpty MChunk
    forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
    NEL.map Chunk -> MChunk
    toMChunk NonEmpty Chunk
    v

        g :: Release -> (VSep, Mess)
        g :: Release -> (VSep, Mess)
    g (Release NonEmpty Chunk
    cs) = (VSep
    VHyphen, NonEmpty MChunk -> Maybe (VSep, Mess) -> Mess
    Mess NonEmpty MChunk
    ms Maybe (VSep, Mess)
    forall a. Maybe a
    Nothing)
          where
            ms :: NonEmpty MChunk
    ms = (Chunk -> MChunk) -> NonEmpty Chunk -> NonEmpty MChunk
    forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
    NEL.map Chunk -> MChunk
    toMChunk NonEmpty Chunk
    cs

    semverAndVer :: SemVer -> Version -> Ordering
    -- A `Version` with a non-zero epoch value is automatically greater than any
    -- `SemVer`.
    semverAndVer :: SemVer -> Version -> Ordering
    semverAndVer SemVer
    _ (Version (Just Word
    e) Chunks
    _ Maybe Release
    _ Maybe Text
    _) | Word
    e Word -> Word -> Bool
    forall a. Ord a => a -> a -> Bool
    > Word
    0 = Ordering
    LT
    semverAndVer (SemVer Word
    ma Word
    mi Word
    pa Maybe Release
    sr Maybe Text
    _) (Version Maybe Word
    _ (Chunks NonEmpty Chunk
    vc) Maybe Release
    vr Maybe Text
    _) =
      case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    ma (Word -> Ordering) -> Maybe Word -> Maybe Ordering
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Int -> [Chunk] -> Maybe Chunk
    nth Int
    0 [Chunk]
    vc' Maybe Chunk -> (Chunk -> Maybe Word) -> Maybe Word
    forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Chunk -> Maybe Word
    singleDigitLenient) of
        Maybe Ordering
    Nothing -> Ordering
    GT
        Just Ordering
    GT -> Ordering
    GT
        Just Ordering
    LT -> Ordering
    LT
        Just Ordering
    EQ -> case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    mi (Word -> Ordering) -> Maybe Word -> Maybe Ordering
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Int -> [Chunk] -> Maybe Chunk
    nth Int
    1 [Chunk]
    vc' Maybe Chunk -> (Chunk -> Maybe Word) -> Maybe Word
    forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Chunk -> Maybe Word
    singleDigitLenient) of
          Maybe Ordering
    Nothing -> Ordering
    GT
          Just Ordering
    GT -> Ordering
    GT
          Just Ordering
    LT -> Ordering
    LT
          Just Ordering
    EQ -> case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    pa (Word -> Ordering) -> Maybe Word -> Maybe Ordering
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Int -> [Chunk] -> Maybe Chunk
    nth Int
    2 [Chunk]
    vc' Maybe Chunk -> (Chunk -> Maybe Word) -> Maybe Word
    forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Chunk -> Maybe Word
    singleDigitLenient) of
            Maybe Ordering
    Nothing -> Ordering
    GT
            Just Ordering
    GT -> Ordering
    GT
            Just Ordering
    LT -> Ordering
    LT
            -- By thes point, the major/minor/patch positions have all been equal.
            -- If there is a fourth position, its type, not its value, will
            -- determine which overall version is greater.
            Just Ordering
    EQ -> case Int -> [Chunk] -> Maybe Chunk
    nth Int
    3 [Chunk]
    vc' of
              -- 1.2.3 > 1.2.3.git
              Just (Alphanum Text
    _) -> Ordering
    GT
              -- 1.2.3 < 1.2.3.0
              Just (Numeric Word
    _)  -> Ordering
    LT
              Maybe Chunk
    Nothing           -> Maybe Release -> Maybe Release -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Maybe Release
    sr Maybe Release
    vr
     where
       vc' :: [Chunk]
       vc' :: [Chunk]
    vc' = NonEmpty Chunk -> [Chunk]
    forall a. NonEmpty a -> [a]
    NEL.toList NonEmpty Chunk
    vc

       nth :: Int -> [Chunk] -> Maybe Chunk
       nth :: Int -> [Chunk] -> Maybe Chunk
    nth Int
    _ []     = Maybe Chunk
    forall a. Maybe a
    Nothing
       nth Int
    0 (Chunk
    c:[Chunk]
    _)  = Chunk -> Maybe Chunk
    forall a. a -> Maybe a
    Just Chunk
    c
       nth Int
    n (Chunk
    _:[Chunk]
    cs) = Int -> [Chunk] -> Maybe Chunk
    nth (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1) [Chunk]
    cs

    -- | Special logic for when semver-like values can be extracted from a `Mess`.
    -- This avoids having to "downcast" the `SemVer` into a `Mess` before comparing,
    -- and in some cases can offer better comparison results.
    semverAndMess :: SemVer -> Mess -> Ordering
    semverAndMess :: SemVer -> Mess -> Ordering
    semverAndMess s :: SemVer
    s@(SemVer Word
    ma Word
    mi Word
    pa Maybe Release
    _ Maybe Text
    _) Mess
    m = case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    ma (Word -> Ordering) -> Maybe Word -> Maybe Ordering
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Mess -> Maybe Word
    messMajor Mess
    m of
      Maybe Ordering
    Nothing -> Ordering
    fallback
      Just Ordering
    LT -> Ordering
    LT
      Just Ordering
    GT -> Ordering
    GT
      Just Ordering
    EQ -> case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    mi (Word -> Ordering) -> Maybe Word -> Maybe Ordering
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Mess -> Maybe Word
    messMinor Mess
    m of
        Maybe Ordering
    Nothing -> Ordering
    fallback
        Just Ordering
    LT -> Ordering
    LT
        Just Ordering
    GT -> Ordering
    GT
        Just Ordering
    EQ -> case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    pa (Word -> Ordering) -> Maybe Word -> Maybe Ordering
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Mess -> Maybe Word
    messPatch Mess
    m of
          Just Ordering
    LT -> Ordering
    LT
          Just Ordering
    GT -> Ordering
    GT
          -- If they've been equal up to this point, the `Mess`
          -- will by definition have more to it, meaning that
          -- it's more likely to be newer, despite its poor shape.
          Just Ordering
    EQ -> Ordering
    fallback
          -- Even if we weren't able to extract a standalone patch number, we might
          -- still be able to find a number at the head of the `Chunk` in that
          -- position.
          Maybe Ordering
    Nothing -> case Mess -> Maybe Chunk
    messPatchChunk Mess
    m Maybe Chunk -> (Chunk -> Maybe Word) -> Maybe Word
    forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Chunk -> Maybe Word
    singleDigitLenient of
            -- We were very close, but in the end the `Mess` had a nonsensical value
            -- in its patch position.
            Maybe Word
    Nothing  -> Ordering
    fallback
            Just Word
    pa' -> case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    pa Word
    pa' of
              Ordering
    LT -> Ordering
    LT
              Ordering
    GT -> Ordering
    GT
              -- This follows semver's rule that pre-releases have lower precedence.
              Ordering
    EQ -> Ordering
    GT
      where
        fallback :: Ordering
        fallback :: Ordering
    fallback = Versioning -> Versioning -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare (Version -> Versioning
    General (Version -> Versioning) -> Version -> Versioning
    forall a b. (a -> b) -> a -> b
    $ SemVer -> Version
    vFromS SemVer
    s) (Mess -> Versioning
    Complex Mess
    m)

    instance Semantic Versioning where
      major :: Traversal' Versioning Word
    major Word -> f Word
    f (Ideal SemVer
    v)   = SemVer -> Versioning
    Ideal   (SemVer -> Versioning) -> f SemVer -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word -> f Word) -> SemVer -> f SemVer
    forall v. Semantic v => Traversal' v Word
    Traversal' SemVer Word
    major Word -> f Word
    f SemVer
    v
      major Word -> f Word
    f (General Version
    v) = Version -> Versioning
    General (Version -> Versioning) -> f Version -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word -> f Word) -> Version -> f Version
    forall v. Semantic v => Traversal' v Word
    Traversal' Version Word
    major Word -> f Word
    f Version
    v
      major Word -> f Word
    f (Complex Mess
    v) = Mess -> Versioning
    Complex (Mess -> Versioning) -> f Mess -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word -> f Word) -> Mess -> f Mess
    forall v. Semantic v => Traversal' v Word
    Traversal' Mess Word
    major Word -> f Word
    f Mess
    v
      {-# INLINE major #-}

      minor :: Traversal' Versioning Word
    minor Word -> f Word
    f (Ideal SemVer
    v)   = SemVer -> Versioning
    Ideal   (SemVer -> Versioning) -> f SemVer -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word -> f Word) -> SemVer -> f SemVer
    forall v. Semantic v => Traversal' v Word
    Traversal' SemVer Word
    minor Word -> f Word
    f SemVer
    v
      minor Word -> f Word
    f (General Version
    v) = Version -> Versioning
    General (Version -> Versioning) -> f Version -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word -> f Word) -> Version -> f Version
    forall v. Semantic v => Traversal' v Word
    Traversal' Version Word
    minor Word -> f Word
    f Version
    v
      minor Word -> f Word
    f (Complex Mess
    v) = Mess -> Versioning
    Complex (Mess -> Versioning) -> f Mess -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word -> f Word) -> Mess -> f Mess
    forall v. Semantic v => Traversal' v Word
    Traversal' Mess Word
    minor Word -> f Word
    f Mess
    v
      {-# INLINE minor #-}

      patch :: Traversal' Versioning Word
    patch Word -> f Word
    f (Ideal SemVer
    v)   = SemVer -> Versioning
    Ideal   (SemVer -> Versioning) -> f SemVer -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word -> f Word) -> SemVer -> f SemVer
    forall v. Semantic v => Traversal' v Word
    Traversal' SemVer Word
    patch Word -> f Word
    f SemVer
    v
      patch Word -> f Word
    f (General Version
    v) = Version -> Versioning
    General (Version -> Versioning) -> f Version -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word -> f Word) -> Version -> f Version
    forall v. Semantic v => Traversal' v Word
    Traversal' Version Word
    patch Word -> f Word
    f Version
    v
      patch Word -> f Word
    f (Complex Mess
    v) = Mess -> Versioning
    Complex (Mess -> Versioning) -> f Mess -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word -> f Word) -> Mess -> f Mess
    forall v. Semantic v => Traversal' v Word
    Traversal' Mess Word
    patch Word -> f Word
    f Mess
    v
      {-# INLINE patch #-}

      release :: Traversal' Versioning (Maybe Release)
    release Maybe Release -> f (Maybe Release)
    f (Ideal SemVer
    v)   = SemVer -> Versioning
    Ideal   (SemVer -> Versioning) -> f SemVer -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Maybe Release -> f (Maybe Release)) -> SemVer -> f SemVer
    forall v. Semantic v => Traversal' v (Maybe Release)
    Traversal' SemVer (Maybe Release)
    release Maybe Release -> f (Maybe Release)
    f SemVer
    v
      release Maybe Release -> f (Maybe Release)
    f (General Version
    v) = Version -> Versioning
    General (Version -> Versioning) -> f Version -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Maybe Release -> f (Maybe Release)) -> Version -> f Version
    forall v. Semantic v => Traversal' v (Maybe Release)
    Traversal' Version (Maybe Release)
    release Maybe Release -> f (Maybe Release)
    f Version
    v
      release Maybe Release -> f (Maybe Release)
    f (Complex Mess
    v) = Mess -> Versioning
    Complex (Mess -> Versioning) -> f Mess -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Maybe Release -> f (Maybe Release)) -> Mess -> f Mess
    forall v. Semantic v => Traversal' v (Maybe Release)
    Traversal' Mess (Maybe Release)
    release Maybe Release -> f (Maybe Release)
    f Mess
    v
      {-# INLINE release #-}

      meta :: Traversal' Versioning (Maybe Text)
    meta Maybe Text -> f (Maybe Text)
    f (Ideal SemVer
    v)   = SemVer -> Versioning
    Ideal   (SemVer -> Versioning) -> f SemVer -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Maybe Text -> f (Maybe Text)) -> SemVer -> f SemVer
    forall v. Semantic v => Traversal' v (Maybe Text)
    Traversal' SemVer (Maybe Text)
    meta Maybe Text -> f (Maybe Text)
    f SemVer
    v
      meta Maybe Text -> f (Maybe Text)
    f (General Version
    v) = Version -> Versioning
    General (Version -> Versioning) -> f Version -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Maybe Text -> f (Maybe Text)) -> Version -> f Version
    forall v. Semantic v => Traversal' v (Maybe Text)
    Traversal' Version (Maybe Text)
    meta Maybe Text -> f (Maybe Text)
    f Version
    v
      meta Maybe Text -> f (Maybe Text)
    f (Complex Mess
    v) = Mess -> Versioning
    Complex (Mess -> Versioning) -> f Mess -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Maybe Text -> f (Maybe Text)) -> Mess -> f Mess
    forall v. Semantic v => Traversal' v (Maybe Text)
    Traversal' Mess (Maybe Text)
    meta Maybe Text -> f (Maybe Text)
    f Mess
    v
      {-# INLINE meta #-}

      semantic :: Traversal' Versioning SemVer
    semantic SemVer -> f SemVer
    f (Ideal SemVer
    v)   = SemVer -> Versioning
    Ideal   (SemVer -> Versioning) -> f SemVer -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (SemVer -> f SemVer) -> SemVer -> f SemVer
    forall v. Semantic v => Traversal' v SemVer
    Traversal' SemVer SemVer
    semantic SemVer -> f SemVer
    f SemVer
    v
      semantic SemVer -> f SemVer
    f (General Version
    v) = Version -> Versioning
    General (Version -> Versioning) -> f Version -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (SemVer -> f SemVer) -> Version -> f Version
    forall v. Semantic v => Traversal' v SemVer
    Traversal' Version SemVer
    semantic SemVer -> f SemVer
    f Version
    v
      semantic SemVer -> f SemVer
    f (Complex Mess
    v) = Mess -> Versioning
    Complex (Mess -> Versioning) -> f Mess -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (SemVer -> f SemVer) -> Mess -> f Mess
    forall v. Semantic v => Traversal' v SemVer
    Traversal' Mess SemVer
    semantic SemVer -> f SemVer
    f Mess
    v
      {-# INLINE semantic #-}

    -- | Traverse some Text for its inner versioning.
    --
    -- @
    -- λ "1.2.3" & _Versioning . _Ideal . patch %~ (+ 1)  -- or just: "1.2.3" & patch %~ (+ 1)
    -- "1.2.4"
    -- @
    _Versioning :: Traversal' Text Versioning
    _Versioning :: Traversal' Text Versioning
    _Versioning Versioning -> f Versioning
    f Text
    t = (ParsingError -> f Text)
    -> (Versioning -> f Text)
    -> Either ParsingError Versioning
    -> f Text
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (f Text -> ParsingError -> f Text
    forall a b. a -> b -> a
    const (Text -> f Text
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Text
    t)) ((Versioning -> Text) -> f Versioning -> f Text
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Versioning -> Text
    prettyV (f Versioning -> f Text)
    -> (Versioning -> f Versioning) -> Versioning -> f Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Versioning -> f Versioning
    f) (Either ParsingError Versioning -> f Text)
    -> Either ParsingError Versioning -> f Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Either ParsingError Versioning
    versioning Text
    t
    {-# INLINE _Versioning #-}

    -- | Traverse some Text for its inner SemVer.
    _SemVer :: Traversal' Text SemVer
    _SemVer :: Traversal' Text SemVer
    _SemVer SemVer -> f SemVer
    f Text
    t = (ParsingError -> f Text)
    -> (SemVer -> f Text) -> Either ParsingError SemVer -> f Text
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (f Text -> ParsingError -> f Text
    forall a b. a -> b -> a
    const (Text -> f Text
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Text
    t)) ((SemVer -> Text) -> f SemVer -> f Text
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap SemVer -> Text
    prettySemVer (f SemVer -> f Text) -> (SemVer -> f SemVer) -> SemVer -> f Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SemVer -> f SemVer
    f) (Either ParsingError SemVer -> f Text)
    -> Either ParsingError SemVer -> f Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Either ParsingError SemVer
    semver Text
    t
    {-# INLINE _SemVer #-}

    -- | Traverse some Text for its inner Version.
    _Version :: Traversal' Text Version
    _Version :: Traversal' Text Version
    _Version Version -> f Version
    f Text
    t = (ParsingError -> f Text)
    -> (Version -> f Text) -> Either ParsingError Version -> f Text
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (f Text -> ParsingError -> f Text
    forall a b. a -> b -> a
    const (Text -> f Text
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Text
    t)) ((Version -> Text) -> f Version -> f Text
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Version -> Text
    prettyVer (f Version -> f Text)
    -> (Version -> f Version) -> Version -> f Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Version -> f Version
    f) (Either ParsingError Version -> f Text)
    -> Either ParsingError Version -> f Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Either ParsingError Version
    version Text
    t
    {-# INLINE _Version #-}

    -- | Traverse some Text for its inner Mess.
    _Mess :: Traversal' Text Mess
    _Mess :: Traversal' Text Mess
    _Mess Mess -> f Mess
    f Text
    t = (ParsingError -> f Text)
    -> (Mess -> f Text) -> Either ParsingError Mess -> f Text
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (f Text -> ParsingError -> f Text
    forall a b. a -> b -> a
    const (Text -> f Text
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Text
    t)) ((Mess -> Text) -> f Mess -> f Text
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Mess -> Text
    prettyMess (f Mess -> f Text) -> (Mess -> f Mess) -> Mess -> f Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Mess -> f Mess
    f) (Either ParsingError Mess -> f Text)
    -> Either ParsingError Mess -> f Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Either ParsingError Mess
    mess Text
    t
    {-# INLINE _Mess #-}

    -- | Possibly extract a `SemVer` from a `Versioning`.
    _Ideal :: Traversal' Versioning SemVer
    _Ideal :: Traversal' Versioning SemVer
    _Ideal SemVer -> f SemVer
    f (Ideal SemVer
    s) = SemVer -> Versioning
    Ideal (SemVer -> Versioning) -> f SemVer -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> SemVer -> f SemVer
    f SemVer
    s
    _Ideal SemVer -> f SemVer
    _ Versioning
    v         = Versioning -> f Versioning
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Versioning
    v
    {-# INLINE _Ideal #-}

    -- | Possibly extract a `Version` from a `Versioning`.
    _General :: Traversal' Versioning Version
    _General :: Traversal' Versioning Version
    _General Version -> f Version
    f (General Version
    v) = Version -> Versioning
    General (Version -> Versioning) -> f Version -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Version -> f Version
    f Version
    v
    _General Version -> f Version
    _ Versioning
    v           = Versioning -> f Versioning
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Versioning
    v
    {-# INLINE _General #-}

    -- | Possibly extract a `Mess` from a `Versioning`.
    _Complex :: Traversal' Versioning Mess
    _Complex :: Traversal' Versioning Mess
    _Complex Mess -> f Mess
    f (Complex Mess
    m) = Mess -> Versioning
    Complex (Mess -> Versioning) -> f Mess -> f Versioning
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Mess -> f Mess
    f Mess
    m
    _Complex Mess -> f Mess
    _ Versioning
    v           = Versioning -> f Versioning
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Versioning
    v
    {-# INLINE _Complex #-}

    -- | Simple Lenses compatible with both lens and microlens.
    type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s

    -- | Simple Traversals compatible with both lens and microlens.
    type Traversal' s a = forall f. Applicative f => (a -> f a) -> s -> f s

    -- | Version types which sanely and safely yield `SemVer`-like information about
    -- themselves. For instances other than `SemVer` itself however, these optics
    -- may /not/ yield anything, depending on the actual value being traversed.
    -- Hence, the optics here are all `Traversal'`s.
    --
    -- Consider the `Version` @1.2.3.4.5@. We can imagine wanting to increment the
    -- minor number:
    --
    -- @
    -- λ "1.2.3.4.5" & minor %~ (+ 1)
    -- "1.3.3.4.5"
    -- @
    --
    -- But of course something like this would fail:
    --
    -- @
    -- λ "1.e.3.4.5" & minor %~ (+ 1)
    -- "1.e.3.4.5"
    -- @
    --
    -- However!
    --
    -- @
    -- λ "1.e.3.4.5" & major %~ (+ 1)
    -- "2.e.3.4.5"
    -- @
    class Semantic v where
      -- | @MAJOR.minor.patch-prerel+meta@
      major    :: Traversal' v Word
      -- | @major.MINOR.patch-prerel+meta@
      minor    :: Traversal' v Word
      -- | @major.minor.PATCH-prerel+meta@
      patch    :: Traversal' v Word
      -- | @major.minor.patch-PREREL+meta@
      release  :: Traversal' v (Maybe Release)
      -- | @major.minor.patch-prerel+META@
      meta     :: Traversal' v (Maybe Text)
      -- | A Natural Transformation into an proper `SemVer`.
      semantic :: Traversal' v SemVer

    instance Semantic Text where
      major :: Traversal' Text Word
    major    = (Versioning -> f Versioning) -> Text -> f Text
    Traversal' Text Versioning
    _Versioning ((Versioning -> f Versioning) -> Text -> f Text)
    -> ((Word -> f Word) -> Versioning -> f Versioning)
    -> (Word -> f Word)
    -> Text
    -> f Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Word -> f Word) -> Versioning -> f Versioning
    forall v. Semantic v => Traversal' v Word
    Traversal' Versioning Word
    major
      minor :: Traversal' Text Word
    minor    = (Versioning -> f Versioning) -> Text -> f Text
    Traversal' Text Versioning
    _Versioning ((Versioning -> f Versioning) -> Text -> f Text)
    -> ((Word -> f Word) -> Versioning -> f Versioning)
    -> (Word -> f Word)
    -> Text
    -> f Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Word -> f Word) -> Versioning -> f Versioning
    forall v. Semantic v => Traversal' v Word
    Traversal' Versioning Word
    minor
      patch :: Traversal' Text Word
    patch    = (Versioning -> f Versioning) -> Text -> f Text
    Traversal' Text Versioning
    _Versioning ((Versioning -> f Versioning) -> Text -> f Text)
    -> ((Word -> f Word) -> Versioning -> f Versioning)
    -> (Word -> f Word)
    -> Text
    -> f Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Word -> f Word) -> Versioning -> f Versioning
    forall v. Semantic v => Traversal' v Word
    Traversal' Versioning Word
    patch
      release :: Traversal' Text (Maybe Release)
    release  = (Versioning -> f Versioning) -> Text -> f Text
    Traversal' Text Versioning
    _Versioning ((Versioning -> f Versioning) -> Text -> f Text)
    -> ((Maybe Release -> f (Maybe Release))
        -> Versioning -> f Versioning)
    -> (Maybe Release -> f (Maybe Release))
    -> Text
    -> f Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Maybe Release -> f (Maybe Release)) -> Versioning -> f Versioning
    forall v. Semantic v => Traversal' v (Maybe Release)
    Traversal' Versioning (Maybe Release)
    release
      meta :: Traversal' Text (Maybe Text)
    meta     = (Versioning -> f Versioning) -> Text -> f Text
    Traversal' Text Versioning
    _Versioning ((Versioning -> f Versioning) -> Text -> f Text)
    -> ((Maybe Text -> f (Maybe Text)) -> Versioning -> f Versioning)
    -> (Maybe Text -> f (Maybe Text))
    -> Text
    -> f Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Maybe Text -> f (Maybe Text)) -> Versioning -> f Versioning
    forall v. Semantic v => Traversal' v (Maybe Text)
    Traversal' Versioning (Maybe Text)
    meta
      semantic :: Traversal' Text SemVer
    semantic = (SemVer -> f SemVer) -> Text -> f Text
    Traversal' Text SemVer
    _SemVer

    --------------------------------------------------------------------------------
    -- (Ideal) SemVer

    -- | An (Ideal) version number that conforms to Semantic Versioning.
    -- This is a /prescriptive/ parser, meaning it follows the SemVer standard.
    --
    -- Legal semvers are of the form: MAJOR.MINOR.PATCH-PREREL+META
    --
    -- Example: @1.2.3-r1+commithash@
    --
    -- Extra Rules:
    --
    -- 1. Pre-release versions have /lower/ precedence than normal versions.
    --
    -- 2. Build metadata does not affect version precedence.
    --
    -- 3. PREREL and META strings may only contain ASCII alphanumerics and hyphens.
    --
    -- For more information, see http://semver.org
    data SemVer = SemVer
      { SemVer -> Word
    _svMajor  :: !Word
      , SemVer -> Word
    _svMinor  :: !Word
      , SemVer -> Word
    _svPatch  :: !Word
      , SemVer -> Maybe Release
    _svPreRel :: !(Maybe Release)
      , SemVer -> Maybe Text
    _svMeta   :: !(Maybe Text) }
      deriving stock (Int -> SemVer -> ShowS
    [SemVer] -> ShowS
    SemVer -> String
    (Int -> SemVer -> ShowS)
    -> (SemVer -> String) -> ([SemVer] -> ShowS) -> Show SemVer
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SemVer -> ShowS
    showsPrec :: Int -> SemVer -> ShowS
    $cshow :: SemVer -> String
    show :: SemVer -> String
    $cshowList :: [SemVer] -> ShowS
    showList :: [SemVer] -> ShowS
    Show, (forall x. SemVer -> Rep SemVer x)
    -> (forall x. Rep SemVer x -> SemVer) -> Generic SemVer
    forall x. Rep SemVer x -> SemVer
    forall x. SemVer -> Rep SemVer x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. SemVer -> Rep SemVer x
    from :: forall x. SemVer -> Rep SemVer x
    $cto :: forall x. Rep SemVer x -> SemVer
    to :: forall x. Rep SemVer x -> SemVer
    Generic, (forall (m :: * -> *). Quote m => SemVer -> m Exp)
    -> (forall (m :: * -> *). Quote m => SemVer -> Code m SemVer)
    -> Lift SemVer
    forall t.
    (forall (m :: * -> *). Quote m => t -> m Exp)
    -> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
    forall (m :: * -> *). Quote m => SemVer -> m Exp
    forall (m :: * -> *). Quote m => SemVer -> Code m SemVer
    $clift :: forall (m :: * -> *). Quote m => SemVer -> m Exp
    lift :: forall (m :: * -> *). Quote m => SemVer -> m Exp
    $cliftTyped :: forall (m :: * -> *). Quote m => SemVer -> Code m SemVer
    liftTyped :: forall (m :: * -> *). Quote m => SemVer -> Code m SemVer
    Lift)
      deriving anyclass (SemVer -> ()
    (SemVer -> ()) -> NFData SemVer
    forall a. (a -> ()) -> NFData a
    $crnf :: SemVer -> ()
    rnf :: SemVer -> ()
    NFData, Eq SemVer
    Eq SemVer
    -> (Int -> SemVer -> Int) -> (SemVer -> Int) -> Hashable SemVer
    Int -> SemVer -> Int
    SemVer -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> SemVer -> Int
    hashWithSalt :: Int -> SemVer -> Int
    $chash :: SemVer -> Int
    hash :: SemVer -> Int
    Hashable)

    -- | Two SemVers are equal if all fields except metadata are equal.
    instance Eq SemVer where
      (SemVer Word
    ma Word
    mi Word
    pa Maybe Release
    pr Maybe Text
    _) == :: SemVer -> SemVer -> Bool
    == (SemVer Word
    ma' Word
    mi' Word
    pa' Maybe Release
    pr' Maybe Text
    _) =
        (Word
    ma,Word
    mi,Word
    pa,Maybe Release
    pr) (Word, Word, Word, Maybe Release)
    -> (Word, Word, Word, Maybe Release) -> Bool
    forall a. Eq a => a -> a -> Bool
    == (Word
    ma',Word
    mi',Word
    pa',Maybe Release
    pr')

    -- | Build metadata does not affect version precedence.
    instance Ord SemVer where
      compare :: SemVer -> SemVer -> Ordering
    compare (SemVer Word
    ma Word
    mi Word
    pa Maybe Release
    pr Maybe Text
    _) (SemVer Word
    ma' Word
    mi' Word
    pa' Maybe Release
    pr' Maybe Text
    _) =
        case (Word, Word, Word) -> (Word, Word, Word) -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare (Word
    ma,Word
    mi,Word
    pa) (Word
    ma',Word
    mi',Word
    pa') of
         Ordering
    LT -> Ordering
    LT
         Ordering
    GT -> Ordering
    GT
         Ordering
    EQ -> case (Maybe Release
    pr, Maybe Release
    pr') of
           (Maybe Release
    Nothing, Maybe Release
    Nothing) -> Ordering
    EQ
           (Maybe Release
    Nothing, Maybe Release
    _)       -> Ordering
    GT
           (Maybe Release
    _, Maybe Release
    Nothing)       -> Ordering
    LT
           (Just Release
    ap, Just Release
    bp) -> Release -> Release -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Release
    ap Release
    bp

    instance Semantic SemVer where
      major :: Traversal' SemVer Word
    major Word -> f Word
    f SemVer
    sv = (Word -> SemVer) -> f Word -> f SemVer
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\Word
    ma -> SemVer
    sv { _svMajor :: Word
    _svMajor = Word
    ma }) (Word -> f Word
    f (Word -> f Word) -> Word -> f Word
    forall a b. (a -> b) -> a -> b
    $ SemVer -> Word
    _svMajor SemVer
    sv)
      {-# INLINE major #-}

      minor :: Traversal' SemVer Word
    minor Word -> f Word
    f SemVer
    sv = (Word -> SemVer) -> f Word -> f SemVer
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\Word
    mi -> SemVer
    sv { _svMinor :: Word
    _svMinor = Word
    mi }) (Word -> f Word
    f (Word -> f Word) -> Word -> f Word
    forall a b. (a -> b) -> a -> b
    $ SemVer -> Word
    _svMinor SemVer
    sv)
      {-# INLINE minor #-}

      patch :: Traversal' SemVer Word
    patch Word -> f Word
    f SemVer
    sv = (Word -> SemVer) -> f Word -> f SemVer
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\Word
    pa -> SemVer
    sv { _svPatch :: Word
    _svPatch = Word
    pa }) (Word -> f Word
    f (Word -> f Word) -> Word -> f Word
    forall a b. (a -> b) -> a -> b
    $ SemVer -> Word
    _svPatch SemVer
    sv)
      {-# INLINE patch #-}

      release :: Traversal' SemVer (Maybe Release)
    release Maybe Release -> f (Maybe Release)
    f SemVer
    sv = (Maybe Release -> SemVer) -> f (Maybe Release) -> f SemVer
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\Maybe Release
    pa -> SemVer
    sv { _svPreRel :: Maybe Release
    _svPreRel = Maybe Release
    pa }) (Maybe Release -> f (Maybe Release)
    f (Maybe Release -> f (Maybe Release))
    -> Maybe Release -> f (Maybe Release)
    forall a b. (a -> b) -> a -> b
    $ SemVer -> Maybe Release
    _svPreRel SemVer
    sv)
      {-# INLINE release #-}

      meta :: Traversal' SemVer (Maybe Text)
    meta Maybe Text -> f (Maybe Text)
    f SemVer
    sv = (Maybe Text -> SemVer) -> f (Maybe Text) -> f SemVer
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\Maybe Text
    pa -> SemVer
    sv { _svMeta :: Maybe Text
    _svMeta = Maybe Text
    pa }) (Maybe Text -> f (Maybe Text)
    f (Maybe Text -> f (Maybe Text)) -> Maybe Text -> f (Maybe Text)
    forall a b. (a -> b) -> a -> b
    $ SemVer -> Maybe Text
    _svMeta SemVer
    sv)
      {-# INLINE meta #-}

      semantic :: Traversal' SemVer SemVer
    semantic = (SemVer -> f SemVer) -> SemVer -> f SemVer
    forall a b. (a -> b) -> a -> b
    ($)
      {-# INLINE semantic #-}

    -- | `Chunk`s have comparison behaviour according to SemVer's rules for preleases.
    newtype Release = Release (NonEmpty Chunk)
      deriving stock (Release -> Release -> Bool
    (Release -> Release -> Bool)
    -> (Release -> Release -> Bool) -> Eq Release
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Release -> Release -> Bool
    == :: Release -> Release -> Bool
    $c/= :: Release -> Release -> Bool
    /= :: Release -> Release -> Bool
    Eq, Int -> Release -> ShowS
    [Release] -> ShowS
    Release -> String
    (Int -> Release -> ShowS)
    -> (Release -> String) -> ([Release] -> ShowS) -> Show Release
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Release -> ShowS
    showsPrec :: Int -> Release -> ShowS
    $cshow :: Release -> String
    show :: Release -> String
    $cshowList :: [Release] -> ShowS
    showList :: [Release] -> ShowS
    Show, ReadPrec [Release]
    ReadPrec Release
    Int -> ReadS Release
    ReadS [Release]
    (Int -> ReadS Release)
    -> ReadS [Release]
    -> ReadPrec Release
    -> ReadPrec [Release]
    -> Read Release
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Release
    readsPrec :: Int -> ReadS Release
    $creadList :: ReadS [Release]
    readList :: ReadS [Release]
    $creadPrec :: ReadPrec Release
    readPrec :: ReadPrec Release
    $creadListPrec :: ReadPrec [Release]
    readListPrec :: ReadPrec [Release]
    Read, (forall x. Release -> Rep Release x)
    -> (forall x. Rep Release x -> Release) -> Generic Release
    forall x. Rep Release x -> Release
    forall x. Release -> Rep Release x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Release -> Rep Release x
    from :: forall x. Release -> Rep Release x
    $cto :: forall x. Rep Release x -> Release
    to :: forall x. Rep Release x -> Release
    Generic, (forall (m :: * -> *). Quote m => Release -> m Exp)
    -> (forall (m :: * -> *). Quote m => Release -> Code m Release)
    -> Lift Release
    forall t.
    (forall (m :: * -> *). Quote m => t -> m Exp)
    -> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
    forall (m :: * -> *). Quote m => Release -> m Exp
    forall (m :: * -> *). Quote m => Release -> Code m Release
    $clift :: forall (m :: * -> *). Quote m => Release -> m Exp
    lift :: forall (m :: * -> *). Quote m => Release -> m Exp
    $cliftTyped :: forall (m :: * -> *). Quote m => Release -> Code m Release
    liftTyped :: forall (m :: * -> *). Quote m => Release -> Code m Release
    Lift)
      deriving anyclass (Release -> ()
    (Release -> ()) -> NFData Release
    forall a. (a -> ()) -> NFData a
    $crnf :: Release -> ()
    rnf :: Release -> ()
    NFData, Eq Release
    Eq Release
    -> (Int -> Release -> Int) -> (Release -> Int) -> Hashable Release
    Int -> Release -> Int
    Release -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> Release -> Int
    hashWithSalt :: Int -> Release -> Int
    $chash :: Release -> Int
    hash :: Release -> Int
    Hashable)

    instance Ord Release where
      compare :: Release -> Release -> Ordering
    compare (Release NonEmpty Chunk
    as) (Release NonEmpty Chunk
    bs) =
        Ordering -> Maybe Ordering -> Ordering
    forall a. a -> Maybe a -> a
    fromMaybe Ordering
    EQ (Maybe Ordering -> Ordering)
    -> ([These Chunk Chunk] -> Maybe Ordering)
    -> [These Chunk Chunk]
    -> Ordering
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Ordering] -> Maybe Ordering
    forall a. [a] -> Maybe a
    listToMaybe ([Ordering] -> Maybe Ordering)
    -> ([These Chunk Chunk] -> [Ordering])
    -> [These Chunk Chunk]
    -> Maybe Ordering
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (These Chunk Chunk -> Maybe Ordering)
    -> [These Chunk Chunk] -> [Ordering]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe These Chunk Chunk -> Maybe Ordering
    f ([These Chunk Chunk] -> Ordering)
    -> [These Chunk Chunk] -> Ordering
    forall a b. (a -> b) -> a -> b
    $ [Chunk] -> [Chunk] -> [These Chunk Chunk]
    forall a b. [a] -> [b] -> [These a b]
    zipLongest (NonEmpty Chunk -> [Chunk]
    forall a. NonEmpty a -> [a]
    NEL.toList NonEmpty Chunk
    as) (NonEmpty Chunk -> [Chunk]
    forall a. NonEmpty a -> [a]
    NEL.toList NonEmpty Chunk
    bs)
        where
          f :: These Chunk Chunk -> Maybe Ordering
          f :: These Chunk Chunk -> Maybe Ordering
    f (Both Chunk
    a Chunk
    b) = case Chunk -> Chunk -> Ordering
    cmpSemVer Chunk
    a Chunk
    b of
            Ordering
    LT -> Ordering -> Maybe Ordering
    forall a. a -> Maybe a
    Just Ordering
    LT
            Ordering
    GT -> Ordering -> Maybe Ordering
    forall a. a -> Maybe a
    Just Ordering
    GT
            Ordering
    EQ -> Maybe Ordering
    forall a. Maybe a
    Nothing
          f (This Chunk
    _)   = Ordering -> Maybe Ordering
    forall a. a -> Maybe a
    Just Ordering
    GT
          f (That Chunk
    _)   = Ordering -> Maybe Ordering
    forall a. a -> Maybe a
    Just Ordering
    LT

    -- | A logical unit of a version number.
    --
    -- Either entirely numerical (with no leading zeroes) or entirely alphanumerical
    -- (with a free mixture of numbers, letters, and hyphens.)
    --
    -- Groups of these (like `Release`) are separated by periods to form a full
    -- section of a version number.
    --
    -- Examples:
    --
    -- @
    -- 1
    -- 20150826
    -- r3
    -- 0rc1-abc3
    -- @
    data Chunk = Numeric Word | Alphanum Text
      deriving stock (Chunk -> Chunk -> Bool
    (Chunk -> Chunk -> Bool) -> (Chunk -> Chunk -> Bool) -> Eq Chunk
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Chunk -> Chunk -> Bool
    == :: Chunk -> Chunk -> Bool
    $c/= :: Chunk -> Chunk -> Bool
    /= :: Chunk -> Chunk -> Bool
    Eq, Int -> Chunk -> ShowS
    [Chunk] -> ShowS
    Chunk -> String
    (Int -> Chunk -> ShowS)
    -> (Chunk -> String) -> ([Chunk] -> ShowS) -> Show Chunk
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Chunk -> ShowS
    showsPrec :: Int -> Chunk -> ShowS
    $cshow :: Chunk -> String
    show :: Chunk -> String
    $cshowList :: [Chunk] -> ShowS
    showList :: [Chunk] -> ShowS
    Show, ReadPrec [Chunk]
    ReadPrec Chunk
    Int -> ReadS Chunk
    ReadS [Chunk]
    (Int -> ReadS Chunk)
    -> ReadS [Chunk]
    -> ReadPrec Chunk
    -> ReadPrec [Chunk]
    -> Read Chunk
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Chunk
    readsPrec :: Int -> ReadS Chunk
    $creadList :: ReadS [Chunk]
    readList :: ReadS [Chunk]
    $creadPrec :: ReadPrec Chunk
    readPrec :: ReadPrec Chunk
    $creadListPrec :: ReadPrec [Chunk]
    readListPrec :: ReadPrec [Chunk]
    Read, (forall x. Chunk -> Rep Chunk x)
    -> (forall x. Rep Chunk x -> Chunk) -> Generic Chunk
    forall x. Rep Chunk x -> Chunk
    forall x. Chunk -> Rep Chunk x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Chunk -> Rep Chunk x
    from :: forall x. Chunk -> Rep Chunk x
    $cto :: forall x. Rep Chunk x -> Chunk
    to :: forall x. Rep Chunk x -> Chunk
    Generic, (forall (m :: * -> *). Quote m => Chunk -> m Exp)
    -> (forall (m :: * -> *). Quote m => Chunk -> Code m Chunk)
    -> Lift Chunk
    forall t.
    (forall (m :: * -> *). Quote m => t -> m Exp)
    -> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
    forall (m :: * -> *). Quote m => Chunk -> m Exp
    forall (m :: * -> *). Quote m => Chunk -> Code m Chunk
    $clift :: forall (m :: * -> *). Quote m => Chunk -> m Exp
    lift :: forall (m :: * -> *). Quote m => Chunk -> m Exp
    $cliftTyped :: forall (m :: * -> *). Quote m => Chunk -> Code m Chunk
    liftTyped :: forall (m :: * -> *). Quote m => Chunk -> Code m Chunk
    Lift)
      deriving anyclass (Chunk -> ()
    (Chunk -> ()) -> NFData Chunk
    forall a. (a -> ()) -> NFData a
    $crnf :: Chunk -> ()
    rnf :: Chunk -> ()
    NFData, Eq Chunk
    Eq Chunk
    -> (Int -> Chunk -> Int) -> (Chunk -> Int) -> Hashable Chunk
    Int -> Chunk -> Int
    Chunk -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> Chunk -> Int
    hashWithSalt :: Int -> Chunk -> Int
    $chash :: Chunk -> Int
    hash :: Chunk -> Int
    Hashable)

    toMChunk :: Chunk -> MChunk
    toMChunk :: Chunk -> MChunk
    toMChunk (Numeric Word
    n)  = Word -> Text -> MChunk
    MDigit Word
    n (Text -> MChunk) -> Text -> MChunk
    forall a b. (a -> b) -> a -> b
    $ Word -> Text
    forall a. Show a => a -> Text
    showt Word
    n
    toMChunk (Alphanum Text
    s) = Text -> MChunk
    MPlain Text
    s

    -- | `Chunk` is used in multiple places but requires different comparison
    -- semantics depending on the wrapping type. This function and `cmpLenient`
    -- below provide this.
    cmpSemVer :: Chunk -> Chunk -> Ordering
    cmpSemVer :: Chunk -> Chunk -> Ordering
    cmpSemVer (Numeric Word
    a) (Numeric Word
    b)   = Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    a Word
    b
    cmpSemVer (Numeric Word
    _) (Alphanum Text
    _)  = Ordering
    LT
    cmpSemVer (Alphanum Text
    _) (Numeric Word
    _)  = Ordering
    GT
    cmpSemVer (Alphanum Text
    a) (Alphanum Text
    b) = Text -> Text -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Text
    a Text
    b

    -- | Like `cmpSemVer`, but for `Version`s. We need to be mindful of comparisons
    -- like @1.2.0 > 1.2.0rc1@ which normally wouldn't occur in SemVer.
    cmpLenient :: Chunk -> Chunk -> Ordering
    cmpLenient :: Chunk -> Chunk -> Ordering
    cmpLenient (Numeric Word
    a) (Numeric Word
    b)       = Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    a Word
    b
    cmpLenient a :: Chunk
    a@(Alphanum Text
    x) b :: Chunk
    b@(Alphanum Text
    y) =
      case (Chunk -> Maybe Word
    singleDigitLenient Chunk
    a, Chunk -> Maybe Word
    singleDigitLenient Chunk
    b) of
        (Just Word
    i, Just Word
    j) -> Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    i Word
    j
        (Maybe Word, Maybe Word)
    _                -> Text -> Text -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Text
    x Text
    y
    cmpLenient (Numeric Word
    n) b :: Chunk
    b@(Alphanum Text
    _) =
      case Chunk -> Maybe Word
    singleDigitLenient Chunk
    b of
        Maybe Word
    Nothing -> Ordering
    GT
        Just Word
    m -> case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    n Word
    m of
          -- 1.2.0 > 1.2.0rc1
          Ordering
    EQ -> Ordering
    GT
          Ordering
    c  -> Ordering
    c
    cmpLenient a :: Chunk
    a@(Alphanum Text
    _) (Numeric Word
    n) =
      case Chunk -> Maybe Word
    singleDigitLenient Chunk
    a of
        Maybe Word
    Nothing -> Ordering
    LT
        Just Word
    m -> case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    m Word
    n of
          -- 1.2.0rc1 < 1.2.0
          Ordering
    EQ -> Ordering
    LT
          Ordering
    c  -> Ordering
    c

    -- | Like `singleDigit` but will grab a leading `Word` even if followed by
    -- letters.
    singleDigitLenient :: Chunk -> Maybe Word
    singleDigitLenient :: Chunk -> Maybe Word
    singleDigitLenient (Numeric Word
    n)  = Word -> Maybe Word
    forall a. a -> Maybe a
    Just Word
    n
    singleDigitLenient (Alphanum Text
    s) = Either ParsingError Word -> Maybe Word
    forall a b. Either a b -> Maybe b
    hush (Either ParsingError Word -> Maybe Word)
    -> Either ParsingError Word -> Maybe Word
    forall a b. (a -> b) -> a -> b
    $ Parsec Void Text Word -> String -> Text -> Either ParsingError Word
    forall e s a.
    Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
    parse Parsec Void Text Word
    unsignedP String
    "Single Digit Lenient" Text
    s

    --------------------------------------------------------------------------------
    -- (Haskell) PVP

    -- | A PVP version number specific to the Haskell ecosystem. Like SemVer this is
    -- a prescriptive scheme, and follows <https://pvp.haskell.org/ the PVP spec>.
    --
    -- Legal PVP values are of the form: MAJOR(.MAJOR.MINOR)
    --
    -- Example: @1.2.3@
    --
    -- Extra Rules:
    --
    -- 1. Each component must be a number.
    --
    -- 2. Only the first MAJOR component is actually necessary. Otherwise, there can
    --    be any number of components. @1.2.3.4.5.6.7@ is legal.
    --
    -- 3. Unlike SemVer there are two MAJOR components, and both indicate a breaking
    --    change. The spec otherwise designates no special meaning to components
    --    past the MINOR position.
    newtype PVP = PVP { PVP -> NonEmpty Word
    _pComponents :: NonEmpty Word }
      deriving stock (PVP -> PVP -> Bool
    (PVP -> PVP -> Bool) -> (PVP -> PVP -> Bool) -> Eq PVP
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PVP -> PVP -> Bool
    == :: PVP -> PVP -> Bool
    $c/= :: PVP -> PVP -> Bool
    /= :: PVP -> PVP -> Bool
    Eq, Eq PVP
    Eq PVP
    -> (PVP -> PVP -> Ordering)
    -> (PVP -> PVP -> Bool)
    -> (PVP -> PVP -> Bool)
    -> (PVP -> PVP -> Bool)
    -> (PVP -> PVP -> Bool)
    -> (PVP -> PVP -> PVP)
    -> (PVP -> PVP -> PVP)
    -> Ord PVP
    PVP -> PVP -> Bool
    PVP -> PVP -> Ordering
    PVP -> PVP -> PVP
    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 :: PVP -> PVP -> Ordering
    compare :: PVP -> PVP -> Ordering
    $c< :: PVP -> PVP -> Bool
    < :: PVP -> PVP -> Bool
    $c<= :: PVP -> PVP -> Bool
    <= :: PVP -> PVP -> Bool
    $c> :: PVP -> PVP -> Bool
    > :: PVP -> PVP -> Bool
    $c>= :: PVP -> PVP -> Bool
    >= :: PVP -> PVP -> Bool
    $cmax :: PVP -> PVP -> PVP
    max :: PVP -> PVP -> PVP
    $cmin :: PVP -> PVP -> PVP
    min :: PVP -> PVP -> PVP
    Ord, Int -> PVP -> ShowS
    [PVP] -> ShowS
    PVP -> String
    (Int -> PVP -> ShowS)
    -> (PVP -> String) -> ([PVP] -> ShowS) -> Show PVP
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PVP -> ShowS
    showsPrec :: Int -> PVP -> ShowS
    $cshow :: PVP -> String
    show :: PVP -> String
    $cshowList :: [PVP] -> ShowS
    showList :: [PVP] -> ShowS
    Show, (forall x. PVP -> Rep PVP x)
    -> (forall x. Rep PVP x -> PVP) -> Generic PVP
    forall x. Rep PVP x -> PVP
    forall x. PVP -> Rep PVP x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. PVP -> Rep PVP x
    from :: forall x. PVP -> Rep PVP x
    $cto :: forall x. Rep PVP x -> PVP
    to :: forall x. Rep PVP x -> PVP
    Generic)
      deriving anyclass (PVP -> ()
    (PVP -> ()) -> NFData PVP
    forall a. (a -> ()) -> NFData a
    $crnf :: PVP -> ()
    rnf :: PVP -> ()
    NFData, Eq PVP
    Eq PVP -> (Int -> PVP -> Int) -> (PVP -> Int) -> Hashable PVP
    Int -> PVP -> Int
    PVP -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> PVP -> Int
    hashWithSalt :: Int -> PVP -> Int
    $chash :: PVP -> Int
    hash :: PVP -> Int
    Hashable)

    instance Semantic PVP where
      major :: Traversal' PVP Word
    major Word -> f Word
    f (PVP (Word
    m :| [Word]
    rs)) = (\Word
    ma -> NonEmpty Word -> PVP
    PVP (NonEmpty Word -> PVP) -> NonEmpty Word -> PVP
    forall a b. (a -> b) -> a -> b
    $ Word
    ma Word -> [Word] -> NonEmpty Word
    forall a. a -> [a] -> NonEmpty a
    :| [Word]
    rs) (Word -> PVP) -> f Word -> f PVP
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    m
      {-# INLINE major #-}

      minor :: Traversal' PVP Word
    minor Word -> f Word
    f (PVP (Word
    m :| Word
    mi : [Word]
    rs)) = (\Word
    mi' -> NonEmpty Word -> PVP
    PVP (NonEmpty Word -> PVP) -> NonEmpty Word -> PVP
    forall a b. (a -> b) -> a -> b
    $ Word
    m Word -> [Word] -> NonEmpty Word
    forall a. a -> [a] -> NonEmpty a
    :| Word
    mi' Word -> [Word] -> [Word]
    forall a. a -> [a] -> [a]
    : [Word]
    rs) (Word -> PVP) -> f Word -> f PVP
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    mi
      minor Word -> f Word
    f (PVP (Word
    m :| []))      = (\Word
    mi' -> NonEmpty Word -> PVP
    PVP (NonEmpty Word -> PVP) -> NonEmpty Word -> PVP
    forall a b. (a -> b) -> a -> b
    $ Word
    m Word -> [Word] -> NonEmpty Word
    forall a. a -> [a] -> NonEmpty a
    :| [Word
    mi']) (Word -> PVP) -> f Word -> f PVP
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    0
      {-# INLINE minor #-}

      patch :: Traversal' PVP Word
    patch Word -> f Word
    f (PVP (Word
    m :| Word
    mi : Word
    pa : [Word]
    rs)) = (\Word
    pa' -> NonEmpty Word -> PVP
    PVP (NonEmpty Word -> PVP) -> NonEmpty Word -> PVP
    forall a b. (a -> b) -> a -> b
    $ Word
    m Word -> [Word] -> NonEmpty Word
    forall a. a -> [a] -> NonEmpty a
    :| Word
    mi Word -> [Word] -> [Word]
    forall a. a -> [a] -> [a]
    : Word
    pa' Word -> [Word] -> [Word]
    forall a. a -> [a] -> [a]
    : [Word]
    rs) (Word -> PVP) -> f Word -> f PVP
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    pa
      patch Word -> f Word
    f (PVP (Word
    m :| [Word
    mi]))         = (\Word
    pa' -> NonEmpty Word -> PVP
    PVP (NonEmpty Word -> PVP) -> NonEmpty Word -> PVP
    forall a b. (a -> b) -> a -> b
    $ Word
    m Word -> [Word] -> NonEmpty Word
    forall a. a -> [a] -> NonEmpty a
    :| Word
    mi Word -> [Word] -> [Word]
    forall a. a -> [a] -> [a]
    : [Word
    pa']) (Word -> PVP) -> f Word -> f PVP
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    0
      patch Word -> f Word
    f (PVP (Word
    m :| []))           = (\Word
    pa' -> NonEmpty Word -> PVP
    PVP (NonEmpty Word -> PVP) -> NonEmpty Word -> PVP
    forall a b. (a -> b) -> a -> b
    $ Word
    m Word -> [Word] -> NonEmpty Word
    forall a. a -> [a] -> NonEmpty a
    :| Word
    0 Word -> [Word] -> [Word]
    forall a. a -> [a] -> [a]
    : [Word
    pa']) (Word -> PVP) -> f Word -> f PVP
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    0
      {-# INLINE patch #-}

      release :: Traversal' PVP (Maybe Release)
    release Maybe Release -> f (Maybe Release)
    f PVP
    p = PVP
    p PVP -> f (Maybe Release) -> f PVP
    forall a b. a -> f b -> f a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Maybe Release -> f (Maybe Release)
    f Maybe Release
    forall a. Maybe a
    Nothing
      {-# INLINE release #-}

      meta :: Traversal' PVP (Maybe Text)
    meta Maybe Text -> f (Maybe Text)
    f PVP
    p = PVP
    p PVP -> f (Maybe Text) -> f PVP
    forall a b. a -> f b -> f a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Maybe Text -> f (Maybe Text)
    f Maybe Text
    forall a. Maybe a
    Nothing
      {-# INLINE meta #-}

      semantic :: Traversal' PVP SemVer
    semantic SemVer -> f SemVer
    f (PVP (Word
    m :| [Word]
    rs)) = (\(SemVer Word
    ma Word
    mi Word
    pa Maybe Release
    _ Maybe Text
    _) -> NonEmpty Word -> PVP
    PVP (NonEmpty Word -> PVP) -> NonEmpty Word -> PVP
    forall a b. (a -> b) -> a -> b
    $ Word
    ma Word -> [Word] -> NonEmpty Word
    forall a. a -> [a] -> NonEmpty a
    :| [Word
    mi, Word
    pa]) (SemVer -> PVP) -> f SemVer -> f PVP
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> SemVer -> f SemVer
    f SemVer
    s
        where
          s :: SemVer
    s = case [Word]
    rs of
            Word
    mi : Word
    pa : [Word]
    _ -> Word -> Word -> Word -> Maybe Release -> Maybe Text -> SemVer
    SemVer Word
    m Word
    mi Word
    pa Maybe Release
    forall a. Maybe a
    Nothing Maybe Text
    forall a. Maybe a
    Nothing
            Word
    mi : [Word]
    _      -> Word -> Word -> Word -> Maybe Release -> Maybe Text -> SemVer
    SemVer Word
    m Word
    mi Word
    0  Maybe Release
    forall a. Maybe a
    Nothing Maybe Text
    forall a. Maybe a
    Nothing
            []          -> Word -> Word -> Word -> Maybe Release -> Maybe Text -> SemVer
    SemVer Word
    m Word
    0 Word
    0   Maybe Release
    forall a. Maybe a
    Nothing Maybe Text
    forall a. Maybe a
    Nothing
      {-# INLINE semantic #-}

    --------------------------------------------------------------------------------
    -- (General) Version

    -- | A version number with decent structure and comparison logic.
    --
    -- This is a /descriptive/ scheme, meaning that it encapsulates the most common,
    -- unconscious patterns that developers use when assigning version numbers to
    -- their software. If not `SemVer`, most version numbers found in the wild will
    -- parse as a `Version`. These generally conform to the @x.x.x-x@ pattern, and
    -- may optionally have an /epoch/.
    --
    -- Epochs are prefixes marked by a colon, like in @1:2.3.4@. When comparing two
    -- `Version` values, epochs take precedent. So @2:1.0.0 > 1:9.9.9@. If one of
    -- the given `Version`s has no epoch, its epoch is assumed to be 0.
    --
    -- Examples of @Version@ that are not @SemVer@: 0.25-2, 8.u51-1, 20150826-1,
    -- 1:2.3.4
    data Version = Version
      { Version -> Maybe Word
    _vEpoch  :: !(Maybe Word)
      , Version -> Chunks
    _vChunks :: !Chunks
      , Version -> Maybe Release
    _vRel    :: !(Maybe Release)
      , Version -> Maybe Text
    _vMeta   :: !(Maybe Text) }
      deriving stock (Version -> Version -> Bool
    (Version -> Version -> Bool)
    -> (Version -> Version -> Bool) -> Eq Version
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Version -> Version -> Bool
    == :: Version -> Version -> Bool
    $c/= :: Version -> Version -> Bool
    /= :: Version -> Version -> Bool
    Eq, 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
    $cshowsPrec :: Int -> Version -> ShowS
    showsPrec :: Int -> Version -> ShowS
    $cshow :: Version -> String
    show :: Version -> String
    $cshowList :: [Version] -> ShowS
    showList :: [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
    $cfrom :: forall x. Version -> Rep Version x
    from :: forall x. Version -> Rep Version x
    $cto :: forall x. Rep Version x -> Version
    to :: forall x. Rep Version x -> Version
    Generic, (forall (m :: * -> *). Quote m => Version -> m Exp)
    -> (forall (m :: * -> *). Quote m => Version -> Code m Version)
    -> Lift Version
    forall t.
    (forall (m :: * -> *). Quote m => t -> m Exp)
    -> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
    forall (m :: * -> *). Quote m => Version -> m Exp
    forall (m :: * -> *). Quote m => Version -> Code m Version
    $clift :: forall (m :: * -> *). Quote m => Version -> m Exp
    lift :: forall (m :: * -> *). Quote m => Version -> m Exp
    $cliftTyped :: forall (m :: * -> *). Quote m => Version -> Code m Version
    liftTyped :: forall (m :: * -> *). Quote m => Version -> Code m Version
    Lift)
      deriving anyclass (Version -> ()
    (Version -> ()) -> NFData Version
    forall a. (a -> ()) -> NFData a
    $crnf :: Version -> ()
    rnf :: Version -> ()
    NFData, Eq Version
    Eq Version
    -> (Int -> Version -> Int) -> (Version -> Int) -> Hashable Version
    Int -> Version -> Int
    Version -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> Version -> Int
    hashWithSalt :: Int -> Version -> Int
    $chash :: Version -> Int
    hash :: Version -> Int
    Hashable)

    -- | Customized. As in SemVer, metadata is ignored for the purpose of
    -- comparison.
    instance Ord Version where
      -- If two epochs are equal, we need to compare their actual version numbers.
      -- Otherwise, the comparison of the epochs is the only thing that matters.
      compare :: Version -> Version -> Ordering
    compare (Version Maybe Word
    mae Chunks
    ac Maybe Release
    ar Maybe Text
    _) (Version Maybe Word
    mbe Chunks
    bc Maybe Release
    br Maybe Text
    _) =
        case Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    ae Word
    be of
          Ordering
    EQ -> case Chunks -> Chunks -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Chunks
    ac Chunks
    bc of
            Ordering
    EQ  -> Maybe Release -> Maybe Release -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Maybe Release
    ar Maybe Release
    br
            Ordering
    ord -> Ordering
    ord
          Ordering
    ord -> Ordering
    ord
        where
          ae :: Word
    ae = Word -> Maybe Word -> Word
    forall a. a -> Maybe a -> a
    fromMaybe Word
    0 Maybe Word
    mae
          be :: Word
    be = Word -> Maybe Word -> Word
    forall a. a -> Maybe a -> a
    fromMaybe Word
    0 Maybe Word
    mbe

    instance Semantic Version where
      major :: Traversal' Version Word
    major Word -> f Word
    f (Version Maybe Word
    e (Chunks (Numeric Word
    n :| [Chunk]
    cs)) Maybe Release
    me Maybe Text
    rs) =
        (\Word
    n' -> Maybe Word -> Chunks -> Maybe Release -> Maybe Text -> Version
    Version Maybe Word
    e (NonEmpty Chunk -> Chunks
    Chunks (NonEmpty Chunk -> Chunks) -> NonEmpty Chunk -> Chunks
    forall a b. (a -> b) -> a -> b
    $ Word -> Chunk
    Numeric Word
    n' Chunk -> [Chunk] -> NonEmpty Chunk
    forall a. a -> [a] -> NonEmpty a
    :| [Chunk]
    cs) Maybe Release
    me Maybe Text
    rs) (Word -> Version) -> f Word -> f Version
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    n
      major Word -> f Word
    _ Version
    v = Version -> f Version
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Version
    v
      {-# INLINE major #-}

      minor :: Traversal' Version Word
    minor Word -> f Word
    f (Version Maybe Word
    e (Chunks (Chunk
    c :| Numeric Word
    n : [Chunk]
    cs)) Maybe Release
    me Maybe Text
    rs) =
        (\Word
    n' -> Maybe Word -> Chunks -> Maybe Release -> Maybe Text -> Version
    Version Maybe Word
    e (NonEmpty Chunk -> Chunks
    Chunks (NonEmpty Chunk -> Chunks) -> NonEmpty Chunk -> Chunks
    forall a b. (a -> b) -> a -> b
    $ Chunk
    c Chunk -> [Chunk] -> NonEmpty Chunk
    forall a. a -> [a] -> NonEmpty a
    :| Word -> Chunk
    Numeric Word
    n' Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    : [Chunk]
    cs) Maybe Release
    me Maybe Text
    rs) (Word -> Version) -> f Word -> f Version
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    n
      minor Word -> f Word
    _ Version
    v = Version -> f Version
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Version
    v
      {-# INLINE minor #-}

      patch :: Traversal' Version Word
    patch Word -> f Word
    f (Version Maybe Word
    e (Chunks (Chunk
    c :| Chunk
    d : Numeric Word
    n : [Chunk]
    cs)) Maybe Release
    me Maybe Text
    rs) =
        (\Word
    n' -> Maybe Word -> Chunks -> Maybe Release -> Maybe Text -> Version
    Version Maybe Word
    e (NonEmpty Chunk -> Chunks
    Chunks (NonEmpty Chunk -> Chunks) -> NonEmpty Chunk -> Chunks
    forall a b. (a -> b) -> a -> b
    $ Chunk
    c Chunk -> [Chunk] -> NonEmpty Chunk
    forall a. a -> [a] -> NonEmpty a
    :| Chunk
    d Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    : Word -> Chunk
    Numeric Word
    n' Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    : [Chunk]
    cs) Maybe Release
    me Maybe Text
    rs) (Word -> Version) -> f Word -> f Version
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    n
      patch Word -> f Word
    _ Version
    v = Version -> f Version
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Version
    v
      {-# INLINE patch #-}

      -- | This will always succeed.
      release :: Traversal' Version (Maybe Release)
    release Maybe Release -> f (Maybe Release)
    f Version
    v = (Maybe Release -> Version) -> f (Maybe Release) -> f Version
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\Maybe Release
    vr -> Version
    v { _vRel :: Maybe Release
    _vRel = Maybe Release
    vr }) (Maybe Release -> f (Maybe Release)
    f (Maybe Release -> f (Maybe Release))
    -> Maybe Release -> f (Maybe Release)
    forall a b. (a -> b) -> a -> b
    $ Version -> Maybe Release
    _vRel Version
    v)
      {-# INLINE release #-}

      -- | This will always fail.
      meta :: Traversal' Version (Maybe Text)
    meta Maybe Text -> f (Maybe Text)
    _ Version
    v = Version -> f Version
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Version
    v
      {-# INLINE meta #-}

      semantic :: Traversal' Version SemVer
    semantic SemVer -> f SemVer
    f (Version Maybe Word
    _ (Chunks (Numeric Word
    a :| Numeric Word
    b : Numeric Word
    c : [Chunk]
    _)) Maybe Release
    rs Maybe Text
    me) =
        SemVer -> Version
    vFromS (SemVer -> Version) -> f SemVer -> f Version
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> SemVer -> f SemVer
    f (Word -> Word -> Word -> Maybe Release -> Maybe Text -> SemVer
    SemVer Word
    a Word
    b Word
    c Maybe Release
    rs Maybe Text
    me)
      semantic SemVer -> f SemVer
    _ Version
    v = Version -> f Version
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Version
    v
      {-# INLINE semantic #-}

    -- | A `Version`'s inner epoch `Word`.
    epoch :: Lens' Version (Maybe Word)
    epoch :: Lens' Version (Maybe Word)
    epoch Maybe Word -> f (Maybe Word)
    f Version
    v = (Maybe Word -> Version) -> f (Maybe Word) -> f Version
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\Maybe Word
    ve -> Version
    v { _vEpoch :: Maybe Word
    _vEpoch = Maybe Word
    ve }) (Maybe Word -> f (Maybe Word)
    f (Maybe Word -> f (Maybe Word)) -> Maybe Word -> f (Maybe Word)
    forall a b. (a -> b) -> a -> b
    $ Version -> Maybe Word
    _vEpoch Version
    v)
    {-# INLINE epoch #-}

    -- | `Chunk`s that have a comparison behaviour specific to `Version`.
    newtype Chunks = Chunks (NonEmpty Chunk)
      deriving stock (Chunks -> Chunks -> Bool
    (Chunks -> Chunks -> Bool)
    -> (Chunks -> Chunks -> Bool) -> Eq Chunks
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Chunks -> Chunks -> Bool
    == :: Chunks -> Chunks -> Bool
    $c/= :: Chunks -> Chunks -> Bool
    /= :: Chunks -> Chunks -> Bool
    Eq, Int -> Chunks -> ShowS
    [Chunks] -> ShowS
    Chunks -> String
    (Int -> Chunks -> ShowS)
    -> (Chunks -> String) -> ([Chunks] -> ShowS) -> Show Chunks
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Chunks -> ShowS
    showsPrec :: Int -> Chunks -> ShowS
    $cshow :: Chunks -> String
    show :: Chunks -> String
    $cshowList :: [Chunks] -> ShowS
    showList :: [Chunks] -> ShowS
    Show, (forall x. Chunks -> Rep Chunks x)
    -> (forall x. Rep Chunks x -> Chunks) -> Generic Chunks
    forall x. Rep Chunks x -> Chunks
    forall x. Chunks -> Rep Chunks x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Chunks -> Rep Chunks x
    from :: forall x. Chunks -> Rep Chunks x
    $cto :: forall x. Rep Chunks x -> Chunks
    to :: forall x. Rep Chunks x -> Chunks
    Generic, (forall (m :: * -> *). Quote m => Chunks -> m Exp)
    -> (forall (m :: * -> *). Quote m => Chunks -> Code m Chunks)
    -> Lift Chunks
    forall t.
    (forall (m :: * -> *). Quote m => t -> m Exp)
    -> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
    forall (m :: * -> *). Quote m => Chunks -> m Exp
    forall (m :: * -> *). Quote m => Chunks -> Code m Chunks
    $clift :: forall (m :: * -> *). Quote m => Chunks -> m Exp
    lift :: forall (m :: * -> *). Quote m => Chunks -> m Exp
    $cliftTyped :: forall (m :: * -> *). Quote m => Chunks -> Code m Chunks
    liftTyped :: forall (m :: * -> *). Quote m => Chunks -> Code m Chunks
    Lift)
      deriving anyclass (Chunks -> ()
    (Chunks -> ()) -> NFData Chunks
    forall a. (a -> ()) -> NFData a
    $crnf :: Chunks -> ()
    rnf :: Chunks -> ()
    NFData, Eq Chunks
    Eq Chunks
    -> (Int -> Chunks -> Int) -> (Chunks -> Int) -> Hashable Chunks
    Int -> Chunks -> Int
    Chunks -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> Chunks -> Int
    hashWithSalt :: Int -> Chunks -> Int
    $chash :: Chunks -> Int
    hash :: Chunks -> Int
    Hashable)

    instance Ord Chunks where
      compare :: Chunks -> Chunks -> Ordering
    compare (Chunks NonEmpty Chunk
    as) (Chunks NonEmpty Chunk
    bs) =
        Ordering -> Maybe Ordering -> Ordering
    forall a. a -> Maybe a -> a
    fromMaybe Ordering
    EQ (Maybe Ordering -> Ordering)
    -> ([These Chunk Chunk] -> Maybe Ordering)
    -> [These Chunk Chunk]
    -> Ordering
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Ordering] -> Maybe Ordering
    forall a. [a] -> Maybe a
    listToMaybe ([Ordering] -> Maybe Ordering)
    -> ([These Chunk Chunk] -> [Ordering])
    -> [These Chunk Chunk]
    -> Maybe Ordering
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (These Chunk Chunk -> Maybe Ordering)
    -> [These Chunk Chunk] -> [Ordering]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe These Chunk Chunk -> Maybe Ordering
    f ([These Chunk Chunk] -> Ordering)
    -> [These Chunk Chunk] -> Ordering
    forall a b. (a -> b) -> a -> b
    $ [Chunk] -> [Chunk] -> [These Chunk Chunk]
    forall a b. [a] -> [b] -> [These a b]
    zipLongest (NonEmpty Chunk -> [Chunk]
    forall a. NonEmpty a -> [a]
    NEL.toList NonEmpty Chunk
    as) (NonEmpty Chunk -> [Chunk]
    forall a. NonEmpty a -> [a]
    NEL.toList NonEmpty Chunk
    bs)
        where
          f :: These Chunk Chunk -> Maybe Ordering
          f :: These Chunk Chunk -> Maybe Ordering
    f (Both Chunk
    a Chunk
    b) = case Chunk -> Chunk -> Ordering
    cmpLenient Chunk
    a Chunk
    b of
            Ordering
    LT -> Ordering -> Maybe Ordering
    forall a. a -> Maybe a
    Just Ordering
    LT
            Ordering
    GT -> Ordering -> Maybe Ordering
    forall a. a -> Maybe a
    Just Ordering
    GT
            Ordering
    EQ -> Maybe Ordering
    forall a. Maybe a
    Nothing
          f (This Chunk
    _)   = Ordering -> Maybe Ordering
    forall a. a -> Maybe a
    Just Ordering
    GT
          f (That Chunk
    _)   = Ordering -> Maybe Ordering
    forall a. a -> Maybe a
    Just Ordering
    LT

    --------------------------------------------------------------------------------
    -- (Complex) Mess

    -- | Possible values of a section of a `Mess`. A numeric value is extracted if
    -- it could be, alongside the original text it came from. This preserves both
    -- `Ord` and pretty-print behaviour for versions like @1.003.0@.
    data MChunk
      = MDigit Word Text
      -- ^ A nice numeric value.
      | MRev Word Text
      -- ^ A numeric value preceeded by an @r@, indicating a revision.
      | MPlain Text
      -- ^ Anything else.
      deriving stock (MChunk -> MChunk -> Bool
    (MChunk -> MChunk -> Bool)
    -> (MChunk -> MChunk -> Bool) -> Eq MChunk
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: MChunk -> MChunk -> Bool
    == :: MChunk -> MChunk -> Bool
    $c/= :: MChunk -> MChunk -> Bool
    /= :: MChunk -> MChunk -> Bool
    Eq, Int -> MChunk -> ShowS
    [MChunk] -> ShowS
    MChunk -> String
    (Int -> MChunk -> ShowS)
    -> (MChunk -> String) -> ([MChunk] -> ShowS) -> Show MChunk
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> MChunk -> ShowS
    showsPrec :: Int -> MChunk -> ShowS
    $cshow :: MChunk -> String
    show :: MChunk -> String
    $cshowList :: [MChunk] -> ShowS
    showList :: [MChunk] -> ShowS
    Show, (forall x. MChunk -> Rep MChunk x)
    -> (forall x. Rep MChunk x -> MChunk) -> Generic MChunk
    forall x. Rep MChunk x -> MChunk
    forall x. MChunk -> Rep MChunk x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. MChunk -> Rep MChunk x
    from :: forall x. MChunk -> Rep MChunk x
    $cto :: forall x. Rep MChunk x -> MChunk
    to :: forall x. Rep MChunk x -> MChunk
    Generic, (forall (m :: * -> *). Quote m => MChunk -> m Exp)
    -> (forall (m :: * -> *). Quote m => MChunk -> Code m MChunk)
    -> Lift MChunk
    forall t.
    (forall (m :: * -> *). Quote m => t -> m Exp)
    -> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
    forall (m :: * -> *). Quote m => MChunk -> m Exp
    forall (m :: * -> *). Quote m => MChunk -> Code m MChunk
    $clift :: forall (m :: * -> *). Quote m => MChunk -> m Exp
    lift :: forall (m :: * -> *). Quote m => MChunk -> m Exp
    $cliftTyped :: forall (m :: * -> *). Quote m => MChunk -> Code m MChunk
    liftTyped :: forall (m :: * -> *). Quote m => MChunk -> Code m MChunk
    Lift)
      deriving anyclass (MChunk -> ()
    (MChunk -> ()) -> NFData MChunk
    forall a. (a -> ()) -> NFData a
    $crnf :: MChunk -> ()
    rnf :: MChunk -> ()
    NFData, Eq MChunk
    Eq MChunk
    -> (Int -> MChunk -> Int) -> (MChunk -> Int) -> Hashable MChunk
    Int -> MChunk -> Int
    MChunk -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> MChunk -> Int
    hashWithSalt :: Int -> MChunk -> Int
    $chash :: MChunk -> Int
    hash :: MChunk -> Int
    Hashable)

    instance Ord MChunk where
      compare :: MChunk -> MChunk -> Ordering
    compare (MDigit Word
    a Text
    _) (MDigit Word
    b Text
    _) = Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    a Word
    b
      compare (MRev Word
    a Text
    _) (MRev Word
    b Text
    _)     = Word -> Word -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word
    a Word
    b
      compare (MPlain Text
    a) (MPlain Text
    b)     = Text -> Text -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Text
    a Text
    b
      compare MChunk
    a MChunk
    b                       = Text -> Text -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare (MChunk -> Text
    mchunkText MChunk
    a) (MChunk -> Text
    mchunkText MChunk
    b)

    -- | A total extraction of the `Text` from an `MChunk`.
    mchunkText :: MChunk -> Text
    mchunkText :: MChunk -> Text
    mchunkText (MDigit Word
    _ Text
    t) = Text
    t
    mchunkText (MRev Word
    _ Text
    t)   = Text
    t
    mchunkText (MPlain Text
    t)   = Text
    t

    -- | A (Complex) Mess. This is a /descriptive/ parser, based on examples of
    -- stupidly crafted version numbers used in the wild.
    --
    -- Groups of letters/numbers, separated by a period, can be further separated by
    -- the symbols @_-+:@
    --
    -- Some `Mess` values have a shape that is tantalizingly close to a `SemVer`.
    -- Example: @1.6.0a+2014+m872b87e73dfb-1@. For values like these, we can extract
    -- the semver-compatible values out with `messMajor`, etc.
    --
    -- Not guaranteed to have well-defined ordering (@Ord@) behaviour, but so far
    -- internal tests show consistency. `messMajor`, etc., are used internally where
    -- appropriate to enhance accuracy.
    data Mess = Mess !(NonEmpty MChunk) !(Maybe (VSep, Mess))
      deriving stock (Mess -> Mess -> Bool
    (Mess -> Mess -> Bool) -> (Mess -> Mess -> Bool) -> Eq Mess
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Mess -> Mess -> Bool
    == :: Mess -> Mess -> Bool
    $c/= :: Mess -> Mess -> Bool
    /= :: Mess -> Mess -> Bool
    Eq, Int -> Mess -> ShowS
    [Mess] -> ShowS
    Mess -> String
    (Int -> Mess -> ShowS)
    -> (Mess -> String) -> ([Mess] -> ShowS) -> Show Mess
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Mess -> ShowS
    showsPrec :: Int -> Mess -> ShowS
    $cshow :: Mess -> String
    show :: Mess -> String
    $cshowList :: [Mess] -> ShowS
    showList :: [Mess] -> ShowS
    Show, (forall x. Mess -> Rep Mess x)
    -> (forall x. Rep Mess x -> Mess) -> Generic Mess
    forall x. Rep Mess x -> Mess
    forall x. Mess -> Rep Mess x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Mess -> Rep Mess x
    from :: forall x. Mess -> Rep Mess x
    $cto :: forall x. Rep Mess x -> Mess
    to :: forall x. Rep Mess x -> Mess
    Generic, (forall (m :: * -> *). Quote m => Mess -> m Exp)
    -> (forall (m :: * -> *). Quote m => Mess -> Code m Mess)
    -> Lift Mess
    forall t.
    (forall (m :: * -> *). Quote m => t -> m Exp)
    -> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
    forall (m :: * -> *). Quote m => Mess -> m Exp
    forall (m :: * -> *). Quote m => Mess -> Code m Mess
    $clift :: forall (m :: * -> *). Quote m => Mess -> m Exp
    lift :: forall (m :: * -> *). Quote m => Mess -> m Exp
    $cliftTyped :: forall (m :: * -> *). Quote m => Mess -> Code m Mess
    liftTyped :: forall (m :: * -> *). Quote m => Mess -> Code m Mess
    Lift)
      deriving anyclass (Mess -> ()
    (Mess -> ()) -> NFData Mess
    forall a. (a -> ()) -> NFData a
    $crnf :: Mess -> ()
    rnf :: Mess -> ()
    NFData, Eq Mess
    Eq Mess -> (Int -> Mess -> Int) -> (Mess -> Int) -> Hashable Mess
    Int -> Mess -> Int
    Mess -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> Mess -> Int
    hashWithSalt :: Int -> Mess -> Int
    $chash :: Mess -> Int
    hash :: Mess -> Int
    Hashable)

    -- | Try to extract the "major" version number from `Mess`, as if it were a
    -- `SemVer`.
    messMajor :: Mess -> Maybe Word
    messMajor :: Mess -> Maybe Word
    messMajor (Mess (MDigit Word
    i Text
    _ :| [MChunk]
    _) Maybe (VSep, Mess)
    _) = Word -> Maybe Word
    forall a. a -> Maybe a
    Just Word
    i
    messMajor Mess
    _                          = Maybe Word
    forall a. Maybe a
    Nothing

    -- | Try to extract the "minor" version number from `Mess`, as if it were a
    -- `SemVer`.
    messMinor :: Mess -> Maybe Word
    messMinor :: Mess -> Maybe Word
    messMinor (Mess (MChunk
    _ :| MDigit Word
    i Text
    _ : [MChunk]
    _) Maybe (VSep, Mess)
    _) = Word -> Maybe Word
    forall a. a -> Maybe a
    Just Word
    i
    messMinor Mess
    _                              = Maybe Word
    forall a. Maybe a
    Nothing

    -- | Try to extract the "patch" version number from `Mess`, as if it were a
    -- `SemVer`.
    messPatch :: Mess -> Maybe Word
    messPatch :: Mess -> Maybe Word
    messPatch (Mess (MChunk
    _ :| MChunk
    _ : MDigit Word
    i Text
    _ : [MChunk]
    _) Maybe (VSep, Mess)
    _) = Word -> Maybe Word
    forall a. a -> Maybe a
    Just Word
    i
    messPatch Mess
    _                                  = Maybe Word
    forall a. Maybe a
    Nothing

    -- | Okay, fine, say `messPatch` couldn't find a nice value. But some `Mess`es
    -- have a "proper" patch-plus-release-candidate value in their patch position,
    -- which is parsable as a `Chunk`.
    --
    -- Example: @1.6.0a+2014+m872b87e73dfb-1@ We should be able to extract @0a@ safely.
    messPatchChunk :: Mess -> Maybe Chunk
    messPatchChunk :: Mess -> Maybe Chunk
    messPatchChunk (Mess (MChunk
    _ :| MChunk
    _ : MPlain Text
    p : [MChunk]
    _) Maybe (VSep, Mess)
    _) = Either ParsingError Chunk -> Maybe Chunk
    forall a b. Either a b -> Maybe b
    hush (Either ParsingError Chunk -> Maybe Chunk)
    -> Either ParsingError Chunk -> Maybe Chunk
    forall a b. (a -> b) -> a -> b
    $ Parsec Void Text Chunk
    -> String -> Text -> Either ParsingError Chunk
    forall e s a.
    Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
    parse Parsec Void Text Chunk
    chunkP String
    "Chunk" Text
    p
    messPatchChunk Mess
    _                                = Maybe Chunk
    forall a. Maybe a
    Nothing

    instance Ord Mess where
      compare :: Mess -> Mess -> Ordering
    compare (Mess NonEmpty MChunk
    t1 Maybe (VSep, Mess)
    m1) (Mess NonEmpty MChunk
    t2 Maybe (VSep, Mess)
    m2) = case NonEmpty MChunk -> NonEmpty MChunk -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare NonEmpty MChunk
    t1 NonEmpty MChunk
    t2 of
        Ordering
    EQ  -> case (Maybe (VSep, Mess)
    m1, Maybe (VSep, Mess)
    m2) of
          (Just (VSep
    _, Mess
    v1), Just (VSep
    _, Mess
    v2)) -> Mess -> Mess -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Mess
    v1 Mess
    v2
          (Just (VSep
    _, Mess
    _), Maybe (VSep, Mess)
    Nothing)       -> Ordering
    GT
          (Maybe (VSep, Mess)
    Nothing, Just (VSep
    _, Mess
    _))       -> Ordering
    LT
          (Maybe (VSep, Mess)
    Nothing, Maybe (VSep, Mess)
    Nothing)           -> Ordering
    EQ
        Ordering
    res -> Ordering
    res

    instance Semantic Mess where
      major :: Traversal' Mess Word
    major Word -> f Word
    f (Mess (MDigit Word
    n Text
    _ :| [MChunk]
    ts) Maybe (VSep, Mess)
    m) = (\Word
    n' -> NonEmpty MChunk -> Maybe (VSep, Mess) -> Mess
    Mess (Word -> Text -> MChunk
    MDigit Word
    n' (Word -> Text
    forall a. Show a => a -> Text
    showt Word
    n') MChunk -> [MChunk] -> NonEmpty MChunk
    forall a. a -> [a] -> NonEmpty a
    :| [MChunk]
    ts) Maybe (VSep, Mess)
    m) (Word -> Mess) -> f Word -> f Mess
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    n
      major Word -> f Word
    _ Mess
    v = Mess -> f Mess
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Mess
    v
      {-# INLINE major #-}

      minor :: Traversal' Mess Word
    minor Word -> f Word
    f (Mess (MChunk
    t0 :| MDigit Word
    n Text
    _ : [MChunk]
    ts) Maybe (VSep, Mess)
    m) = (\Word
    n' -> NonEmpty MChunk -> Maybe (VSep, Mess) -> Mess
    Mess (MChunk
    t0 MChunk -> [MChunk] -> NonEmpty MChunk
    forall a. a -> [a] -> NonEmpty a
    :| Word -> Text -> MChunk
    MDigit Word
    n' (Word -> Text
    forall a. Show a => a -> Text
    showt Word
    n') MChunk -> [MChunk] -> [MChunk]
    forall a. a -> [a] -> [a]
    : [MChunk]
    ts) Maybe (VSep, Mess)
    m) (Word -> Mess) -> f Word -> f Mess
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    n
      minor Word -> f Word
    _ Mess
    v = Mess -> f Mess
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Mess
    v
      {-# INLINE minor #-}

      patch :: Traversal' Mess Word
    patch Word -> f Word
    f (Mess (MChunk
    t0 :| MChunk
    t1 : MDigit Word
    n Text
    _ : [MChunk]
    ts) Maybe (VSep, Mess)
    m) = (\Word
    n' -> NonEmpty MChunk -> Maybe (VSep, Mess) -> Mess
    Mess (MChunk
    t0 MChunk -> [MChunk] -> NonEmpty MChunk
    forall a. a -> [a] -> NonEmpty a
    :| MChunk
    t1 MChunk -> [MChunk] -> [MChunk]
    forall a. a -> [a] -> [a]
    : Word -> Text -> MChunk
    MDigit Word
    n' (Word -> Text
    forall a. Show a => a -> Text
    showt Word
    n') MChunk -> [MChunk] -> [MChunk]
    forall a. a -> [a] -> [a]
    : [MChunk]
    ts) Maybe (VSep, Mess)
    m) (Word -> Mess) -> f Word -> f Mess
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word -> f Word
    f Word
    n
      patch Word -> f Word
    _ Mess
    v = Mess -> f Mess
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Mess
    v
      {-# INLINE patch #-}

      -- | This will always fail.
      release :: Traversal' Mess (Maybe Release)
    release Maybe Release -> f (Maybe Release)
    _ Mess
    v = Mess -> f Mess
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Mess
    v
      {-# INLINE release #-}

      -- | This will always fail.
      meta :: Traversal' Mess (Maybe Text)
    meta Maybe Text -> f (Maybe Text)
    _ Mess
    v = Mess -> f Mess
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Mess
    v
      {-# INLINE meta #-}

      -- | Good luck.
      semantic :: Traversal' Mess SemVer
    semantic SemVer -> f SemVer
    f (Mess (MDigit Word
    t0 Text
    _ :| MDigit Word
    t1 Text
    _ : MDigit Word
    t2 Text
    _ : [MChunk]
    _) Maybe (VSep, Mess)
    _) =
        Version -> Mess
    mFromV (Version -> Mess) -> (SemVer -> Version) -> SemVer -> Mess
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SemVer -> Version
    vFromS (SemVer -> Mess) -> f SemVer -> f Mess
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> SemVer -> f SemVer
    f (Word -> Word -> Word -> Maybe Release -> Maybe Text -> SemVer
    SemVer Word
    t0 Word
    t1 Word
    t2 Maybe Release
    forall a. Maybe a
    Nothing Maybe Text
    forall a. Maybe a
    Nothing)
      semantic SemVer -> f SemVer
    _ Mess
    v = Mess -> f Mess
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Mess
    v
      {-# INLINE semantic #-}

    -- | Developers use a number of symbols to seperate groups of digits/letters in
    -- their version numbers. These are:
    --
    -- * A colon (:). Often denotes an "epoch".
    -- * A hyphen (-).
    -- * A tilde (~). Example: @12.0.0-3ubuntu1~20.04.5@
    -- * A plus (+). Stop using this outside of metadata if you are. Example: @10.2+0.93+1-1@
    -- * An underscore (_). Stop using this if you are.
    data VSep = VColon | VHyphen | VPlus | VUnder | VTilde
      deriving stock (VSep -> VSep -> Bool
    (VSep -> VSep -> Bool) -> (VSep -> VSep -> Bool) -> Eq VSep
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: VSep -> VSep -> Bool
    == :: VSep -> VSep -> Bool
    $c/= :: VSep -> VSep -> Bool
    /= :: VSep -> VSep -> Bool
    Eq, Int -> VSep -> ShowS
    [VSep] -> ShowS
    VSep -> String
    (Int -> VSep -> ShowS)
    -> (VSep -> String) -> ([VSep] -> ShowS) -> Show VSep
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> VSep -> ShowS
    showsPrec :: Int -> VSep -> ShowS
    $cshow :: VSep -> String
    show :: VSep -> String
    $cshowList :: [VSep] -> ShowS
    showList :: [VSep] -> ShowS
    Show, (forall x. VSep -> Rep VSep x)
    -> (forall x. Rep VSep x -> VSep) -> Generic VSep
    forall x. Rep VSep x -> VSep
    forall x. VSep -> Rep VSep x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. VSep -> Rep VSep x
    from :: forall x. VSep -> Rep VSep x
    $cto :: forall x. Rep VSep x -> VSep
    to :: forall x. Rep VSep x -> VSep
    Generic, (forall (m :: * -> *). Quote m => VSep -> m Exp)
    -> (forall (m :: * -> *). Quote m => VSep -> Code m VSep)
    -> Lift VSep
    forall t.
    (forall (m :: * -> *). Quote m => t -> m Exp)
    -> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
    forall (m :: * -> *). Quote m => VSep -> m Exp
    forall (m :: * -> *). Quote m => VSep -> Code m VSep
    $clift :: forall (m :: * -> *). Quote m => VSep -> m Exp
    lift :: forall (m :: * -> *). Quote m => VSep -> m Exp
    $cliftTyped :: forall (m :: * -> *). Quote m => VSep -> Code m VSep
    liftTyped :: forall (m :: * -> *). Quote m => VSep -> Code m VSep
    Lift)
      deriving anyclass (VSep -> ()
    (VSep -> ()) -> NFData VSep
    forall a. (a -> ()) -> NFData a
    $crnf :: VSep -> ()
    rnf :: VSep -> ()
    NFData, Eq VSep
    Eq VSep -> (Int -> VSep -> Int) -> (VSep -> Int) -> Hashable VSep
    Int -> VSep -> Int
    VSep -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> VSep -> Int
    hashWithSalt :: Int -> VSep -> Int
    $chash :: VSep -> Int
    hash :: VSep -> Int
    Hashable)

    --------------------------------------------------------------------------------
    -- Parsing

    -- | A synonym for the more verbose 'megaparsec' error type.
    type ParsingError = ParseErrorBundle Text Void

    -- | Parse a piece of `Text` into either an (Ideal) `SemVer`, a (General)
    -- `Version`, or a (Complex) `Mess`.
    versioning :: Text -> Either ParsingError Versioning
    versioning :: Text -> Either ParsingError Versioning
    versioning = Parsec Void Text Versioning
    -> String -> Text -> Either ParsingError Versioning
    forall e s a.
    Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
    parse Parsec Void Text Versioning
    versioning' String
    "versioning"

    -- | Parse a `Versioning`. Assumes the version number is the last token in
    -- the string.
    versioning' :: Parsec Void Text Versioning
    versioning' :: Parsec Void Text Versioning
    versioning' = [Parsec Void Text Versioning] -> Parsec Void Text Versioning
    forall (f :: * -> *) (m :: * -> *) a.
    (Foldable f, Alternative m) =>
    f (m a) -> m a
    choice [ Parsec Void Text Versioning -> Parsec Void Text Versioning
    forall a.
    ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    try ((SemVer -> Versioning)
    -> ParsecT Void Text Identity SemVer -> Parsec Void Text Versioning
    forall a b.
    (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap SemVer -> Versioning
    Ideal ParsecT Void Text Identity SemVer
    semver''    Parsec Void Text Versioning
    -> ParsecT Void Text Identity () -> Parsec Void Text Versioning
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Void Text Identity ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof)
                         , Parsec Void Text Versioning -> Parsec Void Text Versioning
    forall a.
    ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    try ((Version -> Versioning)
    -> ParsecT Void Text Identity Version
    -> Parsec Void Text Versioning
    forall a b.
    (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Version -> Versioning
    General ParsecT Void Text Identity Version
    version'' Parsec Void Text Versioning
    -> ParsecT Void Text Identity () -> Parsec Void Text Versioning
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Void Text Identity ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof)
                         , (Mess -> Versioning)
    -> ParsecT Void Text Identity Mess -> Parsec Void Text Versioning
    forall a b.
    (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Mess -> Versioning
    Complex ParsecT Void Text Identity Mess
    mess''         Parsec Void Text Versioning
    -> ParsecT Void Text Identity () -> Parsec Void Text Versioning
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Void Text Identity ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof ]

    -- | Parse a (Ideal) Semantic Version.
    semver :: Text -> Either ParsingError SemVer
    semver :: Text -> Either ParsingError SemVer
    semver = ParsecT Void Text Identity SemVer
    -> String -> Text -> Either ParsingError SemVer
    forall e s a.
    Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
    parse (ParsecT Void Text Identity SemVer
    semver'' ParsecT Void Text Identity SemVer
    -> ParsecT Void Text Identity ()
    -> ParsecT Void Text Identity SemVer
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Void Text Identity ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof) String
    "Semantic Version"

    -- | Internal megaparsec parser of `semver`.
    semver' :: Parsec Void Text SemVer
    semver' :: ParsecT Void Text Identity SemVer
    semver' = ParsecT Void Text Identity ()
    -> ParsecT Void Text Identity SemVer
    -> ParsecT Void Text Identity SemVer
    forall e s (m :: * -> *) a. MonadParsec e s m => m () -> m a -> m a
    L.lexeme ParsecT Void Text Identity ()
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    m ()
    space ParsecT Void Text Identity SemVer
    semver''

    semver'' :: Parsec Void Text SemVer
    semver'' :: ParsecT Void Text Identity SemVer
    semver'' = Word -> Word -> Word -> Maybe Release -> Maybe Text -> SemVer
    SemVer (Word -> Word -> Word -> Maybe Release -> Maybe Text -> SemVer)
    -> Parsec Void Text Word
    -> ParsecT
         Void
         Text
         Identity
         (Word -> Word -> Maybe Release -> Maybe Text -> SemVer)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Parsec Void Text Word
    majorP ParsecT
      Void
      Text
      Identity
      (Word -> Word -> Maybe Release -> Maybe Text -> SemVer)
    -> Parsec Void Text Word
    -> ParsecT
         Void Text Identity (Word -> Maybe Release -> Maybe Text -> SemVer)
    forall a b.
    ParsecT Void Text Identity (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Parsec Void Text Word
    minorP ParsecT
      Void Text Identity (Word -> Maybe Release -> Maybe Text -> SemVer)
    -> Parsec Void Text Word
    -> ParsecT
         Void Text Identity (Maybe Release -> Maybe Text -> SemVer)
    forall a b.
    ParsecT Void Text Identity (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Parsec Void Text Word
    patchP ParsecT Void Text Identity (Maybe Release -> Maybe Text -> SemVer)
    -> ParsecT Void Text Identity (Maybe Release)
    -> ParsecT Void Text Identity (Maybe Text -> SemVer)
    forall a b.
    ParsecT Void Text Identity (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ParsecT Void Text Identity Release
    -> ParsecT Void Text Identity (Maybe Release)
    forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    optional ParsecT Void Text Identity Release
    releaseP ParsecT Void Text Identity (Maybe Text -> SemVer)
    -> ParsecT Void Text Identity (Maybe Text)
    -> ParsecT Void Text Identity SemVer
    forall a b.
    ParsecT Void Text Identity (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ParsecT Void Text Identity Text
    -> ParsecT Void Text Identity (Maybe Text)
    forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    optional ParsecT Void Text Identity Text
    metaData

    -- | Parse a group of digits, which can't be lead by a 0, unless it is 0.
    unsignedP :: Parsec Void Text Word
    unsignedP :: Parsec Void Text Word
    unsignedP = (Word
    0 Word -> ParsecT Void Text Identity Char -> Parsec Void Text Word
    forall a b.
    a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '0') Parsec Void Text Word
    -> Parsec Void Text Word -> Parsec Void Text Word
    forall a.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parsec Void Text Word
    forall e s (m :: * -> *) a.
    (MonadParsec e s m, Token s ~ Char, Num a) =>
    m a
    decimal

    majorP :: Parsec Void Text Word
    majorP :: Parsec Void Text Word
    majorP = Parsec Void Text Word
    unsignedP Parsec Void Text Word
    -> ParsecT Void Text Identity Char -> Parsec Void Text Word
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '.'

    minorP :: Parsec Void Text Word
    minorP :: Parsec Void Text Word
    minorP = Parsec Void Text Word
    majorP

    patchP :: Parsec Void Text Word
    patchP :: Parsec Void Text Word
    patchP = Parsec Void Text Word
    unsignedP

    releaseP :: Parsec Void Text Release
    releaseP :: ParsecT Void Text Identity Release
    releaseP = Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '-' ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity Release
    -> ParsecT Void Text Identity Release
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> (NonEmpty Chunk -> Release)
    -> ParsecT Void Text Identity (NonEmpty Chunk)
    -> ParsecT Void Text Identity Release
    forall a b.
    (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap NonEmpty Chunk -> Release
    Release (Parsec Void Text Chunk
    chunkP Parsec Void Text Chunk
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity (NonEmpty Chunk)
    forall (m :: * -> *) a sep.
    Alternative m =>
    m a -> m sep -> m (NonEmpty a)
    `PC.sepBy1` Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '.')

    chunkP :: Parsec Void Text Chunk
    chunkP :: Parsec Void Text Chunk
    chunkP = Parsec Void Text Chunk -> Parsec Void Text Chunk
    forall a.
    ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    try Parsec Void Text Chunk
    alphanumP Parsec Void Text Chunk
    -> Parsec Void Text Chunk -> Parsec Void Text Chunk
    forall a.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parsec Void Text Chunk
    numericP

    alphanumP :: Parsec Void Text Chunk
    alphanumP :: Parsec Void Text Chunk
    alphanumP = do
      Text
    ids <- Maybe String
    -> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
    forall e s (m :: * -> *).
    MonadParsec e s m =>
    Maybe String -> (Token s -> Bool) -> m (Tokens s)
    takeWhile1P (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    "Hyphenated Alphanums") (\Token Text
    c -> Char -> Bool
    isAlphaNum Char
    Token Text
    c Bool -> Bool -> Bool
    || Char
    Token Text
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '-')
      -- It's okay for this to `fail` like this, since this fail is caught higher up
      -- in `chunkP` and another parser which should be guaranteed to succeed is
      -- called. It's guaranteed since by this point we /did/ parse something, but
      -- the test below proves it contains only numbers. Therefore the fallback call
      -- to `numericP` should succeed.
      Bool
    -> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ((Char -> Bool) -> Text -> Bool
    T.any (\Char
    c -> Char -> Bool
    isAlpha Char
    c Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '-') Text
    ids) (ParsecT Void Text Identity () -> ParsecT Void Text Identity ())
    -> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
    forall a b. (a -> b) -> a -> b
    $ String -> ParsecT Void Text Identity ()
    forall a. String -> ParsecT Void Text Identity a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Only numeric!"
      Chunk -> Parsec Void Text Chunk
    forall a. a -> ParsecT Void Text Identity a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Chunk -> Parsec Void Text Chunk)
    -> Chunk -> Parsec Void Text Chunk
    forall a b. (a -> b) -> a -> b
    $ Text -> Chunk
    Alphanum Text
    ids

    alphanumWithoutHyphensP :: Parsec Void Text Chunk
    alphanumWithoutHyphensP :: Parsec Void Text Chunk
    alphanumWithoutHyphensP = do
      Text
    ids <- Maybe String
    -> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
    forall e s (m :: * -> *).
    MonadParsec e s m =>
    Maybe String -> (Token s -> Bool) -> m (Tokens s)
    takeWhile1P (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    "Unhyphenated Alphanums") Char -> Bool
    Token Text -> Bool
    isAlphaNum
      Bool
    -> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ((Char -> Bool) -> Text -> Bool
    T.any Char -> Bool
    isAlpha Text
    ids) (ParsecT Void Text Identity () -> ParsecT Void Text Identity ())
    -> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
    forall a b. (a -> b) -> a -> b
    $ String -> ParsecT Void Text Identity ()
    forall a. String -> ParsecT Void Text Identity a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Only numeric!"
      Chunk -> Parsec Void Text Chunk
    forall a. a -> ParsecT Void Text Identity a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Chunk -> Parsec Void Text Chunk)
    -> Chunk -> Parsec Void Text Chunk
    forall a b. (a -> b) -> a -> b
    $ Text -> Chunk
    Alphanum Text
    ids

    numericP :: Parsec Void Text Chunk
    numericP :: Parsec Void Text Chunk
    numericP = Word -> Chunk
    Numeric (Word -> Chunk) -> Parsec Void Text Word -> Parsec Void Text Chunk
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Parsec Void Text Word
    unsignedP

    chunkWithoutHyphensP :: Parsec Void Text Chunk
    chunkWithoutHyphensP :: Parsec Void Text Chunk
    chunkWithoutHyphensP = Parsec Void Text Chunk -> Parsec Void Text Chunk
    forall a.
    ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    try Parsec Void Text Chunk
    alphanumWithoutHyphensP Parsec Void Text Chunk
    -> Parsec Void Text Chunk -> Parsec Void Text Chunk
    forall a.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parsec Void Text Chunk
    numericP

    metaData :: Parsec Void Text Text
    metaData :: ParsecT Void Text Identity Text
    metaData = do
      ParsecT Void Text Identity Char -> ParsecT Void Text Identity ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (ParsecT Void Text Identity Char -> ParsecT Void Text Identity ())
    -> ParsecT Void Text Identity Char -> ParsecT Void Text Identity ()
    forall a b. (a -> b) -> a -> b
    $ Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '+'
      NonEmpty Text -> Text
    forall m. Monoid m => NonEmpty m -> m
    forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
    fold (NonEmpty Text -> Text)
    -> (NonEmpty Text -> NonEmpty Text) -> NonEmpty Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> NonEmpty Text -> NonEmpty Text
    forall a. a -> NonEmpty a -> NonEmpty a
    NEL.intersperse Text
    "." (NonEmpty Text -> Text)
    -> ParsecT Void Text Identity (NonEmpty Text)
    -> ParsecT Void Text Identity Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT Void Text Identity Text
    section ParsecT Void Text Identity Text
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity (NonEmpty Text)
    forall (m :: * -> *) a sep.
    Alternative m =>
    m a -> m sep -> m (NonEmpty a)
    `PC.sepBy1` Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '.'
      where
        section :: Parsec Void Text Text
        section :: ParsecT Void Text Identity Text
    section = Maybe String
    -> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
    forall e s (m :: * -> *).
    MonadParsec e s m =>
    Maybe String -> (Token s -> Bool) -> m (Tokens s)
    takeWhile1P (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    "Metadata char") (\Token Text
    c -> Char -> Bool
    isAlphaNum Char
    Token Text
    c Bool -> Bool -> Bool
    || Char
    Token Text
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '-')

    -- | Parse a (Haskell) `PVP`, as defined above.
    pvp :: Text -> Either ParsingError PVP
    pvp :: Text -> Either ParsingError PVP
    pvp = Parsec Void Text PVP -> String -> Text -> Either ParsingError PVP
    forall e s a.
    Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
    parse (Parsec Void Text PVP
    pvp' Parsec Void Text PVP
    -> ParsecT Void Text Identity () -> Parsec Void Text PVP
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Void Text Identity ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof) String
    "PVP"

    -- | Internal megaparsec parser of `pvp`.
    pvp' :: Parsec Void Text PVP
    pvp' :: Parsec Void Text PVP
    pvp' = ParsecT Void Text Identity ()
    -> Parsec Void Text PVP -> Parsec Void Text PVP
    forall e s (m :: * -> *) a. MonadParsec e s m => m () -> m a -> m a
    L.lexeme ParsecT Void Text Identity ()
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    m ()
    space (NonEmpty Word -> PVP
    PVP (NonEmpty Word -> PVP)
    -> ([Word] -> NonEmpty Word) -> [Word] -> PVP
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Word] -> NonEmpty Word
    forall a. HasCallStack => [a] -> NonEmpty a
    NEL.fromList ([Word] -> PVP)
    -> ParsecT Void Text Identity [Word] -> Parsec Void Text PVP
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Parsec Void Text Word
    forall e s (m :: * -> *) a.
    (MonadParsec e s m, Token s ~ Char, Num a) =>
    m a
    L.decimal Parsec Void Text Word
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity [Word]
    forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
    `sepBy` Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '.')

    -- | Parse a (General) `Version`, as defined above.
    version :: Text -> Either ParsingError Version
    version :: Text -> Either ParsingError Version
    version = ParsecT Void Text Identity Version
    -> String -> Text -> Either ParsingError Version
    forall e s a.
    Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
    parse (ParsecT Void Text Identity Version
    version'' ParsecT Void Text Identity Version
    -> ParsecT Void Text Identity ()
    -> ParsecT Void Text Identity Version
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Void Text Identity ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof) String
    "Version"

    -- | Internal megaparsec parser of `version`.
    version' :: Parsec Void Text Version
    version' :: ParsecT Void Text Identity Version
    version' = ParsecT Void Text Identity ()
    -> ParsecT Void Text Identity Version
    -> ParsecT Void Text Identity Version
    forall e s (m :: * -> *) a. MonadParsec e s m => m () -> m a -> m a
    L.lexeme ParsecT Void Text Identity ()
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    m ()
    space ParsecT Void Text Identity Version
    version''

    version'' :: Parsec Void Text Version
    version'' :: ParsecT Void Text Identity Version
    version'' = Maybe Word -> Chunks -> Maybe Release -> Maybe Text -> Version
    Version (Maybe Word -> Chunks -> Maybe Release -> Maybe Text -> Version)
    -> ParsecT Void Text Identity (Maybe Word)
    -> ParsecT
         Void
         Text
         Identity
         (Chunks -> Maybe Release -> Maybe Text -> Version)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Parsec Void Text Word -> ParsecT Void Text Identity (Maybe Word)
    forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    optional (Parsec Void Text Word -> Parsec Void Text Word
    forall a.
    ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    try Parsec Void Text Word
    epochP) ParsecT
      Void
      Text
      Identity
      (Chunks -> Maybe Release -> Maybe Text -> Version)
    -> ParsecT Void Text Identity Chunks
    -> ParsecT
         Void Text Identity (Maybe Release -> Maybe Text -> Version)
    forall a b.
    ParsecT Void Text Identity (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ParsecT Void Text Identity Chunks
    chunksP ParsecT Void Text Identity (Maybe Release -> Maybe Text -> Version)
    -> ParsecT Void Text Identity (Maybe Release)
    -> ParsecT Void Text Identity (Maybe Text -> Version)
    forall a b.
    ParsecT Void Text Identity (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ParsecT Void Text Identity Release
    -> ParsecT Void Text Identity (Maybe Release)
    forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    optional ParsecT Void Text Identity Release
    releaseP ParsecT Void Text Identity (Maybe Text -> Version)
    -> ParsecT Void Text Identity (Maybe Text)
    -> ParsecT Void Text Identity Version
    forall a b.
    ParsecT Void Text Identity (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ParsecT Void Text Identity Text
    -> ParsecT Void Text Identity (Maybe Text)
    forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    optional ParsecT Void Text Identity Text
    metaData

    epochP :: Parsec Void Text Word
    epochP :: Parsec Void Text Word
    epochP = String -> Word
    forall a. Read a => String -> a
    read (String -> Word)
    -> ParsecT Void Text Identity String -> Parsec Void Text Word
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity String
    forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
    some ParsecT Void Text Identity Char
    ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    m (Token s)
    digitChar ParsecT Void Text Identity String
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity String
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    ':')

    chunksP :: Parsec Void Text Chunks
    chunksP :: ParsecT Void Text Identity Chunks
    chunksP = NonEmpty Chunk -> Chunks
    Chunks (NonEmpty Chunk -> Chunks)
    -> ParsecT Void Text Identity (NonEmpty Chunk)
    -> ParsecT Void Text Identity Chunks
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Parsec Void Text Chunk
    chunkWithoutHyphensP Parsec Void Text Chunk
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity (NonEmpty Chunk)
    forall (m :: * -> *) a sep.
    Alternative m =>
    m a -> m sep -> m (NonEmpty a)
    `PC.sepBy1` Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '.'

    -- | Parse a (Complex) `Mess`, as defined above.
    mess :: Text -> Either ParsingError Mess
    mess :: Text -> Either ParsingError Mess
    mess = ParsecT Void Text Identity Mess
    -> String -> Text -> Either ParsingError Mess
    forall e s a.
    Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
    parse (ParsecT Void Text Identity Mess
    mess'' ParsecT Void Text Identity Mess
    -> ParsecT Void Text Identity () -> ParsecT Void Text Identity Mess
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Void Text Identity ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof) String
    "Mess"

    -- | Internal megaparsec parser of `mess`.
    mess' :: Parsec Void Text Mess
    mess' :: ParsecT Void Text Identity Mess
    mess' = ParsecT Void Text Identity ()
    -> ParsecT Void Text Identity Mess
    -> ParsecT Void Text Identity Mess
    forall e s (m :: * -> *) a. MonadParsec e s m => m () -> m a -> m a
    L.lexeme ParsecT Void Text Identity ()
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    m ()
    space ParsecT Void Text Identity Mess
    mess''

    mess'' :: Parsec Void Text Mess
    mess'' :: ParsecT Void Text Identity Mess
    mess'' = NonEmpty MChunk -> Maybe (VSep, Mess) -> Mess
    Mess (NonEmpty MChunk -> Maybe (VSep, Mess) -> Mess)
    -> ParsecT Void Text Identity (NonEmpty MChunk)
    -> ParsecT Void Text Identity (Maybe (VSep, Mess) -> Mess)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT Void Text Identity (NonEmpty MChunk)
    mchunks ParsecT Void Text Identity (Maybe (VSep, Mess) -> Mess)
    -> ParsecT Void Text Identity (Maybe (VSep, Mess))
    -> ParsecT Void Text Identity Mess
    forall a b.
    ParsecT Void Text Identity (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ParsecT Void Text Identity (VSep, Mess)
    -> ParsecT Void Text Identity (Maybe (VSep, Mess))
    forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    optional ((,) (VSep -> Mess -> (VSep, Mess))
    -> ParsecT Void Text Identity VSep
    -> ParsecT Void Text Identity (Mess -> (VSep, Mess))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT Void Text Identity VSep
    sep ParsecT Void Text Identity (Mess -> (VSep, Mess))
    -> ParsecT Void Text Identity Mess
    -> ParsecT Void Text Identity (VSep, Mess)
    forall a b.
    ParsecT Void Text Identity (a -> b)
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ParsecT Void Text Identity Mess
    mess')

    mchunks :: Parsec Void Text (NonEmpty MChunk)
    mchunks :: ParsecT Void Text Identity (NonEmpty MChunk)
    mchunks = Parsec Void Text MChunk
    mchunk Parsec Void Text MChunk
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity (NonEmpty MChunk)
    forall (m :: * -> *) a sep.
    Alternative m =>
    m a -> m sep -> m (NonEmpty a)
    `PC.sepBy1` Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '.'

    mchunk :: Parsec Void Text MChunk
    mchunk :: Parsec Void Text MChunk
    mchunk = [Parsec Void Text MChunk] -> Parsec Void Text MChunk
    forall (f :: * -> *) (m :: * -> *) a.
    (Foldable f, Alternative m) =>
    f (m a) -> m a
    choice [ Parsec Void Text MChunk -> Parsec Void Text MChunk
    forall a.
    ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    try (Parsec Void Text MChunk -> Parsec Void Text MChunk)
    -> Parsec Void Text MChunk -> Parsec Void Text MChunk
    forall a b. (a -> b) -> a -> b
    $ (\(Text
    t, Word
    i) -> Word -> Text -> MChunk
    MDigit Word
    i Text
    t) ((Text, Word) -> MChunk)
    -> ParsecT Void Text Identity (Text, Word)
    -> Parsec Void Text MChunk
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Parsec Void Text Word
    -> ParsecT Void Text Identity (Tokens Text, Word)
    forall e s (m :: * -> *) a.
    MonadParsec e s m =>
    m a -> m (Tokens s, a)
    match (Parsec Void Text Word
    forall e s (m :: * -> *) a.
    (MonadParsec e s m, Token s ~ Char, Num a) =>
    m a
    L.decimal Parsec Void Text Word
    -> ParsecT Void Text Identity () -> Parsec Void Text Word
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Void Text Identity ()
    next)
                    , Parsec Void Text MChunk -> Parsec Void Text MChunk
    forall a.
    ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    try (Parsec Void Text MChunk -> Parsec Void Text MChunk)
    -> Parsec Void Text MChunk -> Parsec Void Text MChunk
    forall a b. (a -> b) -> a -> b
    $ (\(Text
    t, Word
    i) -> Word -> Text -> MChunk
    MRev Word
    i Text
    t) ((Text, Word) -> MChunk)
    -> ParsecT Void Text Identity (Text, Word)
    -> Parsec Void Text MChunk
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Parsec Void Text Word
    -> ParsecT Void Text Identity (Tokens Text, Word)
    forall e s (m :: * -> *) a.
    MonadParsec e s m =>
    m a -> m (Tokens s, a)
    match (Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    MonadParsec e s m =>
    Token s -> m (Token s)
    single Char
    Token Text
    'r' ParsecT Void Text Identity (Token Text)
    -> Parsec Void Text Word -> Parsec Void Text Word
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> Parsec Void Text Word
    forall e s (m :: * -> *) a.
    (MonadParsec e s m, Token s ~ Char, Num a) =>
    m a
    L.decimal Parsec Void Text Word
    -> ParsecT Void Text Identity () -> Parsec Void Text Word
    forall a b.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Void Text Identity ()
    next)
                    , Text -> MChunk
    MPlain (Text -> MChunk) -> (String -> Text) -> String -> MChunk
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    T.pack (String -> MChunk)
    -> ParsecT Void Text Identity String -> Parsec Void Text MChunk
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity String
    forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
    some (ParsecT Void Text Identity Char
    ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    m (Token s)
    letterChar ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity Char
    forall a.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParsecT Void Text Identity Char
    ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    m (Token s)
    digitChar) ]
      where
        next :: Parsec Void Text ()
        next :: ParsecT Void Text Identity ()
    next = ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
    forall a.
    ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    lookAhead (ParsecT Void Text Identity (Token Text)
    -> ParsecT Void Text Identity ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    MonadParsec e s m =>
    Token s -> m (Token s)
    single Char
    Token Text
    '.') ParsecT Void Text Identity ()
    -> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
    forall a.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParsecT Void Text Identity VSep -> ParsecT Void Text Identity ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void ParsecT Void Text Identity VSep
    sep ParsecT Void Text Identity ()
    -> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
    forall a.
    ParsecT Void Text Identity a
    -> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParsecT Void Text Identity ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof)

    sep :: Parsec Void Text VSep
    sep :: ParsecT Void Text Identity VSep
    sep = [ParsecT Void Text Identity VSep]
    -> ParsecT Void Text Identity VSep
    forall (f :: * -> *) (m :: * -> *) a.
    (Foldable f, Alternative m) =>
    f (m a) -> m a
    choice [ VSep
    VColon  VSep
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity VSep
    forall a b.
    a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    ':'
                 , VSep
    VHyphen VSep
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity VSep
    forall a b.
    a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '-'
                 , VSep
    VPlus   VSep
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity VSep
    forall a b.
    a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '+'
                 , VSep
    VUnder  VSep
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity VSep
    forall a b.
    a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '_'
                 , VSep
    VTilde  VSep
    -> ParsecT Void Text Identity Char
    -> ParsecT Void Text Identity VSep
    forall a b.
    a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Token Text -> ParsecT Void Text Identity (Token Text)
    forall e s (m :: * -> *).
    (MonadParsec e s m, Token s ~ Char) =>
    Token s -> m (Token s)
    char Char
    Token Text
    '~' ]

    sepCh :: VSep -> Char
    sepCh :: VSep -> Char
    sepCh VSep
    VColon  = Char
    ':'
    sepCh VSep
    VHyphen = Char
    '-'
    sepCh VSep
    VPlus   = Char
    '+'
    sepCh VSep
    VUnder  = Char
    '_'
    sepCh VSep
    VTilde  = Char
    '~'

    -- | Convert any parsed Versioning type to its textual representation.
    prettyV :: Versioning -> Text
    prettyV :: Versioning -> Text
    prettyV (Ideal SemVer
    sv)  = SemVer -> Text
    prettySemVer SemVer
    sv
    prettyV (General Version
    v) = Version -> Text
    prettyVer Version
    v
    prettyV (Complex Mess
    m) = Mess -> Text
    prettyMess Mess
    m

    -- | Convert a `SemVer` back to its textual representation.
    prettySemVer :: SemVer -> Text
    prettySemVer :: SemVer -> Text
    prettySemVer (SemVer Word
    ma Word
    mi Word
    pa Maybe Release
    pr Maybe Text
    me) = [Text] -> Text
    forall a. Monoid a => [a] -> a
    mconcat ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ [Text]
    ver [Text] -> [Text] -> [Text]
    forall a. Semigroup a => a -> a -> a
    <> [Text]
    pr' [Text] -> [Text] -> [Text]
    forall a. Semigroup a => a -> a -> a
    <> [Text]
    me'
      where
        ver :: [Text]
    ver = Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    intersperse Text
    "." [ Word -> Text
    forall a. Show a => a -> Text
    showt Word
    ma, Word -> Text
    forall a. Show a => a -> Text
    showt Word
    mi, Word -> Text
    forall a. Show a => a -> Text
    showt Word
    pa ]
        pr' :: [Text]
    pr' = [Text] -> (Release -> [Text]) -> Maybe Release -> [Text]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\Release
    m -> [Text
    "-", Release -> Text
    prettyRelease Release
    m]) Maybe Release
    pr
        me' :: [Text]
    me' = [Text] -> (Text -> [Text]) -> Maybe Text -> [Text]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\Text
    m -> [Text
    "+", Text
    m]) Maybe Text
    me

    -- | Convert a `PVP` back to its textual representation.
    prettyPVP :: PVP -> Text
    prettyPVP :: PVP -> Text
    prettyPVP (PVP (Word
    m :| [Word]
    rs)) = Text -> [Text] -> Text
    T.intercalate Text
    "." ([Text] -> Text) -> ([Word] -> [Text]) -> [Word] -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Word -> Text) -> [Word] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map Word -> Text
    forall a. Show a => a -> Text
    showt ([Word] -> Text) -> [Word] -> Text
    forall a b. (a -> b) -> a -> b
    $ Word
    m Word -> [Word] -> [Word]
    forall a. a -> [a] -> [a]
    : [Word]
    rs

    -- | Convert a `Version` back to its textual representation.
    prettyVer :: Version -> Text
    prettyVer :: Version -> Text
    prettyVer (Version Maybe Word
    ep Chunks
    cs Maybe Release
    pr Maybe Text
    me) = [Text] -> Text
    forall a. Monoid a => [a] -> a
    mconcat ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ [Text]
    ep' [Text] -> [Text] -> [Text]
    forall a. Semigroup a => a -> a -> a
    <> [Text
    ver] [Text] -> [Text] -> [Text]
    forall a. Semigroup a => a -> a -> a
    <> [Text]
    pr' [Text] -> [Text] -> [Text]
    forall a. Semigroup a => a -> a -> a
    <> [Text]
    me'
      where
        ver :: Text
    ver = Chunks -> Text
    prettyChunks Chunks
    cs
        me' :: [Text]
    me' = [Text] -> (Text -> [Text]) -> Maybe Text -> [Text]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\Text
    m -> [Text
    "+", Text
    m]) Maybe Text
    me
        pr' :: [Text]
    pr' = [Text] -> (Release -> [Text]) -> Maybe Release -> [Text]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\Release
    m -> [Text
    "-", Release -> Text
    prettyRelease Release
    m]) Maybe Release
    pr
        ep' :: [Text]
    ep' = [Text] -> (Word -> [Text]) -> Maybe Word -> [Text]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\Word
    e -> [Word -> Text
    forall a. Show a => a -> Text
    showt Word
    e, Text
    ":"]) Maybe Word
    ep

    -- | Convert a `Mess` back to its textual representation.
    prettyMess :: Mess -> Text
    prettyMess :: Mess -> Text
    prettyMess (Mess NonEmpty MChunk
    t Maybe (VSep, Mess)
    m) = case Maybe (VSep, Mess)
    m of
      Maybe (VSep, Mess)
    Nothing     -> Text
    t'
      Just (VSep
    s, Mess
    v) -> Text -> Char -> Text
    T.snoc Text
    t' (VSep -> Char
    sepCh VSep
    s) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Mess -> Text
    prettyMess Mess
    v
      where
        t' :: Text
        t' :: Text
    t' = NonEmpty Text -> Text
    forall m. Monoid m => NonEmpty m -> m
    forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
    fold (NonEmpty Text -> Text)
    -> (NonEmpty Text -> NonEmpty Text) -> NonEmpty Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> NonEmpty Text -> NonEmpty Text
    forall a. a -> NonEmpty a -> NonEmpty a
    NEL.intersperse Text
    "." (NonEmpty Text -> Text) -> NonEmpty Text -> Text
    forall a b. (a -> b) -> a -> b
    $ (MChunk -> Text) -> NonEmpty MChunk -> NonEmpty Text
    forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
    NEL.map MChunk -> Text
    mchunkText NonEmpty MChunk
    t

    prettyChunks :: Chunks -> Text
    prettyChunks :: Chunks -> Text
    prettyChunks (Chunks NonEmpty Chunk
    cs) = Text -> [Text] -> Text
    T.intercalate Text
    "." ([Text] -> Text) -> ([Chunk] -> [Text]) -> [Chunk] -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Chunk -> Text) -> [Chunk] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map Chunk -> Text
    prettyChunk ([Chunk] -> Text) -> [Chunk] -> Text
    forall a b. (a -> b) -> a -> b
    $ NonEmpty Chunk -> [Chunk]
    forall a. NonEmpty a -> [a]
    NEL.toList NonEmpty Chunk
    cs

    prettyRelease :: Release -> Text
    prettyRelease :: Release -> Text
    prettyRelease (Release NonEmpty Chunk
    cs) = Text -> [Text] -> Text
    T.intercalate Text
    "." ([Text] -> Text) -> ([Chunk] -> [Text]) -> [Chunk] -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Chunk -> Text) -> [Chunk] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map Chunk -> Text
    prettyChunk ([Chunk] -> Text) -> [Chunk] -> Text
    forall a b. (a -> b) -> a -> b
    $ NonEmpty Chunk -> [Chunk]
    forall a. NonEmpty a -> [a]
    NEL.toList NonEmpty Chunk
    cs

    prettyChunk :: Chunk -> Text
    prettyChunk :: Chunk -> Text
    prettyChunk (Numeric Word
    n)  = Word -> Text
    forall a. Show a => a -> Text
    showt Word
    n
    prettyChunk (Alphanum Text
    s) = Text
    s

    --------------------------------------------------------------------------------
    -- Utilities

    -- | Flip an Ordering.
    opposite :: Ordering -> Ordering
    opposite :: Ordering -> Ordering
    opposite Ordering
    EQ = Ordering
    EQ
    opposite Ordering
    LT = Ordering
    GT
    opposite Ordering
    GT = Ordering
    LT

    -- Yes, `text-show` exists, but this reduces external dependencies.
    showt :: Show a => a -> Text
    showt :: forall a. Show a => a -> Text
    showt = String -> Text
    T.pack (String -> Text) -> (a -> String) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> String
    forall a. Show a => a -> String
    show

    hush :: Either a b -> Maybe b
    hush :: forall a b. Either a b -> Maybe b
    hush (Left a
    _)  = Maybe b
    forall a. Maybe a
    Nothing
    hush (Right b
    b) = b -> Maybe b
    forall a. a -> Maybe a
    Just b
    b

    data These a b = This a | That b | Both a b

    zipLongest :: [a] -> [b] -> [These a b]
    zipLongest :: forall a b. [a] -> [b] -> [These a b]
    zipLongest [] []         = []
    zipLongest (a
    a:[a]
    as) (b
    b:[b]
    bs) = a -> b -> These a b
    forall a b. a -> b -> These a b
    Both a
    a b
    b These a b -> [These a b] -> [These a b]
    forall a. a -> [a] -> [a]
    : [a] -> [b] -> [These a b]
    forall a b. [a] -> [b] -> [These a b]
    zipLongest [a]
    as [b]
    bs
    zipLongest (a
    a:[a]
    as) []     = a -> These a b
    forall a b. a -> These a b
    This a
    a These a b -> [These a b] -> [These a b]
    forall a. a -> [a] -> [a]
    : [a] -> [b] -> [These a b]
    forall a b. [a] -> [b] -> [These a b]
    zipLongest [a]
    as []
    zipLongest [] (b
    b:[b]
    bs)     = b -> These a b
    forall a b. b -> These a b
    That b
    b These a b -> [These a b] -> [These a b]
    forall a. a -> [a] -> [a]
    : [a] -> [b] -> [These a b]
    forall a b. [a] -> [b] -> [These a b]
    zipLongest [] [b]
    bs