Eben.hs 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Data.Eben where
  3. import qualified Data.ByteString as B
  4. import Data.ByteString.Lazy (ByteString)
  5. import qualified Data.ByteString.Lazy as BS
  6. import Data.ByteString.Builder (Builder)
  7. import qualified Data.ByteString.Builder as BL
  8. import Data.Int (Int64)
  9. import Data.List (sortOn)
  10. import Data.Map.Strict (Map)
  11. import qualified Data.Map as M
  12. import Data.Monoid ((<>))
  13. data Value
  14. = List [Value]
  15. | Dict (Map B.ByteString Value)
  16. | String B.ByteString
  17. | Integer Int64
  18. | Float Float
  19. deriving (Eq, Show, Read)
  20. decode :: ByteString -> Either String Value
  21. decode bs = case BS.uncons bs of
  22. ('l', rs) -> ()
  23. ('d', rs) -> ()
  24. ('i', rs) -> ()
  25. ('f', rs) -> ()
  26. (i , rs)
  27. | isDigit i ->
  28. encode :: Value -> ByteString
  29. encode = BL.toLazyByteString . go
  30. where go (List vs) =
  31. BL.char7 'l' <> foldMap go vs <> BL.char7 'e'
  32. go (Dict vs) =
  33. BL.char7 'd'
  34. <> mconcat [ str k <> go v | (k, v) <- sortOn fst (M.toList vs) ]
  35. <> BL.char7 'e'
  36. go (Integer i) =
  37. BL.char7 'i' <> BL.string8 (show i) <> BL.char7 'e'
  38. go (Float f) =
  39. BL.char7 'f' <> BL.floatLE f <> BL.char7 'e'
  40. go (String bs) = str bs
  41. str bs =
  42. BL.intDec (B.length bs)
  43. <> BL.char7 ':'
  44. <> BL.byteString bs