packages feed

semantic-version-0.0.1: src/Data/SemanticVersion/Version.hs

{-# OPTIONS_GHC -Wall #-}

module Data.SemanticVersion.Version where

import Control.Lens
import Data.SemanticVersion.NumericIdentifier
import Text.Parser.Char

-- $setup
-- >>> import Text.Parsec(parse)
-- >>> import Data.Either(isLeft)

-- <version core> ::= <major> "." <minor> "." <patch>
data Version =
  Version NumericIdentifier NumericIdentifier NumericIdentifier
  deriving (Eq, Show)

class HasVersion a where
  version ::
    Lens' a Version
  versionMajor ::
    Lens' a NumericIdentifier
  versionMajor =
    version . \f (Version j n p) -> fmap (\j' -> Version j' n p) (f j)
  versionMinor ::
    Lens' a NumericIdentifier
  versionMinor =
    version . \f (Version j n p) -> fmap (\n' -> Version j n' p) (f n)
  versionPatch ::
    Lens' a NumericIdentifier
  versionPatch =
    version . \f (Version j n p) -> fmap (Version j n) (f p)

instance HasVersion Version where
  version =
    id

class AsVersion a where
  _Version ::
    Prism' a Version

instance AsVersion Version where
  _Version =
    id

-- |
--
-- >>> parse (parseVersion <* eof) "parseVersion" "0.0.0"
-- Right (Version NumericIdentifierZero NumericIdentifierZero NumericIdentifierZero)
--
-- >>> isLeft (parse parseVersion "parseVersion" "")
-- True
--
-- >>> parse (parseVersion <* eof) "parseVersion" "1.2.3"
-- Right (Version (NumericIdentifierDigits DecDigitNoZero1 []) (NumericIdentifierDigits DecDigitNoZero2 []) (NumericIdentifierDigits DecDigitNoZero3 []))
--
-- >>> isLeft(parse parseVersion "parseVersion" "01.2.3")
-- True
--
-- >>> parse (parseVersion <* eof) "parseVersion" "10.2.3"
-- Right (Version (NumericIdentifierDigits DecDigitNoZero1 [DecDigit0]) (NumericIdentifierDigits DecDigitNoZero2 []) (NumericIdentifierDigits DecDigitNoZero3 []))
--
-- >>> parse (parseVersion <* eof) "parseVersion" "38012.5.6"
-- Right (Version (NumericIdentifierDigits DecDigitNoZero3 [DecDigit8,DecDigit0,DecDigit1,DecDigit2]) (NumericIdentifierDigits DecDigitNoZero5 []) (NumericIdentifierDigits DecDigitNoZero6 []))
--
-- >>> parse (parseVersion <* eof) "parseVersion" "38012.5.5432"
-- Right (Version (NumericIdentifierDigits DecDigitNoZero3 [DecDigit8,DecDigit0,DecDigit1,DecDigit2]) (NumericIdentifierDigits DecDigitNoZero5 []) (NumericIdentifierDigits DecDigitNoZero5 [DecDigit4,DecDigit3,DecDigit2]))
--
-- >>> isLeft (parse (parseVersion <* eof) "parseVersion" "38012.05.5432")
-- True
--
-- >>> isLeft (parse (parseVersion <* eof) "parseVersion" "38012.5.05432")
-- True
--
-- >>> isLeft (parse parseVersion "parseVersion" "a")
-- True
--
-- >>> isLeft (parse parseVersion "parseVersion" "-")
-- True
parseVersion ::
  CharParsing p =>
  p Version
parseVersion =
  Version <$> parseNumericIdentifier <* char '.' <*> parseNumericIdentifier <* char '.' <*> parseNumericIdentifier