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);
369
370request_messages!(
371    (AcceptTermsOfService, AcceptTermsOfServiceResponse),
372    (ApplyCodeAction, ApplyCodeActionResponse),
373    (
374        ApplyCompletionAdditionalEdits,
375        ApplyCompletionAdditionalEditsResponse
376    ),
377    (Call, Ack),
378    (CancelCall, Ack),
379    (CopyProjectEntry, ProjectEntryResponse),
380    (ComputeEmbeddings, ComputeEmbeddingsResponse),
381    (CreateChannel, CreateChannelResponse),
382    (CreateProjectEntry, ProjectEntryResponse),
383    (CreateRoom, CreateRoomResponse),
384    (DeclineCall, Ack),
385    (DeleteChannel, Ack),
386    (DeleteProjectEntry, ProjectEntryResponse),
387    (ExpandProjectEntry, ExpandProjectEntryResponse),
388    (Follow, FollowResponse),
389    (FormatBuffers, FormatBuffersResponse),
390    (FuzzySearchUsers, UsersResponse),
391    (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
392    (GetChannelMembers, GetChannelMembersResponse),
393    (GetChannelMessages, GetChannelMessagesResponse),
394    (GetChannelMessagesById, GetChannelMessagesResponse),
395    (GetCodeActions, GetCodeActionsResponse),
396    (GetCompletions, GetCompletionsResponse),
397    (GetDefinition, GetDefinitionResponse),
398    (GetDeclaration, GetDeclarationResponse),
399    (GetImplementation, GetImplementationResponse),
400    (GetDocumentHighlights, GetDocumentHighlightsResponse),
401    (GetHover, GetHoverResponse),
402    (GetLlmToken, GetLlmTokenResponse),
403    (GetNotifications, GetNotificationsResponse),
404    (GetPrivateUserInfo, GetPrivateUserInfoResponse),
405    (GetProjectSymbols, GetProjectSymbolsResponse),
406    (GetReferences, GetReferencesResponse),
407    (GetSignatureHelp, GetSignatureHelpResponse),
408    (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
409    (GetTypeDefinition, GetTypeDefinitionResponse),
410    (LinkedEditingRange, LinkedEditingRangeResponse),
411    (ListRemoteDirectory, ListRemoteDirectoryResponse),
412    (UpdateDevServerProject, Ack),
413    (GetUsers, UsersResponse),
414    (IncomingCall, Ack),
415    (InlayHints, InlayHintsResponse),
416    (InviteChannelMember, Ack),
417    (JoinChannel, JoinRoomResponse),
418    (JoinChannelBuffer, JoinChannelBufferResponse),
419    (JoinChannelChat, JoinChannelChatResponse),
420    (JoinHostedProject, JoinProjectResponse),
421    (JoinProject, JoinProjectResponse),
422    (JoinRoom, JoinRoomResponse),
423    (LeaveChannelBuffer, Ack),
424    (LeaveRoom, Ack),
425    (MarkNotificationRead, Ack),
426    (MoveChannel, Ack),
427    (OnTypeFormatting, OnTypeFormattingResponse),
428    (OpenBufferById, OpenBufferResponse),
429    (OpenBufferByPath, OpenBufferResponse),
430    (OpenBufferForSymbol, OpenBufferForSymbolResponse),
431    (OpenNewBuffer, OpenBufferResponse),
432    (PerformRename, PerformRenameResponse),
433    (Ping, Ack),
434    (PrepareRename, PrepareRenameResponse),
435    (CountLanguageModelTokens, CountLanguageModelTokensResponse),
436    (RefreshInlayHints, Ack),
437    (RejoinChannelBuffers, RejoinChannelBuffersResponse),
438    (RejoinRoom, RejoinRoomResponse),
439    (ReloadBuffers, ReloadBuffersResponse),
440    (RemoveChannelMember, Ack),
441    (RemoveChannelMessage, Ack),
442    (UpdateChannelMessage, Ack),
443    (RemoveContact, Ack),
444    (RenameChannel, RenameChannelResponse),
445    (RenameProjectEntry, ProjectEntryResponse),
446    (RequestContact, Ack),
447    (
448        ResolveCompletionDocumentation,
449        ResolveCompletionDocumentationResponse
450    ),
451    (ResolveInlayHint, ResolveInlayHintResponse),
452    (RespondToChannelInvite, Ack),
453    (RespondToContactRequest, Ack),
454    (SaveBuffer, BufferSaved),
455    (FindSearchCandidates, FindSearchCandidatesResponse),
456    (SendChannelMessage, SendChannelMessageResponse),
457    (SetChannelMemberRole, Ack),
458    (SetChannelVisibility, Ack),
459    (ShareProject, ShareProjectResponse),
460    (SynchronizeBuffers, SynchronizeBuffersResponse),
461    (TaskContextForLocation, TaskContext),
462    (TaskTemplates, TaskTemplatesResponse),
463    (Test, Test),
464    (UpdateBuffer, Ack),
465    (UpdateParticipantLocation, Ack),
466    (UpdateProject, Ack),
467    (UpdateWorktree, Ack),
468    (LspExtExpandMacro, LspExtExpandMacroResponse),
469    (SetRoomParticipantRole, Ack),
470    (BlameBuffer, BlameBufferResponse),
471    (CreateDevServerProject, CreateDevServerProjectResponse),
472    (CreateDevServer, CreateDevServerResponse),
473    (ShutdownDevServer, Ack),
474    (ShareDevServerProject, ShareProjectResponse),
475    (JoinDevServerProject, JoinProjectResponse),
476    (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
477    (ReconnectDevServer, ReconnectDevServerResponse),
478    (ValidateDevServerProjectRequest, Ack),
479    (MultiLspQuery, MultiLspQueryResponse),
480    (DeleteDevServer, Ack),
481    (DeleteDevServerProject, Ack),
482    (RegenerateDevServerToken, RegenerateDevServerTokenResponse),
483    (RenameDevServer, Ack),
484    (RestartLanguageServers, Ack),
485    (OpenContext, OpenContextResponse),
486    (CreateContext, CreateContextResponse),
487    (SynchronizeContexts, SynchronizeContextsResponse),
488    (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
489    (AddWorktree, AddWorktreeResponse),
490    (CheckFileExists, CheckFileExistsResponse)
491);
492
493entity_messages!(
494    {project_id, ShareProject},
495    AddProjectCollaborator,
496    AddWorktree,
497    ApplyCodeAction,
498    ApplyCompletionAdditionalEdits,
499    BlameBuffer,
500    BufferReloaded,
501    BufferSaved,
502    CloseBuffer,
503    CopyProjectEntry,
504    CreateBufferForPeer,
505    CreateProjectEntry,
506    DeleteProjectEntry,
507    ExpandProjectEntry,
508    FindSearchCandidates,
509    FormatBuffers,
510    GetCodeActions,
511    GetCompletions,
512    GetDefinition,
513    GetDeclaration,
514    GetImplementation,
515    GetDocumentHighlights,
516    GetHover,
517    GetProjectSymbols,
518    GetReferences,
519    GetSignatureHelp,
520    GetTypeDefinition,
521    InlayHints,
522    JoinProject,
523    LeaveProject,
524    LinkedEditingRange,
525    MultiLspQuery,
526    RestartLanguageServers,
527    OnTypeFormatting,
528    OpenNewBuffer,
529    OpenBufferById,
530    OpenBufferByPath,
531    OpenBufferForSymbol,
532    PerformRename,
533    PrepareRename,
534    RefreshInlayHints,
535    ReloadBuffers,
536    RemoveProjectCollaborator,
537    RenameProjectEntry,
538    ResolveCompletionDocumentation,
539    ResolveInlayHint,
540    SaveBuffer,
541    StartLanguageServer,
542    SynchronizeBuffers,
543    TaskContextForLocation,
544    TaskTemplates,
545    UnshareProject,
546    UpdateBuffer,
547    UpdateBufferFile,
548    UpdateDiagnosticSummary,
549    UpdateDiffBase,
550    UpdateLanguageServer,
551    UpdateProject,
552    UpdateProjectCollaborator,
553    UpdateWorktree,
554    UpdateWorktreeSettings,
555    LspExtExpandMacro,
556    AdvertiseContexts,
557    OpenContext,
558    CreateContext,
559    UpdateContext,
560    SynchronizeContexts,
561    LspExtSwitchSourceHeader,
562    UpdateUserSettings,
563    CheckFileExists,
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}