{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}

module Data.Packed.Packable (Packable (..), pack) where

import Data.Packed.Needs (
    NeedsWriter,
    runBuilder,
    writeStorable,
 )
import Data.Packed.Packed (Packed)
import Foreign
import Prelude hiding (length)

-- | Typeclass for values that can be packed, i.e. written inside a 'Data.Packed.Needs.Needs'
class Packable a where
    write :: a -> NeedsWriter a r t

instance (Storable a) => Packable a where
    write :: forall (r :: [*]) (t :: [*]). a -> NeedsWriter a r t
write = a -> NeedsBuilder (a : r) t r t
forall a (r :: [*]) (t :: [*]).
Storable a =>
a -> NeedsBuilder (a : r) t r t
writeStorable

-- | Shortcut to produce a 'Data.Packed.Packed' buffer from a single 'Packable' value
pack :: (Packable a) => a -> Packed '[a]
pack :: forall a. Packable a => a -> Packed '[a]
pack = NeedsBuilder '[a] '[a] '[] '[a] -> Packed '[a]
forall (p1 :: [*]) (r :: [*]). NeedsBuilder p1 r '[] r -> Packed r
runBuilder (NeedsBuilder '[a] '[a] '[] '[a] -> Packed '[a])
-> (a -> NeedsBuilder '[a] '[a] '[] '[a]) -> a -> Packed '[a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> NeedsBuilder '[a] '[a] '[] '[a]
forall (r :: [*]) (t :: [*]). a -> NeedsWriter a r t
forall a (r :: [*]) (t :: [*]).
Packable a =>
a -> NeedsWriter a r t
write