proto.rs

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