module Network.MPD.Util (
parseDate, parseIso8601, formatIso8601, parseNum, parseFrac,
parseBool, showBool, breakChar, parseTriple,
toAssoc, toAssocList, splitGroups, read
) where
import Data.Char (isDigit)
import Data.Time.Format (ParseTime, parseTime, FormatTime, formatTime)
import System.Locale (defaultTimeLocale)
import qualified Prelude
import Prelude hiding (break, take, drop, takeWhile, dropWhile, read, reads)
import Data.ByteString.Char8 (break, take, drop, takeWhile, dropWhile, ByteString)
import qualified Data.ByteString.UTF8 as UTF8
import Data.String
read :: Read a => ByteString -> a
read = Prelude.read . UTF8.toString
reads :: Read a => ByteString -> [(a, String)]
reads = Prelude.reads . UTF8.toString
breakChar :: Char -> ByteString -> (ByteString, ByteString)
breakChar c s = let (x, y) = break (== c) s in (x, drop 1 y)
parseDate :: ByteString -> Maybe Int
parseDate = parseNum . takeWhile isDigit
parseIso8601 :: (ParseTime t) => ByteString -> Maybe t
parseIso8601 = parseTime defaultTimeLocale iso8601Format . UTF8.toString
formatIso8601 :: FormatTime t => t -> String
formatIso8601 = formatTime defaultTimeLocale iso8601Format
iso8601Format :: String
iso8601Format = "%FT%TZ"
parseNum :: (Read a, Integral a) => ByteString -> Maybe a
parseNum s = do
[(x, "")] <- return (reads s)
return x
parseFrac :: (Fractional a, Read a) => ByteString -> Maybe a
parseFrac s =
case s of
"nan" -> return $ Prelude.read "NaN"
"inf" -> return $ Prelude.read "Infinity"
"-inf" -> return $ Prelude.read "-Infinity"
_ -> do [(x, "")] <- return $ reads s
return x
showBool :: IsString a => Bool -> a
showBool x = if x then "1" else "0"
parseBool :: ByteString -> Maybe Bool
parseBool s = case take 1 s of
"1" -> Just True
"0" -> Just False
_ -> Nothing
parseTriple :: Char -> (ByteString -> Maybe a) -> ByteString -> 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 :: ByteString -> (ByteString, ByteString)
toAssoc x = (k, dropWhile (== ' ') $ drop 1 v)
where
(k,v) = break (== ':') x
toAssocList :: [ByteString] -> [(ByteString, ByteString)]
toAssocList = map toAssoc
splitGroups :: [ByteString] -> [(ByteString, ByteString)] -> [[(ByteString, ByteString)]]
splitGroups groupHeads = go
where
go [] = []
go (x:xs) =
let
(ys, zs) = Prelude.break isGroupHead xs
in
(x:ys) : go zs
isGroupHead = (`elem` groupHeads) . fst