rawstring-qm 0.2.2.2 → 0.2.3.0
raw patch · 4 files changed
+103/−41 lines, 4 files
Files
- rawstring-qm.cabal +7/−6
- src/Data/String/QM.hs +45/−22
- src/Data/Text/ToText.hs +7/−13
- src/Data/Text/ToTextBuilder.hs +44/−0
rawstring-qm.cabal view
@@ -1,15 +1,15 @@ name: rawstring-qm-version: 0.2.2.2+version: 0.2.3.0 cabal-version: >=1.10 synopsis: Simple raw string quotation and dictionary interpolation description: Supply a couple of usefull QuasiQuotes so we can use functions to lookup values- This is an initial, and unstable package.+ It has quasiquotes for Strings, Text and Builders homepage: https://github.com/tolysz/rawstring-qm license: BSD3 license-file: LICENSE author: Marcin Tolysz maintainer: tolysz@gmail.com-copyright: (c)2014-15 Marcin Tolysz+copyright: (c)2014-16 Marcin Tolysz category: Text build-type: Simple extra-source-files: CHANGES@@ -19,12 +19,13 @@ location: https://github.com/tolysz/rawstring-qm.git library- exposed-modules: Data.String.QM- , Data.Text.ToText+ exposed-modules: Data.String.QM+ , Data.Text.ToText+ , Data.Text.ToTextBuilder -- other-modules: -- other-extensions: - build-depends: base >4.6 && <4.9+ build-depends: base >4.6 && <5 , text , template-haskell , bytestring
src/Data/String/QM.hs view
@@ -1,6 +1,5 @@-{-# LANGUAGE TemplateHaskell- , OverloadedStrings- #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-} module Data.String.QM@@ -9,26 +8,36 @@ , qn , qt , qtl+ , qtb+ , module TT ) where -import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Data.Text.ToText+import Prelude -import qualified Language.Haskell.TH as TH-import GHC.Exts (IsString(..))-import Data.Monoid (Monoid(..), (<>))-import Data.ByteString.Char8 as Strict (ByteString, unpack)-import Data.ByteString.Lazy.Char8 as Lazy (ByteString, unpack)-import Data.Text as T (Text, unpack)-import Data.Text.Lazy as LazyT(Text, unpack)-import Data.Char (isAlpha, isAlphaNum)-import Prelude-import Data.Maybe+import Language.Haskell.TH+import Language.Haskell.TH.Quote +import Data.ByteString.Char8 as Strict (ByteString,+ unpack)+import Data.ByteString.Lazy.Char8 as Lazy (ByteString,+ unpack)+import Data.Char (isAlpha, isAlphaNum)+import Data.Maybe+import Data.Monoid (Monoid (..), (<>))+import Data.Text as T (Text, unpack)+import qualified Data.Text.Internal.Builder as B+import qualified Data.Text.Internal.Builder.Functions as B+import Data.Text.Lazy as LazyT (Text, unpack)+import GHC.Exts (IsString (..))+import qualified Language.Haskell.TH as TH++import Data.Text.ToText as TT+import Data.Text.ToTextBuilder as TT+ data StringPart = Literal String | AntiQuote String deriving Show + -- | qq is a block quote extension, it can be used anywhere you would put normal quotes -- but you would require to have new line in them -- if you put it as a pattern it will expan to 'a':'b':'c'...@@ -56,22 +65,30 @@ (error "Cannot use qm as a type") (error "Cannot use qm as a dec") --- | QuasiQuoter for interpolating '$var' and '${expr}' into a string literal.+-- | QuasiQuoter for interpolating '${expr}' into strict text. -- var and expr are just Names output is of type text vars are auto converted to text qt :: QuasiQuoter-qt = QuasiQuoter (makeExprT . parseQM [])+qt = QuasiQuoter (makeExprT . parseQN []) (error "Cannot use qm as a pattern") (error "Cannot use qm as a type") (error "Cannot use qm as a dec") --- | QuasiQuoter for interpolating '$var' and '${expr}' into a string literal.+-- | QuasiQuoter for interpolating '${expr}' into a lazy text. -- var and expr are just Names type lazy text, vars are magically (via `ToText` typeclass) converted to text qtl :: QuasiQuoter-qtl = QuasiQuoter (makeExprTL . parseQM [])+qtl = QuasiQuoter (makeExprTL . parseQN []) (error "Cannot use qm as a pattern") (error "Cannot use qm as a type") (error "Cannot use qm as a dec") +-- | QuasiQuoter for interpolating '${expr}' into a text builder.+-- var and expr are just Names type lazy text, vars are magically (via `ToTextBuilder` typeclass) converted to text+qtb :: QuasiQuoter+qtb = QuasiQuoter (makeExprTB . parseQN [])+ (error "Cannot use qm as a pattern")+ (error "Cannot use qm as a type")+ (error "Cannot use qm as a dec")+ parseQM a [] = [Literal (reverse a)] parseQM a ('\\':x:xs) = parseQM (x:a) xs parseQM a "\\" = parseQM ('\\':a) []@@ -95,7 +112,7 @@ parseQN a ('\\':x:xs) = parseQN (x:a) xs parseQN a "\\" = parseQN ('\\':a) [] -parseQN a ('$':'{':xs) = Literal (reverse a) : unQN [] xs+parseQN a ('$':'{':xs) = Literal (reverse a) : unQN [] xs -- parseQN a ('$':x:xs) | x == '_' || isAlpha x = -- Literal (reverse a) : AntiQuote (x:pre) : parseQN [] post -- where@@ -126,6 +143,12 @@ makeExprTL (AntiQuote a:xs) = TH.appE [| (<>) (toLazyText $(varE (mkName a))) |] $ makeExprTL xs +makeExprTB [] = ls ""+makeExprTB (Literal a:xs) = TH.appE [| (B.<>) (B.fromLazyText a) |]+ $ makeExprTB xs+makeExprTB (AntiQuote a:xs) = TH.appE [| (B.<>) (toTextBuilder $(varE (mkName a))) |]+ $ makeExprTB xs+ -- reify' = varE . mkName -- reify @@ -136,5 +159,5 @@ isIdent x = isAlphaNum x -- Convert cons into pattern cons-expandIntoCons [c] = LitP (CharL c)+expandIntoCons [c] = LitP (CharL c) expandIntoCons (c:cs) = InfixP (LitP (CharL c)) '(:) (expandIntoCons cs)
src/Data/Text/ToText.hs view
@@ -3,6 +3,7 @@ , FlexibleInstances , ScopedTypeVariables , OverloadedStrings+ , UndecidableInstances #-} module Data.Text.ToText where@@ -12,8 +13,6 @@ import qualified Data.Text.Lazy as TL import Data.Text.Lazy (toStrict) import qualified Data.Text.Lazy.Builder as TLB (toLazyText)-import Data.Text.Lazy.Builder.Int (decimal)-import Data.Text.Lazy.Builder.RealFloat (realFloat) import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as BSL@@ -21,6 +20,8 @@ import qualified Data.Text.Encoding as T import qualified Data.Text.Lazy.Encoding as TL +import Data.Text.ToTextBuilder+ import Text.Read import Data.Typeable import Data.Maybe (maybe)@@ -33,25 +34,18 @@ fromText :: Text -> Either Text a fromText v = maybe (Left $ "parse failed: `" <> v <>"` can not be parsed as" <> pack (show (typeOf (undefined :: a))) ) Right . readMaybe . unpack $ v+ maybeFromText :: Text -> Maybe a maybeFromText = either (const Nothing) Just . fromText fromLazyText :: TL.Text -> Either Text a fromLazyText = fromText . toStrict+ maybeFromLazyText :: TL.Text -> Maybe a maybeFromLazyText = either (const Nothing) Just . fromLazyText -instance ToText Int where- toLazyText = TLB.toLazyText . decimal--instance ToText Integer where- toLazyText = TLB.toLazyText . decimal--instance ToText Float where- toLazyText = TLB.toLazyText . realFloat--instance ToText Double where- toLazyText = TLB.toLazyText . realFloat+instance {-# OVERLAPPABLE #-} (ToTextBuilder a, Read a, Typeable a) => ToText a where+ toLazyText = TLB.toLazyText . toTextBuilder instance ToText Text where toText = id
+ src/Data/Text/ToTextBuilder.hs view
@@ -0,0 +1,44 @@++{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeSynonymInstances #-}++module Data.Text.ToTextBuilder where++import Data.Text.Lazy.Builder+import Data.Text.Lazy.Builder.Int (decimal)+import Data.Text.Lazy.Builder.RealFloat (realFloat)++import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.Encoding as TL++class ToTextBuilder a where+ toTextBuilder :: a -> Builder++instance ToTextBuilder Int where+ toTextBuilder = decimal++instance ToTextBuilder Integer where+ toTextBuilder = decimal++instance ToTextBuilder Float where+ toTextBuilder = realFloat++instance ToTextBuilder Double where+ toTextBuilder = realFloat++instance ToTextBuilder Char where+ toTextBuilder = singleton++instance ToTextBuilder T.Text where+ toTextBuilder = fromText++instance ToTextBuilder TL.Text where+ toTextBuilder = fromLazyText++instance ToTextBuilder String where+ toTextBuilder = fromString+