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    (GetStagedText, Foreground),
220    (GetStagedTextResponse, Foreground),
221    (GetUsers, Foreground),
222    (Hello, Foreground),
223    (IncomingCall, Foreground),
224    (InlayHints, Background),
225    (InlayHintsResponse, Background),
226    (InviteChannelMember, Foreground),
227    (JoinChannel, Foreground),
228    (JoinChannelBuffer, Foreground),
229    (JoinChannelBufferResponse, Foreground),
230    (JoinChannelChat, Foreground),
231    (JoinChannelChatResponse, Foreground),
232    (JoinProject, Foreground),
233    (JoinProjectResponse, Foreground),
234    (JoinRoom, Foreground),
235    (JoinRoomResponse, Foreground),
236    (LeaveChannelBuffer, Background),
237    (LeaveChannelChat, Foreground),
238    (LeaveProject, Foreground),
239    (LeaveRoom, Foreground),
240    (MarkNotificationRead, Foreground),
241    (MoveChannel, Foreground),
242    (OnTypeFormatting, Background),
243    (OnTypeFormattingResponse, Background),
244    (OpenBufferById, Background),
245    (OpenBufferByPath, Background),
246    (OpenBufferForSymbol, Background),
247    (OpenBufferForSymbolResponse, Background),
248    (OpenBufferResponse, Background),
249    (PerformRename, Background),
250    (PerformRenameResponse, Background),
251    (Ping, Foreground),
252    (PrepareRename, Background),
253    (PrepareRenameResponse, Background),
254    (ProjectEntryResponse, Foreground),
255    (CountLanguageModelTokens, Background),
256    (CountLanguageModelTokensResponse, Background),
257    (RefreshLlmToken, Background),
258    (RefreshInlayHints, Foreground),
259    (RejoinChannelBuffers, Foreground),
260    (RejoinChannelBuffersResponse, Foreground),
261    (RejoinRoom, Foreground),
262    (RejoinRoomResponse, Foreground),
263    (ReloadBuffers, Foreground),
264    (ReloadBuffersResponse, Foreground),
265    (RemoveChannelMember, Foreground),
266    (RemoveChannelMessage, Foreground),
267    (UpdateChannelMessage, Foreground),
268    (RemoveContact, Foreground),
269    (RemoveProjectCollaborator, Foreground),
270    (RenameChannel, Foreground),
271    (RenameChannelResponse, Foreground),
272    (RenameProjectEntry, Foreground),
273    (RequestContact, Foreground),
274    (ResolveCompletionDocumentation, Background),
275    (ResolveCompletionDocumentationResponse, Background),
276    (ResolveInlayHint, Background),
277    (ResolveInlayHintResponse, Background),
278    (RespondToChannelInvite, Foreground),
279    (RespondToContactRequest, Foreground),
280    (RoomUpdated, Foreground),
281    (SaveBuffer, Foreground),
282    (SetChannelMemberRole, Foreground),
283    (SetChannelVisibility, Foreground),
284    (SendChannelMessage, Background),
285    (SendChannelMessageResponse, Background),
286    (ShareProject, Foreground),
287    (ShareProjectResponse, Foreground),
288    (ShowContacts, Foreground),
289    (StartLanguageServer, Foreground),
290    (SubscribeToChannels, Foreground),
291    (SynchronizeBuffers, Foreground),
292    (SynchronizeBuffersResponse, Foreground),
293    (TaskContextForLocation, Background),
294    (TaskContext, 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    (LspExtOpenDocs, Background),
320    (LspExtOpenDocsResponse, Background),
321    (SetRoomParticipantRole, Foreground),
322    (BlameBuffer, Foreground),
323    (BlameBufferResponse, Foreground),
324    (RejoinRemoteProjects, Foreground),
325    (RejoinRemoteProjectsResponse, Foreground),
326    (MultiLspQuery, Background),
327    (MultiLspQueryResponse, Background),
328    (ListRemoteDirectory, Background),
329    (ListRemoteDirectoryResponse, Background),
330    (OpenNewBuffer, Foreground),
331    (RestartLanguageServers, Foreground),
332    (LinkedEditingRange, Background),
333    (LinkedEditingRangeResponse, Background),
334    (AdvertiseContexts, Foreground),
335    (OpenContext, Foreground),
336    (OpenContextResponse, Foreground),
337    (CreateContext, Foreground),
338    (CreateContextResponse, Foreground),
339    (UpdateContext, Foreground),
340    (SynchronizeContexts, Foreground),
341    (SynchronizeContextsResponse, Foreground),
342    (LspExtSwitchSourceHeader, Background),
343    (LspExtSwitchSourceHeaderResponse, Background),
344    (AddWorktree, Foreground),
345    (AddWorktreeResponse, Foreground),
346    (FindSearchCandidates, Background),
347    (FindSearchCandidatesResponse, Background),
348    (CloseBuffer, Foreground),
349    (ShutdownRemoteServer, Foreground),
350    (RemoveWorktree, Foreground),
351    (LanguageServerLog, Foreground),
352    (Toast, Background),
353    (HideToast, Background),
354    (OpenServerSettings, Foreground),
355    (GetPermalinkToLine, Foreground),
356    (GetPermalinkToLineResponse, Foreground),
357    (FlushBufferedMessages, Foreground),
358    (LanguageServerPromptRequest, Foreground),
359    (LanguageServerPromptResponse, Foreground),
360    (GitBranches, Background),
361    (GitBranchesResponse, Background),
362    (UpdateGitBranch, Background),
363    (ListToolchains, Foreground),
364    (ListToolchainsResponse, Foreground),
365    (ActivateToolchain, Foreground),
366    (ActiveToolchain, Foreground),
367    (ActiveToolchainResponse, Foreground),
368    (GetPathMetadata, Background),
369    (GetPathMetadataResponse, Background),
370    (GetPanicFiles, Background),
371    (GetPanicFilesResponse, Background),
372    (CancelLanguageServerWork, Foreground),
373    (SyncExtensions, Background),
374    (SyncExtensionsResponse, Background),
375    (InstallExtension, Background),
376    (RegisterBufferWithLanguageServers, Background),
377);
378
379request_messages!(
380    (AcceptTermsOfService, AcceptTermsOfServiceResponse),
381    (ApplyCodeAction, ApplyCodeActionResponse),
382    (
383        ApplyCompletionAdditionalEdits,
384        ApplyCompletionAdditionalEditsResponse
385    ),
386    (Call, Ack),
387    (CancelCall, Ack),
388    (CopyProjectEntry, ProjectEntryResponse),
389    (ComputeEmbeddings, ComputeEmbeddingsResponse),
390    (CreateChannel, CreateChannelResponse),
391    (CreateProjectEntry, ProjectEntryResponse),
392    (CreateRoom, CreateRoomResponse),
393    (DeclineCall, Ack),
394    (DeleteChannel, Ack),
395    (DeleteProjectEntry, ProjectEntryResponse),
396    (ExpandProjectEntry, ExpandProjectEntryResponse),
397    (Follow, FollowResponse),
398    (FormatBuffers, FormatBuffersResponse),
399    (FuzzySearchUsers, UsersResponse),
400    (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
401    (GetChannelMembers, GetChannelMembersResponse),
402    (GetChannelMessages, GetChannelMessagesResponse),
403    (GetChannelMessagesById, GetChannelMessagesResponse),
404    (GetCodeActions, GetCodeActionsResponse),
405    (GetCompletions, GetCompletionsResponse),
406    (GetDefinition, GetDefinitionResponse),
407    (GetDeclaration, GetDeclarationResponse),
408    (GetImplementation, GetImplementationResponse),
409    (GetDocumentHighlights, GetDocumentHighlightsResponse),
410    (GetHover, GetHoverResponse),
411    (GetLlmToken, GetLlmTokenResponse),
412    (GetNotifications, GetNotificationsResponse),
413    (GetPrivateUserInfo, GetPrivateUserInfoResponse),
414    (GetProjectSymbols, GetProjectSymbolsResponse),
415    (GetReferences, GetReferencesResponse),
416    (GetSignatureHelp, GetSignatureHelpResponse),
417    (GetStagedText, GetStagedTextResponse),
418    (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
419    (GetTypeDefinition, GetTypeDefinitionResponse),
420    (LinkedEditingRange, LinkedEditingRangeResponse),
421    (ListRemoteDirectory, ListRemoteDirectoryResponse),
422    (GetUsers, UsersResponse),
423    (IncomingCall, Ack),
424    (InlayHints, InlayHintsResponse),
425    (InviteChannelMember, Ack),
426    (JoinChannel, JoinRoomResponse),
427    (JoinChannelBuffer, JoinChannelBufferResponse),
428    (JoinChannelChat, JoinChannelChatResponse),
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    (LspExtOpenDocs, LspExtOpenDocsResponse),
477    (SetRoomParticipantRole, Ack),
478    (BlameBuffer, BlameBufferResponse),
479    (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
480    (MultiLspQuery, MultiLspQueryResponse),
481    (RestartLanguageServers, Ack),
482    (OpenContext, OpenContextResponse),
483    (CreateContext, CreateContextResponse),
484    (SynchronizeContexts, SynchronizeContextsResponse),
485    (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
486    (AddWorktree, AddWorktreeResponse),
487    (ShutdownRemoteServer, Ack),
488    (RemoveWorktree, Ack),
489    (OpenServerSettings, OpenBufferResponse),
490    (GetPermalinkToLine, GetPermalinkToLineResponse),
491    (FlushBufferedMessages, Ack),
492    (LanguageServerPromptRequest, LanguageServerPromptResponse),
493    (GitBranches, GitBranchesResponse),
494    (UpdateGitBranch, Ack),
495    (ListToolchains, ListToolchainsResponse),
496    (ActivateToolchain, Ack),
497    (ActiveToolchain, ActiveToolchainResponse),
498    (GetPathMetadata, GetPathMetadataResponse),
499    (GetPanicFiles, GetPanicFilesResponse),
500    (CancelLanguageServerWork, Ack),
501    (SyncExtensions, SyncExtensionsResponse),
502    (InstallExtension, Ack),
503    (RegisterBufferWithLanguageServers, Ack),
504);
505
506entity_messages!(
507    {project_id, ShareProject},
508    AddProjectCollaborator,
509    AddWorktree,
510    ApplyCodeAction,
511    ApplyCompletionAdditionalEdits,
512    BlameBuffer,
513    BufferReloaded,
514    BufferSaved,
515    CloseBuffer,
516    CopyProjectEntry,
517    CreateBufferForPeer,
518    CreateProjectEntry,
519    DeleteProjectEntry,
520    ExpandProjectEntry,
521    FindSearchCandidates,
522    FormatBuffers,
523    GetCodeActions,
524    GetCompletions,
525    GetDefinition,
526    GetDeclaration,
527    GetImplementation,
528    GetDocumentHighlights,
529    GetHover,
530    GetProjectSymbols,
531    GetReferences,
532    GetSignatureHelp,
533    GetStagedText,
534    GetTypeDefinition,
535    InlayHints,
536    JoinProject,
537    LeaveProject,
538    LinkedEditingRange,
539    MultiLspQuery,
540    RestartLanguageServers,
541    OnTypeFormatting,
542    OpenNewBuffer,
543    OpenBufferById,
544    OpenBufferByPath,
545    OpenBufferForSymbol,
546    PerformRename,
547    PrepareRename,
548    RefreshInlayHints,
549    ReloadBuffers,
550    RemoveProjectCollaborator,
551    RenameProjectEntry,
552    ResolveCompletionDocumentation,
553    ResolveInlayHint,
554    SaveBuffer,
555    StartLanguageServer,
556    SynchronizeBuffers,
557    TaskContextForLocation,
558    UnshareProject,
559    UpdateBuffer,
560    UpdateBufferFile,
561    UpdateDiagnosticSummary,
562    UpdateDiffBase,
563    UpdateLanguageServer,
564    UpdateProject,
565    UpdateProjectCollaborator,
566    UpdateWorktree,
567    UpdateWorktreeSettings,
568    LspExtExpandMacro,
569    LspExtOpenDocs,
570    AdvertiseContexts,
571    OpenContext,
572    CreateContext,
573    UpdateContext,
574    SynchronizeContexts,
575    LspExtSwitchSourceHeader,
576    LanguageServerLog,
577    Toast,
578    HideToast,
579    OpenServerSettings,
580    GetPermalinkToLine,
581    LanguageServerPromptRequest,
582    GitBranches,
583    UpdateGitBranch,
584    ListToolchains,
585    ActivateToolchain,
586    ActiveToolchain,
587    GetPathMetadata,
588    CancelLanguageServerWork,
589    RegisterBufferWithLanguageServers,
590);
591
592entity_messages!(
593    {channel_id, Channel},
594    ChannelMessageSent,
595    ChannelMessageUpdate,
596    RemoveChannelMessage,
597    UpdateChannelMessage,
598    UpdateChannelBuffer,
599    UpdateChannelBufferCollaborators,
600);
601
602impl From<Timestamp> for SystemTime {
603    fn from(val: Timestamp) -> Self {
604        UNIX_EPOCH
605            .checked_add(Duration::new(val.seconds, val.nanos))
606            .unwrap()
607    }
608}
609
610impl From<SystemTime> for Timestamp {
611    fn from(time: SystemTime) -> Self {
612        let duration = time.duration_since(UNIX_EPOCH).unwrap();
613        Self {
614            seconds: duration.as_secs(),
615            nanos: duration.subsec_nanos(),
616        }
617    }
618}
619
620impl From<u128> for Nonce {
621    fn from(nonce: u128) -> Self {
622        let upper_half = (nonce >> 64) as u64;
623        let lower_half = nonce as u64;
624        Self {
625            upper_half,
626            lower_half,
627        }
628    }
629}
630
631impl From<Nonce> for u128 {
632    fn from(nonce: Nonce) -> Self {
633        let upper_half = (nonce.upper_half as u128) << 64;
634        let lower_half = nonce.lower_half as u128;
635        upper_half | lower_half
636    }
637}
638
639#[cfg(any(test, feature = "test-support"))]
640pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 2;
641#[cfg(not(any(test, feature = "test-support")))]
642pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 256;
643
644pub fn split_worktree_update(mut message: UpdateWorktree) -> impl Iterator<Item = UpdateWorktree> {
645    let mut done_files = false;
646
647    let mut repository_map = message
648        .updated_repositories
649        .into_iter()
650        .map(|repo| (repo.work_directory_id, repo))
651        .collect::<HashMap<_, _>>();
652
653    iter::from_fn(move || {
654        if done_files {
655            return None;
656        }
657
658        let updated_entries_chunk_size = cmp::min(
659            message.updated_entries.len(),
660            MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
661        );
662        let updated_entries: Vec<_> = message
663            .updated_entries
664            .drain(..updated_entries_chunk_size)
665            .collect();
666
667        let removed_entries_chunk_size = cmp::min(
668            message.removed_entries.len(),
669            MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
670        );
671        let removed_entries = message
672            .removed_entries
673            .drain(..removed_entries_chunk_size)
674            .collect();
675
676        done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
677
678        let mut updated_repositories = Vec::new();
679
680        if !repository_map.is_empty() {
681            for entry in &updated_entries {
682                if let Some(repo) = repository_map.remove(&entry.id) {
683                    updated_repositories.push(repo);
684                }
685            }
686        }
687
688        let removed_repositories = if done_files {
689            mem::take(&mut message.removed_repositories)
690        } else {
691            Default::default()
692        };
693
694        if done_files {
695            updated_repositories.extend(mem::take(&mut repository_map).into_values());
696        }
697
698        Some(UpdateWorktree {
699            project_id: message.project_id,
700            worktree_id: message.worktree_id,
701            root_name: message.root_name.clone(),
702            abs_path: message.abs_path.clone(),
703            updated_entries,
704            removed_entries,
705            scan_id: message.scan_id,
706            is_last_update: done_files && message.is_last_update,
707            updated_repositories,
708            removed_repositories,
709        })
710    })
711}
712
713#[cfg(test)]
714mod tests {
715    use super::*;
716
717    #[test]
718    fn test_converting_peer_id_from_and_to_u64() {
719        let peer_id = PeerId {
720            owner_id: 10,
721            id: 3,
722        };
723        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
724        let peer_id = PeerId {
725            owner_id: u32::MAX,
726            id: 3,
727        };
728        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
729        let peer_id = PeerId {
730            owner_id: 10,
731            id: u32::MAX,
732        };
733        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
734        let peer_id = PeerId {
735            owner_id: u32::MAX,
736            id: u32::MAX,
737        };
738        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
739    }
740}