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