{-# LANGUAGE ScopedTypeVariables #-}
module Flat.Repr where

import Flat.Class ( Flat(..) )
import qualified Data.ByteString as B
import Flat.Decoder.Types ( Get )
import Flat.Run ( flat, unflat )

-- Flat representation of a value
newtype Repr a = Repr {Repr a -> ByteString
repr :: B.ByteString}

-- Get the underlying value
unrepr :: Flat a => Repr a -> a
unrepr :: Repr a -> a
unrepr (Repr ByteString
bs)= let Right a
a = ByteString -> Either DecodeException a
forall a b. (Flat a, AsByteString b) => b -> Decoded a
unflat ByteString
bs in a
a

instance Flat a => Flat (Repr a) where
    size :: Repr a -> NumBits -> NumBits
size = [Char] -> Repr a -> NumBits -> NumBits
forall a. HasCallStack => [Char] -> a
error [Char]
"unused"
    encode :: Repr a -> Encoding
encode = [Char] -> Repr a -> Encoding
forall a. HasCallStack => [Char] -> a
error [Char]
"unused"

    -- To create the representation we just re 'flat' the parsed value (this could be optimised by copying directly the parsed representation)
    decode :: Get (Repr a)
decode = ByteString -> Repr a
forall a. ByteString -> Repr a
Repr (ByteString -> Repr a) -> (a -> ByteString) -> a -> Repr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ByteString
forall a. Flat a => a -> ByteString
flat (a -> Repr a) -> Get a -> Get (Repr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Get a
forall a. Flat a => Get a
decode :: Get a)