on master help sign in
Merge pull request #127 from sol/master

Add Data.Yaml.TH.yamlQQ

commit9b0ff2443ea7faa85c9f1f5698ae270ffad7fb3f authorMichael Snoyman <michael@snoyman.com> dateTue 16 Jan 2018, 20:14 (9 years ago) parentf9a542c2736d21
4 files changed+73−10
ChangeLog.md+4 Data/Yaml/TH.hs+48−6 test/Data/Yaml/THSpec.hs+17 yaml.cabal+4−4
ChangeLog.md+4
@@ -1,3 +1,7 @@
1+## 0.8.28
2+
3+* Add `Data.Yaml.TH.yamlQQ`
4+
15## 0.8.27
26
37* Support conduit 1.3
Data/Yaml/TH.hs+48−6
@@ -1,10 +1,13 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE LambdaCase #-}
23{-# LANGUAGE ScopedTypeVariables #-}
3−{-# LANGUAGE TemplateHaskell #-}
44
55module Data.Yaml.TH
66 ( -- * Decoding
7− decodeFile
7+ yamlQQ
8+#if MIN_VERSION_template_haskell(2,9,0)
9+ , decodeFile
10+#endif
811 -- * Re-exports from "Data.Yaml"
912 , Value (..)
1013 , Parser
@@ -19,11 +22,16 @@ module Data.Yaml.TH
1922 , FromJSON (..)
2023 ) where
2124
22−import Data.Yaml hiding (decodeFile)
23−import Language.Haskell.TH
24−import Language.Haskell.TH.Syntax
25+import Data.Text.Encoding
26+import qualified Data.Text as T
27+import Language.Haskell.TH
28+import Language.Haskell.TH.Syntax
29+import Language.Haskell.TH.Quote
2530
26−-- | Decode a @yaml@ file at compile time. Only available on GHC version @7.8.1@
31+import Data.Yaml hiding (decodeFile)
32+
33+#if MIN_VERSION_template_haskell(2,9,0)
34+-- | Decode a YAML file at compile time. Only available on GHC version @7.8.1@
2735-- or higher.
2836--
2937-- @since 0.8.19.0
@@ -42,3 +50,37 @@ decodeFile path = do
4250 runIO (decodeFileEither path) >>= \case
4351 Left err -> fail (prettyPrintParseException err)
4452 Right x -> fmap TExp (lift (x :: a))
53+#endif
54+
55+decodeValue :: String -> Either String Value
56+decodeValue = decodeEither . encodeUtf8 . T.pack
57+
58+yamlExp :: String -> Q Exp
59+yamlExp input = case decodeValue input of
60+ Left err -> fail err
61+ Right a -> lift a
62+
63+-- | A @QuasiQuoter@ for YAML.
64+--
65+-- @since 0.8.28.0
66+--
67+-- ==== __Examples__
68+--
69+-- @
70+-- {-\# LANGUAGE QuasiQuotes \#-}
71+-- import Data.Yaml.TH
72+--
73+-- value :: Value
74+-- value = [yamlQQ|
75+-- name: John Doe
76+-- age: 23
77+-- |]
78+-- @
79+yamlQQ :: QuasiQuoter
80+yamlQQ = QuasiQuoter {
81+ quoteExp = yamlExp
82+, quotePat = notDefined "quotePat"
83+, quoteType = notDefined "quoteType"
84+, quoteDec = notDefined "quoteDec"
85+} where
86+ notDefined name _ = fail (name ++ " is not defined for yamlQQ")
test/Data/Yaml/THSpec.hsnew file+17
@@ -0,0 +1,17 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE QuasiQuotes #-}
3+module Data.Yaml.THSpec (spec) where
4+
5+import Test.Hspec
6+import Data.Aeson
7+
8+import Data.Yaml.TH
9+
10+spec :: Spec
11+spec = do
12+ describe "yamlQQ" $ do
13+ it "parses yaml" $ do
14+ [yamlQQ|
15+ name: John Doe
16+ age: 23
17+ |] `shouldBe` object ["name" .= String "John Doe", "age" .= Number 23]
yaml.cabal+4−4
@@ -1,5 +1,5 @@
11name: yaml
2−version: 0.8.27
2+version: 0.8.28
33license: BSD3
44license-file: LICENSE
55author: Michael Snoyman <michael@snoyman.com>, Anton Ageev <antage@gmail.com>,Kirill Simonov
@@ -60,6 +60,7 @@ library
6060 , filepath
6161 , directory
6262 , semigroups
63+ , template-haskell
6364 exposed-modules: Text.Libyaml
6465 Data.Yaml
6566 Data.Yaml.Aeson
@@ -68,9 +69,7 @@ library
6869 Data.Yaml.Include
6970 Data.Yaml.Parser
7071 Data.Yaml.Pretty
71− if impl(ghc >= 7.8.1)
72− build-depends: template-haskell >= 2.8.0.0
73− exposed-modules: Data.Yaml.TH
72+ Data.Yaml.TH
7473 other-modules:
7574 Data.Yaml.Internal
7675 ghc-options: -Wall
@@ -126,6 +125,7 @@ test-suite spec
126125 main-is: Spec.hs
127126 other-modules: Data.YamlSpec
128127 Data.Yaml.IncludeSpec
128+ Data.Yaml.THSpec
129129 cpp-options: -DTEST
130130 build-depends: hspec >= 1.3
131131 , HUnit