-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMessage.hs
More file actions
105 lines (87 loc) · 2.39 KB
/
Copy pathMessage.hs
File metadata and controls
105 lines (87 loc) · 2.39 KB
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE DeriveGeneric #-}
module Message where
import Data.Aeson
import Data.Char
import Data.Maybe
import GHC.Generics
import Data.Time.Clock
-- This file contains the JSON decoding / encoding stuff. Not very interesting,
-- As there's a bit of boilerplate for this in haskell as its so strict.
data CommandType = CGET | CPUT deriving (Show, Generic, Eq)
data Command = Command {
ctype :: CommandType,
cterm :: Int,
creator :: !String,
cmid :: !String,
ckey :: !String,
cvalue :: !String
} deriving (Show, Generic, Eq)
instance ToJSON Command
instance FromJSON Command
instance ToJSON CommandType
instance FromJSON CommandType
data MessType = GET | PUT | OK | FAIL | REDIRECT | RAFT deriving (Read, Eq)
instance Show MessType where
show GET = "get"
show PUT = "put"
show OK = "ok"
show FAIL = "fail"
show REDIRECT = "redirect"
show RAFT = "RAFT"
data Message = Message {
src :: !String,
dst :: !String,
leader :: !String,
messType :: !MessType,
mid :: !String,
key :: Maybe String,
value :: Maybe String,
rmess :: Maybe RMessage
} deriving (Show, Eq)
instance FromJSON Message where
parseJSON = withObject "message" $ \o -> do
src <- o .: "src"
dst <- o .: "dst"
leader <- o .: "leader"
rawType <- o .: "type"
mid <- o .: "MID"
key <- o .:? "key" -- might not be there
value <- o .:? "value" -- might not be there
rmess <- o .:? "rmess" -- will be here if messType == AE or RV or...
let messType = (read $ map toUpper rawType) :: MessType
return Message{..}
instance ToJSON Message where
toJSON Message{..} = object [
"src" .= src,
"dst" .= dst,
"leader" .= leader,
"type" .= (show messType),
"MID" .= mid,
"key" .= key, -- Aeson encodes these maybes as "null"
"value" .= value,
"rmess" .= rmess ]
data RMessage = AE {
term :: Int,
leaderId :: !String,
prevLogIndex :: Int,
prevLogTerm :: Int,
entries :: [Command],
leaderCommit :: Int
} | AER {
term :: Int,
lastIndex :: Int, -- ONLY USE THIS IF SUCCESS IS TRUE
success :: Bool
} | RV {
term :: Int,
candidateId :: !String,
lastLogIndex :: Int,
lastLogTerm :: Int
} | RVR {
term :: Int,
voteGranted :: Bool
} deriving (Generic, Show, Eq)
instance ToJSON RMessage
instance FromJSON RMessage