1#![allow(non_snake_case)]
2
3pub mod error;
4mod macros;
5mod typed_envelope;
6
7pub use error::*;
8pub use typed_envelope::*;
9
10use collections::HashMap;
11pub use prost::{DecodeError, Message};
12use serde::Serialize;
13use std::{
14 any::{Any, TypeId},
15 cmp,
16 fmt::{self, Debug},
17 iter, mem,
18 time::{Duration, SystemTime, UNIX_EPOCH},
19};
20
21include!(concat!(env!("OUT_DIR"), "/zed.messages.rs"));
22
23pub const SSH_PEER_ID: PeerId = PeerId { owner_id: 0, id: 0 };
24pub const SSH_PROJECT_ID: u64 = 0;
25
26pub trait EnvelopedMessage: Clone + Debug + Serialize + Sized + Send + Sync + 'static {
27 const NAME: &'static str;
28 const PRIORITY: MessagePriority;
29 fn into_envelope(
30 self,
31 id: u32,
32 responding_to: Option<u32>,
33 original_sender_id: Option<PeerId>,
34 ) -> Envelope;
35 fn from_envelope(envelope: Envelope) -> Option<Self>;
36}
37
38pub trait EntityMessage: EnvelopedMessage {
39 type Entity;
40 fn remote_entity_id(&self) -> u64;
41}
42
43pub trait RequestMessage: EnvelopedMessage {
44 type Response: EnvelopedMessage;
45}
46
47pub trait AnyTypedEnvelope: 'static + Send + Sync {
48 fn payload_type_id(&self) -> TypeId;
49 fn payload_type_name(&self) -> &'static str;
50 fn as_any(&self) -> &dyn Any;
51 fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync>;
52 fn is_background(&self) -> bool;
53 fn original_sender_id(&self) -> Option<PeerId>;
54 fn sender_id(&self) -> PeerId;
55 fn message_id(&self) -> u32;
56}
57
58pub enum MessagePriority {
59 Foreground,
60 Background,
61}
62
63impl<T: EnvelopedMessage> AnyTypedEnvelope for TypedEnvelope<T> {
64 fn payload_type_id(&self) -> TypeId {
65 TypeId::of::<T>()
66 }
67
68 fn payload_type_name(&self) -> &'static str {
69 T::NAME
70 }
71
72 fn as_any(&self) -> &dyn Any {
73 self
74 }
75
76 fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync> {
77 self
78 }
79
80 fn is_background(&self) -> bool {
81 matches!(T::PRIORITY, MessagePriority::Background)
82 }
83
84 fn original_sender_id(&self) -> Option<PeerId> {
85 self.original_sender_id
86 }
87
88 fn sender_id(&self) -> PeerId {
89 self.sender_id
90 }
91
92 fn message_id(&self) -> u32 {
93 self.message_id
94 }
95}
96
97impl PeerId {
98 pub fn from_u64(peer_id: u64) -> Self {
99 let owner_id = (peer_id >> 32) as u32;
100 let id = peer_id as u32;
101 Self { owner_id, id }
102 }
103
104 pub fn as_u64(self) -> u64 {
105 ((self.owner_id as u64) << 32) | (self.id as u64)
106 }
107}
108
109impl Copy for PeerId {}
110
111impl Eq for PeerId {}
112
113impl Ord for PeerId {
114 fn cmp(&self, other: &Self) -> cmp::Ordering {
115 self.owner_id
116 .cmp(&other.owner_id)
117 .then_with(|| self.id.cmp(&other.id))
118 }
119}
120
121impl PartialOrd for PeerId {
122 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
123 Some(self.cmp(other))
124 }
125}
126
127impl std::hash::Hash for PeerId {
128 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
129 self.owner_id.hash(state);
130 self.id.hash(state);
131 }
132}
133
134impl fmt::Display for PeerId {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 write!(f, "{}/{}", self.owner_id, self.id)
137 }
138}
139
140messages!(
141 (AcceptTermsOfService, Foreground),
142 (AcceptTermsOfServiceResponse, Foreground),
143 (Ack, Foreground),
144 (AckBufferOperation, Background),
145 (AckChannelMessage, Background),
146 (AddNotification, Foreground),
147 (AddProjectCollaborator, Foreground),
148 (ApplyCodeAction, Background),
149 (ApplyCodeActionResponse, Background),
150 (ApplyCompletionAdditionalEdits, Background),
151 (ApplyCompletionAdditionalEditsResponse, Background),
152 (BufferReloaded, Foreground),
153 (BufferSaved, Foreground),
154 (Call, Foreground),
155 (CallCanceled, Foreground),
156 (CancelCall, Foreground),
157 (ChannelMessageSent, Foreground),
158 (ChannelMessageUpdate, Foreground),
159 (ComputeEmbeddings, Background),
160 (ComputeEmbeddingsResponse, Background),
161 (CopyProjectEntry, Foreground),
162 (CreateBufferForPeer, Foreground),
163 (CreateChannel, Foreground),
164 (CreateChannelResponse, Foreground),
165 (CreateProjectEntry, Foreground),
166 (CreateRoom, Foreground),
167 (CreateRoomResponse, Foreground),
168 (DeclineCall, Foreground),
169 (DeleteChannel, Foreground),
170 (DeleteNotification, Foreground),
171 (UpdateNotification, Foreground),
172 (DeleteProjectEntry, Foreground),
173 (EndStream, Foreground),
174 (Error, Foreground),
175 (ExpandProjectEntry, Foreground),
176 (ExpandProjectEntryResponse, Foreground),
177 (Follow, Foreground),
178 (FollowResponse, Foreground),
179 (FormatBuffers, Foreground),
180 (FormatBuffersResponse, Foreground),
181 (FuzzySearchUsers, Foreground),
182 (GetCachedEmbeddings, Background),
183 (GetCachedEmbeddingsResponse, Background),
184 (GetChannelMembers, Foreground),
185 (GetChannelMembersResponse, Foreground),
186 (GetChannelMessages, Background),
187 (GetChannelMessagesById, Background),
188 (GetChannelMessagesResponse, Background),
189 (GetCodeActions, Background),
190 (GetCodeActionsResponse, Background),
191 (GetCompletions, Background),
192 (GetCompletionsResponse, Background),
193 (GetDefinition, Background),
194 (GetDefinitionResponse, Background),
195 (GetDeclaration, Background),
196 (GetDeclarationResponse, Background),
197 (GetDocumentHighlights, Background),
198 (GetDocumentHighlightsResponse, Background),
199 (GetHover, Background),
200 (GetHoverResponse, Background),
201 (GetNotifications, Foreground),
202 (GetNotificationsResponse, Foreground),
203 (GetPrivateUserInfo, Foreground),
204 (GetPrivateUserInfoResponse, Foreground),
205 (GetProjectSymbols, Background),
206 (GetProjectSymbolsResponse, Background),
207 (GetReferences, Background),
208 (GetReferencesResponse, Background),
209 (GetSignatureHelp, Background),
210 (GetSignatureHelpResponse, Background),
211 (GetSupermavenApiKey, Background),
212 (GetSupermavenApiKeyResponse, Background),
213 (GetTypeDefinition, Background),
214 (GetTypeDefinitionResponse, Background),
215 (GetImplementation, Background),
216 (GetImplementationResponse, Background),
217 (GetLlmToken, Background),
218 (GetLlmTokenResponse, Background),
219 (GetUsers, Foreground),
220 (Hello, Foreground),
221 (IncomingCall, Foreground),
222 (InlayHints, Background),
223 (InlayHintsResponse, Background),
224 (InviteChannelMember, Foreground),
225 (JoinChannel, Foreground),
226 (JoinChannelBuffer, Foreground),
227 (JoinChannelBufferResponse, Foreground),
228 (JoinChannelChat, Foreground),
229 (JoinChannelChatResponse, Foreground),
230 (JoinProject, Foreground),
231 (JoinHostedProject, Foreground),
232 (JoinProjectResponse, Foreground),
233 (JoinRoom, Foreground),
234 (JoinRoomResponse, Foreground),
235 (LeaveChannelBuffer, Background),
236 (LeaveChannelChat, Foreground),
237 (LeaveProject, Foreground),
238 (LeaveRoom, Foreground),
239 (MarkNotificationRead, Foreground),
240 (MoveChannel, Foreground),
241 (OnTypeFormatting, Background),
242 (OnTypeFormattingResponse, Background),
243 (OpenBufferById, Background),
244 (OpenBufferByPath, Background),
245 (OpenBufferForSymbol, Background),
246 (OpenBufferForSymbolResponse, Background),
247 (OpenBufferResponse, Background),
248 (PerformRename, Background),
249 (PerformRenameResponse, Background),
250 (Ping, Foreground),
251 (PrepareRename, Background),
252 (PrepareRenameResponse, Background),
253 (ProjectEntryResponse, Foreground),
254 (CountLanguageModelTokens, Background),
255 (CountLanguageModelTokensResponse, Background),
256 (RefreshLlmToken, Background),
257 (RefreshInlayHints, Foreground),
258 (RejoinChannelBuffers, Foreground),
259 (RejoinChannelBuffersResponse, Foreground),
260 (RejoinRoom, Foreground),
261 (RejoinRoomResponse, Foreground),
262 (ReloadBuffers, Foreground),
263 (ReloadBuffersResponse, Foreground),
264 (RemoveChannelMember, Foreground),
265 (RemoveChannelMessage, Foreground),
266 (UpdateChannelMessage, Foreground),
267 (RemoveContact, Foreground),
268 (RemoveProjectCollaborator, Foreground),
269 (RenameChannel, Foreground),
270 (RenameChannelResponse, Foreground),
271 (RenameProjectEntry, Foreground),
272 (RequestContact, Foreground),
273 (ResolveCompletionDocumentation, Background),
274 (ResolveCompletionDocumentationResponse, Background),
275 (ResolveInlayHint, Background),
276 (ResolveInlayHintResponse, Background),
277 (RespondToChannelInvite, Foreground),
278 (RespondToContactRequest, Foreground),
279 (RoomUpdated, Foreground),
280 (SaveBuffer, Foreground),
281 (SetChannelMemberRole, Foreground),
282 (SetChannelVisibility, Foreground),
283 (SendChannelMessage, Background),
284 (SendChannelMessageResponse, Background),
285 (ShareProject, Foreground),
286 (ShareProjectResponse, Foreground),
287 (ShowContacts, Foreground),
288 (StartLanguageServer, Foreground),
289 (SubscribeToChannels, Foreground),
290 (SynchronizeBuffers, Foreground),
291 (SynchronizeBuffersResponse, Foreground),
292 (TaskContextForLocation, Background),
293 (TaskContext, Background),
294 (Test, Foreground),
295 (Unfollow, Foreground),
296 (UnshareProject, Foreground),
297 (UpdateBuffer, Foreground),
298 (UpdateBufferFile, Foreground),
299 (UpdateChannelBuffer, Foreground),
300 (UpdateChannelBufferCollaborators, Foreground),
301 (UpdateChannels, Foreground),
302 (UpdateUserChannels, Foreground),
303 (UpdateContacts, Foreground),
304 (UpdateDiagnosticSummary, Foreground),
305 (UpdateDiffBase, Foreground),
306 (UpdateFollowers, Foreground),
307 (UpdateInviteInfo, Foreground),
308 (UpdateLanguageServer, Foreground),
309 (UpdateParticipantLocation, Foreground),
310 (UpdateProject, Foreground),
311 (UpdateProjectCollaborator, Foreground),
312 (UpdateUserPlan, Foreground),
313 (UpdateWorktree, Foreground),
314 (UpdateWorktreeSettings, Foreground),
315 (UsersResponse, Foreground),
316 (LspExtExpandMacro, Background),
317 (LspExtExpandMacroResponse, Background),
318 (SetRoomParticipantRole, Foreground),
319 (BlameBuffer, Foreground),
320 (BlameBufferResponse, Foreground),
321 (CreateDevServerProject, Background),
322 (CreateDevServerProjectResponse, Foreground),
323 (CreateDevServer, Foreground),
324 (CreateDevServerResponse, Foreground),
325 (DevServerInstructions, Foreground),
326 (ShutdownDevServer, Foreground),
327 (ReconnectDevServer, Foreground),
328 (ReconnectDevServerResponse, Foreground),
329 (ShareDevServerProject, Foreground),
330 (JoinDevServerProject, Foreground),
331 (RejoinRemoteProjects, Foreground),
332 (RejoinRemoteProjectsResponse, Foreground),
333 (MultiLspQuery, Background),
334 (MultiLspQueryResponse, Background),
335 (DevServerProjectsUpdate, Foreground),
336 (ValidateDevServerProjectRequest, Background),
337 (ListRemoteDirectory, Background),
338 (ListRemoteDirectoryResponse, Background),
339 (UpdateDevServerProject, Background),
340 (DeleteDevServer, Foreground),
341 (DeleteDevServerProject, Foreground),
342 (RegenerateDevServerToken, Foreground),
343 (RegenerateDevServerTokenResponse, Foreground),
344 (RenameDevServer, Foreground),
345 (OpenNewBuffer, Foreground),
346 (RestartLanguageServers, Foreground),
347 (LinkedEditingRange, Background),
348 (LinkedEditingRangeResponse, Background),
349 (AdvertiseContexts, Foreground),
350 (OpenContext, Foreground),
351 (OpenContextResponse, Foreground),
352 (CreateContext, Foreground),
353 (CreateContextResponse, Foreground),
354 (UpdateContext, Foreground),
355 (SynchronizeContexts, Foreground),
356 (SynchronizeContextsResponse, Foreground),
357 (LspExtSwitchSourceHeader, Background),
358 (LspExtSwitchSourceHeaderResponse, Background),
359 (AddWorktree, Foreground),
360 (AddWorktreeResponse, Foreground),
361 (FindSearchCandidates, Background),
362 (FindSearchCandidatesResponse, Background),
363 (CloseBuffer, Foreground),
364 (UpdateUserSettings, Foreground),
365 (CheckFileExists, Background),
366 (CheckFileExistsResponse, Background),
367 (ShutdownRemoteServer, Foreground),
368 (RemoveWorktree, Foreground),
369 (LanguageServerLog, Foreground),
370 (Toast, Background),
371 (HideToast, Background),
372 (OpenServerSettings, Foreground),
373 (GetPermalinkToLine, Foreground),
374 (GetPermalinkToLineResponse, Foreground),
375 (FlushBufferedMessages, Foreground),
376 (LanguageServerPromptRequest, Foreground),
377 (LanguageServerPromptResponse, Foreground),
378);
379
380request_messages!(
381 (AcceptTermsOfService, AcceptTermsOfServiceResponse),
382 (ApplyCodeAction, ApplyCodeActionResponse),
383 (
384 ApplyCompletionAdditionalEdits,
385 ApplyCompletionAdditionalEditsResponse
386 ),
387 (Call, Ack),
388 (CancelCall, Ack),
389 (CopyProjectEntry, ProjectEntryResponse),
390 (ComputeEmbeddings, ComputeEmbeddingsResponse),
391 (CreateChannel, CreateChannelResponse),
392 (CreateProjectEntry, ProjectEntryResponse),
393 (CreateRoom, CreateRoomResponse),
394 (DeclineCall, Ack),
395 (DeleteChannel, Ack),
396 (DeleteProjectEntry, ProjectEntryResponse),
397 (ExpandProjectEntry, ExpandProjectEntryResponse),
398 (Follow, FollowResponse),
399 (FormatBuffers, FormatBuffersResponse),
400 (FuzzySearchUsers, UsersResponse),
401 (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
402 (GetChannelMembers, GetChannelMembersResponse),
403 (GetChannelMessages, GetChannelMessagesResponse),
404 (GetChannelMessagesById, GetChannelMessagesResponse),
405 (GetCodeActions, GetCodeActionsResponse),
406 (GetCompletions, GetCompletionsResponse),
407 (GetDefinition, GetDefinitionResponse),
408 (GetDeclaration, GetDeclarationResponse),
409 (GetImplementation, GetImplementationResponse),
410 (GetDocumentHighlights, GetDocumentHighlightsResponse),
411 (GetHover, GetHoverResponse),
412 (GetLlmToken, GetLlmTokenResponse),
413 (GetNotifications, GetNotificationsResponse),
414 (GetPrivateUserInfo, GetPrivateUserInfoResponse),
415 (GetProjectSymbols, GetProjectSymbolsResponse),
416 (GetReferences, GetReferencesResponse),
417 (GetSignatureHelp, GetSignatureHelpResponse),
418 (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
419 (GetTypeDefinition, GetTypeDefinitionResponse),
420 (LinkedEditingRange, LinkedEditingRangeResponse),
421 (ListRemoteDirectory, ListRemoteDirectoryResponse),
422 (UpdateDevServerProject, Ack),
423 (GetUsers, UsersResponse),
424 (IncomingCall, Ack),
425 (InlayHints, InlayHintsResponse),
426 (InviteChannelMember, Ack),
427 (JoinChannel, JoinRoomResponse),
428 (JoinChannelBuffer, JoinChannelBufferResponse),
429 (JoinChannelChat, JoinChannelChatResponse),
430 (JoinHostedProject, JoinProjectResponse),
431 (JoinProject, JoinProjectResponse),
432 (JoinRoom, JoinRoomResponse),
433 (LeaveChannelBuffer, Ack),
434 (LeaveRoom, Ack),
435 (MarkNotificationRead, Ack),
436 (MoveChannel, Ack),
437 (OnTypeFormatting, OnTypeFormattingResponse),
438 (OpenBufferById, OpenBufferResponse),
439 (OpenBufferByPath, OpenBufferResponse),
440 (OpenBufferForSymbol, OpenBufferForSymbolResponse),
441 (OpenNewBuffer, OpenBufferResponse),
442 (PerformRename, PerformRenameResponse),
443 (Ping, Ack),
444 (PrepareRename, PrepareRenameResponse),
445 (CountLanguageModelTokens, CountLanguageModelTokensResponse),
446 (RefreshInlayHints, Ack),
447 (RejoinChannelBuffers, RejoinChannelBuffersResponse),
448 (RejoinRoom, RejoinRoomResponse),
449 (ReloadBuffers, ReloadBuffersResponse),
450 (RemoveChannelMember, Ack),
451 (RemoveChannelMessage, Ack),
452 (UpdateChannelMessage, Ack),
453 (RemoveContact, Ack),
454 (RenameChannel, RenameChannelResponse),
455 (RenameProjectEntry, ProjectEntryResponse),
456 (RequestContact, Ack),
457 (
458 ResolveCompletionDocumentation,
459 ResolveCompletionDocumentationResponse
460 ),
461 (ResolveInlayHint, ResolveInlayHintResponse),
462 (RespondToChannelInvite, Ack),
463 (RespondToContactRequest, Ack),
464 (SaveBuffer, BufferSaved),
465 (FindSearchCandidates, FindSearchCandidatesResponse),
466 (SendChannelMessage, SendChannelMessageResponse),
467 (SetChannelMemberRole, Ack),
468 (SetChannelVisibility, Ack),
469 (ShareProject, ShareProjectResponse),
470 (SynchronizeBuffers, SynchronizeBuffersResponse),
471 (TaskContextForLocation, TaskContext),
472 (Test, Test),
473 (UpdateBuffer, Ack),
474 (UpdateParticipantLocation, Ack),
475 (UpdateProject, Ack),
476 (UpdateWorktree, Ack),
477 (LspExtExpandMacro, LspExtExpandMacroResponse),
478 (SetRoomParticipantRole, Ack),
479 (BlameBuffer, BlameBufferResponse),
480 (CreateDevServerProject, CreateDevServerProjectResponse),
481 (CreateDevServer, CreateDevServerResponse),
482 (ShutdownDevServer, Ack),
483 (ShareDevServerProject, ShareProjectResponse),
484 (JoinDevServerProject, JoinProjectResponse),
485 (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
486 (ReconnectDevServer, ReconnectDevServerResponse),
487 (ValidateDevServerProjectRequest, Ack),
488 (MultiLspQuery, MultiLspQueryResponse),
489 (DeleteDevServer, Ack),
490 (DeleteDevServerProject, Ack),
491 (RegenerateDevServerToken, RegenerateDevServerTokenResponse),
492 (RenameDevServer, Ack),
493 (RestartLanguageServers, Ack),
494 (OpenContext, OpenContextResponse),
495 (CreateContext, CreateContextResponse),
496 (SynchronizeContexts, SynchronizeContextsResponse),
497 (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
498 (AddWorktree, AddWorktreeResponse),
499 (CheckFileExists, CheckFileExistsResponse),
500 (ShutdownRemoteServer, Ack),
501 (RemoveWorktree, Ack),
502 (OpenServerSettings, OpenBufferResponse),
503 (GetPermalinkToLine, GetPermalinkToLineResponse),
504 (FlushBufferedMessages, Ack),
505 (LanguageServerPromptRequest, LanguageServerPromptResponse),
506);
507
508entity_messages!(
509 {project_id, ShareProject},
510 AddProjectCollaborator,
511 AddWorktree,
512 ApplyCodeAction,
513 ApplyCompletionAdditionalEdits,
514 BlameBuffer,
515 BufferReloaded,
516 BufferSaved,
517 CloseBuffer,
518 CopyProjectEntry,
519 CreateBufferForPeer,
520 CreateProjectEntry,
521 DeleteProjectEntry,
522 ExpandProjectEntry,
523 FindSearchCandidates,
524 FormatBuffers,
525 GetCodeActions,
526 GetCompletions,
527 GetDefinition,
528 GetDeclaration,
529 GetImplementation,
530 GetDocumentHighlights,
531 GetHover,
532 GetProjectSymbols,
533 GetReferences,
534 GetSignatureHelp,
535 GetTypeDefinition,
536 InlayHints,
537 JoinProject,
538 LeaveProject,
539 LinkedEditingRange,
540 MultiLspQuery,
541 RestartLanguageServers,
542 OnTypeFormatting,
543 OpenNewBuffer,
544 OpenBufferById,
545 OpenBufferByPath,
546 OpenBufferForSymbol,
547 PerformRename,
548 PrepareRename,
549 RefreshInlayHints,
550 ReloadBuffers,
551 RemoveProjectCollaborator,
552 RenameProjectEntry,
553 ResolveCompletionDocumentation,
554 ResolveInlayHint,
555 SaveBuffer,
556 StartLanguageServer,
557 SynchronizeBuffers,
558 TaskContextForLocation,
559 UnshareProject,
560 UpdateBuffer,
561 UpdateBufferFile,
562 UpdateDiagnosticSummary,
563 UpdateDiffBase,
564 UpdateLanguageServer,
565 UpdateProject,
566 UpdateProjectCollaborator,
567 UpdateWorktree,
568 UpdateWorktreeSettings,
569 LspExtExpandMacro,
570 AdvertiseContexts,
571 OpenContext,
572 CreateContext,
573 UpdateContext,
574 SynchronizeContexts,
575 LspExtSwitchSourceHeader,
576 UpdateUserSettings,
577 CheckFileExists,
578 LanguageServerLog,
579 Toast,
580 HideToast,
581 OpenServerSettings,
582 GetPermalinkToLine,
583 LanguageServerPromptRequest
584);
585
586entity_messages!(
587 {channel_id, Channel},
588 ChannelMessageSent,
589 ChannelMessageUpdate,
590 RemoveChannelMessage,
591 UpdateChannelMessage,
592 UpdateChannelBuffer,
593 UpdateChannelBufferCollaborators,
594);
595
596impl From<Timestamp> for SystemTime {
597 fn from(val: Timestamp) -> Self {
598 UNIX_EPOCH
599 .checked_add(Duration::new(val.seconds, val.nanos))
600 .unwrap()
601 }
602}
603
604impl From<SystemTime> for Timestamp {
605 fn from(time: SystemTime) -> Self {
606 let duration = time.duration_since(UNIX_EPOCH).unwrap();
607 Self {
608 seconds: duration.as_secs(),
609 nanos: duration.subsec_nanos(),
610 }
611 }
612}
613
614impl From<u128> for Nonce {
615 fn from(nonce: u128) -> Self {
616 let upper_half = (nonce >> 64) as u64;
617 let lower_half = nonce as u64;
618 Self {
619 upper_half,
620 lower_half,
621 }
622 }
623}
624
625impl From<Nonce> for u128 {
626 fn from(nonce: Nonce) -> Self {
627 let upper_half = (nonce.upper_half as u128) << 64;
628 let lower_half = nonce.lower_half as u128;
629 upper_half | lower_half
630 }
631}
632
633pub fn split_worktree_update(
634 mut message: UpdateWorktree,
635 max_chunk_size: usize,
636) -> impl Iterator<Item = UpdateWorktree> {
637 let mut done_files = false;
638
639 let mut repository_map = message
640 .updated_repositories
641 .into_iter()
642 .map(|repo| (repo.work_directory_id, repo))
643 .collect::<HashMap<_, _>>();
644
645 iter::from_fn(move || {
646 if done_files {
647 return None;
648 }
649
650 let updated_entries_chunk_size = cmp::min(message.updated_entries.len(), max_chunk_size);
651 let updated_entries: Vec<_> = message
652 .updated_entries
653 .drain(..updated_entries_chunk_size)
654 .collect();
655
656 let removed_entries_chunk_size = cmp::min(message.removed_entries.len(), max_chunk_size);
657 let removed_entries = message
658 .removed_entries
659 .drain(..removed_entries_chunk_size)
660 .collect();
661
662 done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
663
664 let mut updated_repositories = Vec::new();
665
666 if !repository_map.is_empty() {
667 for entry in &updated_entries {
668 if let Some(repo) = repository_map.remove(&entry.id) {
669 updated_repositories.push(repo)
670 }
671 }
672 }
673
674 let removed_repositories = if done_files {
675 mem::take(&mut message.removed_repositories)
676 } else {
677 Default::default()
678 };
679
680 if done_files {
681 updated_repositories.extend(mem::take(&mut repository_map).into_values());
682 }
683
684 Some(UpdateWorktree {
685 project_id: message.project_id,
686 worktree_id: message.worktree_id,
687 root_name: message.root_name.clone(),
688 abs_path: message.abs_path.clone(),
689 updated_entries,
690 removed_entries,
691 scan_id: message.scan_id,
692 is_last_update: done_files && message.is_last_update,
693 updated_repositories,
694 removed_repositories,
695 })
696 })
697}
698
699#[cfg(test)]
700mod tests {
701 use super::*;
702
703 #[test]
704 fn test_converting_peer_id_from_and_to_u64() {
705 let peer_id = PeerId {
706 owner_id: 10,
707 id: 3,
708 };
709 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
710 let peer_id = PeerId {
711 owner_id: u32::MAX,
712 id: 3,
713 };
714 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
715 let peer_id = PeerId {
716 owner_id: 10,
717 id: u32::MAX,
718 };
719 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
720 let peer_id = PeerId {
721 owner_id: u32::MAX,
722 id: u32::MAX,
723 };
724 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
725 }
726}