17 import qualified Blaze.ByteString.Builder as BBB
19 import Control.Arrow.ArrowList
20 import Data.Ascii (Ascii)
21 import qualified Data.Ascii as A
22 import qualified Data.ByteString as BS
23 import qualified Data.ByteString.Unsafe as BS
24 import qualified Data.ByteString.Lazy as LS
25 import Data.Monoid.Unicode
26 import qualified Data.Text as T
27 import qualified Data.Text.Lazy as LT
28 import Data.Text.Encoding
30 import Network.HTTP.Lucu
32 import Prelude.Unicode
33 import System.IO.Unsafe
35 yesOrNo ∷ Bool → String
39 trueOrFalse ∷ Bool → String
40 trueOrFalse True = "true"
41 trueOrFalse False = "false"
43 parseYesOrNo ∷ ArrowChoice a ⇒ a String Bool
45 = proc str → do case str of
46 "yes" → returnA ⤙ True
47 "no" → returnA ⤙ False
48 _ → returnA ⤙ error ("Expected yes or no: " ⧺ str)
50 maybeA ∷ (ArrowList a, ArrowChoice a) ⇒ a b c → a b (Maybe c)
54 [] → returnA ⤙ Nothing
55 (x:_) → returnA ⤙ Just x
57 deleteIfEmpty ∷ (ArrowList a, ArrowChoice a) ⇒ a String String
59 = proc str → do case str of
63 chomp ∷ String → String
65 chomp = reverse . snd . break (≢ '\n') . reverse
67 guessMIMEType ∷ LS.ByteString → MIMEType
68 {-# INLINEABLE guessMIMEType #-}
71 ∘ flip BS.unsafeUseAsCStringLen (magicCString magic)
76 {-# NOINLINE magic #-}
77 magic = unsafePerformIO
78 $ do m ← magicOpen [MagicMime]
82 isSafeChar ∷ Char → Bool
83 {-# INLINEABLE isSafeChar #-}
86 | isReserved c = False
87 | isUnreserved c = True
90 mkQueryString ∷ [(T.Text, T.Text)] → Ascii
91 {-# INLINE mkQueryString #-}
92 mkQueryString = A.unsafeFromByteString
96 mkBBB ∷ [(T.Text, T.Text)] → BBB.Builder → BBB.Builder
97 {-# INLINEABLE mkBBB #-}
99 mkBBB (kv:[]) acc = acc ⊕ pair kv
100 mkBBB (kv:xs) acc = mkBBB xs (acc ⊕ pair kv ⊕ semicolon)
102 pair ∷ (T.Text, T.Text) → BBB.Builder
105 = encodeText k ⊕ equal ⊕ encodeText v
107 encodeText ∷ T.Text → BBB.Builder
108 {-# INLINE encodeText #-}
109 encodeText = BBB.fromByteString ∘ URI.encode ∘ encodeUtf8