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