@@ -1,4 +1,6 @@
11{-# LANGUAGE FlexibleInstances #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE CPP #-}
24-- | NOTE: This module is a highly experimental preview release. It may change
35-- drastically, or be entirely removed, in a future release.
46module Data.Yaml.Builder
@@ -7,6 +9,10 @@ module Data.Yaml.Builder
79 , mapping
810 , array
911 , string
12+ , bool
13+ , null
14+ , scientific
15+ , number
1016 , toByteString
1117 , writeYamlFile
1218 , (.=)
@@ -15,12 +21,26 @@ module Data.Yaml.Builder
1521import Data.Conduit
1622import Data.ByteString (ByteString)
1723import Text.Libyaml
24+import Data.Yaml.Internal
1825import Data.Text (Text)
26+import Data.Scientific (Scientific)
27+import Data.Aeson.Types (Value(..))
28+import qualified Data.HashSet as HashSet
29+import qualified Data.Text as T
1930import Data.Text.Encoding (encodeUtf8)
2031import System.IO.Unsafe (unsafePerformIO)
2132import Control.Arrow (second)
2233import qualified Data.ByteString.Char8 as S8
2334import Control.Monad.Trans.Resource (runResourceT)
35+#if MIN_VERSION_aeson(0, 7, 0)
36+import qualified Data.Text.Encoding as TE
37+import qualified Data.Text.Lazy as TL
38+import Data.Text.Lazy.Builder (toLazyText)
39+import Data.Aeson.Encode (encodeToTextBuilder)
40+#else
41+import qualified Data.ByteString.Char8 as S8
42+#endif
43+import Prelude hiding (null)
2444
2545(.=) :: ToYaml a => Text -> a -> (Text, YamlBuilder)
2646k .= v = (k, toYaml v)
@@ -55,7 +75,37 @@ array bs =
5575 go (YamlBuilder b) rest = b rest
5676
5777string :: Text -> YamlBuilder
58−string t = YamlBuilder (EventScalar (encodeUtf8 t) StrTag PlainNoTag Nothing:)
78+-- Empty strings need special handling to ensure they get quoted. This avoids:
79+-- https://github.com/snoyberg/yaml/issues/24
80+string "" = YamlBuilder (EventScalar "" NoTag SingleQuoted Nothing :)
81+string s =
82+ YamlBuilder (event :)
83+ where
84+ event
85+ -- Make sure that special strings are encoded as strings properly.
86+ -- See: https://github.com/snoyberg/yaml/issues/31
87+ | s `HashSet.member` specialStrings || isNumeric s = EventScalar (encodeUtf8 s) NoTag SingleQuoted Nothing
88+ | otherwise = EventScalar (encodeUtf8 s) StrTag PlainNoTag Nothing
89+
90+-- Use aeson's implementation which gets rid of annoying decimal points
91+scientific :: Scientific -> YamlBuilder
92+scientific n = YamlBuilder (EventScalar (TE.encodeUtf8 $ TL.toStrict $ toLazyText $ encodeToTextBuilder (Number n)) IntTag PlainNoTag Nothing :)
93+
94+{-# DEPRECATED number "Use scientific" #-}
95+#if MIN_VERSION_aeson(0,7,0)
96+number :: Scientific -> YamlBuilder
97+number = scientific
98+#else
99+number :: Number -> YamlBuilder
100+number n rest = YamlBuilder (EventScalar (S8.pack $ show n) IntTag PlainNoTag Nothing :)
101+#endif
102+
103+bool :: Bool -> YamlBuilder
104+bool True = YamlBuilder (EventScalar "true" BoolTag PlainNoTag Nothing :)
105+bool False = YamlBuilder (EventScalar "false" BoolTag PlainNoTag Nothing :)
106+
107+null :: YamlBuilder
108+null = YamlBuilder (EventScalar "null" NullTag PlainNoTag Nothing :)
59109
60110toEvents :: YamlBuilder -> [Event]
61111toEvents (YamlBuilder front) =