Skip to content

Commit ab2297c

Browse files
committed
Pull out shared sync types
1 parent e42cfca commit ab2297c

File tree

4 files changed

+104
-27
lines changed

4 files changed

+104
-27
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- Types common to multiple versions of Sync
2+
module Unison.SyncCommon.Types
3+
( BranchRef (..),
4+
)
5+
where
6+
7+
import Codec.Serialise (Serialise (..))
8+
import Data.Aeson (FromJSON (..), ToJSON (..))
9+
import Data.Text (Text)
10+
import Unison.Core.Project (ProjectAndBranch (..), ProjectBranchName, ProjectName)
11+
import Unison.Prelude (From (..))
12+
import Unison.Server.Orphans ()
13+
14+
newtype BranchRef = BranchRef {unBranchRef :: Text}
15+
deriving (Serialise, Eq, Show, Ord, ToJSON, FromJSON) via Text
16+
17+
instance From (ProjectAndBranch ProjectName ProjectBranchName) BranchRef where
18+
from pab = BranchRef $ from pab

unison-share-api/src/Unison/SyncV2/Types.hs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,13 @@ import Data.Text qualified as Text
3838
import Data.Word (Word16, Word64)
3939
import U.Codebase.HashTags (CausalHash)
4040
import U.Codebase.Sqlite.TempEntity (TempEntity)
41-
import Unison.Core.Project (ProjectAndBranch (..), ProjectBranchName, ProjectName)
4241
import Unison.Hash32 (Hash32)
43-
import Unison.Prelude (From (..))
4442
import Unison.Server.Orphans ()
4543
import Unison.Share.API.Hash (HashJWT)
4644
import Unison.Sync.Types qualified as SyncV1
45+
import Unison.SyncCommon.Types
4746
import Unison.Util.Servant.CBOR
4847

49-
newtype BranchRef = BranchRef {unBranchRef :: Text}
50-
deriving (Serialise, Eq, Show, Ord, ToJSON, FromJSON) via Text
51-
52-
instance From (ProjectAndBranch ProjectName ProjectBranchName) BranchRef where
53-
from pab = BranchRef $ from pab
54-
5548
data GetCausalHashErrorTag
5649
= GetCausalHashNoReadPermissionTag
5750
| GetCausalHashUserNotFoundTag

unison-share-api/src/Unison/SyncV3/Types.hs

Lines changed: 84 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ module Unison.SyncV3.Types
88
Entity (..),
99
EntityKind (..),
1010
EntityDepth (..),
11-
HashMappings (..),
1211
HashTag (..),
1312
BranchRef (..),
1413
)
1514
where
1615

17-
import Codec.CBOR.Term (decodeTerm)
16+
import Unison.SyncCommon.Types
1817
import Codec.Serialise (Serialise)
1918
import Codec.Serialise qualified as CBOR
2019
import Control.Lens hiding ((.=))
@@ -23,7 +22,6 @@ import Data.Aeson qualified as Aeson
2322
import Data.ByteString qualified as BS
2423
import Data.ByteString.Lazy.Char8 qualified as BL
2524
import Data.Int (Int32, Int64)
26-
import Data.Map (Map)
2725
import Data.Set (Set)
2826
import Data.Set qualified as Set
2927
import Data.Text (Text)
@@ -68,6 +66,11 @@ data EntityRequestMsg hash = EntityRequestMsg
6866
}
6967
deriving (Show, Eq)
7068

69+
-- | Roundtrip test:
70+
-- >>> import qualified Codec.Serialise as CBOR
71+
-- >>> let msg = EntityRequestMsg {hashes = [(CausalEntity, "hash1"), (NamespaceEntity, "hash2")]}
72+
-- >>> CBOR.deserialise (CBOR.serialise msg) == msg
73+
-- True
7174
instance (CBOR.Serialise sh) => CBOR.Serialise (EntityRequestMsg sh) where
7275
encode (EntityRequestMsg {hashes}) =
7376
CBOR.encode hashes
@@ -81,6 +84,12 @@ data FromReceiverMessageTag
8184
| ReceiverEntityRequestTag
8285
deriving (Show, Eq)
8386

87+
-- | Roundtrip test:
88+
-- >>> import qualified Codec.Serialise as CBOR
89+
-- >>> CBOR.deserialise (CBOR.serialise ReceiverInitStreamTag) == ReceiverInitStreamTag
90+
-- True
91+
-- >>> CBOR.deserialise (CBOR.serialise ReceiverEntityRequestTag) == ReceiverEntityRequestTag
92+
-- True
8493
instance CBOR.Serialise FromReceiverMessageTag where
8594
encode = \case
8695
ReceiverInitStreamTag -> CBOR.encode (0 :: Int)
@@ -117,6 +126,17 @@ instance (ToJSON ah, FromJSON ah) => CBOR.Serialise (InitMsg ah) where
117126
Left err -> fail $ "Error decoding InitMsg from JSON: " <> err
118127
Right msg -> pure msg
119128

