{-# LANGUAGE FlexibleInstances #-}{-# LANGUAGE GeneralizedNewtypeDeriving #-}{-# LANGUAGE StandaloneDeriving #-}{-# LANGUAGE TypeSynonymInstances #-}{-# LANGUAGE Rank2Types #-}{-# LANGUAGE OverloadedStrings #-}{-# LANGUAGE CPP #-}moduleYesod.Core.Content(-- * ContentContent(..),emptyContent,ToContent(..),ToFlushBuilder(..)-- * Mime types-- ** Data type,ContentType,typeHtml,typePlain,typeJson,typeXml,typeAtom,typeRss,typeJpeg,typePng,typeGif,typeSvg,typeJavascript,typeCss,typeFlv,typeOgv,typeOctet-- * Utilities,simpleContentType,contentTypeTypes-- * Evaluation strategy,DontFullyEvaluate(..)-- * Representations,TypedContent(..),ToTypedContent(..),HasContentType(..)-- ** Specific content types,RepHtml,RepJson(..),RepPlain(..),RepXml(..)-- ** Smart constructors,repJson,repPlain,repXml)whereimportqualifiedData.ByteStringasBimportqualifiedData.ByteString.LazyasLimportData.Text.Lazy(Text,pack)importqualifiedData.TextasTimportControl.Monad(liftM)importBlaze.ByteString.Builder(Builder,fromByteString,fromLazyByteString)importData.Monoid(mempty)importText.Hamlet(Html)importText.Blaze.Html.Renderer.Utf8(renderHtmlBuilder)importData.Conduit(Source,ResourceT,Flush(Chunk),ResumableSource,mapOutput)importData.Conduit.Internal(ResumableSource(ResumableSource))importqualifiedData.AesonasJimportData.Aeson.Encode(fromValue)importqualifiedBlaze.ByteString.Builder.Char.Utf8asBlazeimportData.Text.Lazy.Builder(toLazyText)importYesod.Core.Types-- | Zero-length enumerator.emptyContent::ContentemptyContent=ContentBuildermempty$Just0-- | Anything which can be converted into 'Content'. Most of the time, you will-- want to use the 'ContentBuilder' constructor. An easier approach will be to use-- a pre-defined 'toContent' function, such as converting your data into a lazy-- bytestring and then calling 'toContent' on that.---- Please note that the built-in instances for lazy data structures ('String',-- lazy 'L.ByteString', lazy 'Text' and 'Html') will not automatically include-- the content length for the 'ContentBuilder' constructor.classToContentawheretoContent::a->ContentinstanceToContentContentwheretoContent=idinstanceToContentBuilderwheretoContent=flipContentBuilderNothinginstanceToContentB.ByteStringwheretoContentbs=ContentBuilder(fromByteStringbs)$Just$B.lengthbsinstanceToContentL.ByteStringwheretoContent=flipContentBuilderNothing.fromLazyByteStringinstanceToContentT.TextwheretoContent=toContent.Blaze.fromTextinstanceToContentTextwheretoContent=toContent.Blaze.fromLazyTextinstanceToContentStringwheretoContent=toContent.Blaze.fromStringinstanceToContentHtmlwheretoContentbs=ContentBuilder(renderHtmlBuilderbs)NothinginstanceToContent()wheretoContent()=toContentB.emptyinstanceToContent(ContentType,Content)wheretoContent=sndinstanceToContentTypedContentwheretoContent(TypedContent_c)=cinstanceToFlushBuilderbuilder=>ToContent(Source(ResourceTIO)builder)wheretoContentsrc=ContentSource$mapOutputtoFlushBuildersrcinstanceToFlushBuilderbuilder=>ToContent(ResumableSource(ResourceTIO)builder)wheretoContent(ResumableSourcesrc_)=toContentsrc-- | A class for all data which can be sent in a streaming response. Note that-- for textual data, instances must use UTF-8 encoding.---- Since 1.2.0classToFlushBuilderawheretoFlushBuilder::a->FlushBuilderinstanceToFlushBuilder(FlushBuilder)wheretoFlushBuilder=idinstanceToFlushBuilderBuilderwheretoFlushBuilder=ChunkinstanceToFlushBuilder(FlushB.ByteString)wheretoFlushBuilder=fmapfromByteStringinstanceToFlushBuilderB.ByteStringwheretoFlushBuilder=Chunk.fromByteStringinstanceToFlushBuilder(FlushL.ByteString)wheretoFlushBuilder=fmapfromLazyByteStringinstanceToFlushBuilderL.ByteStringwheretoFlushBuilder=Chunk.fromLazyByteStringinstanceToFlushBuilder(FlushText)wheretoFlushBuilder=fmapBlaze.fromLazyTextinstanceToFlushBuilderTextwheretoFlushBuilder=Chunk.Blaze.fromLazyTextinstanceToFlushBuilder(FlushT.Text)wheretoFlushBuilder=fmapBlaze.fromTextinstanceToFlushBuilderT.TextwheretoFlushBuilder=Chunk.Blaze.fromTextinstanceToFlushBuilder(FlushString)wheretoFlushBuilder=fmapBlaze.fromStringinstanceToFlushBuilderStringwheretoFlushBuilder=Chunk.Blaze.fromStringinstanceToFlushBuilder(FlushHtml)wheretoFlushBuilder=fmaprenderHtmlBuilderinstanceToFlushBuilderHtmlwheretoFlushBuilder=Chunk.renderHtmlBuilderrepJson::ToContenta=>a->RepJsonrepJson=RepJson.toContentrepPlain::ToContenta=>a->RepPlainrepPlain=RepPlain.toContentrepXml::ToContenta=>a->RepXmlrepXml=RepXml.toContentclassToTypedContenta=>HasContentTypeawheregetContentType::Monadm=>ma->ContentTypeinstanceHasContentTypeRepJsonwheregetContentType_=typeJsonderivinginstanceToContentRepJsoninstanceHasContentTypeRepPlainwheregetContentType_=typePlainderivinginstanceToContentRepPlaininstanceHasContentTypeRepXmlwheregetContentType_=typeXmlderivinginstanceToContentRepXmltypeHtml::ContentTypetypeHtml="text/html; charset=utf-8"typePlain::ContentTypetypePlain="text/plain; charset=utf-8"typeJson::ContentTypetypeJson="application/json; charset=utf-8"typeXml::ContentTypetypeXml="text/xml"typeAtom::ContentTypetypeAtom="application/atom+xml"typeRss::ContentTypetypeRss="application/rss+xml"typeJpeg::ContentTypetypeJpeg="image/jpeg"typePng::ContentTypetypePng="image/png"typeGif::ContentTypetypeGif="image/gif"typeSvg::ContentTypetypeSvg="image/svg+xml"typeJavascript::ContentTypetypeJavascript="text/javascript; charset=utf-8"typeCss::ContentTypetypeCss="text/css; charset=utf-8"typeFlv::ContentTypetypeFlv="video/x-flv"typeOgv::ContentTypetypeOgv="video/ogg"typeOctet::ContentTypetypeOctet="application/octet-stream"-- | Removes \"extra\" information at the end of a content type string. In-- particular, removes everything after the semicolon, if present.---- For example, \"text/html; charset=utf-8\" is commonly used to specify the-- character encoding for HTML data. This function would return \"text/html\".simpleContentType::ContentType->ContentTypesimpleContentType=fst.B.breakByte59-- 59 == ;-- Give just the media types as a pair.-- For example, \"text/html; charset=utf-8\" returns ("text", "html")contentTypeTypes::ContentType->(B.ByteString,B.ByteString)contentTypeTypesct=(main,fst$B.breakBytesemicolon(tailEmptysub))wheretailEmptyx=ifB.nullxthen""elseB.tailx(main,sub)=B.breakByteslashctslash=47semicolon=59instanceHasContentTypea=>HasContentType(DontFullyEvaluatea)wheregetContentType=getContentType.liftMunDontFullyEvaluateinstanceToContenta=>ToContent(DontFullyEvaluatea)wheretoContent(DontFullyEvaluatea)=ContentDontEvaluate$toContentainstanceToContentJ.ValuewheretoContent=flipContentBuilderNothing.Blaze.fromLazyText.toLazyText.fromValueinstanceHasContentTypeJ.ValuewheregetContentType_=typeJsoninstanceHasContentTypeHtmlwheregetContentType_=typeHtmlinstanceHasContentTypeTextwheregetContentType_=typePlaininstanceHasContentTypeT.TextwheregetContentType_=typePlain-- | Any type which can be converted to 'TypedContent'.---- Since 1.2.0classToContenta=>ToTypedContentawheretoTypedContent::a->TypedContentinstanceToTypedContentTypedContentwheretoTypedContent=idinstanceToTypedContent()wheretoTypedContent()=TypedContenttypePlain(toContent())instanceToTypedContent(ContentType,Content)wheretoTypedContent(ct,content)=TypedContentctcontentinstanceToTypedContentRepJsonwheretoTypedContent(RepJsonc)=TypedContenttypeJsoncinstanceToTypedContentRepPlainwheretoTypedContent(RepPlainc)=TypedContenttypePlaincinstanceToTypedContentRepXmlwheretoTypedContent(RepXmlc)=TypedContenttypeXmlcinstanceToTypedContentJ.ValuewheretoTypedContentv=TypedContenttypeJson(toContentv)instanceToTypedContentHtmlwheretoTypedContenth=TypedContenttypeHtml(toContenth)instanceToTypedContentT.TextwheretoTypedContentt=TypedContenttypePlain(toContentt)instanceToTypedContent[Char]wheretoTypedContent=toTypedContent.packinstanceToTypedContentTextwheretoTypedContentt=TypedContenttypePlain(toContentt)instanceToTypedContenta=>ToTypedContent(DontFullyEvaluatea)wheretoTypedContent(DontFullyEvaluatea)=letTypedContentctc=toTypedContentainTypedContentct(ContentDontEvaluatec)