8 module Network.HTTP.Lucu.Implant.PrettyPrint
12 import Codec.Compression.GZip
14 import Data.Ascii (CIAscii)
15 import qualified Data.Ascii as A
16 import qualified Data.ByteString.Lazy as L
18 import qualified Data.Map as M
20 import Language.Haskell.TH.Lib
21 import Language.Haskell.TH.Ppr
22 import Language.Haskell.TH.PprLib
23 import Language.Haskell.TH.Syntax
24 import Network.HTTP.Lucu.ETag
25 import Network.HTTP.Lucu.Implant.Input
26 import Network.HTTP.Lucu.Implant.Rewrite
27 import Network.HTTP.Lucu.MIMEType
28 import Network.HTTP.Lucu.Resource
29 import Network.HTTP.Lucu.Utils
30 import Prelude.Unicode
34 = vcat [ text "{- DO NOT EDIT THIS FILE."
36 vcat [ text "This file is automatically generated by lucu-implant-file."
38 , text " Source:" <+> if iPath ≡ "-" then
42 , hsep [ text " Original Length:"
43 , integer (originalLen i)
47 vcat [ hsep [ text "Compressed Length:"
48 , integer (gzippedLen i)
51 , text " Compression: gzip"
54 text " Compression: disabled"
55 , text " MIME Type:" <+> mimeTypeToDoc iType
56 , text " ETag:" <+> eTagToDoc iETag
57 , text " Last Modified:" <+> text (show iLastMod)
60 , text "{-# LANGUAGE MagicHash #-}"
63 eTagToDoc ∷ ETag → Doc
64 eTagToDoc = text ∘ A.toString ∘ A.fromAsciiBuilder ∘ printETag
66 mimeTypeToDoc ∷ MIMEType → Doc
67 mimeTypeToDoc = text ∘ A.toString ∘ A.fromAsciiBuilder ∘ printMIMEType
69 moduleDecl ∷ ModName → Name → Doc
70 moduleDecl modName symName
71 = hsep [ text "module"
72 , text (modString modName)
79 importDecls ∷ ModMap → Doc
80 importDecls = vcat ∘ map f ∘ M.toAscList
82 f ∷ (ModName, Maybe ModName) → Doc
83 f (m, Nothing) = hsep [ text "import"
86 f (m, Just m') = hsep [ text "import"
94 entityTag = mkName "entityTag"
97 lastModified = mkName "lastModified"
100 contentType = mkName "contentType"
103 rawData = mkName "rawData"
106 gzippedData = mkName "gzippedData"
109 gzipEncoding = mkName "gzipEncoding"
111 resourceDecl ∷ Input → Name → Q [Dec]
112 resourceDecl i symName
113 = sequence [ sigD symName [t| ResourceDef |]
114 , valD (varP symName) (normalB (resourceE i)) decls
119 = [ sigD gzipEncoding [t| CIAscii |]
120 , valD (varP gzipEncoding) (normalB (liftCIAscii "gzip")) []
125 resourceE ∷ Input → Q Exp
126 resourceE i = [| emptyResource {
127 resGet = $(resGetE i)
128 , resHead = $(resHeadE i)
132 resGetE ∷ Input → Q Exp
136 do foundEntity $(varE entityTag) $(varE lastModified)
137 setContentType $(varE contentType)
139 gzipAllowed ← isEncodingAcceptable $(varE gzipEncoding)
141 do setContentEncoding [$(varE gzipEncoding)]
142 putChunks $(varE gzippedData)
144 putChunks (decompress $(varE gzippedData))
148 do foundEntity $(varE entityTag) $(varE lastModified)
149 setContentType $(varE contentType)
150 putChunks $(varE rawData)
153 resHeadE ∷ Input → Q Exp
157 do foundEntity $(varE entityTag) $(varE lastModified)
158 setContentType $(varE contentType)
160 gzipAllowed ← isEncodingAcceptable $(varE gzipEncoding)
161 when gzipAllowed (setContentEncoding [$(varE gzipEncoding)])
165 do foundEntity $(varE entityTag)
167 setContentType $(varE contentType)
170 eTagDecl ∷ Input → Q [Dec]
171 eTagDecl (Input {..})
172 = sequence [ sigD entityTag [t| ETag |]
173 , valD (varP entityTag) (normalB (lift iETag)) []
176 lastModDecl ∷ Input → Q [Dec]
177 lastModDecl (Input {..})
178 = sequence [ sigD lastModified [t| UTCTime |]
179 , valD (varP lastModified) (normalB (liftUTCTime iLastMod)) []
182 contTypeDecl ∷ Input → Q [Dec]
183 contTypeDecl (Input {..})
184 = sequence [ sigD contentType [t| MIMEType |]
185 , valD (varP contentType) (normalB (lift iType)) []
188 binDecl ∷ Input → Q [Dec]
189 binDecl i@(Input {..})
191 = sequence [ sigD gzippedData [t| L.ByteString |]
192 , valD (varP gzippedData) (normalB (liftLazyByteString iGZipped)) []
195 = sequence [ sigD rawData [t| L.ByteString |]
196 , valD (varP rawData) (normalB (liftLazyByteString iRawData)) []
199 pprInput ∷ Quasi m ⇒ Input → ModName → Name → m Doc
200 pprInput i modName symName
201 = do decls ← runQ $ sequence [ resourceDecl i symName
207 let (decls', mods) = rewriteNames decls
208 return $ vcat [ header i
209 , moduleDecl modName symName
212 , vcat $ intersperse (text "") $ map ppr decls'