129+
-- | Roundtrip test:
130+
-- >>> import qualified Codec.Serialise as CBOR
131+
-- >>> let msg = InitMsg {initMsgClientVersion = 1, initMsgBranchRef = BranchRef "main", initMsgRootCausal = "hash123", initMsgRequestedDepth = Just 10}
132+
-- >>> CBOR.deserialise (CBOR.serialise msg) == msg
133+
-- True
134+
-- >>> let initMsg :: FromReceiverMessage Text Text = ReceiverInitStream msg
135+
-- >>> CBOR.deserialise (CBOR.serialise initMsg) == initMsg
136+
-- True
137+
-- >>> let entityReq :: FromReceiverMessage Text Text = ReceiverEntityRequest (EntityRequestMsg {hashes = [(CausalEntity, "h1")]})
138+
-- >>> CBOR.deserialise (CBOR.serialise entityReq) == entityReq
139+
-- True
120140
instance (CBOR.Serialise h, ToJSON ah, FromJSON ah) => CBOR.Serialise (FromReceiverMessage ah h) where
121141
encode = \case
122142
ReceiverInitStream initMsg ->
@@ -141,6 +161,16 @@ data SyncError
141161
| ConnectionError Text
142162
deriving (Show, Eq)
143163

164+
-- | Roundtrip test:
165+
-- >>> import qualified Codec.Serialise as CBOR
166+
-- >>> import qualified Data.Set as Set
167+
-- >>> CBOR.deserialise (CBOR.serialise (InitializationError "test")) == InitializationError "test"
168+
-- True
169+
-- >>> CBOR.deserialise (CBOR.serialise (EncodingFailure "fail")) == EncodingFailure "fail"
170+
-- True
171+
-- >>> let forbidden = ForbiddenEntityRequest (Set.fromList [(CausalEntity, undefined)])
172+
-- >>> CBOR.deserialise (CBOR.serialise (ConnectionError "err")) == ConnectionError "err"
173+
-- True
144174
instance CBOR.Serialise SyncError where
145175
encode = \case
146176
InitializationError msg ->
@@ -173,10 +203,6 @@ data FromEmitterMessage hash text
173203
= EmitterEntityMsg (Entity hash text)
174204
deriving (Show, Eq)
175205

176-
data HashMappings hash smallHash = HashMappings
177-
{ hashMappings :: Map smallHash hash
178-
}
179-
180206
data EntityKind
181207
= CausalEntity
182208
| NamespaceEntity
@@ -202,6 +228,16 @@ instance Sqlite.FromField EntityKind where
202228
3 -> pure PatchEntity
203229
_ -> fail $ "Unknown EntityKind tag: " <> show tag
204230

231+
-- | Roundtrip test:
232+
-- >>> import qualified Codec.Serialise as CBOR
233+
-- >>> CBOR.deserialise (CBOR.serialise CausalEntity) == CausalEntity
234+
-- True
235+
-- >>> CBOR.deserialise (CBOR.serialise NamespaceEntity) == NamespaceEntity
236+
-- True
237+
-- >>> CBOR.deserialise (CBOR.serialise DefnComponentEntity) == DefnComponentEntity
238+
-- True
239+
-- >>> CBOR.deserialise (CBOR.serialise PatchEntity) == PatchEntity
240+
-- True
205241
instance CBOR.Serialise EntityKind where
206242
encode = \case
207243
CausalEntity -> CBOR.encode (0 :: Int)
@@ -235,6 +271,12 @@ data Entity hash text = Entity
235271
}
236272
deriving (Show, Eq)
237273

