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.Map as Map
29import qualified Data.Scientific as Sci
30import Data.Monoid ((<>))
31import qualified Data.Name as Name
32import qualified Data.Utf8 as Utf8
33import System.IO (IOMode(WriteMode), withBinaryFile)
42 | Object [(Utf8.String, Value)]
46 | Number Sci.Scientific
50array :: [Value] -> Value
55object :: [(Utf8.String,Value)] -> Value
60string :: Utf8.String -> Value
62 String (encodeUtf8 str)
65name :: Name.Name -> Value
67 String (B.char7 '"' <> Name.toBuilder nm <> B.char7 '"')
80number :: Sci.Scientific -> Value
90dict :: (k -> Utf8.String) -> (v -> Value) -> Map.Map k v -> Value
91dict encodeKey encodeValue pairs =
92 Object $ map (encodeKey *** encodeValue) (Map.toList pairs)
95list :: (a -> Value) -> [a] -> Value
96list encodeEntry entries =
97 Array $ map encodeEntry entries
104(==>) :: a -> b -> (a, b)
113write :: FilePath -> Value -> IO ()
115 withBinaryFile path WriteMode $ \handle ->
116 B.hPutBuilder handle (encode value <> "\n")
119writeUgly :: FilePath -> Value -> IO ()
120writeUgly path value =
121 withBinaryFile path WriteMode $ \handle ->
122 B.hPutBuilder handle (encodeUgly value)
129encodeUgly :: Value -> B.Builder
135 Array (first : rest) ->
138 B.char7 ',' <> encodeUgly entry
140 B.char7 '[' <> encodeUgly first <> mconcat (map encodeEntry rest) <> B.char7 ']'
145 Object (first : rest) ->
147 encodeEntry char (key, entry) =
148 B.char7 char <> encodeUtf8 key <> B.char7 ':' <> encodeUgly entry
150 encodeEntry '{' first <> mconcat (map (encodeEntry ',') rest) <> B.char7 '}'
156 B.string7 (if boolean then "true" else "false")
162 B.string7 (Sci.formatScientific Sci.Generic Nothing scientific)
172encode :: Value -> B.Builder
177encodeHelp :: BSC.ByteString -> Value -> B.Builder
178encodeHelp indent value =
183 Array (first : rest) ->
184 encodeArray indent first rest
189 Object (first : rest) ->
190 encodeObject indent first rest
196 B.string7 (if boolean then "true" else "false")
202 B.string7 (Sci.formatScientific Sci.Generic Nothing scientific)
212encodeUtf8 :: Utf8.String -> B.Builder
214 B.char7 '"' <> Utf8.toBuilder str <> B.char7 '"'
221encodeArray :: BSC.ByteString -> Value -> [Value] -> B.Builder
223 encodeSequence arrayOpen arrayClose encodeHelp
226arrayOpen :: B.Builder
231arrayClose :: B.Builder
240encodeObject :: BSC.ByteString -> (Utf8.String, Value) -> [(Utf8.String, Value)] -> B.Builder
242 encodeSequence objectOpen objectClose encodeField
245objectOpen :: B.Builder
250objectClose :: B.Builder
255encodeField :: BSC.ByteString -> (Utf8.String, Value) -> B.Builder
256encodeField indent (key, value) =
257 encodeUtf8 key <> B.string7 ": " <> encodeHelp indent value
264encodeSequence :: B.Builder -> B.Builder -> (BSC.ByteString -> a -> B.Builder) -> BSC.ByteString -> a -> [a] -> B.Builder
265encodeSequence open close encodeEntry indent first rest =
271 B.byteString newIndent
274 newline <> B.byteString indent <> close
276 addValue field builder =
279 <> encodeEntry newIndent field
284 <> encodeEntry newIndent first
285 <> foldr addValue closer rest
288commaNewline :: B.Builder
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