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