module Image.VK where
import Data.ByteString.Lazy (ByteString)
import Data.Eben (Value(..))
import qualified Data.Eben as Eben
type Point = (Int, Int)
data VKImage = VKImage
{ vkLines :: [[Point]]
, vkMeta :: VKMeta
} deriving (Eq, Show)
data VKMeta = VKMeta { vkSize :: (Int, Int) } deriving (Eq, Show)
catch :: Maybe a -> String -> Either String a
catch (Just a) _ = Right a
catch Nothing m = Left m
asPoint :: Value -> Either String Point
asPoint v = Eben.fromEben v `catch` "Unable to parse point"
decode :: ByteString -> Either String VKImage
decode bs = do
(ds, _) <- Eben.decode bs `catch` "Invalid EBEN value"
metaV <- Eben.lookup "meta" ds `catch` "Missing field: `meta`"
(w,h) <- asPoint metaV
linesV <- Eben.lookup "lines" ds `catch` "Missing field: `lines`"
ls <- Eben.asList linesV `catch` "`lines` field not a list"
ls' <- mapM Eben.asList ls `catch` "arglbargl"
points <- sequence [ mapM asPoint l | l <- ls' ]
return VKImage { vkLines = points
, vkMeta = VKMeta { vkSize = (w, h) }
}
encode :: VKImage -> ByteString
encode vk = Eben.encode $ Eben.dict
[ ("meta", Eben.toEben (vkSize (vkMeta vk)))
, ("lines", Eben.toEben (vkLines vk))
]