module SemVer where import Control.Applicative import Text.Trifecta -- 1. Write a parser for semantic versions as defined by http://semver.org/. -- After making a working parser, write an Ord instance for the SemVer type -- that obeys the specification outlined on the SemVer website. -- Relevant to precedence/ordering, -- cannot sort numbers like strings. data NumberOrString = NOSS String | NOSI Integer deriving (Eq, Show) 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) parseNos :: Parser NumberOrString parseNos = do nos <- (NOSI <$> integer) <|> (NOSS <$> some letter) return nos parseRelease :: Parser [NumberOrString] parseRelease = do _ <- char '-' sepBy parseNos (char '.') parseMetadata :: Parser [NumberOrString] parseMetadata = do _ <- char '+' sepBy parseNos (char '.') parseSemVer :: Parser SemVer parseSemVer = do major <- decimal _ <- char '.' minor <- decimal _ <- char '.' patch <- decimal release <- option [] parseRelease metadata <- option [] parseMetadata return $ SemVer major minor patch release metadata