module Network.MPD.Util (
parseDate, parseIso8601, formatIso8601, parseNum, parseFrac,
parseBool, showBool, breakChar, parseTriple,
toAssoc, toAssocList, splitGroups
) where
import Data.Char (isDigit)
import Data.Maybe (fromMaybe)
import Data.Time.Format (ParseTime, parseTime, FormatTime, formatTime)
import System.Locale (defaultTimeLocale)
breakChar :: Char -> String -> (String, String)
breakChar c s = let (x, y) = break (== c) s in (x, drop 1 y)
parseDate :: String -> Maybe Int
parseDate = parseNum . takeWhile isDigit
parseIso8601 :: (ParseTime t) => String -> Maybe t
parseIso8601 = parseTime defaultTimeLocale iso8601Format
formatIso8601 :: FormatTime t => t -> String
formatIso8601 = formatTime defaultTimeLocale iso8601Format
iso8601Format :: String
iso8601Format = "%FT%TZ"
parseNum :: (Read a, Integral a) => String -> Maybe a
parseNum s = do
[(x, "")] <- return (reads s)
return x
parseFrac :: (Fractional a, Read a) => String -> Maybe a
parseFrac s =
case s of
"nan" -> return $ read "NaN"
"inf" -> return $ read "Infinity"
"-inf" -> return $ read "-Infinity"
_ -> do [(x, "")] <- return $ reads s
return x
showBool :: Bool -> String
showBool x = if x then "1" else "0"
parseBool :: String -> Maybe Bool
parseBool s = case take 1 s of
"1" -> Just True
"0" -> Just False
_ -> Nothing
parseTriple :: Char -> (String -> Maybe a) -> String -> Maybe (a, a, a)
parseTriple c f s = let (u, u') = breakChar c s
(v, w) = breakChar c u' in
case (f u, f v, f w) of
(Just a, Just b, Just c') -> Just (a, b, c')
_ -> Nothing
toAssoc :: String -> (String, String)
toAssoc x = (k, dropWhile (== ' ') $ drop 1 v)
where
(k,v) = break (== ':') x
toAssocList :: [String] -> [(String, String)]
toAssocList = map toAssoc
splitGroups :: Eq a => [(a,[(a,b)] -> c)] -> [(a, b)] -> [c]
splitGroups [] _ = []
splitGroups _ [] = []
splitGroups wrappers (x@(k,_):xs) =
fromMaybe (splitGroups wrappers xs) $ do
f <- k `lookup` wrappers
let (us,vs) = break (\(k',_) -> k' `elem` map fst wrappers) xs
return $ f (x:us) : splitGroups wrappers vs