1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
24import Prelude hiding (null)
25import Control.Arrow ((***))
26import qualified Data.ByteString.Char8 as BSC
27import qualified Data.ByteString.Builder as B
28import qualified Data.ByteString.Builder.Prim as BP
29import Data.ByteString.Builder.Prim ((>*<))
30import qualified Data.Map as Map
31import qualified Data.Scientific as Sci
32import Data.Monoid ((<>))
33import qualified Data.Name as Name
34import qualified Data.Text as Text
35import qualified Data.Text.Encoding as Text
36import qualified Data.Word as W
37import System.IO (IOMode(WriteMode), withBinaryFile)
46 | Object [(Text.Text, Value)]
50 | Number Sci.Scientific
54array :: [Value] -> Value
59object :: [(Text.Text,Value)] -> Value
64text :: Text.Text -> Value
66 String (encodeText txt)
69name :: Name.Name -> Value
71 String ("\"" <> Name.toBuilder nm <> "\"")
84number :: Sci.Scientific -> Value
94dict :: (k -> Text.Text) -> (v -> Value) -> Map.Map k v -> Value
95dict encodeKey encodeValue pairs =
96 Object $ map (encodeKey *** encodeValue) (Map.toList pairs)
99list :: (a -> Value) -> [a] -> Value
100list encodeEntry entries =
101 Array $ map encodeEntry entries
108(==>) :: a -> b -> (a, b)
117write :: FilePath -> Value -> IO ()
119 withBinaryFile path WriteMode $ \handle ->
120 B.hPutBuilder handle (encode value <> "\n")
123writeUgly :: FilePath -> Value -> IO ()
124writeUgly path value =
125 withBinaryFile path WriteMode $ \handle ->
126 B.hPutBuilder handle (encodeUgly value)
133encodeUgly :: Value -> B.Builder
139 Array (first : rest) ->
142 B.char7 ',' <> encodeUgly entry
144 B.char7 '[' <> encodeUgly first <> mconcat (map encodeEntry rest) <> B.char7 ']'
149 Object (first : rest) ->
151 encodeEntry char (key, entry) =
152 B.char7 char <> encodeText key <> B.char7 ':' <> encodeUgly entry
154 encodeEntry '{' first <> mconcat (map (encodeEntry ',') rest) <> B.char7 '}'
160 B.string7 (if boolean then "true" else "false")
166 B.string7 (Sci.formatScientific Sci.Generic Nothing scientific)
176encode :: Value -> B.Builder
181encodeHelp :: BSC.ByteString -> Value -> B.Builder
182encodeHelp indent value =
187 Array (first : rest) ->
188 encodeArray indent first rest
193 Object (first : rest) ->
194 encodeObject indent first rest
200 B.string7 (if boolean then "true" else "false")
206 B.string7 (Sci.formatScientific Sci.Generic Nothing scientific)
216encodeArray :: BSC.ByteString -> Value -> [Value] -> B.Builder
218 encodeSequence arrayOpen arrayClose encodeHelp
221arrayOpen :: B.Builder
226arrayClose :: B.Builder
235encodeObject :: BSC.ByteString -> (Text.Text, Value) -> [(Text.Text, Value)] -> B.Builder
237 encodeSequence objectOpen objectClose encodeField
240objectOpen :: B.Builder
245objectClose :: B.Builder
250encodeField :: BSC.ByteString -> (Text.Text, Value) -> B.Builder
251encodeField indent (key, value) =
252 encodeText key <> B.string7 ": " <> encodeHelp indent value
259encodeSequence :: B.Builder -> B.Builder -> (BSC.ByteString -> a -> B.Builder) -> BSC.ByteString -> a -> [a] -> B.Builder
260encodeSequence open close encodeEntry indent first rest =
266 B.byteString newIndent
269 newline <> B.byteString indent <> close
271 addValue field builder =
274 <> encodeEntry newIndent field
279 <> encodeEntry newIndent first
280 <> foldr addValue closer rest
283commaNewline :: B.Builder
297encodeText :: Text.Text -> B.Builder
299 B.char7 '"' <> Text.encodeUtf8BuilderEscaped escapeAscii txt <> B.char7 '"'
302{-# INLINE escapeAscii #-}
303escapeAscii :: BP.BoundedPrim W.Word8
305 BP.condB (== 0x5C {- \\ -}) (ascii2 ('\\','\\')) $
306 BP.condB (== 0x22 {- \" -}) (ascii2 ('\\','"' )) $
307 BP.condB (>= 0x20 ) (BP.liftFixedToBounded BP.word8) $
308 BP.condB (== 0x0A {- \n -}) (ascii2 ('\\','n' )) $
309 BP.condB (== 0x0D {- \r -}) (ascii2 ('\\','r' )) $
310 BP.condB (== 0x09 {- \t -}) (ascii2 ('\\','t' )) $
311 BP.liftFixedToBounded hexEscape -- fallback for chars < 0x20
313 hexEscape :: BP.FixedPrim W.Word8
314 hexEscape = (\c -> ('\\', ('u', fromIntegral c))) BP.>$<
315 BP.char8 >*< BP.char8 >*< BP.word16HexFixed
319ascii2 :: (Char, Char) -> BP.BoundedPrim a
321 BP.liftFixedToBounded $ const cs BP.>$< BP.char7 >*< BP.char7
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list