proto.rs

  1#![allow(non_snake_case)]
  2
  3pub mod error;
  4mod macros;
  5mod proto_client;
  6mod typed_envelope;
  7
  8pub use error::*;
  9pub use proto_client::*;
 10pub use typed_envelope::*;
 11
 12use collections::HashMap;
 13pub use prost::{DecodeError, Message};
 14use serde::Serialize;
 15use std::{
 16    any::{Any, TypeId},
 17    cmp,
 18    fmt::{self, Debug},
 19    iter, mem,
 20    time::{Duration, SystemTime, UNIX_EPOCH},
 21};
 22
 23include!(concat!(env!("OUT_DIR"), "/zed.messages.rs"));
 24
 25pub const SSH_PEER_ID: PeerId = PeerId { owner_id: 0, id: 0 };
 26pub const SSH_PROJECT_ID: u64 = 0;
 27
 28pub trait EnvelopedMessage: Clone + Debug + Serialize + Sized + Send + Sync + 'static {
 29    const NAME: &'static str;
 30    const PRIORITY: MessagePriority;
 31    fn into_envelope(
 32        self,
 33        id: u32,
 34        responding_to: Option<u32>,
 35        original_sender_id: Option<PeerId>,
 36    ) -> Envelope;
 37    fn from_envelope(envelope: Envelope) -> Option<Self>;
 38}
 39
 40pub trait EntityMessage: EnvelopedMessage {
 41    type Entity;
 42    fn remote_entity_id(&self) -> u64;
 43}
 44
 45pub trait RequestMessage: EnvelopedMessage {
 46    type Response: EnvelopedMessage;
 47}
 48
 49pub trait AnyTypedEnvelope: 'static + Send + Sync {
 50    fn payload_type_id(&self) -> TypeId;
 51    fn payload_type_name(&self) -> &'static str;
 52    fn as_any(&self) -> &dyn Any;
 53    fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync>;
 54    fn is_background(&self) -> bool;
 55    fn original_sender_id(&self) -> Option<PeerId>;
 56    fn sender_id(&self) -> PeerId;
 57    fn message_id(&self) -> u32;
 58}
 59
 60pub enum MessagePriority {
 61    Foreground,
 62    Background,
 63}
 64
 65impl<T: EnvelopedMessage> AnyTypedEnvelope for TypedEnvelope<T> {
 66    fn payload_type_id(&self) -> TypeId {
 67        TypeId::of::<T>()
 68    }
 69
 70    fn payload_type_name(&self) -> &'static str {
 71        T::NAME
 72    }
 73
 74    fn as_any(&self) -> &dyn Any {
 75        self
 76    }
 77
 78    fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync> {
 79        self
 80    }
 81
 82    fn is_background(&self) -> bool {
 83        matches!(T::PRIORITY, MessagePriority::Background)
 84    }
 85
 86    fn original_sender_id(&self) -> Option<PeerId> {
 87        self.original_sender_id
 88    }
 89
 90    fn sender_id(&self) -> PeerId {
 91        self.sender_id
 92    }
 93
 94    fn message_id(&self) -> u32 {
 95        self.message_id
 96    }
 97}
 98
 99impl PeerId {
100    pub fn from_u64(peer_id: u64) -> Self {
101        let owner_id = (peer_id >> 32) as u32;
102        let id = peer_id as u32;
103        Self { owner_id, id }
104    }
105
106    pub fn as_u64(self) -> u64 {
107        ((self.owner_id as u64) << 32) | (self.id as u64)
108    }
109}
110
111impl Copy for PeerId {}
112
113impl Eq for PeerId {}
114
115impl Ord for PeerId {
116    fn cmp(&self, other: &Self) -> cmp::Ordering {
117        self.owner_id
118            .cmp(&other.owner_id)
119            .then_with(|| self.id.cmp(&other.id))
120    }
121}
122
123impl PartialOrd for PeerId {
124    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
125        Some(self.cmp(other))
126    }
127}
128
129impl std::hash::Hash for PeerId {
130    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
131        self.owner_id.hash(state);
132        self.id.hash(state);
133    }
134}
135
136impl fmt::Display for PeerId {
137    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138        write!(f, "{}/{}", self.owner_id, self.id)
139    }
140}
141
142messages!(
143    (AcceptTermsOfService, Foreground),
144    (AcceptTermsOfServiceResponse, Foreground),
145    (Ack, Foreground),
146    (AckBufferOperation, Background),
147    (AckChannelMessage, Background),
148    (AddNotification, Foreground),
149    (AddProjectCollaborator, Foreground),
150    (ApplyCodeAction, Background),
151    (ApplyCodeActionResponse, Background),
152    (ApplyCompletionAdditionalEdits, Background),
153    (ApplyCompletionAdditionalEditsResponse, Background),
154    (BufferReloaded, Foreground),
155    (BufferSaved, Foreground),
156    (Call, Foreground),
157    (CallCanceled, Foreground),
158    (CancelCall, Foreground),
159    (ChannelMessageSent, Foreground),
160    (ChannelMessageUpdate, Foreground),
161    (ComputeEmbeddings, Background),
162    (ComputeEmbeddingsResponse, Background),
163    (CopyProjectEntry, Foreground),
164    (CreateBufferForPeer, Foreground),
165    (CreateChannel, Foreground),
166    (CreateChannelResponse, Foreground),
167    (CreateProjectEntry, Foreground),
168    (CreateRoom, Foreground),
169    (CreateRoomResponse, Foreground),
170    (DeclineCall, Foreground),
171    (DeleteChannel, Foreground),
172    (DeleteNotification, Foreground),
173    (UpdateNotification, Foreground),
174    (DeleteProjectEntry, Foreground),
175    (EndStream, Foreground),
176    (Error, Foreground),
177    (ExpandProjectEntry, Foreground),
178    (ExpandProjectEntryResponse, Foreground),
179    (Follow, Foreground),
180    (FollowResponse, Foreground),
181    (FormatBuffers, Foreground),
182    (FormatBuffersResponse, Foreground),
183    (FuzzySearchUsers, Foreground),
184    (GetCachedEmbeddings, Background),
185    (GetCachedEmbeddingsResponse, Background),
186    (GetChannelMembers, Foreground),
187    (GetChannelMembersResponse, Foreground),
188    (GetChannelMessages, Background),
189    (GetChannelMessagesById, Background),
190    (GetChannelMessagesResponse, Background),
191    (GetCodeActions, Background),
192    (GetCodeActionsResponse, Background),
193    (GetCompletions, Background),
194    (GetCompletionsResponse, Background),
195    (GetDefinition, Background),
196    (GetDefinitionResponse, Background),
197    (GetDeclaration, Background),
198    (GetDeclarationResponse, Background),
199    (GetDocumentHighlights, Background),
200    (GetDocumentHighlightsResponse, Background),
201    (GetHover, Background),
202    (GetHoverResponse, Background),
203    (GetNotifications, Foreground),
204    (GetNotificationsResponse, Foreground),
205    (GetPrivateUserInfo, Foreground),
206    (GetPrivateUserInfoResponse, Foreground),
207    (GetProjectSymbols, Background),
208    (GetProjectSymbolsResponse, Background),
209    (GetReferences, Background),
210    (GetReferencesResponse, Background),
211    (GetSignatureHelp, Background),
212    (GetSignatureHelpResponse, Background),
213    (GetSupermavenApiKey, Background),
214    (GetSupermavenApiKeyResponse, Background),
215    (GetTypeDefinition, Background),
216    (GetTypeDefinitionResponse, Background),
217    (GetImplementation, Background),
218    (GetImplementationResponse, Background),
219    (GetLlmToken, Background),
220    (GetLlmTokenResponse, Background),
221    (GetUsers, Foreground),
222    (Hello, Foreground),
223    (IncomingCall, Foreground),
224    (InlayHints, Background),
225    (InlayHintsResponse, Background),
226    (InviteChannelMember, Foreground),
227    (JoinChannel, Foreground),
228    (JoinChannelBuffer, Foreground),
229    (JoinChannelBufferResponse, Foreground),
230    (JoinChannelChat, Foreground),
231    (JoinChannelChatResponse, Foreground),
232    (JoinProject, Foreground),
233    (JoinHostedProject, Foreground),
234    (JoinProjectResponse, Foreground),
235    (JoinRoom, Foreground),
236    (JoinRoomResponse, Foreground),
237    (LeaveChannelBuffer, Background),
238    (LeaveChannelChat, Foreground),
239    (LeaveProject, Foreground),
240    (LeaveRoom, Foreground),
241    (MarkNotificationRead, Foreground),
242    (MoveChannel, Foreground),
243    (OnTypeFormatting, Background),
244    (OnTypeFormattingResponse, Background),
245    (OpenBufferById, Background),
246    (OpenBufferByPath, Background),
247    (OpenBufferForSymbol, Background),
248    (OpenBufferForSymbolResponse, Background),
249    (OpenBufferResponse, Background),
250    (PerformRename, Background),
251    (PerformRenameResponse, Background),
252    (Ping, Foreground),
253    (PrepareRename, Background),
254    (PrepareRenameResponse, Background),
255    (ProjectEntryResponse, Foreground),
256    (CountLanguageModelTokens, Background),
257    (CountLanguageModelTokensResponse, Background),
258    (RefreshInlayHints, Foreground),
259    (RejoinChannelBuffers, Foreground),
260    (RejoinChannelBuffersResponse, Foreground),
261    (RejoinRoom, Foreground),
262    (RejoinRoomResponse, Foreground),
263    (ReloadBuffers, Foreground),
264    (ReloadBuffersResponse, Foreground),
265    (RemoveChannelMember, Foreground),
266    (RemoveChannelMessage, Foreground),
267    (UpdateChannelMessage, Foreground),
268    (RemoveContact, Foreground),
269    (RemoveProjectCollaborator, Foreground),
270    (RenameChannel, Foreground),
271    (RenameChannelResponse, Foreground),
272    (RenameProjectEntry, Foreground),
273    (RequestContact, Foreground),
274    (ResolveCompletionDocumentation, Background),
275    (ResolveCompletionDocumentationResponse, Background),
276    (ResolveInlayHint, Background),
277    (ResolveInlayHintResponse, Background),
278    (RespondToChannelInvite, Foreground),
279    (RespondToContactRequest, Foreground),
280    (RoomUpdated, Foreground),
281    (SaveBuffer, Foreground),
282    (SetChannelMemberRole, Foreground),
283    (SetChannelVisibility, Foreground),
284    (SearchProject, Background),
285    (SearchProjectResponse, Background),
286    (SendChannelMessage, Background),
287    (SendChannelMessageResponse, Background),
288    (ShareProject, Foreground),
289    (ShareProjectResponse, Foreground),
290    (ShowContacts, Foreground),
291    (StartLanguageServer, Foreground),
292    (SubscribeToChannels, Foreground),
293    (SynchronizeBuffers, Foreground),
294    (SynchronizeBuffersResponse, Foreground),
295    (TaskContextForLocation, Background),
296    (TaskContext, Background),
297    (TaskTemplates, Background),
298    (TaskTemplatesResponse, Background),
299    (Test, Foreground),
300    (Unfollow, Foreground),
301    (UnshareProject, Foreground),
302    (UpdateBuffer, Foreground),
303    (UpdateBufferFile, Foreground),
304    (UpdateChannelBuffer, Foreground),
305    (UpdateChannelBufferCollaborators, Foreground),
306    (UpdateChannels, Foreground),
307    (UpdateUserChannels, Foreground),
308    (UpdateContacts, Foreground),
309    (UpdateDiagnosticSummary, Foreground),
310    (UpdateDiffBase, Foreground),
311    (UpdateFollowers, Foreground),
312    (UpdateInviteInfo, Foreground),
313    (UpdateLanguageServer, Foreground),
314    (UpdateParticipantLocation, Foreground),
315    (UpdateProject, Foreground),
316    (UpdateProjectCollaborator, Foreground),
317    (UpdateUserPlan, Foreground),
318    (UpdateWorktree, Foreground),
319    (UpdateWorktreeSettings, Foreground),
320    (UsersResponse, Foreground),
321    (LspExtExpandMacro, Background),
322    (LspExtExpandMacroResponse, Background),
323    (SetRoomParticipantRole, Foreground),
324    (BlameBuffer, Foreground),
325    (BlameBufferResponse, Foreground),
326    (CreateDevServerProject, Background),
327    (CreateDevServerProjectResponse, Foreground),
328    (CreateDevServer, Foreground),
329    (CreateDevServerResponse, Foreground),
330    (DevServerInstructions, Foreground),
331    (ShutdownDevServer, Foreground),
332    (ReconnectDevServer, Foreground),
333    (ReconnectDevServerResponse, Foreground),
334    (ShareDevServerProject, Foreground),
335    (JoinDevServerProject, Foreground),
336    (RejoinRemoteProjects, Foreground),
337    (RejoinRemoteProjectsResponse, Foreground),
338    (MultiLspQuery, Background),
339    (MultiLspQueryResponse, Background),
340    (DevServerProjectsUpdate, Foreground),
341    (ValidateDevServerProjectRequest, Background),
342    (ListRemoteDirectory, Background),
343    (ListRemoteDirectoryResponse, Background),
344    (UpdateDevServerProject, Background),
345    (DeleteDevServer, Foreground),
346    (DeleteDevServerProject, Foreground),
347    (RegenerateDevServerToken, Foreground),
348    (RegenerateDevServerTokenResponse, Foreground),
349    (RenameDevServer, Foreground),
350    (OpenNewBuffer, Foreground),
351    (RestartLanguageServers, Foreground),
352    (LinkedEditingRange, Background),
353    (LinkedEditingRangeResponse, Background),
354    (AdvertiseContexts, Foreground),
355    (OpenContext, Foreground),
356    (OpenContextResponse, Foreground),
357    (CreateContext, Foreground),
358    (CreateContextResponse, Foreground),
359    (UpdateContext, Foreground),
360    (SynchronizeContexts, Foreground),
361    (SynchronizeContextsResponse, Foreground),
362    (LspExtSwitchSourceHeader, Background),
363    (LspExtSwitchSourceHeaderResponse, Background),
364    (AddWorktree, Foreground),
365    (AddWorktreeResponse, Foreground),
366    (FindSearchCandidates, Background),
367    (FindSearchCandidatesResponse, Background),
368    (CloseBuffer, 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    (SearchProject, SearchProjectResponse),
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);
493
494entity_messages!(
495    {project_id, ShareProject},
496    AddProjectCollaborator,
497    AddWorktree,
498    ApplyCodeAction,
499    ApplyCompletionAdditionalEdits,
500    BlameBuffer,
501    BufferReloaded,
502    BufferSaved,
503    CloseBuffer,
504    CopyProjectEntry,
505    CreateBufferForPeer,
506    CreateProjectEntry,
507    DeleteProjectEntry,
508    ExpandProjectEntry,
509    FindSearchCandidates,
510    FormatBuffers,
511    GetCodeActions,
512    GetCompletions,
513    GetDefinition,
514    GetDeclaration,
515    GetImplementation,
516    GetDocumentHighlights,
517    GetHover,
518    GetProjectSymbols,
519    GetReferences,
520    GetSignatureHelp,
521    GetTypeDefinition,
522    InlayHints,
523    JoinProject,
524    LeaveProject,
525    LinkedEditingRange,
526    MultiLspQuery,
527    RestartLanguageServers,
528    OnTypeFormatting,
529    OpenNewBuffer,
530    OpenBufferById,
531    OpenBufferByPath,
532    OpenBufferForSymbol,
533    PerformRename,
534    PrepareRename,
535    RefreshInlayHints,
536    ReloadBuffers,
537    RemoveProjectCollaborator,
538    RenameProjectEntry,
539    ResolveCompletionDocumentation,
540    ResolveInlayHint,
541    SaveBuffer,
542    SearchProject,
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);
565
566entity_messages!(
567    {channel_id, Channel},
568    ChannelMessageSent,
569    ChannelMessageUpdate,
570    RemoveChannelMessage,
571    UpdateChannelMessage,
572    UpdateChannelBuffer,
573    UpdateChannelBufferCollaborators,
574);
575
576impl From<Timestamp> for SystemTime {
577    fn from(val: Timestamp) -> Self {
578        UNIX_EPOCH
579            .checked_add(Duration::new(val.seconds, val.nanos))
580            .unwrap()
581    }
582}
583
584impl From<SystemTime> for Timestamp {
585    fn from(time: SystemTime) -> Self {
586        let duration = time.duration_since(UNIX_EPOCH).unwrap();
587        Self {
588            seconds: duration.as_secs(),
589            nanos: duration.subsec_nanos(),
590        }
591    }
592}
593
594impl From<u128> for Nonce {
595    fn from(nonce: u128) -> Self {
596        let upper_half = (nonce >> 64) as u64;
597        let lower_half = nonce as u64;
598        Self {
599            upper_half,
600            lower_half,
601        }
602    }
603}
604
605impl From<Nonce> for u128 {
606    fn from(nonce: Nonce) -> Self {
607        let upper_half = (nonce.upper_half as u128) << 64;
608        let lower_half = nonce.lower_half as u128;
609        upper_half | lower_half
610    }
611}
612
613pub fn split_worktree_update(
614    mut message: UpdateWorktree,
615    max_chunk_size: usize,
616) -> impl Iterator<Item = UpdateWorktree> {
617    let mut done_files = false;
618
619    let mut repository_map = message
620        .updated_repositories
621        .into_iter()
622        .map(|repo| (repo.work_directory_id, repo))
623        .collect::<HashMap<_, _>>();
624
625    iter::from_fn(move || {
626        if done_files {
627            return None;
628        }
629
630        let updated_entries_chunk_size = cmp::min(message.updated_entries.len(), max_chunk_size);
631        let updated_entries: Vec<_> = message
632            .updated_entries
633            .drain(..updated_entries_chunk_size)
634            .collect();
635
636        let removed_entries_chunk_size = cmp::min(message.removed_entries.len(), max_chunk_size);
637        let removed_entries = message
638            .removed_entries
639            .drain(..removed_entries_chunk_size)
640            .collect();
641
642        done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
643
644        let mut updated_repositories = Vec::new();
645
646        if !repository_map.is_empty() {
647            for entry in &updated_entries {
648                if let Some(repo) = repository_map.remove(&entry.id) {
649                    updated_repositories.push(repo)
650                }
651            }
652        }
653
654        let removed_repositories = if done_files {
655            mem::take(&mut message.removed_repositories)
656        } else {
657            Default::default()
658        };
659
660        if done_files {
661            updated_repositories.extend(mem::take(&mut repository_map).into_values());
662        }
663
664        Some(UpdateWorktree {
665            project_id: message.project_id,
666            worktree_id: message.worktree_id,
667            root_name: message.root_name.clone(),
668            abs_path: message.abs_path.clone(),
669            updated_entries,
670            removed_entries,
671            scan_id: message.scan_id,
672            is_last_update: done_files && message.is_last_update,
673            updated_repositories,
674            removed_repositories,
675        })
676    })
677}
678
679#[cfg(test)]
680mod tests {
681    use super::*;
682
683    #[test]
684    fn test_converting_peer_id_from_and_to_u64() {
685        let peer_id = PeerId {
686            owner_id: 10,
687            id: 3,
688        };
689        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
690        let peer_id = PeerId {
691            owner_id: u32::MAX,
692            id: 3,
693        };
694        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
695        let peer_id = PeerId {
696            owner_id: 10,
697            id: u32::MAX,
698        };
699        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
700        let peer_id = PeerId {
701            owner_id: u32::MAX,
702            id: u32::MAX,
703        };
704        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
705    }
706}