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 (Commit, Background),
160 (ComputeEmbeddings, Background),
161 (ComputeEmbeddingsResponse, Background),
162 (CopyProjectEntry, Foreground),
163 (CreateBufferForPeer, Foreground),
164 (CreateChannel, Foreground),
165 (CreateChannelResponse, Foreground),
166 (CreateProjectEntry, Foreground),
167 (CreateRoom, Foreground),
168 (CreateRoomResponse, Foreground),
169 (DeclineCall, Foreground),
170 (DeleteChannel, Foreground),
171 (DeleteNotification, Foreground),
172 (UpdateNotification, Foreground),
173 (DeleteProjectEntry, Foreground),
174 (EndStream, Foreground),
175 (Error, Foreground),
176 (ExpandProjectEntry, Foreground),
177 (ExpandProjectEntryResponse, Foreground),
178 (ExpandAllForProjectEntry, Foreground),
179 (ExpandAllForProjectEntryResponse, Foreground),
180 (Follow, Foreground),
181 (FollowResponse, Foreground),
182 (FormatBuffers, Foreground),
183 (FormatBuffersResponse, Foreground),
184 (FuzzySearchUsers, Foreground),
185 (GetCachedEmbeddings, Background),
186 (GetCachedEmbeddingsResponse, Background),
187 (GetChannelMembers, Foreground),
188 (GetChannelMembersResponse, Foreground),
189 (GetChannelMessages, Background),
190 (GetChannelMessagesById, Background),
191 (GetChannelMessagesResponse, Background),
192 (GetCodeActions, Background),
193 (GetCodeActionsResponse, Background),
194 (GetCompletions, Background),
195 (GetCompletionsResponse, Background),
196 (GetDefinition, Background),
197 (GetDefinitionResponse, Background),
198 (GetDeclaration, Background),
199 (GetDeclarationResponse, Background),
200 (GetDocumentHighlights, Background),
201 (GetDocumentHighlightsResponse, Background),
202 (GetHover, Background),
203 (GetHoverResponse, Background),
204 (GetNotifications, Foreground),
205 (GetNotificationsResponse, Foreground),
206 (GetPrivateUserInfo, Foreground),
207 (GetPrivateUserInfoResponse, Foreground),
208 (GetProjectSymbols, Background),
209 (GetProjectSymbolsResponse, Background),
210 (GetReferences, Background),
211 (GetReferencesResponse, Background),
212 (GetSignatureHelp, Background),
213 (GetSignatureHelpResponse, Background),
214 (GetSupermavenApiKey, Background),
215 (GetSupermavenApiKeyResponse, Background),
216 (GetTypeDefinition, Background),
217 (GetTypeDefinitionResponse, Background),
218 (GetImplementation, Background),
219 (GetImplementationResponse, Background),
220 (GetLlmToken, Background),
221 (GetLlmTokenResponse, Background),
222 (GetStagedText, Foreground),
223 (GetStagedTextResponse, Foreground),
224 (GetUsers, Foreground),
225 (Hello, Foreground),
226 (IncomingCall, Foreground),
227 (InlayHints, Background),
228 (InlayHintsResponse, Background),
229 (InviteChannelMember, Foreground),
230 (JoinChannel, Foreground),
231 (JoinChannelBuffer, Foreground),
232 (JoinChannelBufferResponse, Foreground),
233 (JoinChannelChat, Foreground),
234 (JoinChannelChatResponse, Foreground),
235 (JoinProject, Foreground),
236 (JoinProjectResponse, Foreground),
237 (JoinRoom, Foreground),
238 (JoinRoomResponse, Foreground),
239 (LeaveChannelBuffer, Background),
240 (LeaveChannelChat, Foreground),
241 (LeaveProject, Foreground),
242 (LeaveRoom, Foreground),
243 (MarkNotificationRead, Foreground),
244 (MoveChannel, Foreground),
245 (OnTypeFormatting, Background),
246 (OnTypeFormattingResponse, Background),
247 (OpenBufferById, Background),
248 (OpenBufferByPath, Background),
249 (OpenBufferForSymbol, Background),
250 (OpenBufferForSymbolResponse, Background),
251 (OpenBufferResponse, Background),
252 (PerformRename, Background),
253 (PerformRenameResponse, Background),
254 (Ping, Foreground),
255 (PrepareRename, Background),
256 (PrepareRenameResponse, Background),
257 (ProjectEntryResponse, Foreground),
258 (CountLanguageModelTokens, Background),
259 (CountLanguageModelTokensResponse, Background),
260 (RefreshLlmToken, Background),
261 (RefreshInlayHints, Foreground),
262 (RejoinChannelBuffers, Foreground),
263 (RejoinChannelBuffersResponse, Foreground),
264 (RejoinRoom, Foreground),
265 (RejoinRoomResponse, Foreground),
266 (ReloadBuffers, Foreground),
267 (ReloadBuffersResponse, Foreground),
268 (RemoveChannelMember, Foreground),
269 (RemoveChannelMessage, Foreground),
270 (UpdateChannelMessage, Foreground),
271 (RemoveContact, Foreground),
272 (RemoveProjectCollaborator, Foreground),
273 (RenameChannel, Foreground),
274 (RenameChannelResponse, Foreground),
275 (RenameProjectEntry, Foreground),
276 (RequestContact, Foreground),
277 (ResolveCompletionDocumentation, Background),
278 (ResolveCompletionDocumentationResponse, Background),
279 (ResolveInlayHint, Background),
280 (ResolveInlayHintResponse, Background),
281 (RespondToChannelInvite, Foreground),
282 (RespondToContactRequest, Foreground),
283 (RoomUpdated, Foreground),
284 (SaveBuffer, Foreground),
285 (SetChannelMemberRole, Foreground),
286 (SetChannelVisibility, Foreground),
287 (SendChannelMessage, Background),
288 (SendChannelMessageResponse, Background),
289 (ShareProject, Foreground),
290 (ShareProjectResponse, Foreground),
291 (ShowContacts, Foreground),
292 (Stage, Background),
293 (StartLanguageServer, Foreground),
294 (SubscribeToChannels, Foreground),
295 (SynchronizeBuffers, Foreground),
296 (SynchronizeBuffersResponse, Foreground),
297 (TaskContextForLocation, Background),
298 (TaskContext, Background),
299 (Test, Foreground),
300 (Unfollow, Foreground),
301 (UnshareProject, Foreground),
302 (Unstage, Background),
303 (UpdateBuffer, Foreground),
304 (UpdateBufferFile, Foreground),
305 (UpdateChannelBuffer, Foreground),
306 (UpdateChannelBufferCollaborators, Foreground),
307 (UpdateChannels, Foreground),
308 (UpdateUserChannels, Foreground),
309 (UpdateContacts, Foreground),
310 (UpdateDiagnosticSummary, Foreground),
311 (UpdateDiffBase, Foreground),
312 (UpdateFollowers, Foreground),
313 (UpdateInviteInfo, Foreground),
314 (UpdateLanguageServer, Foreground),
315 (UpdateParticipantLocation, Foreground),
316 (UpdateProject, Foreground),
317 (UpdateProjectCollaborator, Foreground),
318 (UpdateUserPlan, Foreground),
319 (UpdateWorktree, Foreground),
320 (UpdateWorktreeSettings, Foreground),
321 (UsersResponse, Foreground),
322 (LspExtExpandMacro, Background),
323 (LspExtExpandMacroResponse, Background),
324 (LspExtOpenDocs, Background),
325 (LspExtOpenDocsResponse, Background),
326 (SetRoomParticipantRole, Foreground),
327 (BlameBuffer, Foreground),
328 (BlameBufferResponse, Foreground),
329 (RejoinRemoteProjects, Foreground),
330 (RejoinRemoteProjectsResponse, Foreground),
331 (MultiLspQuery, Background),
332 (MultiLspQueryResponse, Background),
333 (ListRemoteDirectory, Background),
334 (ListRemoteDirectoryResponse, Background),
335 (OpenNewBuffer, Foreground),
336 (RestartLanguageServers, Foreground),
337 (LinkedEditingRange, Background),
338 (LinkedEditingRangeResponse, Background),
339 (AdvertiseContexts, Foreground),
340 (OpenContext, Foreground),
341 (OpenContextResponse, Foreground),
342 (CreateContext, Foreground),
343 (CreateContextResponse, Foreground),
344 (UpdateContext, Foreground),
345 (SynchronizeContexts, Foreground),
346 (SynchronizeContextsResponse, Foreground),
347 (LspExtSwitchSourceHeader, Background),
348 (LspExtSwitchSourceHeaderResponse, Background),
349 (AddWorktree, Foreground),
350 (AddWorktreeResponse, Foreground),
351 (FindSearchCandidates, Background),
352 (FindSearchCandidatesResponse, Background),
353 (CloseBuffer, Foreground),
354 (ShutdownRemoteServer, Foreground),
355 (RemoveWorktree, Foreground),
356 (LanguageServerLog, Foreground),
357 (Toast, Background),
358 (HideToast, Background),
359 (OpenServerSettings, Foreground),
360 (GetPermalinkToLine, Foreground),
361 (GetPermalinkToLineResponse, Foreground),
362 (FlushBufferedMessages, Foreground),
363 (LanguageServerPromptRequest, Foreground),
364 (LanguageServerPromptResponse, Foreground),
365 (GitBranches, Background),
366 (GitBranchesResponse, Background),
367 (UpdateGitBranch, Background),
368 (ListToolchains, Foreground),
369 (ListToolchainsResponse, Foreground),
370 (ActivateToolchain, Foreground),
371 (ActiveToolchain, Foreground),
372 (ActiveToolchainResponse, Foreground),
373 (GetPathMetadata, Background),
374 (GetPathMetadataResponse, Background),
375 (GetPanicFiles, Background),
376 (GetPanicFilesResponse, Background),
377 (CancelLanguageServerWork, Foreground),
378 (SyncExtensions, Background),
379 (SyncExtensionsResponse, Background),
380 (InstallExtension, Background),
381 (RegisterBufferWithLanguageServers, Background),
382);
383
384request_messages!(
385 (AcceptTermsOfService, AcceptTermsOfServiceResponse),
386 (ApplyCodeAction, ApplyCodeActionResponse),
387 (
388 ApplyCompletionAdditionalEdits,
389 ApplyCompletionAdditionalEditsResponse
390 ),
391 (Call, Ack),
392 (CancelCall, Ack),
393 (Commit, Ack),
394 (CopyProjectEntry, ProjectEntryResponse),
395 (ComputeEmbeddings, ComputeEmbeddingsResponse),
396 (CreateChannel, CreateChannelResponse),
397 (CreateProjectEntry, ProjectEntryResponse),
398 (CreateRoom, CreateRoomResponse),
399 (DeclineCall, Ack),
400 (DeleteChannel, Ack),
401 (DeleteProjectEntry, ProjectEntryResponse),
402 (ExpandProjectEntry, ExpandProjectEntryResponse),
403 (ExpandAllForProjectEntry, ExpandAllForProjectEntryResponse),
404 (Follow, FollowResponse),
405 (FormatBuffers, FormatBuffersResponse),
406 (FuzzySearchUsers, UsersResponse),
407 (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
408 (GetChannelMembers, GetChannelMembersResponse),
409 (GetChannelMessages, GetChannelMessagesResponse),
410 (GetChannelMessagesById, GetChannelMessagesResponse),
411 (GetCodeActions, GetCodeActionsResponse),
412 (GetCompletions, GetCompletionsResponse),
413 (GetDefinition, GetDefinitionResponse),
414 (GetDeclaration, GetDeclarationResponse),
415 (GetImplementation, GetImplementationResponse),
416 (GetDocumentHighlights, GetDocumentHighlightsResponse),
417 (GetHover, GetHoverResponse),
418 (GetLlmToken, GetLlmTokenResponse),
419 (GetNotifications, GetNotificationsResponse),
420 (GetPrivateUserInfo, GetPrivateUserInfoResponse),
421 (GetProjectSymbols, GetProjectSymbolsResponse),
422 (GetReferences, GetReferencesResponse),
423 (GetSignatureHelp, GetSignatureHelpResponse),
424 (GetStagedText, GetStagedTextResponse),
425 (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
426 (GetTypeDefinition, GetTypeDefinitionResponse),
427 (LinkedEditingRange, LinkedEditingRangeResponse),
428 (ListRemoteDirectory, ListRemoteDirectoryResponse),
429 (GetUsers, UsersResponse),
430 (IncomingCall, Ack),
431 (InlayHints, InlayHintsResponse),
432 (InviteChannelMember, Ack),
433 (JoinChannel, JoinRoomResponse),
434 (JoinChannelBuffer, JoinChannelBufferResponse),
435 (JoinChannelChat, JoinChannelChatResponse),
436 (JoinProject, JoinProjectResponse),
437 (JoinRoom, JoinRoomResponse),
438 (LeaveChannelBuffer, Ack),
439 (LeaveRoom, Ack),
440 (MarkNotificationRead, Ack),
441 (MoveChannel, Ack),
442 (OnTypeFormatting, OnTypeFormattingResponse),
443 (OpenBufferById, OpenBufferResponse),
444 (OpenBufferByPath, OpenBufferResponse),
445 (OpenBufferForSymbol, OpenBufferForSymbolResponse),
446 (OpenNewBuffer, OpenBufferResponse),
447 (PerformRename, PerformRenameResponse),
448 (Ping, Ack),
449 (PrepareRename, PrepareRenameResponse),
450 (CountLanguageModelTokens, CountLanguageModelTokensResponse),
451 (RefreshInlayHints, Ack),
452 (RejoinChannelBuffers, RejoinChannelBuffersResponse),
453 (RejoinRoom, RejoinRoomResponse),
454 (ReloadBuffers, ReloadBuffersResponse),
455 (RemoveChannelMember, Ack),
456 (RemoveChannelMessage, Ack),
457 (UpdateChannelMessage, Ack),
458 (RemoveContact, Ack),
459 (RenameChannel, RenameChannelResponse),
460 (RenameProjectEntry, ProjectEntryResponse),
461 (RequestContact, Ack),
462 (
463 ResolveCompletionDocumentation,
464 ResolveCompletionDocumentationResponse
465 ),
466 (ResolveInlayHint, ResolveInlayHintResponse),
467 (RespondToChannelInvite, Ack),
468 (RespondToContactRequest, Ack),
469 (SaveBuffer, BufferSaved),
470 (Stage, Ack),
471 (FindSearchCandidates, FindSearchCandidatesResponse),
472 (SendChannelMessage, SendChannelMessageResponse),
473 (SetChannelMemberRole, Ack),
474 (SetChannelVisibility, Ack),
475 (ShareProject, ShareProjectResponse),
476 (SynchronizeBuffers, SynchronizeBuffersResponse),
477 (TaskContextForLocation, TaskContext),
478 (Test, Test),
479 (Unstage, Ack),
480 (UpdateBuffer, Ack),
481 (UpdateParticipantLocation, Ack),
482 (UpdateProject, Ack),
483 (UpdateWorktree, Ack),
484 (LspExtExpandMacro, LspExtExpandMacroResponse),
485 (LspExtOpenDocs, LspExtOpenDocsResponse),
486 (SetRoomParticipantRole, Ack),
487 (BlameBuffer, BlameBufferResponse),
488 (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
489 (MultiLspQuery, MultiLspQueryResponse),
490 (RestartLanguageServers, Ack),
491 (OpenContext, OpenContextResponse),
492 (CreateContext, CreateContextResponse),
493 (SynchronizeContexts, SynchronizeContextsResponse),
494 (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
495 (AddWorktree, AddWorktreeResponse),
496 (ShutdownRemoteServer, Ack),
497 (RemoveWorktree, Ack),
498 (OpenServerSettings, OpenBufferResponse),
499 (GetPermalinkToLine, GetPermalinkToLineResponse),
500 (FlushBufferedMessages, Ack),
501 (LanguageServerPromptRequest, LanguageServerPromptResponse),
502 (GitBranches, GitBranchesResponse),
503 (UpdateGitBranch, Ack),
504 (ListToolchains, ListToolchainsResponse),
505 (ActivateToolchain, Ack),
506 (ActiveToolchain, ActiveToolchainResponse),
507 (GetPathMetadata, GetPathMetadataResponse),
508 (GetPanicFiles, GetPanicFilesResponse),
509 (CancelLanguageServerWork, Ack),
510 (SyncExtensions, SyncExtensionsResponse),
511 (InstallExtension, Ack),
512 (RegisterBufferWithLanguageServers, Ack),
513);
514
515entity_messages!(
516 {project_id, ShareProject},
517 AddProjectCollaborator,
518 AddWorktree,
519 ApplyCodeAction,
520 ApplyCompletionAdditionalEdits,
521 BlameBuffer,
522 BufferReloaded,
523 BufferSaved,
524 CloseBuffer,
525 Commit,
526 CopyProjectEntry,
527 CreateBufferForPeer,
528 CreateProjectEntry,
529 DeleteProjectEntry,
530 ExpandProjectEntry,
531 ExpandAllForProjectEntry,
532 FindSearchCandidates,
533 FormatBuffers,
534 GetCodeActions,
535 GetCompletions,
536 GetDefinition,
537 GetDeclaration,
538 GetImplementation,
539 GetDocumentHighlights,
540 GetHover,
541 GetProjectSymbols,
542 GetReferences,
543 GetSignatureHelp,
544 GetStagedText,
545 GetTypeDefinition,
546 InlayHints,
547 JoinProject,
548 LeaveProject,
549 LinkedEditingRange,
550 MultiLspQuery,
551 RestartLanguageServers,
552 OnTypeFormatting,
553 OpenNewBuffer,
554 OpenBufferById,
555 OpenBufferByPath,
556 OpenBufferForSymbol,
557 PerformRename,
558 PrepareRename,
559 RefreshInlayHints,
560 ReloadBuffers,
561 RemoveProjectCollaborator,
562 RenameProjectEntry,
563 ResolveCompletionDocumentation,
564 ResolveInlayHint,
565 SaveBuffer,
566 Stage,
567 StartLanguageServer,
568 SynchronizeBuffers,
569 TaskContextForLocation,
570 UnshareProject,
571 Unstage,
572 UpdateBuffer,
573 UpdateBufferFile,
574 UpdateDiagnosticSummary,
575 UpdateDiffBase,
576 UpdateLanguageServer,
577 UpdateProject,
578 UpdateProjectCollaborator,
579 UpdateWorktree,
580 UpdateWorktreeSettings,
581 LspExtExpandMacro,
582 LspExtOpenDocs,
583 AdvertiseContexts,
584 OpenContext,
585 CreateContext,
586 UpdateContext,
587 SynchronizeContexts,
588 LspExtSwitchSourceHeader,
589 LanguageServerLog,
590 Toast,
591 HideToast,
592 OpenServerSettings,
593 GetPermalinkToLine,
594 LanguageServerPromptRequest,
595 GitBranches,
596 UpdateGitBranch,
597 ListToolchains,
598 ActivateToolchain,
599 ActiveToolchain,
600 GetPathMetadata,
601 CancelLanguageServerWork,
602 RegisterBufferWithLanguageServers,
603);
604
605entity_messages!(
606 {channel_id, Channel},
607 ChannelMessageSent,
608 ChannelMessageUpdate,
609 RemoveChannelMessage,
610 UpdateChannelMessage,
611 UpdateChannelBuffer,
612 UpdateChannelBufferCollaborators,
613);
614
615impl From<Timestamp> for SystemTime {
616 fn from(val: Timestamp) -> Self {
617 UNIX_EPOCH
618 .checked_add(Duration::new(val.seconds, val.nanos))
619 .unwrap()
620 }
621}
622
623impl From<SystemTime> for Timestamp {
624 fn from(time: SystemTime) -> Self {
625 let duration = time.duration_since(UNIX_EPOCH).unwrap();
626 Self {
627 seconds: duration.as_secs(),
628 nanos: duration.subsec_nanos(),
629 }
630 }
631}
632
633impl From<u128> for Nonce {
634 fn from(nonce: u128) -> Self {
635 let upper_half = (nonce >> 64) as u64;
636 let lower_half = nonce as u64;
637 Self {
638 upper_half,
639 lower_half,
640 }
641 }
642}
643
644impl From<Nonce> for u128 {
645 fn from(nonce: Nonce) -> Self {
646 let upper_half = (nonce.upper_half as u128) << 64;
647 let lower_half = nonce.lower_half as u128;
648 upper_half | lower_half
649 }
650}
651
652#[cfg(any(test, feature = "test-support"))]
653pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 2;
654#[cfg(not(any(test, feature = "test-support")))]
655pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 256;
656
657pub fn split_worktree_update(mut message: UpdateWorktree) -> impl Iterator<Item = UpdateWorktree> {
658 let mut done_files = false;
659
660 let mut repository_map = message
661 .updated_repositories
662 .into_iter()
663 .map(|repo| (repo.work_directory_id, repo))
664 .collect::<HashMap<_, _>>();
665
666 iter::from_fn(move || {
667 if done_files {
668 return None;
669 }
670
671 let updated_entries_chunk_size = cmp::min(
672 message.updated_entries.len(),
673 MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
674 );
675 let updated_entries: Vec<_> = message
676 .updated_entries
677 .drain(..updated_entries_chunk_size)
678 .collect();
679
680 let removed_entries_chunk_size = cmp::min(
681 message.removed_entries.len(),
682 MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
683 );
684 let removed_entries = message
685 .removed_entries
686 .drain(..removed_entries_chunk_size)
687 .collect();
688
689 done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
690
691 let mut updated_repositories = Vec::new();
692
693 if !repository_map.is_empty() {
694 for entry in &updated_entries {
695 if let Some(repo) = repository_map.remove(&entry.id) {
696 updated_repositories.push(repo);
697 }
698 }
699 }
700
701 let removed_repositories = if done_files {
702 mem::take(&mut message.removed_repositories)
703 } else {
704 Default::default()
705 };
706
707 if done_files {
708 updated_repositories.extend(mem::take(&mut repository_map).into_values());
709 }
710
711 Some(UpdateWorktree {
712 project_id: message.project_id,
713 worktree_id: message.worktree_id,
714 root_name: message.root_name.clone(),
715 abs_path: message.abs_path.clone(),
716 updated_entries,
717 removed_entries,
718 scan_id: message.scan_id,
719 is_last_update: done_files && message.is_last_update,
720 updated_repositories,
721 removed_repositories,
722 })
723 })
724}
725
726#[cfg(test)]
727mod tests {
728 use super::*;
729
730 #[test]
731 fn test_converting_peer_id_from_and_to_u64() {
732 let peer_id = PeerId {
733 owner_id: 10,
734 id: 3,
735 };
736 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
737 let peer_id = PeerId {
738 owner_id: u32::MAX,
739 id: 3,
740 };
741 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
742 let peer_id = PeerId {
743 owner_id: 10,
744 id: u32::MAX,
745 };
746 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
747 let peer_id = PeerId {
748 owner_id: u32::MAX,
749 id: u32::MAX,
750 };
751 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
752 }
753}