{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE StrictData #-} module Octane.Type.ReplayWithoutFrames (ReplayWithoutFrames(..), fromRawReplay, toRawReplay) where import qualified Control.DeepSeq as DeepSeq import qualified Data.Binary as Binary import qualified Data.Binary.Get as Binary import qualified Data.Binary.Put as Binary import qualified Data.ByteString.Lazy as LazyBytes import qualified GHC.Generics as Generics import qualified Octane.Type.CacheItem as CacheItem import qualified Octane.Type.ClassItem as ClassItem import qualified Octane.Type.Dictionary as Dictionary import qualified Octane.Type.KeyFrame as KeyFrame import qualified Octane.Type.List as List import qualified Octane.Type.Mark as Mark import qualified Octane.Type.Message as Message import qualified Octane.Type.Property as Property import qualified Octane.Type.RawReplay as RawReplay import qualified Octane.Type.Stream as Stream import qualified Octane.Type.Text as Text import qualified Octane.Type.Word32 as Word32 -- | A partially-processed replay. This has parsed all of the high-level -- metadata, but it has not parsed any of the network stream. -- -- See 'Octane.Type.ReplayWithFrames.ReplayWithFrames'. data ReplayWithoutFrames = ReplayWithoutFrames { version1 :: Word32.Word32 , version2 :: Word32.Word32 , label :: Text.Text , properties :: Dictionary.Dictionary Property.Property , levels :: List.List Text.Text , keyFrames :: List.List KeyFrame.KeyFrame , stream :: Stream.Stream , messages :: List.List Message.Message , marks :: List.List Mark.Mark , packages :: List.List Text.Text , objects :: List.List Text.Text , names :: List.List Text.Text , classes :: List.List ClassItem.ClassItem , cache :: List.List CacheItem.CacheItem } deriving (Eq, Generics.Generic, Show) instance Binary.Binary ReplayWithoutFrames where get = do rawReplay <- Binary.get fromRawReplay rawReplay put replayWithoutFrames = do rawReplay <- toRawReplay replayWithoutFrames Binary.put rawReplay instance DeepSeq.NFData ReplayWithoutFrames where -- | Converts a 'RawReplay.RawReplay' into a 'ReplayWithoutFrames'. -- Operates in a 'Monad' so that it can 'fail' somewhat gracefully. fromRawReplay :: (Monad m) => RawReplay.RawReplay -> m ReplayWithoutFrames fromRawReplay rawReplay = do let header = RawReplay.header rawReplay let content = RawReplay.content rawReplay let get = do version1 <- Binary.get version2 <- Binary.get label <- Binary.get properties <- Binary.get levels <- Binary.get keyFrames <- Binary.get stream <- Binary.get messages <- Binary.get marks <- Binary.get packages <- Binary.get objects <- Binary.get names <- Binary.get classes <- Binary.get cache <- Binary.get pure ReplayWithoutFrames { .. } let bytes = LazyBytes.append header content pure (Binary.runGet get bytes) -- | Converts a 'ReplayWithoutFrames' into a 'RawReplay.RawReplay'. -- Operates in a 'Monad' so that it can 'fail' somewhat gracefully. toRawReplay :: (Monad m) => ReplayWithoutFrames -> m RawReplay.RawReplay toRawReplay replay = do let header = Binary.runPut (do Binary.put (version1 replay) Binary.put (version2 replay) Binary.put (label replay) Binary.put (properties replay)) let content = Binary.runPut (do Binary.put (levels replay) Binary.put (keyFrames replay) Binary.put (stream replay) Binary.put (messages replay) Binary.put (marks replay) Binary.put (packages replay) Binary.put (objects replay) Binary.put (names replay) Binary.put (classes replay) Binary.put (cache replay)) let footer = LazyBytes.empty pure (RawReplay.newRawReplay header content footer)