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