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