module Data.BinEmbed
( Node(File, Dir)
, unBinEmbed
, unBinEmbedFile
) where
import Prelude hiding (sequence)
import Foreign.Ptr (Ptr, castPtr, minusPtr)
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafePackCStringLen)
import Data.Foldable (Foldable, foldMap)
import Data.Traversable (Traversable, traverse, sequence)
import Data.Map (Map)
data Node a
= File a
| Dir (Map String (Node a))
deriving (Show, Read, Eq, Ord)
instance Functor Node where
fmap f (File a) = File ( f a)
fmap f (Dir a) = Dir (fmap (fmap f) a)
instance Foldable Node where
foldMap f (File a) = f a
foldMap f (Dir a) = foldMap (foldMap f) a
instance Traversable Node where
traverse f (File a) = File `fmap` f a
traverse f (Dir a) = Dir `fmap` traverse (traverse f) a
unBinEmbed :: Node (IO ByteString) -> IO (Node ByteString)
unBinEmbed = sequence
unBinEmbedFile :: Ptr () -> Ptr () -> IO ByteString
unBinEmbedFile s e = unsafePackCStringLen (castPtr s, e `minusPtr` s)