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