Skip to content

Instantly share code, notes, and snippets.

@saevarb
Created October 6, 2014 19:55
Show Gist options
  • Save saevarb/6cb40851918578c406e8 to your computer and use it in GitHub Desktop.
Save saevarb/6cb40851918578c406e8 to your computer and use it in GitHub Desktop.
{-# LANGUAGE RecordWildCards #-}
import Control.Applicative ((<$>))
import Text.Parsec hiding (label)
import Text.Parsec.String
import Data.Either
data SemanticVersion
= SemanticVersion
{ major :: Int
, minor :: Int
, patch :: Int
, label :: Maybe String
, meta :: Maybe String
} deriving (Eq, Read)
instance (Ord SemanticVersion) where
(<) a b =
or [ major a < major b
, minor a < minor b
, patch a < patch b
, maybe 0 (const 1) (label a) < maybe 0 (const 1) (label b)
]
(<=) a b =
a == b || a < b
(>) a b = not $ a <= b
(>=) a b = a == b || a > b
max a b = if a >= b then a else b
min a b = if a <= b then a else b
compare a b
| a < b = LT
| a > b = GT
| otherwise = EQ
instance (Show SemanticVersion) where
show (SemanticVersion {..}) =
show major ++ "." ++
show minor ++ "." ++
show patch ++
maybe "" ("-" ++) label ++
maybe "" ("+" ++) meta
semVerP :: Parser SemanticVersion
semVerP = do
maj <- parseInt
char '.'
min' <- parseInt
char '.'
pat <- parseInt
lab <- optionMaybe (char '-' >> many1 alphaNum)
met <- optionMaybe (char '+' >> many1 alphaNum)
return $ SemanticVersion maj min' pat lab met
where
parseInt :: Parser Int
parseInt = read <$> many1 digit
tests = rights $ map (parse semVerP "foobar")
[ "2.0.11-alpha"
, "0.1.7+amd64"
, "0.10.7+20141005"
, "2.0.12+i386"
, "1.2.34"
, "2.0.11+i386"
, "20.1.1+i386"
]
main :: IO ()
main = undefined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment