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