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