-- boilerplate {{{ module Version (CurrentFormat, parseCurrentFormat, versionNumber, versionYeganesh, versionStrip) where import Data.Char (isSpace) import Data.Map (Map, elems, empty) import Data.Time (UTCTime, getCurrentTime) type CurrentFormat = FormatV2 versionNumber :: String versionYeganesh :: String versionStrip :: String parseCurrentFormat :: String -> IO CurrentFormat versionNumber = "2.4" versionYeganesh = "yeganesh version " ++ versionNumber versionStrip = "yeganesh-strip version " ++ versionNumber parseCurrentFormat = parseFormatV2 -- }}} -- v2 {{{ type FormatV2 = (UTCTime, FormatV1) parseFormatV2 :: String -> IO FormatV2 parseFormatV2 = parse parseFormatV1 upgradeFormatV1 -- }}} -- v1 {{{ type FormatV1 = Map String Double upgradeFormatV1 :: FormatV1 -> IO FormatV2 upgradeFormatV1 v1 = fmap (flip (,) popularities) getCurrentTime where maximal = case (elems v1, maximum (elems v1)) of ([], _) -> 1 (_ , 0) -> 1 (_ , m) -> m popularities = fmap (/maximal) v1 parseFormatV1 :: String -> IO FormatV1 parseFormatV1 = parse (const (return empty)) return -- }}} -- utilities {{{ parse :: Read new => (String -> IO old) -> (old -> IO new) -> (String -> IO new) parse old upgrade s = maybe (old s >>= upgrade) return (readMaybe s) readMaybe :: Read a => String -> Maybe a readMaybe s = case reads s of [(x, unparsed)] | all isSpace unparsed -> Just x _ -> Nothing -- }}}