274+
-- | Roundtrip test:
275+
-- >>> import qualified Codec.Serialise as CBOR
276+
-- >>> import U.Codebase.Sqlite.TempEntity (TempEntity(..))
277+
-- >>> let ent :: Entity Text Text = Entity {entityHash = "hash", entityKind = CausalEntity, entityDepth = EntityDepth 5, entityData = CBOR.CBORBytes "abc"}
278+
-- >>> CBOR.deserialise (CBOR.serialise ent) == ent
279+
-- True
238280
instance (CBOR.Serialise smallHash, CBOR.Serialise text) => CBOR.Serialise (Entity smallHash text) where
239281
encode (Entity {entityHash, entityKind, entityDepth, entityData}) =
240282
CBOR.encode entityHash
@@ -250,14 +292,13 @@ instance (CBOR.Serialise smallHash, CBOR.Serialise text) => CBOR.Serialise (Enti
250292

251293
pure $ Entity {entityHash, entityKind, entityData, entityDepth}
252294

253-
instance (Ord smallHash, CBOR.Serialise hash, CBOR.Serialise smallHash) => CBOR.Serialise (HashMappings hash smallHash) where
254-
encode (HashMappings {hashMappings}) =
255-
CBOR.encode hashMappings
256-
257-
decode = do
258-
hashMappings <- CBOR.decode @(Map smallHash hash)
259-
pure $ HashMappings {hashMappings}
260-
295+
-- | Roundtrip test:
296+
-- >>> import qualified Codec.Serialise as CBOR
297+
-- >>> import U.Codebase.Sqlite.TempEntity (TempEntity(..))
298+
-- >>> let ent :: Entity Text Text = Entity {entityHash = "hash", entityKind = CausalEntity, entityDepth = EntityDepth 5, entityData = CBOR.CBORBytes "abc"}
299+
-- >>> let msg = EmitterEntityMsg ent
300+
-- >>> CBOR.deserialise (CBOR.serialise msg) == msg
301+
-- True
261302
instance (CBOR.Serialise hash, CBOR.Serialise text) => CBOR.Serialise (FromEmitterMessage hash text) where
262303
encode = \case
263304
EmitterEntityMsg msg -> CBOR.encode EmitterEntityTag <> CBOR.encode msg
@@ -269,7 +310,12 @@ instance (CBOR.Serialise hash, CBOR.Serialise text) => CBOR.Serialise (FromEmitt
269310

270311
data FromEmitterMessageTag
271312
= EmitterEntityTag
313+
deriving (Show, Eq)
272314

315+
-- | Roundtrip test:
316+
-- >>> import qualified Codec.Serialise as CBOR
317+
-- >>> CBOR.deserialise (CBOR.serialise EmitterEntityTag) == EmitterEntityTag
318+
-- True
273319
instance CBOR.Serialise FromEmitterMessageTag where
274320
encode = \case
275321
EmitterEntityTag -> CBOR.encode (0 :: Int)
@@ -285,6 +331,12 @@ data MsgOrError err a
285331
| Err err
286332
deriving (Show, Eq, Ord)
287333

334+
-- | Roundtrip test:
335+
-- >>> import qualified Codec.Serialise as CBOR
336+
-- >>> CBOR.deserialise (CBOR.serialise (Msg "test" :: MsgOrError Text Text)) == Msg "test"
337+
-- True
338+
-- >>> CBOR.deserialise (CBOR.serialise (Err "error" :: MsgOrError Text Text)) == Err "error"
339+
-- True
288340
instance (CBOR.Serialise a, CBOR.Serialise err) => CBOR.Serialise (MsgOrError err a) where
289341
encode = \case
290342
Msg a -> CBOR.encode (0 :: Int) <> CBOR.encode a
@@ -298,10 +350,21 @@ instance (CBOR.Serialise a, CBOR.Serialise err) => CBOR.Serialise (MsgOrError er
298350
1 -> Err <$> CBOR.decode
299351
_ -> fail $ "Unknown MsgOrError tag: " <> show tag
300352

353+
-- | Roundtrip test:
354+
-- >>> import qualified Network.WebSockets as WS
355+
-- >>> let msgVal = Msg "test" :: MsgOrError SyncError Text
356+
-- >>> WS.fromLazyByteString (WS.toLazyByteString msgVal) == msgVal
357+
-- True
358+
-- >>> let errVal = Err (InitializationError "init error") :: MsgOrError SyncError Text
359+
-- >>> WS.fromLazyByteString (WS.toLazyByteString errVal) == errVal
360+
-- True
361+
-- >>> let dataMsg = WS.Binary (WS.toLazyByteString msgVal)
362+
-- >>> WS.fromDataMessage dataMsg == msgVal
363+
-- True
301364
instance (Serialise msg) => WebSocketsData (MsgOrError SyncError msg) where
302365
fromLazyByteString bytes =
303366
CBOR.deserialiseOrFail bytes
304-
& either (\err -> Err . EncodingFailure $ "Error decoding CBOR message from bytes: " <> tShow err) Msg
367+
& either (\err -> Err . EncodingFailure $ "Error decoding CBOR message from bytes: " <> tShow err) id
305368

306369
toLazyByteString = CBOR.serialise
307370

@@ -316,13 +379,15 @@ instance (Serialise msg) => WebSocketsData (MsgOrError SyncError msg) where
316379
data HashTag = HashTag (EntityKind, Int64)
317380
deriving (Show, Eq, Ord)
318381

382+
-- | Roundtrip test:
383+
-- >>> import qualified Codec.Serialise as CBOR
384+
-- >>> let tag = HashTag (CausalEntity, 42)
385+
-- >>> CBOR.deserialise (CBOR.serialise tag) == tag
386+
-- True
319387
instance CBOR.Serialise HashTag where
320388
encode (HashTag (kind, idx)) =
321389
CBOR.encode (kind, idx)
322390

323391
decode = do
324392
(kind, idx) <- CBOR.decode @(EntityKind, Int64)
325393
pure $ HashTag (kind, idx)
326-
327-
newtype BranchRef = BranchRef {unBranchRef :: Text}
328-
deriving (Serialise, Eq, Show, Ord, ToJSON, FromJSON) via Text

unison-share-api/unison-share-api.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ library
4949
Unison.Sync.Common
5050
Unison.Sync.EntityValidation
5151
Unison.Sync.Types
52+
Unison.SyncCommon.Types
5253
Unison.SyncV2.API
5354
Unison.SyncV2.Types
5455
Unison.SyncV3.Types

0 commit comments

Comments
 (0)