X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Rakka%2FUtils.hs;h=3148c6bf108906112b39ebb81f63132ae8baa158;hb=42f51754dea02201aececaacbf194d714cd58aaf;hp=9f2873c9ae328d626d9679b2ac0c777750c1e50e;hpb=3c5211253dc61c31196a47486c538b64c32d8c5e;p=Rakka.git diff --git a/Rakka/Utils.hs b/Rakka/Utils.hs index 9f2873c..3148c6b 100644 --- a/Rakka/Utils.hs +++ b/Rakka/Utils.hs @@ -1,31 +1,49 @@ +{-# LANGUAGE + Arrows + , OverloadedStrings + , TypeOperators + , UnicodeSyntax + #-} module Rakka.Utils ( yesOrNo + , trueOrFalse , parseYesOrNo , maybeA , deleteIfEmpty - , formatW3CDateTime , chomp + , guessMIMEType + , isSafeChar + , mkQueryString ) where - +import qualified Codec.Binary.UTF8.String as UTF8 import Control.Arrow import Control.Arrow.ArrowList -import System.Time -import Text.Printf - +import qualified Data.ByteString.Lazy as Lazy (ByteString) +import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString) +import Data.Monoid.Unicode +import Data.String +import Magic +import Network.HTTP.Lucu +import Network.URI +import Prelude.Unicode +import System.IO.Unsafe -yesOrNo :: Bool -> String +yesOrNo ∷ Bool → String yesOrNo True = "yes" yesOrNo False = "no" +trueOrFalse ∷ Bool → String +trueOrFalse True = "true" +trueOrFalse False = "false" -parseYesOrNo :: ArrowChoice a => a String Bool -parseYesOrNo - = proc str -> do case str of - "yes" -> returnA -< True - "no" -> returnA -< False - _ -> returnA -< error ("Expected yes or no: " ++ str) - +parseYesOrNo ∷ (Eq s, Show s, IsString s, ArrowChoice (⇝)) ⇒ s ⇝ Bool +parseYesOrNo + = proc str → + case str of + _ | str ≡ "yes" → returnA ⤙ True + | str ≡ "no" → returnA ⤙ False + | otherwise → returnA ⤙ error ("Expected yes or no: " ⊕ show str) maybeA :: (ArrowList a, ArrowChoice a) => a b c -> a b (Maybe c) maybeA a = listA a @@ -42,38 +60,35 @@ deleteIfEmpty _ -> returnA -< str -formatW3CDateTime :: CalendarTime -> String -formatW3CDateTime time - = formatDateTime time ++ formatTimeZone time +chomp :: String -> String +chomp = reverse . snd . break (/= '\n') . reverse + + +guessMIMEType :: Lazy.ByteString -> MIMEType +guessMIMEType = read . unsafePerformIO . magicString magic . L8.unpack where - formatDateTime :: CalendarTime -> String - formatDateTime time - = printf "%04d-%02d-%02dT%02d:%02d:%02d" - (ctYear time) - (fromEnum (ctMonth time) + 1) - (ctDay time) - (ctHour time) - (ctMin time) - (ctSec time) - - formatTimeZone :: CalendarTime -> String - formatTimeZone time - = case ctTZ time - of offset | offset < 0 -> '-':(showTZ $ negate offset) - | offset == 0 -> "Z" - | otherwise -> '+':(showTZ offset) - - showTZ :: Int -> String - showTZ offset - = let hour = offset `div` 3600 - min = (offset - hour * 3600) `div` 60 - in - show2 hour ++ ":" ++ show2 min - - show2 :: Int -> String - show2 n | n < 10 = '0':(show n) - | otherwise = show n + magic :: Magic + magic = unsafePerformIO + $ do m <- magicOpen [MagicMime] + magicLoadDefault m + return m -chomp :: String -> String -chomp = reverse . snd . break (/= '\n') . reverse +isSafeChar :: Char -> Bool +isSafeChar c + | c == '/' = True + | isReserved c = False + | c > ' ' && c <= '~' = True + | otherwise = False + + +mkQueryString :: [(String, String)] -> String +mkQueryString [] = "" +mkQueryString ((k, v) : xs) = encode k ++ "=" ++ encode v ++ + if xs == [] then + "" + else + ';' : mkQueryString(xs) + where + encode :: String -> String + encode = escapeURIString isSafeChar . UTF8.encodeString \ No newline at end of file