blob: 04a2a576ed37e47dc5f8e267de48c1487ef25c02 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
module Montis.Core.State.Marshal (marshalState, demarshalState) where
import Data.Map qualified as M
import Data.Maybe (mapMaybe)
import Montis.Core.Extensions
import Montis.Core.State
data MarshalledState where
MarshalledState ::
[(String, String)] ->
MarshalledState
deriving (Show, Read)
-- | Marshals the serializable parts of the state to a string. This happens
-- during a hot-reload where some state must be saved to persist across hot
-- reloads.
-- Only the extensible state is persisted; hooks and other runtime data are
-- reconstructed from the config on restart.
marshalState :: State m -> String
marshalState
( State
{ extensibleState = xs
}
) =
show $
MarshalledState
(mapMaybe (\(k, v) -> (extensionKeyValue k,) <$> doMarshalEx v) (M.toList xs))
where
-- Left values are already marshalled; Right values are re-encoded here.
doMarshalEx :: Either String (Extension StateExtension) -> Maybe String
doMarshalEx (Left s) = Just s
doMarshalEx (Right (Extension a)) = marshalExtension a
-- | Demarshals the string from "marshalState" into a state. Uses the provided
-- config to fill out non-persistent parts of the state.
-- The extensible map is rehydrated as marshalled strings so decoding can be
-- deferred until a specific extension is requested.
demarshalState :: Config m -> String -> State m
demarshalState Config {startingHooks = hooks} str =
State hooks xs
where
( MarshalledState
(M.mapKeys ExtensionKey . fmap Left . M.fromList -> xs)
) = read str
|