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