Report a paste

Please put a quick comment for the admin.

If it looks like spam, the admin will mark it as spam so that the spam filter picks it up in the future.

If the paste contains something private or offensive, it'll probably just be deleted.

trifecta

{-# LANGUAGE OverloadedStrings #-}
module Book where

import           Control.Applicative
import           Test.Hspec
import           Text.Trifecta

data NumberOrString =
    NOSS String
  | NOSI Integer
  deriving (Show, Eq)

type Major = Integer
type Minor = Integer
type Patch = Integer
type Release = [NumberOrString]
type Metadata = [NumberOrString]

data SemVer = SemVer Major Minor Patch Release Metadata deriving (Eq, Show)

skipPeriod :: Parser ()
skipPeriod = skipMany (oneOf ".")

parseNoS :: Parser NumberOrString
parseNoS = do
  skipPeriod
  v <- (NOSI <$> integer) <|> (NOSS <$> some letter)
  return v

parseSemVer :: Parser SemVer
parseSemVer = do
  major <- integer
  skipPeriod
  minor <- integer
  skipPeriod
  patch <- integer
  skipPeriod
  skipMany (oneOf "-")
  rel <- try (manyTill parseNoS (oneOf "+")) <|> many parseNoS <|> return []
  meta <- (many parseNoS) <|> return []
  return $ SemVer major minor patch rel meta

maybeSuccess :: Result a -> Maybe a
maybeSuccess (Success a) = Just a
maybeSuccess _ = Nothing

main :: IO ()
main =
    hspec $
    do describe "SemVer Major Version Parsing" $
           it "can parse a major version" $
           do let m = parseByteString parseSemVer mempty "0.1.1"
              maybeSuccess m `shouldBe` Just (SemVer 0 1 1 [] [])
       describe "SemVer Pre-Release Version Parsing" $
           it "can parse a simple pre-release string" $
           do let m = parseByteString parseSemVer mempty "1.0.0-beta.2"
              maybeSuccess m `shouldBe`
                  Just (SemVer 1 0 0 [NOSS "beta", NOSI 2] [])
       describe "SemVer Metadata Parsing" $
           it "can parse metadata from a string" $
           do let m = parseByteString parseSemVer mempty "1.0.0+2013"
              maybeSuccess m `shouldBe` Just (SemVer 1 0 0 [] [NOSI 2013])
       describe "SemVer Full Parsing" $
           it "can parse a simple full semver from a string" $
           do let m = parseByteString parseSemVer mempty "1.0.0-alpha+2013"
              maybeSuccess m `shouldBe`
                  Just (SemVer 1 0 0 [NOSS "alpha"] [NOSI 2013])
       describe "SemVer Full Parsing" $
           it "can parse a full complicated SemVer string" $
           do let m =
                      parseByteString
                          parseSemVer
                          mempty
                          "1.23.0-beta+exp.sha.5114f85"
              maybeSuccess m `shouldBe`
                  Just
                      (SemVer
                           1
                           23
                           0
                           [NOSS "beta"]
                           [ NOSS "exp"
                           , NOSS "sha"
                           , NOSI 5114
                           , NOSS "f"
                           , NOSI 85])