12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 |
- {-# LANGUAGE OverloadedStrings #-}
- module Data.Eben where
- import qualified Data.ByteString as B
- import Data.ByteString.Lazy (ByteString)
- import qualified Data.ByteString.Lazy as BS
- import Data.ByteString.Builder (Builder)
- import qualified Data.ByteString.Builder as BL
- import Data.Int (Int64)
- import Data.List (sortOn)
- import Data.Map.Strict (Map)
- import qualified Data.Map as M
- import Data.Monoid ((<>))
- data Value
- = List [Value]
- | Dict (Map B.ByteString Value)
- | String B.ByteString
- | Integer Int64
- | Float Float
- deriving (Eq, Show, Read)
- decode :: ByteString -> Either String Value
- decode bs = case BS.uncons bs of
- ('l', rs) -> ()
- ('d', rs) -> ()
- ('i', rs) -> ()
- ('f', rs) -> ()
- (i , rs)
- | isDigit i ->
- encode :: Value -> ByteString
- encode = BL.toLazyByteString . go
- where go (List vs) =
- BL.char7 'l' <> foldMap go vs <> BL.char7 'e'
- go (Dict vs) =
- BL.char7 'd'
- <> mconcat [ str k <> go v | (k, v) <- sortOn fst (M.toList vs) ]
- <> BL.char7 'e'
- go (Integer i) =
- BL.char7 'i' <> BL.string8 (show i) <> BL.char7 'e'
- go (Float f) =
- BL.char7 'f' <> BL.floatLE f <> BL.char7 'e'
- go (String bs) = str bs
- str bs =
- BL.intDec (B.length bs)
- <> BL.char7 ':'
- <> BL.byteString bs
|