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 (RefreshInlayHints, Foreground),
257 (RejoinChannelBuffers, Foreground),
258 (RejoinChannelBuffersResponse, Foreground),
259 (RejoinRoom, Foreground),
260 (RejoinRoomResponse, Foreground),
261 (ReloadBuffers, Foreground),
262 (ReloadBuffersResponse, Foreground),
263 (RemoveChannelMember, Foreground),
264 (RemoveChannelMessage, Foreground),
265 (UpdateChannelMessage, Foreground),
266 (RemoveContact, Foreground),
267 (RemoveProjectCollaborator, Foreground),
268 (RenameChannel, Foreground),
269 (RenameChannelResponse, Foreground),
270 (RenameProjectEntry, Foreground),
271 (RequestContact, Foreground),
272 (ResolveCompletionDocumentation, Background),
273 (ResolveCompletionDocumentationResponse, Background),
274 (ResolveInlayHint, Background),
275 (ResolveInlayHintResponse, Background),
276 (RespondToChannelInvite, Foreground),
277 (RespondToContactRequest, Foreground),
278 (RoomUpdated, Foreground),
279 (SaveBuffer, Foreground),
280 (SetChannelMemberRole, Foreground),
281 (SetChannelVisibility, Foreground),
282 (SearchProject, Background),
283 (SearchProjectResponse, Background),
284 (SendChannelMessage, Background),
285 (SendChannelMessageResponse, Background),
286 (ShareProject, Foreground),
287 (ShareProjectResponse, Foreground),
288 (ShowContacts, Foreground),
289 (StartLanguageServer, Foreground),
290 (SubscribeToChannels, Foreground),
291 (SynchronizeBuffers, Foreground),
292 (SynchronizeBuffersResponse, Foreground),
293 (TaskContextForLocation, Background),
294 (TaskContext, Background),
295 (TaskTemplates, Background),
296 (TaskTemplatesResponse, Background),
297 (Test, Foreground),
298 (Unfollow, Foreground),
299 (UnshareProject, Foreground),
300 (UpdateBuffer, Foreground),
301 (UpdateBufferFile, Foreground),
302 (UpdateChannelBuffer, Foreground),
303 (UpdateChannelBufferCollaborators, Foreground),
304 (UpdateChannels, Foreground),
305 (UpdateUserChannels, Foreground),
306 (UpdateContacts, Foreground),
307 (UpdateDiagnosticSummary, Foreground),
308 (UpdateDiffBase, Foreground),
309 (UpdateFollowers, Foreground),
310 (UpdateInviteInfo, Foreground),
311 (UpdateLanguageServer, Foreground),
312 (UpdateParticipantLocation, Foreground),
313 (UpdateProject, Foreground),
314 (UpdateProjectCollaborator, Foreground),
315 (UpdateUserPlan, Foreground),
316 (UpdateWorktree, Foreground),
317 (UpdateWorktreeSettings, Foreground),
318 (UsersResponse, Foreground),
319 (LspExtExpandMacro, Background),
320 (LspExtExpandMacroResponse, Background),
321 (SetRoomParticipantRole, Foreground),
322 (BlameBuffer, Foreground),
323 (BlameBufferResponse, Foreground),
324 (CreateDevServerProject, Background),
325 (CreateDevServerProjectResponse, Foreground),
326 (CreateDevServer, Foreground),
327 (CreateDevServerResponse, Foreground),
328 (DevServerInstructions, Foreground),
329 (ShutdownDevServer, Foreground),
330 (ReconnectDevServer, Foreground),
331 (ReconnectDevServerResponse, Foreground),
332 (ShareDevServerProject, Foreground),
333 (JoinDevServerProject, Foreground),
334 (RejoinRemoteProjects, Foreground),
335 (RejoinRemoteProjectsResponse, Foreground),
336 (MultiLspQuery, Background),
337 (MultiLspQueryResponse, Background),
338 (DevServerProjectsUpdate, Foreground),
339 (ValidateDevServerProjectRequest, Background),
340 (ListRemoteDirectory, Background),
341 (ListRemoteDirectoryResponse, Background),
342 (UpdateDevServerProject, Background),
343 (DeleteDevServer, Foreground),
344 (DeleteDevServerProject, Foreground),
345 (RegenerateDevServerToken, Foreground),
346 (RegenerateDevServerTokenResponse, Foreground),
347 (RenameDevServer, Foreground),
348 (OpenNewBuffer, Foreground),
349 (RestartLanguageServers, Foreground),
350 (LinkedEditingRange, Background),
351 (LinkedEditingRangeResponse, Background),
352 (AdvertiseContexts, Foreground),
353 (OpenContext, Foreground),
354 (OpenContextResponse, Foreground),
355 (CreateContext, Foreground),
356 (CreateContextResponse, Foreground),
357 (UpdateContext, Foreground),
358 (SynchronizeContexts, Foreground),
359 (SynchronizeContextsResponse, Foreground),
360 (LspExtSwitchSourceHeader, Background),
361 (LspExtSwitchSourceHeaderResponse, Background),
362 (AddWorktree, Foreground),
363 (AddWorktreeResponse, Foreground),
364 (FindSearchCandidates, Background),
365 (FindSearchCandidatesResponse, Background),
366 (CloseBuffer, Foreground),
367 (UpdateUserSettings, Foreground),
368 (CreateLanguageServer, Foreground),
369 (WhichCommand, Foreground),
370 (WhichCommandResponse, Foreground),
371 (ShellEnv, Foreground),
372 (ShellEnvResponse, Foreground),
373 (TryExec, Foreground),
374 (ReadTextFile, Foreground),
375 (ReadTextFileResponse, Foreground),
376 (CheckFileExists, Background),
377 (CheckFileExistsResponse, Background)
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 (SearchProject, SearchProjectResponse),
466 (FindSearchCandidates, FindSearchCandidatesResponse),
467 (SendChannelMessage, SendChannelMessageResponse),
468 (SetChannelMemberRole, Ack),
469 (SetChannelVisibility, Ack),
470 (ShareProject, ShareProjectResponse),
471 (SynchronizeBuffers, SynchronizeBuffersResponse),
472 (TaskContextForLocation, TaskContext),
473 (TaskTemplates, TaskTemplatesResponse),
474 (Test, Test),
475 (UpdateBuffer, Ack),
476 (UpdateParticipantLocation, Ack),
477 (UpdateProject, Ack),
478 (UpdateWorktree, Ack),
479 (LspExtExpandMacro, LspExtExpandMacroResponse),
480 (SetRoomParticipantRole, Ack),
481 (BlameBuffer, BlameBufferResponse),
482 (CreateDevServerProject, CreateDevServerProjectResponse),
483 (CreateDevServer, CreateDevServerResponse),
484 (ShutdownDevServer, Ack),
485 (ShareDevServerProject, ShareProjectResponse),
486 (JoinDevServerProject, JoinProjectResponse),
487 (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
488 (ReconnectDevServer, ReconnectDevServerResponse),
489 (ValidateDevServerProjectRequest, Ack),
490 (MultiLspQuery, MultiLspQueryResponse),
491 (DeleteDevServer, Ack),
492 (DeleteDevServerProject, Ack),
493 (RegenerateDevServerToken, RegenerateDevServerTokenResponse),
494 (RenameDevServer, Ack),
495 (RestartLanguageServers, Ack),
496 (OpenContext, OpenContextResponse),
497 (CreateContext, CreateContextResponse),
498 (SynchronizeContexts, SynchronizeContextsResponse),
499 (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
500 (AddWorktree, AddWorktreeResponse),
501 (CreateLanguageServer, Ack),
502 (WhichCommand, WhichCommandResponse),
503 (ShellEnv, ShellEnvResponse),
504 (ReadTextFile, ReadTextFileResponse),
505 (TryExec, Ack),
506 (CheckFileExists, CheckFileExistsResponse)
507);
508
509entity_messages!(
510 {project_id, ShareProject},
511 AddProjectCollaborator,
512 AddWorktree,
513 ApplyCodeAction,
514 ApplyCompletionAdditionalEdits,
515 BlameBuffer,
516 BufferReloaded,
517 BufferSaved,
518 CloseBuffer,
519 CopyProjectEntry,
520 CreateBufferForPeer,
521 CreateProjectEntry,
522 DeleteProjectEntry,
523 ExpandProjectEntry,
524 FindSearchCandidates,
525 FormatBuffers,
526 GetCodeActions,
527 GetCompletions,
528 GetDefinition,
529 GetDeclaration,
530 GetImplementation,
531 GetDocumentHighlights,
532 GetHover,
533 GetProjectSymbols,
534 GetReferences,
535 GetSignatureHelp,
536 GetTypeDefinition,
537 InlayHints,
538 JoinProject,
539 LeaveProject,
540 LinkedEditingRange,
541 MultiLspQuery,
542 RestartLanguageServers,
543 OnTypeFormatting,
544 OpenNewBuffer,
545 OpenBufferById,
546 OpenBufferByPath,
547 OpenBufferForSymbol,
548 PerformRename,
549 PrepareRename,
550 RefreshInlayHints,
551 ReloadBuffers,
552 RemoveProjectCollaborator,
553 RenameProjectEntry,
554 ResolveCompletionDocumentation,
555 ResolveInlayHint,
556 SaveBuffer,
557 SearchProject,
558 StartLanguageServer,
559 SynchronizeBuffers,
560 TaskContextForLocation,
561 TaskTemplates,
562 UnshareProject,
563 UpdateBuffer,
564 UpdateBufferFile,
565 UpdateDiagnosticSummary,
566 UpdateDiffBase,
567 UpdateLanguageServer,
568 UpdateProject,
569 UpdateProjectCollaborator,
570 UpdateWorktree,
571 UpdateWorktreeSettings,
572 LspExtExpandMacro,
573 AdvertiseContexts,
574 OpenContext,
575 CreateContext,
576 UpdateContext,
577 SynchronizeContexts,
578 LspExtSwitchSourceHeader,
579 UpdateUserSettings,
580 CreateLanguageServer,
581 WhichCommand,
582 ShellEnv,
583 TryExec,
584 ReadTextFile,
585 CheckFileExists,
586);
587
588entity_messages!(
589 {channel_id, Channel},
590 ChannelMessageSent,
591 ChannelMessageUpdate,
592 RemoveChannelMessage,
593 UpdateChannelMessage,
594 UpdateChannelBuffer,
595 UpdateChannelBufferCollaborators,
596);
597
598impl From<Timestamp> for SystemTime {
599 fn from(val: Timestamp) -> Self {
600 UNIX_EPOCH
601 .checked_add(Duration::new(val.seconds, val.nanos))
602 .unwrap()
603 }
604}
605
606impl From<SystemTime> for Timestamp {
607 fn from(time: SystemTime) -> Self {
608 let duration = time.duration_since(UNIX_EPOCH).unwrap();
609 Self {
610 seconds: duration.as_secs(),
611 nanos: duration.subsec_nanos(),
612 }
613 }
614}
615
616impl From<u128> for Nonce {
617 fn from(nonce: u128) -> Self {
618 let upper_half = (nonce >> 64) as u64;
619 let lower_half = nonce as u64;
620 Self {
621 upper_half,
622 lower_half,
623 }
624 }
625}
626
627impl From<Nonce> for u128 {
628 fn from(nonce: Nonce) -> Self {
629 let upper_half = (nonce.upper_half as u128) << 64;
630 let lower_half = nonce.lower_half as u128;
631 upper_half | lower_half
632 }
633}
634
635pub fn split_worktree_update(
636 mut message: UpdateWorktree,
637 max_chunk_size: usize,
638) -> impl Iterator<Item = UpdateWorktree> {
639 let mut done_files = false;
640
641 let mut repository_map = message
642 .updated_repositories
643 .into_iter()
644 .map(|repo| (repo.work_directory_id, repo))
645 .collect::<HashMap<_, _>>();
646
647 iter::from_fn(move || {
648 if done_files {
649 return None;
650 }
651
652 let updated_entries_chunk_size = cmp::min(message.updated_entries.len(), max_chunk_size);
653 let updated_entries: Vec<_> = message
654 .updated_entries
655 .drain(..updated_entries_chunk_size)
656 .collect();
657
658 let removed_entries_chunk_size = cmp::min(message.removed_entries.len(), max_chunk_size);
659 let removed_entries = message
660 .removed_entries
661 .drain(..removed_entries_chunk_size)
662 .collect();
663
664 done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
665
666 let mut updated_repositories = Vec::new();
667
668 if !repository_map.is_empty() {
669 for entry in &updated_entries {
670 if let Some(repo) = repository_map.remove(&entry.id) {
671 updated_repositories.push(repo)
672 }
673 }
674 }
675
676 let removed_repositories = if done_files {
677 mem::take(&mut message.removed_repositories)
678 } else {
679 Default::default()
680 };
681
682 if done_files {
683 updated_repositories.extend(mem::take(&mut repository_map).into_values());
684 }
685
686 Some(UpdateWorktree {
687 project_id: message.project_id,
688 worktree_id: message.worktree_id,
689 root_name: message.root_name.clone(),
690 abs_path: message.abs_path.clone(),
691 updated_entries,
692 removed_entries,
693 scan_id: message.scan_id,
694 is_last_update: done_files && message.is_last_update,
695 updated_repositories,
696 removed_repositories,
697 })
698 })
699}
700
701#[cfg(test)]
702mod tests {
703 use super::*;
704
705 #[test]
706 fn test_converting_peer_id_from_and_to_u64() {
707 let peer_id = PeerId {
708 owner_id: 10,
709 id: 3,
710 };
711 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
712 let peer_id = PeerId {
713 owner_id: u32::MAX,
714 id: 3,
715 };
716 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
717 let peer_id = PeerId {
718 owner_id: 10,
719 id: u32::MAX,
720 };
721 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
722 let peer_id = PeerId {
723 owner_id: u32::MAX,
724 id: u32::MAX,
725 };
726 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
727 }
728}