-
Notifications
You must be signed in to change notification settings - Fork 0
/
Client.hs
68 lines (60 loc) · 1.68 KB
/
Client.hs
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
{-# LANGUAGE RecordWildCards #-}
module Client
( Client
, make
, applyLocal
, applyRemote
, checkSend
)
where
import Patch (Patch)
import qualified Patch
import Data.Text (Text)
data Client = Client
{ document :: Text
, revision :: !Int
, inflight :: Patch
, buffered :: Patch
}
deriving (Show)
make :: Text -> Int -> Client
make document revision = Client{..}
where
inflight = Patch.empty
buffered = Patch.empty
applyLocal :: Client -> Patch -> Client
applyLocal client patch = client
{ buffered = Patch.append (buffered client) patch
}
applyRemote :: Client -> Patch -> (Client, Patch)
applyRemote client patch
| Patch.apply (inflight client) (document client)
== Patch.apply patch (document client)
= (client
{ document = Patch.apply patch (document client)
, revision = revision client + 1
, inflight = Patch.empty
}, Patch.empty)
applyRemote client patch = (client
{ document = Patch.apply patch (document client)
, revision = revision client + 1
, inflight = inflight'
, buffered = buffered'
}, patch'')
where
(patch', inflight') = Patch.transform patch (inflight client)
(patch'', buffered') = Patch.transform patch' (buffered client)
checkSend :: Client -> Maybe (Client, Patch, Int)
checkSend client =
if emptyInflate && not emptyBuffered
then let client' = client
{ inflight = buffered client
, buffered = Patch.empty
}
in Just (client', inflight client', revision client')
else Nothing
where
emptyInflate =
Patch.apply (inflight client) (document client) == document client
emptyBuffered =
Patch.apply (buffered client) (document client) == document client