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    (JoinProjectResponse, Foreground),
232    (JoinRoom, Foreground),
233    (JoinRoomResponse, Foreground),
234    (LeaveChannelBuffer, Background),
235    (LeaveChannelChat, Foreground),
236    (LeaveProject, Foreground),
237    (LeaveRoom, Foreground),
238    (MarkNotificationRead, Foreground),
239    (MoveChannel, Foreground),
240    (OnTypeFormatting, Background),
241    (OnTypeFormattingResponse, Background),
242    (OpenBufferById, Background),
243    (OpenBufferByPath, Background),
244    (OpenBufferForSymbol, Background),
245    (OpenBufferForSymbolResponse, Background),
246    (OpenBufferResponse, Background),
247    (PerformRename, Background),
248    (PerformRenameResponse, Background),
249    (Ping, Foreground),
250    (PrepareRename, Background),
251    (PrepareRenameResponse, Background),
252    (ProjectEntryResponse, Foreground),
253    (CountLanguageModelTokens, Background),
254    (CountLanguageModelTokensResponse, Background),
255    (RefreshLlmToken, 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    (Test, Foreground),
294    (Unfollow, Foreground),
295    (UnshareProject, Foreground),
296    (UpdateBuffer, Foreground),
297    (UpdateBufferFile, Foreground),
298    (UpdateChannelBuffer, Foreground),
299    (UpdateChannelBufferCollaborators, Foreground),
300    (UpdateChannels, Foreground),
301    (UpdateUserChannels, Foreground),
302    (UpdateContacts, Foreground),
303    (UpdateDiagnosticSummary, Foreground),
304    (UpdateDiffBase, Foreground),
305    (UpdateFollowers, Foreground),
306    (UpdateInviteInfo, Foreground),
307    (UpdateLanguageServer, Foreground),
308    (UpdateParticipantLocation, Foreground),
309    (UpdateProject, Foreground),
310    (UpdateProjectCollaborator, Foreground),
311    (UpdateUserPlan, Foreground),
312    (UpdateWorktree, Foreground),
313    (UpdateWorktreeSettings, Foreground),
314    (UsersResponse, Foreground),
315    (LspExtExpandMacro, Background),
316    (LspExtExpandMacroResponse, Background),
317    (SetRoomParticipantRole, Foreground),
318    (BlameBuffer, Foreground),
319    (BlameBufferResponse, Foreground),
320    (RejoinRemoteProjects, Foreground),
321    (RejoinRemoteProjectsResponse, Foreground),
322    (MultiLspQuery, Background),
323    (MultiLspQueryResponse, Background),
324    (ListRemoteDirectory, Background),
325    (ListRemoteDirectoryResponse, Background),
326    (OpenNewBuffer, Foreground),
327    (RestartLanguageServers, Foreground),
328    (LinkedEditingRange, Background),
329    (LinkedEditingRangeResponse, Background),
330    (AdvertiseContexts, Foreground),
331    (OpenContext, Foreground),
332    (OpenContextResponse, Foreground),
333    (CreateContext, Foreground),
334    (CreateContextResponse, Foreground),
335    (UpdateContext, Foreground),
336    (SynchronizeContexts, Foreground),
337    (SynchronizeContextsResponse, Foreground),
338    (LspExtSwitchSourceHeader, Background),
339    (LspExtSwitchSourceHeaderResponse, Background),
340    (AddWorktree, Foreground),
341    (AddWorktreeResponse, Foreground),
342    (FindSearchCandidates, Background),
343    (FindSearchCandidatesResponse, Background),
344    (CloseBuffer, Foreground),
345    (UpdateUserSettings, Foreground),
346    (ShutdownRemoteServer, Foreground),
347    (RemoveWorktree, Foreground),
348    (LanguageServerLog, Foreground),
349    (Toast, Background),
350    (HideToast, Background),
351    (OpenServerSettings, Foreground),
352    (GetPermalinkToLine, Foreground),
353    (GetPermalinkToLineResponse, Foreground),
354    (FlushBufferedMessages, Foreground),
355    (LanguageServerPromptRequest, Foreground),
356    (LanguageServerPromptResponse, Foreground),
357    (GitBranches, Background),
358    (GitBranchesResponse, Background),
359    (UpdateGitBranch, Background),
360    (ListToolchains, Foreground),
361    (ListToolchainsResponse, Foreground),
362    (ActivateToolchain, Foreground),
363    (ActiveToolchain, Foreground),
364    (ActiveToolchainResponse, Foreground),
365    (GetPathMetadata, Background),
366    (GetPathMetadataResponse, Background),
367    (GetPanicFiles, Background),
368    (GetPanicFilesResponse, Background),
369    (CancelLanguageServerWork, Foreground),
370);
371
372request_messages!(
373    (AcceptTermsOfService, AcceptTermsOfServiceResponse),
374    (ApplyCodeAction, ApplyCodeActionResponse),
375    (
376        ApplyCompletionAdditionalEdits,
377        ApplyCompletionAdditionalEditsResponse
378    ),
379    (Call, Ack),
380    (CancelCall, Ack),
381    (CopyProjectEntry, ProjectEntryResponse),
382    (ComputeEmbeddings, ComputeEmbeddingsResponse),
383    (CreateChannel, CreateChannelResponse),
384    (CreateProjectEntry, ProjectEntryResponse),
385    (CreateRoom, CreateRoomResponse),
386    (DeclineCall, Ack),
387    (DeleteChannel, Ack),
388    (DeleteProjectEntry, ProjectEntryResponse),
389    (ExpandProjectEntry, ExpandProjectEntryResponse),
390    (Follow, FollowResponse),
391    (FormatBuffers, FormatBuffersResponse),
392    (FuzzySearchUsers, UsersResponse),
393    (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
394    (GetChannelMembers, GetChannelMembersResponse),
395    (GetChannelMessages, GetChannelMessagesResponse),
396    (GetChannelMessagesById, GetChannelMessagesResponse),
397    (GetCodeActions, GetCodeActionsResponse),
398    (GetCompletions, GetCompletionsResponse),
399    (GetDefinition, GetDefinitionResponse),
400    (GetDeclaration, GetDeclarationResponse),
401    (GetImplementation, GetImplementationResponse),
402    (GetDocumentHighlights, GetDocumentHighlightsResponse),
403    (GetHover, GetHoverResponse),
404    (GetLlmToken, GetLlmTokenResponse),
405    (GetNotifications, GetNotificationsResponse),
406    (GetPrivateUserInfo, GetPrivateUserInfoResponse),
407    (GetProjectSymbols, GetProjectSymbolsResponse),
408    (GetReferences, GetReferencesResponse),
409    (GetSignatureHelp, GetSignatureHelpResponse),
410    (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
411    (GetTypeDefinition, GetTypeDefinitionResponse),
412    (LinkedEditingRange, LinkedEditingRangeResponse),
413    (ListRemoteDirectory, ListRemoteDirectoryResponse),
414    (GetUsers, UsersResponse),
415    (IncomingCall, Ack),
416    (InlayHints, InlayHintsResponse),
417    (InviteChannelMember, Ack),
418    (JoinChannel, JoinRoomResponse),
419    (JoinChannelBuffer, JoinChannelBufferResponse),
420    (JoinChannelChat, JoinChannelChatResponse),
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    (Test, Test),
463    (UpdateBuffer, Ack),
464    (UpdateParticipantLocation, Ack),
465    (UpdateProject, Ack),
466    (UpdateWorktree, Ack),
467    (LspExtExpandMacro, LspExtExpandMacroResponse),
468    (SetRoomParticipantRole, Ack),
469    (BlameBuffer, BlameBufferResponse),
470    (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
471    (MultiLspQuery, MultiLspQueryResponse),
472    (RestartLanguageServers, Ack),
473    (OpenContext, OpenContextResponse),
474    (CreateContext, CreateContextResponse),
475    (SynchronizeContexts, SynchronizeContextsResponse),
476    (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
477    (AddWorktree, AddWorktreeResponse),
478    (ShutdownRemoteServer, Ack),
479    (RemoveWorktree, Ack),
480    (OpenServerSettings, OpenBufferResponse),
481    (GetPermalinkToLine, GetPermalinkToLineResponse),
482    (FlushBufferedMessages, Ack),
483    (LanguageServerPromptRequest, LanguageServerPromptResponse),
484    (GitBranches, GitBranchesResponse),
485    (UpdateGitBranch, Ack),
486    (ListToolchains, ListToolchainsResponse),
487    (ActivateToolchain, Ack),
488    (ActiveToolchain, ActiveToolchainResponse),
489    (GetPathMetadata, GetPathMetadataResponse),
490    (GetPanicFiles, GetPanicFilesResponse),
491    (CancelLanguageServerWork, Ack),
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    StartLanguageServer,
543    SynchronizeBuffers,
544    TaskContextForLocation,
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    LanguageServerLog,
564    Toast,
565    HideToast,
566    OpenServerSettings,
567    GetPermalinkToLine,
568    LanguageServerPromptRequest,
569    GitBranches,
570    UpdateGitBranch,
571    ListToolchains,
572    ActivateToolchain,
573    ActiveToolchain,
574    GetPathMetadata,
575    CancelLanguageServerWork,
576);
577
578entity_messages!(
579    {channel_id, Channel},
580    ChannelMessageSent,
581    ChannelMessageUpdate,
582    RemoveChannelMessage,
583    UpdateChannelMessage,
584    UpdateChannelBuffer,
585    UpdateChannelBufferCollaborators,
586);
587
588impl From<Timestamp> for SystemTime {
589    fn from(val: Timestamp) -> Self {
590        UNIX_EPOCH
591            .checked_add(Duration::new(val.seconds, val.nanos))
592            .unwrap()
593    }
594}
595
596impl From<SystemTime> for Timestamp {
597    fn from(time: SystemTime) -> Self {
598        let duration = time.duration_since(UNIX_EPOCH).unwrap();
599        Self {
600            seconds: duration.as_secs(),
601            nanos: duration.subsec_nanos(),
602        }
603    }
604}
605
606impl From<u128> for Nonce {
607    fn from(nonce: u128) -> Self {
608        let upper_half = (nonce >> 64) as u64;
609        let lower_half = nonce as u64;
610        Self {
611            upper_half,
612            lower_half,
613        }
614    }
615}
616
617impl From<Nonce> for u128 {
618    fn from(nonce: Nonce) -> Self {
619        let upper_half = (nonce.upper_half as u128) << 64;
620        let lower_half = nonce.lower_half as u128;
621        upper_half | lower_half
622    }
623}
624
625#[cfg(any(test, feature = "test-support"))]
626pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 2;
627#[cfg(not(any(test, feature = "test-support")))]
628pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 256;
629
630pub fn split_worktree_update(mut message: UpdateWorktree) -> impl Iterator<Item = UpdateWorktree> {
631    let mut done_files = false;
632
633    let mut repository_map = message
634        .updated_repositories
635        .into_iter()
636        .map(|repo| (repo.work_directory_id, repo))
637        .collect::<HashMap<_, _>>();
638
639    iter::from_fn(move || {
640        if done_files {
641            return None;
642        }
643
644        let updated_entries_chunk_size = cmp::min(
645            message.updated_entries.len(),
646            MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
647        );
648        let updated_entries: Vec<_> = message
649            .updated_entries
650            .drain(..updated_entries_chunk_size)
651            .collect();
652
653        let removed_entries_chunk_size = cmp::min(
654            message.removed_entries.len(),
655            MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
656        );
657        let removed_entries = message
658            .removed_entries
659            .drain(..removed_entries_chunk_size)
660            .collect();
661
662        done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
663
664        let mut updated_repositories = Vec::new();
665
666        if !repository_map.is_empty() {
667            for entry in &updated_entries {
668                if let Some(repo) = repository_map.remove(&entry.id) {
669                    updated_repositories.push(repo)
670                }
671            }
672        }
673
674        let removed_repositories = if done_files {
675            mem::take(&mut message.removed_repositories)
676        } else {
677            Default::default()
678        };
679
680        if done_files {
681            updated_repositories.extend(mem::take(&mut repository_map).into_values());
682        }
683
684        Some(UpdateWorktree {
685            project_id: message.project_id,
686            worktree_id: message.worktree_id,
687            root_name: message.root_name.clone(),
688            abs_path: message.abs_path.clone(),
689            updated_entries,
690            removed_entries,
691            scan_id: message.scan_id,
692            is_last_update: done_files && message.is_last_update,
693            updated_repositories,
694            removed_repositories,
695        })
696    })
697}
698
699#[cfg(test)]
700mod tests {
701    use super::*;
702
703    #[test]
704    fn test_converting_peer_id_from_and_to_u64() {
705        let peer_id = PeerId {
706            owner_id: 10,
707            id: 3,
708        };
709        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
710        let peer_id = PeerId {
711            owner_id: u32::MAX,
712            id: 3,
713        };
714        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
715        let peer_id = PeerId {
716            owner_id: 10,
717            id: u32::MAX,
718        };
719        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
720        let peer_id = PeerId {
721            owner_id: u32::MAX,
722            id: u32::MAX,
723        };
724        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
725    }
726}