Created
January 10, 2019 12:09
-
-
Save blabber/1c6134cf23cf8ff8ef88a0466d3af33d to your computer and use it in GitHub Desktop.
Semantic Version parser exercise
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Control.Applicative | |
import Text.Trifecta | |
import Test.Hspec | |
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 (Show, Eq) | |
parseSemVer :: Parser SemVer | |
parseSemVer = SemVer <$> parseVersion | |
<*> parseVersion | |
<*> parseVersion | |
<*> option [] parseRel | |
<*> option [] parseMeta | |
<* eof | |
parseVersion :: Parser Integer | |
parseVersion = skipOptional (char '.') *> decimal | |
parseRel :: Parser [NumberOrString] | |
parseRel = char '-' *> parseNOSs | |
parseMeta :: Parser [NumberOrString] | |
parseMeta = char '+' *> parseNOSs | |
parseNOSs :: Parser [NumberOrString] | |
parseNOSs = some (parseNOS <* skipOptional (char '.')) | |
parseNOS :: Parser NumberOrString | |
parseNOS = | |
(try (NOSI <$> (decimal <* notFollowedBy letter) <?> "tried NOSI")) | |
<|> (NOSS <$> some (noneOf ['.', '+']) <?> "tried NOSS") | |
maybeSuccess :: Result a -> Maybe a | |
maybeSuccess (Success a) = Just a | |
maybeSuccess _ = Nothing | |
main :: IO () | |
main = hspec $ do | |
describe "parseSemVer" $ do | |
it "parses \"2.1.1\"" $ do | |
maybeSuccess (parseString parseSemVer mempty "2.1.1") | |
`shouldBe` Just (SemVer 2 1 1 [] []) | |
it "parses \"1.0.0-x.7.z.92\"" $ do | |
maybeSuccess (parseString parseSemVer mempty "1.0.0-x.7.z.92") | |
`shouldBe` Just (SemVer 1 0 0 | |
[ NOSS "x" | |
, NOSI 7 | |
, NOSS "z" | |
, NOSI 92 | |
] | |
[]) | |
it "parses \"1.0.0-beta+oof.sha.41af286\"" $ do | |
maybeSuccess (parseString parseSemVer mempty "1.0.0-beta+oof.sha.41af286") | |
`shouldBe` Just (SemVer 1 0 0 | |
[ NOSS "beta" ] | |
[ NOSS "oof" | |
, NOSS "sha" | |
, NOSS "41af286" | |
]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment