module Elm.Package.Version where import Control.Applicative ((<$>), (<*>)) import Data.Aeson import Data.Binary import Data.Char (isDigit) import Data.Function (on) import qualified Data.List as List import qualified Data.Text as T import qualified Elm.Compiler as Elm elm :: Version elm = case Elm.rawVersion of major : minor : patch : _ -> Version major minor patch [major, minor] -> Version major minor 0 [major] -> Version major 0 0 [] -> error "could not detect version of elm-compiler you are using" data Version = Version { major :: Int , minor :: Int , patch :: Int } deriving (Eq, Ord) initialVersion :: Version initialVersion = Version 1 0 0 dummyVersion :: Version dummyVersion = Version 0 0 0 bumpPatch :: Version -> Version bumpPatch (Version major minor patch) = Version major minor (patch + 1) bumpMinor :: Version -> Version bumpMinor (Version major minor _patch) = Version major (minor + 1) 0 bumpMajor :: Version -> Version bumpMajor (Version major _minor _patch) = Version (major + 1) 0 0 -- FILTERING filterLatest :: (Ord a) => (Version -> a) -> [Version] -> [Version] filterLatest characteristic versions = map last (List.groupBy ((==) `on` characteristic) (List.sort versions)) majorAndMinor :: Version -> (Int,Int) majorAndMinor (Version major minor _patch) = (major, minor) -- CONVERSIONS toString :: Version -> String toString (Version major minor patch) = show major ++ "." ++ show minor ++ "." ++ show patch fromString :: String -> Maybe Version fromString string = case splitNumbers string of Just [major, minor, patch] -> Just (Version major minor patch) _ -> Nothing where splitNumbers :: String -> Maybe [Int] splitNumbers ns = case span isDigit ns of ("", _) -> Nothing (numbers, []) -> Just [ read numbers ] (numbers, '.':rest) -> (read numbers :) <$> splitNumbers rest _ -> Nothing instance Binary Version where get = Version <$> get <*> get <*> get put (Version major minor patch) = do put major put minor put patch instance FromJSON Version where parseJSON (String text) = let string = T.unpack text in case fromString string of Just v -> return v Nothing -> fail $ unlines [ "Dependency file has an invalid version number: " ++ string , "Must have format MAJOR.MINOR.PATCH (e.g. 0.1.2)" ] parseJSON _ = fail "Version number must be stored as a string." instance ToJSON Version where toJSON version = toJSON (toString version)