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