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
 10pub use prost::{DecodeError, Message};
 11use serde::Serialize;
 12use std::{
 13    any::{Any, TypeId},
 14    cmp,
 15    fmt::{self, Debug},
 16    iter, mem,
 17    path::{Path, PathBuf},
 18    sync::Arc,
 19    time::{Duration, SystemTime, UNIX_EPOCH},
 20};
 21
 22include!(concat!(env!("OUT_DIR"), "/zed.messages.rs"));
 23
 24pub const SSH_PEER_ID: PeerId = PeerId { owner_id: 0, id: 0 };
 25pub const SSH_PROJECT_ID: u64 = 0;
 26
 27pub trait EnvelopedMessage: Clone + Debug + Serialize + Sized + Send + Sync + 'static {
 28    const NAME: &'static str;
 29    const PRIORITY: MessagePriority;
 30    fn into_envelope(
 31        self,
 32        id: u32,
 33        responding_to: Option<u32>,
 34        original_sender_id: Option<PeerId>,
 35    ) -> Envelope;
 36    fn from_envelope(envelope: Envelope) -> Option<Self>;
 37}
 38
 39pub trait EntityMessage: EnvelopedMessage {
 40    type Entity;
 41    fn remote_entity_id(&self) -> u64;
 42}
 43
 44pub trait RequestMessage: EnvelopedMessage {
 45    type Response: EnvelopedMessage;
 46}
 47
 48pub trait AnyTypedEnvelope: 'static + Send + Sync {
 49    fn payload_type_id(&self) -> TypeId;
 50    fn payload_type_name(&self) -> &'static str;
 51    fn as_any(&self) -> &dyn Any;
 52    fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync>;
 53    fn is_background(&self) -> bool;
 54    fn original_sender_id(&self) -> Option<PeerId>;
 55    fn sender_id(&self) -> PeerId;
 56    fn message_id(&self) -> u32;
 57}
 58
 59pub enum MessagePriority {
 60    Foreground,
 61    Background,
 62}
 63
 64impl<T: EnvelopedMessage> AnyTypedEnvelope for TypedEnvelope<T> {
 65    fn payload_type_id(&self) -> TypeId {
 66        TypeId::of::<T>()
 67    }
 68
 69    fn payload_type_name(&self) -> &'static str {
 70        T::NAME
 71    }
 72
 73    fn as_any(&self) -> &dyn Any {
 74        self
 75    }
 76
 77    fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync> {
 78        self
 79    }
 80
 81    fn is_background(&self) -> bool {
 82        matches!(T::PRIORITY, MessagePriority::Background)
 83    }
 84
 85    fn original_sender_id(&self) -> Option<PeerId> {
 86        self.original_sender_id
 87    }
 88
 89    fn sender_id(&self) -> PeerId {
 90        self.sender_id
 91    }
 92
 93    fn message_id(&self) -> u32 {
 94        self.message_id
 95    }
 96}
 97
 98impl PeerId {
 99    pub fn from_u64(peer_id: u64) -> Self {
100        let owner_id = (peer_id >> 32) as u32;
101        let id = peer_id as u32;
102        Self { owner_id, id }
103    }
104
105    pub fn as_u64(self) -> u64 {
106        ((self.owner_id as u64) << 32) | (self.id as u64)
107    }
108}
109
110impl Copy for PeerId {}
111
112impl Eq for PeerId {}
113
114impl Ord for PeerId {
115    fn cmp(&self, other: &Self) -> cmp::Ordering {
116        self.owner_id
117            .cmp(&other.owner_id)
118            .then_with(|| self.id.cmp(&other.id))
119    }
120}
121
122impl PartialOrd for PeerId {
123    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
124        Some(self.cmp(other))
125    }
126}
127
128impl std::hash::Hash for PeerId {
129    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
130        self.owner_id.hash(state);
131        self.id.hash(state);
132    }
133}
134
135impl fmt::Display for PeerId {
136    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137        write!(f, "{}/{}", self.owner_id, self.id)
138    }
139}
140
141pub trait FromProto {
142    fn from_proto(proto: String) -> Self;
143}
144
145pub trait ToProto {
146    fn to_proto(self) -> String;
147}
148
149impl FromProto for PathBuf {
150    #[cfg(target_os = "windows")]
151    fn from_proto(proto: String) -> Self {
152        proto.split("/").collect()
153    }
154
155    #[cfg(not(target_os = "windows"))]
156    fn from_proto(proto: String) -> Self {
157        PathBuf::from(proto)
158    }
159}
160
161impl FromProto for Arc<Path> {
162    fn from_proto(proto: String) -> Self {
163        PathBuf::from_proto(proto).into()
164    }
165}
166
167impl ToProto for PathBuf {
168    #[cfg(target_os = "windows")]
169    fn to_proto(self) -> String {
170        self.components()
171            .map(|comp| comp.as_os_str().to_string_lossy().to_string())
172            .collect::<Vec<_>>()
173            .join("/")
174    }
175
176    #[cfg(not(target_os = "windows"))]
177    fn to_proto(self) -> String {
178        self.to_string_lossy().to_string()
179    }
180}
181
182impl ToProto for &Path {
183    #[cfg(target_os = "windows")]
184    fn to_proto(self) -> String {
185        self.components()
186            .map(|comp| comp.as_os_str().to_string_lossy().to_string())
187            .collect::<Vec<_>>()
188            .join("/")
189    }
190
191    #[cfg(not(target_os = "windows"))]
192    fn to_proto(self) -> String {
193        self.to_string_lossy().to_string()
194    }
195}
196
197messages!(
198    (AcceptTermsOfService, Foreground),
199    (AcceptTermsOfServiceResponse, Foreground),
200    (Ack, Foreground),
201    (AckBufferOperation, Background),
202    (AckChannelMessage, Background),
203    (ActivateToolchain, Foreground),
204    (ActiveToolchain, Foreground),
205    (ActiveToolchainResponse, Foreground),
206    (AddNotification, Foreground),
207    (AddProjectCollaborator, Foreground),
208    (AddWorktree, Foreground),
209    (AddWorktreeResponse, Foreground),
210    (AdvertiseContexts, Foreground),
211    (ApplyCodeAction, Background),
212    (ApplyCodeActionResponse, Background),
213    (ApplyCompletionAdditionalEdits, Background),
214    (ApplyCompletionAdditionalEditsResponse, Background),
215    (BlameBuffer, Foreground),
216    (BlameBufferResponse, Foreground),
217    (BufferReloaded, Foreground),
218    (BufferSaved, Foreground),
219    (Call, Foreground),
220    (CallCanceled, Foreground),
221    (CancelCall, Foreground),
222    (CancelLanguageServerWork, Foreground),
223    (ChannelMessageSent, Foreground),
224    (ChannelMessageUpdate, Foreground),
225    (CloseBuffer, Foreground),
226    (Commit, Background),
227    (ComputeEmbeddings, Background),
228    (ComputeEmbeddingsResponse, Background),
229    (CopyProjectEntry, Foreground),
230    (CountLanguageModelTokens, Background),
231    (CountLanguageModelTokensResponse, Background),
232    (CreateBufferForPeer, Foreground),
233    (CreateChannel, Foreground),
234    (CreateChannelResponse, Foreground),
235    (CreateContext, Foreground),
236    (CreateContextResponse, Foreground),
237    (CreateProjectEntry, Foreground),
238    (CreateRoom, Foreground),
239    (CreateRoomResponse, Foreground),
240    (DeclineCall, Foreground),
241    (DeleteChannel, Foreground),
242    (DeleteNotification, Foreground),
243    (DeleteProjectEntry, Foreground),
244    (EndStream, Foreground),
245    (Error, Foreground),
246    (ExpandProjectEntry, Foreground),
247    (ExpandProjectEntryResponse, Foreground),
248    (FindSearchCandidatesResponse, Background),
249    (FindSearchCandidates, Background),
250    (FlushBufferedMessages, Foreground),
251    (ExpandAllForProjectEntry, Foreground),
252    (ExpandAllForProjectEntryResponse, Foreground),
253    (Follow, Foreground),
254    (FollowResponse, Foreground),
255    (ApplyCodeActionKind, Foreground),
256    (ApplyCodeActionKindResponse, Foreground),
257    (FormatBuffers, Foreground),
258    (FormatBuffersResponse, Foreground),
259    (FuzzySearchUsers, Foreground),
260    (GetCachedEmbeddings, Background),
261    (GetCachedEmbeddingsResponse, Background),
262    (GetChannelMembers, Foreground),
263    (GetChannelMembersResponse, Foreground),
264    (GetChannelMessages, Background),
265    (GetChannelMessagesById, Background),
266    (GetChannelMessagesResponse, Background),
267    (GetCodeActions, Background),
268    (GetCodeActionsResponse, Background),
269    (GetCompletions, Background),
270    (GetCompletionsResponse, Background),
271    (GetDeclaration, Background),
272    (GetDeclarationResponse, Background),
273    (GetDefinition, Background),
274    (GetDefinitionResponse, Background),
275    (GetDocumentHighlights, Background),
276    (GetDocumentHighlightsResponse, Background),
277    (GetHover, Background),
278    (GetHoverResponse, Background),
279    (GetNotifications, Foreground),
280    (GetNotificationsResponse, Foreground),
281    (GetPanicFiles, Background),
282    (GetPanicFilesResponse, Background),
283    (GetPathMetadata, Background),
284    (GetPathMetadataResponse, Background),
285    (GetPermalinkToLine, Foreground),
286    (GetPermalinkToLineResponse, Foreground),
287    (GetPrivateUserInfo, Foreground),
288    (GetPrivateUserInfoResponse, Foreground),
289    (GetProjectSymbols, Background),
290    (GetProjectSymbolsResponse, Background),
291    (GetReferences, Background),
292    (GetReferencesResponse, Background),
293    (GetSignatureHelp, Background),
294    (GetSignatureHelpResponse, Background),
295    (GetSupermavenApiKey, Background),
296    (GetSupermavenApiKeyResponse, Background),
297    (GetTypeDefinition, Background),
298    (GetTypeDefinitionResponse, Background),
299    (GetImplementation, Background),
300    (GetImplementationResponse, Background),
301    (GetLlmToken, Background),
302    (GetLlmTokenResponse, Background),
303    (OpenUnstagedDiff, Foreground),
304    (OpenUnstagedDiffResponse, Foreground),
305    (OpenUncommittedDiff, Foreground),
306    (OpenUncommittedDiffResponse, Foreground),
307    (GetUsers, Foreground),
308    (GitGetBranches, Background),
309    (GitBranchesResponse, Background),
310    (Hello, Foreground),
311    (HideToast, Background),
312    (IncomingCall, Foreground),
313    (InlayHints, Background),
314    (InlayHintsResponse, Background),
315    (InstallExtension, Background),
316    (InviteChannelMember, Foreground),
317    (JoinChannel, Foreground),
318    (JoinChannelBuffer, Foreground),
319    (JoinChannelBufferResponse, Foreground),
320    (JoinChannelChat, Foreground),
321    (JoinChannelChatResponse, Foreground),
322    (JoinProject, Foreground),
323    (JoinProjectResponse, Foreground),
324    (JoinRoom, Foreground),
325    (JoinRoomResponse, Foreground),
326    (LanguageServerLog, Foreground),
327    (LanguageServerPromptRequest, Foreground),
328    (LanguageServerPromptResponse, Foreground),
329    (LeaveChannelBuffer, Background),
330    (LeaveChannelChat, Foreground),
331    (LeaveProject, Foreground),
332    (LeaveRoom, Foreground),
333    (LinkedEditingRange, Background),
334    (LinkedEditingRangeResponse, Background),
335    (ListRemoteDirectory, Background),
336    (ListRemoteDirectoryResponse, Background),
337    (ListToolchains, Foreground),
338    (ListToolchainsResponse, Foreground),
339    (LspExtExpandMacro, Background),
340    (LspExtExpandMacroResponse, Background),
341    (LspExtOpenDocs, Background),
342    (LspExtOpenDocsResponse, Background),
343    (LspExtSwitchSourceHeader, Background),
344    (LspExtSwitchSourceHeaderResponse, Background),
345    (MarkNotificationRead, Foreground),
346    (MoveChannel, Foreground),
347    (MultiLspQuery, Background),
348    (MultiLspQueryResponse, Background),
349    (OnTypeFormatting, Background),
350    (OnTypeFormattingResponse, Background),
351    (OpenBufferById, Background),
352    (OpenBufferByPath, Background),
353    (OpenBufferForSymbol, Background),
354    (OpenBufferForSymbolResponse, Background),
355    (OpenBufferResponse, Background),
356    (OpenCommitMessageBuffer, Background),
357    (OpenContext, Foreground),
358    (OpenContextResponse, Foreground),
359    (OpenNewBuffer, Foreground),
360    (OpenServerSettings, Foreground),
361    (PerformRename, Background),
362    (PerformRenameResponse, Background),
363    (Ping, Foreground),
364    (PrepareRename, Background),
365    (PrepareRenameResponse, Background),
366    (ProjectEntryResponse, Foreground),
367    (RefreshInlayHints, Foreground),
368    (RefreshLlmToken, Background),
369    (RegisterBufferWithLanguageServers, Background),
370    (RejoinChannelBuffers, Foreground),
371    (RejoinChannelBuffersResponse, Foreground),
372    (RejoinRemoteProjects, Foreground),
373    (RejoinRemoteProjectsResponse, Foreground),
374    (RejoinRoom, Foreground),
375    (RejoinRoomResponse, Foreground),
376    (ReloadBuffers, Foreground),
377    (ReloadBuffersResponse, Foreground),
378    (RemoveChannelMember, Foreground),
379    (RemoveChannelMessage, Foreground),
380    (RemoveContact, Foreground),
381    (RemoveProjectCollaborator, Foreground),
382    (RemoveWorktree, Foreground),
383    (RenameChannel, Foreground),
384    (RenameChannelResponse, Foreground),
385    (RenameProjectEntry, Foreground),
386    (RequestContact, Foreground),
387    (ResolveCompletionDocumentation, Background),
388    (ResolveCompletionDocumentationResponse, Background),
389    (ResolveInlayHint, Background),
390    (ResolveInlayHintResponse, Background),
391    (RefreshCodeLens, Background),
392    (GetCodeLens, Background),
393    (GetCodeLensResponse, Background),
394    (RespondToChannelInvite, Foreground),
395    (RespondToContactRequest, Foreground),
396    (RestartLanguageServers, Foreground),
397    (RoomUpdated, Foreground),
398    (SaveBuffer, Foreground),
399    (SendChannelMessage, Background),
400    (SendChannelMessageResponse, Background),
401    (SetChannelMemberRole, Foreground),
402    (SetChannelVisibility, Foreground),
403    (SetRoomParticipantRole, Foreground),
404    (ShareProject, Foreground),
405    (ShareProjectResponse, Foreground),
406    (ShowContacts, Foreground),
407    (ShutdownRemoteServer, Foreground),
408    (Stage, Background),
409    (StartLanguageServer, Foreground),
410    (SubscribeToChannels, Foreground),
411    (SyncExtensions, Background),
412    (SyncExtensionsResponse, Background),
413    (BreakpointsForFile, Background),
414    (ToggleBreakpoint, Foreground),
415    (SynchronizeBuffers, Foreground),
416    (SynchronizeBuffersResponse, Foreground),
417    (SynchronizeContexts, Foreground),
418    (SynchronizeContextsResponse, Foreground),
419    (TaskContext, Background),
420    (TaskContextForLocation, Background),
421    (Test, Foreground),
422    (Toast, Background),
423    (Unfollow, Foreground),
424    (UnshareProject, Foreground),
425    (Unstage, Background),
426    (UpdateBuffer, Foreground),
427    (UpdateBufferFile, Foreground),
428    (UpdateChannelBuffer, Foreground),
429    (UpdateChannelBufferCollaborators, Foreground),
430    (UpdateChannelMessage, Foreground),
431    (UpdateChannels, Foreground),
432    (UpdateContacts, Foreground),
433    (UpdateContext, Foreground),
434    (UpdateDiagnosticSummary, Foreground),
435    (UpdateDiffBases, Foreground),
436    (UpdateFollowers, Foreground),
437    (UpdateGitBranch, Background),
438    (UpdateInviteInfo, Foreground),
439    (UpdateLanguageServer, Foreground),
440    (UpdateNotification, Foreground),
441    (UpdateParticipantLocation, Foreground),
442    (UpdateProject, Foreground),
443    (UpdateProjectCollaborator, Foreground),
444    (UpdateUserChannels, Foreground),
445    (UpdateUserPlan, Foreground),
446    (UpdateWorktree, Foreground),
447    (UpdateWorktreeSettings, Foreground),
448    (UpdateRepository, Foreground),
449    (RemoveRepository, Foreground),
450    (UsersResponse, Foreground),
451    (GitReset, Background),
452    (GitCheckoutFiles, Background),
453    (GitShow, Background),
454    (GitCommitDetails, Background),
455    (SetIndexText, Background),
456    (Push, Background),
457    (Fetch, Background),
458    (GetRemotes, Background),
459    (GetRemotesResponse, Background),
460    (Pull, Background),
461    (RemoteMessageResponse, Background),
462    (AskPassRequest, Background),
463    (AskPassResponse, Background),
464    (GitCreateBranch, Background),
465    (GitChangeBranch, Background),
466    (CheckForPushedCommits, Background),
467    (CheckForPushedCommitsResponse, Background),
468    (GitDiff, Background),
469    (GitDiffResponse, Background),
470    (GitInit, Background),
471);
472
473request_messages!(
474    (AcceptTermsOfService, AcceptTermsOfServiceResponse),
475    (ApplyCodeAction, ApplyCodeActionResponse),
476    (
477        ApplyCompletionAdditionalEdits,
478        ApplyCompletionAdditionalEditsResponse
479    ),
480    (Call, Ack),
481    (CancelCall, Ack),
482    (Commit, Ack),
483    (CopyProjectEntry, ProjectEntryResponse),
484    (ComputeEmbeddings, ComputeEmbeddingsResponse),
485    (CreateChannel, CreateChannelResponse),
486    (CreateProjectEntry, ProjectEntryResponse),
487    (CreateRoom, CreateRoomResponse),
488    (DeclineCall, Ack),
489    (DeleteChannel, Ack),
490    (DeleteProjectEntry, ProjectEntryResponse),
491    (ExpandProjectEntry, ExpandProjectEntryResponse),
492    (ExpandAllForProjectEntry, ExpandAllForProjectEntryResponse),
493    (Follow, FollowResponse),
494    (ApplyCodeActionKind, ApplyCodeActionKindResponse),
495    (FormatBuffers, FormatBuffersResponse),
496    (FuzzySearchUsers, UsersResponse),
497    (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
498    (GetChannelMembers, GetChannelMembersResponse),
499    (GetChannelMessages, GetChannelMessagesResponse),
500    (GetChannelMessagesById, GetChannelMessagesResponse),
501    (GetCodeActions, GetCodeActionsResponse),
502    (GetCompletions, GetCompletionsResponse),
503    (GetDefinition, GetDefinitionResponse),
504    (GetDeclaration, GetDeclarationResponse),
505    (GetImplementation, GetImplementationResponse),
506    (GetDocumentHighlights, GetDocumentHighlightsResponse),
507    (GetHover, GetHoverResponse),
508    (GetLlmToken, GetLlmTokenResponse),
509    (GetNotifications, GetNotificationsResponse),
510    (GetPrivateUserInfo, GetPrivateUserInfoResponse),
511    (GetProjectSymbols, GetProjectSymbolsResponse),
512    (GetReferences, GetReferencesResponse),
513    (GetSignatureHelp, GetSignatureHelpResponse),
514    (OpenUnstagedDiff, OpenUnstagedDiffResponse),
515    (OpenUncommittedDiff, OpenUncommittedDiffResponse),
516    (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
517    (GetTypeDefinition, GetTypeDefinitionResponse),
518    (LinkedEditingRange, LinkedEditingRangeResponse),
519    (ListRemoteDirectory, ListRemoteDirectoryResponse),
520    (GetUsers, UsersResponse),
521    (IncomingCall, Ack),
522    (InlayHints, InlayHintsResponse),
523    (GetCodeLens, GetCodeLensResponse),
524    (InviteChannelMember, Ack),
525    (JoinChannel, JoinRoomResponse),
526    (JoinChannelBuffer, JoinChannelBufferResponse),
527    (JoinChannelChat, JoinChannelChatResponse),
528    (JoinProject, JoinProjectResponse),
529    (JoinRoom, JoinRoomResponse),
530    (LeaveChannelBuffer, Ack),
531    (LeaveRoom, Ack),
532    (MarkNotificationRead, Ack),
533    (MoveChannel, Ack),
534    (OnTypeFormatting, OnTypeFormattingResponse),
535    (OpenBufferById, OpenBufferResponse),
536    (OpenBufferByPath, OpenBufferResponse),
537    (OpenBufferForSymbol, OpenBufferForSymbolResponse),
538    (OpenCommitMessageBuffer, OpenBufferResponse),
539    (OpenNewBuffer, OpenBufferResponse),
540    (PerformRename, PerformRenameResponse),
541    (Ping, Ack),
542    (PrepareRename, PrepareRenameResponse),
543    (CountLanguageModelTokens, CountLanguageModelTokensResponse),
544    (RefreshInlayHints, Ack),
545    (RefreshCodeLens, Ack),
546    (RejoinChannelBuffers, RejoinChannelBuffersResponse),
547    (RejoinRoom, RejoinRoomResponse),
548    (ReloadBuffers, ReloadBuffersResponse),
549    (RemoveChannelMember, Ack),
550    (RemoveChannelMessage, Ack),
551    (UpdateChannelMessage, Ack),
552    (RemoveContact, Ack),
553    (RenameChannel, RenameChannelResponse),
554    (RenameProjectEntry, ProjectEntryResponse),
555    (RequestContact, Ack),
556    (
557        ResolveCompletionDocumentation,
558        ResolveCompletionDocumentationResponse
559    ),
560    (ResolveInlayHint, ResolveInlayHintResponse),
561    (RespondToChannelInvite, Ack),
562    (RespondToContactRequest, Ack),
563    (SaveBuffer, BufferSaved),
564    (Stage, Ack),
565    (FindSearchCandidates, FindSearchCandidatesResponse),
566    (SendChannelMessage, SendChannelMessageResponse),
567    (SetChannelMemberRole, Ack),
568    (SetChannelVisibility, Ack),
569    (ShareProject, ShareProjectResponse),
570    (SynchronizeBuffers, SynchronizeBuffersResponse),
571    (TaskContextForLocation, TaskContext),
572    (Test, Test),
573    (Unstage, Ack),
574    (UpdateBuffer, Ack),
575    (UpdateParticipantLocation, Ack),
576    (UpdateProject, Ack),
577    (UpdateWorktree, Ack),
578    (UpdateRepository, Ack),
579    (RemoveRepository, Ack),
580    (LspExtExpandMacro, LspExtExpandMacroResponse),
581    (LspExtOpenDocs, LspExtOpenDocsResponse),
582    (SetRoomParticipantRole, Ack),
583    (BlameBuffer, BlameBufferResponse),
584    (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
585    (MultiLspQuery, MultiLspQueryResponse),
586    (RestartLanguageServers, Ack),
587    (OpenContext, OpenContextResponse),
588    (CreateContext, CreateContextResponse),
589    (SynchronizeContexts, SynchronizeContextsResponse),
590    (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
591    (AddWorktree, AddWorktreeResponse),
592    (ShutdownRemoteServer, Ack),
593    (RemoveWorktree, Ack),
594    (OpenServerSettings, OpenBufferResponse),
595    (GetPermalinkToLine, GetPermalinkToLineResponse),
596    (FlushBufferedMessages, Ack),
597    (LanguageServerPromptRequest, LanguageServerPromptResponse),
598    (GitGetBranches, GitBranchesResponse),
599    (UpdateGitBranch, Ack),
600    (ListToolchains, ListToolchainsResponse),
601    (ActivateToolchain, Ack),
602    (ActiveToolchain, ActiveToolchainResponse),
603    (GetPathMetadata, GetPathMetadataResponse),
604    (GetPanicFiles, GetPanicFilesResponse),
605    (CancelLanguageServerWork, Ack),
606    (SyncExtensions, SyncExtensionsResponse),
607    (InstallExtension, Ack),
608    (RegisterBufferWithLanguageServers, Ack),
609    (GitShow, GitCommitDetails),
610    (GitReset, Ack),
611    (GitCheckoutFiles, Ack),
612    (SetIndexText, Ack),
613    (Push, RemoteMessageResponse),
614    (Fetch, RemoteMessageResponse),
615    (GetRemotes, GetRemotesResponse),
616    (Pull, RemoteMessageResponse),
617    (AskPassRequest, AskPassResponse),
618    (GitCreateBranch, Ack),
619    (GitChangeBranch, Ack),
620    (CheckForPushedCommits, CheckForPushedCommitsResponse),
621    (GitDiff, GitDiffResponse),
622    (GitInit, Ack),
623    (ToggleBreakpoint, Ack),
624);
625
626entity_messages!(
627    {project_id, ShareProject},
628    AddProjectCollaborator,
629    AddWorktree,
630    ApplyCodeAction,
631    ApplyCompletionAdditionalEdits,
632    BlameBuffer,
633    BufferReloaded,
634    BufferSaved,
635    CloseBuffer,
636    Commit,
637    CopyProjectEntry,
638    CreateBufferForPeer,
639    CreateProjectEntry,
640    DeleteProjectEntry,
641    ExpandProjectEntry,
642    ExpandAllForProjectEntry,
643    FindSearchCandidates,
644    ApplyCodeActionKind,
645    FormatBuffers,
646    GetCodeActions,
647    GetCodeLens,
648    GetCompletions,
649    GetDefinition,
650    GetDeclaration,
651    GetImplementation,
652    GetDocumentHighlights,
653    GetHover,
654    GetProjectSymbols,
655    GetReferences,
656    GetSignatureHelp,
657    OpenUnstagedDiff,
658    OpenUncommittedDiff,
659    GetTypeDefinition,
660    InlayHints,
661    JoinProject,
662    LeaveProject,
663    LinkedEditingRange,
664    MultiLspQuery,
665    RestartLanguageServers,
666    OnTypeFormatting,
667    OpenNewBuffer,
668    OpenBufferById,
669    OpenBufferByPath,
670    OpenBufferForSymbol,
671    OpenCommitMessageBuffer,
672    PerformRename,
673    PrepareRename,
674    RefreshInlayHints,
675    RefreshCodeLens,
676    ReloadBuffers,
677    RemoveProjectCollaborator,
678    RenameProjectEntry,
679    ResolveCompletionDocumentation,
680    ResolveInlayHint,
681    SaveBuffer,
682    Stage,
683    StartLanguageServer,
684    SynchronizeBuffers,
685    TaskContextForLocation,
686    UnshareProject,
687    Unstage,
688    UpdateBuffer,
689    UpdateBufferFile,
690    UpdateDiagnosticSummary,
691    UpdateDiffBases,
692    UpdateLanguageServer,
693    UpdateProject,
694    UpdateProjectCollaborator,
695    UpdateWorktree,
696    UpdateRepository,
697    RemoveRepository,
698    UpdateWorktreeSettings,
699    LspExtExpandMacro,
700    LspExtOpenDocs,
701    AdvertiseContexts,
702    OpenContext,
703    CreateContext,
704    UpdateContext,
705    SynchronizeContexts,
706    LspExtSwitchSourceHeader,
707    LanguageServerLog,
708    Toast,
709    HideToast,
710    OpenServerSettings,
711    GetPermalinkToLine,
712    LanguageServerPromptRequest,
713    GitGetBranches,
714    UpdateGitBranch,
715    ListToolchains,
716    ActivateToolchain,
717    ActiveToolchain,
718    GetPathMetadata,
719    CancelLanguageServerWork,
720    RegisterBufferWithLanguageServers,
721    GitShow,
722    GitReset,
723    GitCheckoutFiles,
724    SetIndexText,
725
726    Push,
727    Fetch,
728    GetRemotes,
729    Pull,
730    AskPassRequest,
731    GitChangeBranch,
732    GitCreateBranch,
733    CheckForPushedCommits,
734    GitDiff,
735    GitInit,
736    BreakpointsForFile,
737    ToggleBreakpoint,
738);
739
740entity_messages!(
741    {channel_id, Channel},
742    ChannelMessageSent,
743    ChannelMessageUpdate,
744    RemoveChannelMessage,
745    UpdateChannelMessage,
746    UpdateChannelBuffer,
747    UpdateChannelBufferCollaborators,
748);
749
750impl From<Timestamp> for SystemTime {
751    fn from(val: Timestamp) -> Self {
752        UNIX_EPOCH
753            .checked_add(Duration::new(val.seconds, val.nanos))
754            .unwrap()
755    }
756}
757
758impl From<SystemTime> for Timestamp {
759    fn from(time: SystemTime) -> Self {
760        let duration = time.duration_since(UNIX_EPOCH).unwrap();
761        Self {
762            seconds: duration.as_secs(),
763            nanos: duration.subsec_nanos(),
764        }
765    }
766}
767
768impl From<u128> for Nonce {
769    fn from(nonce: u128) -> Self {
770        let upper_half = (nonce >> 64) as u64;
771        let lower_half = nonce as u64;
772        Self {
773            upper_half,
774            lower_half,
775        }
776    }
777}
778
779impl From<Nonce> for u128 {
780    fn from(nonce: Nonce) -> Self {
781        let upper_half = (nonce.upper_half as u128) << 64;
782        let lower_half = nonce.lower_half as u128;
783        upper_half | lower_half
784    }
785}
786
787#[cfg(any(test, feature = "test-support"))]
788pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 2;
789#[cfg(not(any(test, feature = "test-support")))]
790pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 256;
791
792#[derive(Clone, Debug)]
793pub enum WorktreeRelatedMessage {
794    UpdateWorktree(UpdateWorktree),
795    UpdateRepository(UpdateRepository),
796    RemoveRepository(RemoveRepository),
797}
798
799impl From<UpdateWorktree> for WorktreeRelatedMessage {
800    fn from(value: UpdateWorktree) -> Self {
801        Self::UpdateWorktree(value)
802    }
803}
804
805impl From<UpdateRepository> for WorktreeRelatedMessage {
806    fn from(value: UpdateRepository) -> Self {
807        Self::UpdateRepository(value)
808    }
809}
810
811impl From<RemoveRepository> for WorktreeRelatedMessage {
812    fn from(value: RemoveRepository) -> Self {
813        Self::RemoveRepository(value)
814    }
815}
816
817pub fn split_worktree_update(mut message: UpdateWorktree) -> impl Iterator<Item = UpdateWorktree> {
818    let mut done = false;
819
820    iter::from_fn(move || {
821        if done {
822            return None;
823        }
824
825        let updated_entries_chunk_size = cmp::min(
826            message.updated_entries.len(),
827            MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
828        );
829        let updated_entries: Vec<_> = message
830            .updated_entries
831            .drain(..updated_entries_chunk_size)
832            .collect();
833
834        let removed_entries_chunk_size = cmp::min(
835            message.removed_entries.len(),
836            MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
837        );
838        let removed_entries = message
839            .removed_entries
840            .drain(..removed_entries_chunk_size)
841            .collect();
842
843        let mut updated_repositories = Vec::new();
844        let mut limit = MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE;
845        while let Some(repo) = message.updated_repositories.first_mut() {
846            let updated_statuses_limit = cmp::min(repo.updated_statuses.len(), limit);
847            let removed_statuses_limit = cmp::min(repo.removed_statuses.len(), limit);
848
849            updated_repositories.push(RepositoryEntry {
850                work_directory_id: repo.work_directory_id,
851                branch_summary: repo.branch_summary.clone(),
852                updated_statuses: repo
853                    .updated_statuses
854                    .drain(..updated_statuses_limit)
855                    .collect(),
856                removed_statuses: repo
857                    .removed_statuses
858                    .drain(..removed_statuses_limit)
859                    .collect(),
860                current_merge_conflicts: repo.current_merge_conflicts.clone(),
861            });
862            if repo.removed_statuses.is_empty() && repo.updated_statuses.is_empty() {
863                message.updated_repositories.remove(0);
864            }
865            limit = limit.saturating_sub(removed_statuses_limit + updated_statuses_limit);
866            if limit == 0 {
867                break;
868            }
869        }
870
871        done = message.updated_entries.is_empty()
872            && message.removed_entries.is_empty()
873            && message.updated_repositories.is_empty();
874
875        let removed_repositories = if done {
876            mem::take(&mut message.removed_repositories)
877        } else {
878            Default::default()
879        };
880
881        Some(UpdateWorktree {
882            project_id: message.project_id,
883            worktree_id: message.worktree_id,
884            root_name: message.root_name.clone(),
885            abs_path: message.abs_path.clone(),
886            updated_entries,
887            removed_entries,
888            scan_id: message.scan_id,
889            is_last_update: done && message.is_last_update,
890            updated_repositories,
891            removed_repositories,
892        })
893    })
894}
895
896pub fn split_repository_update(
897    mut update: UpdateRepository,
898) -> impl Iterator<Item = UpdateRepository> {
899    let mut updated_statuses_iter = mem::take(&mut update.updated_statuses).into_iter().fuse();
900    let mut removed_statuses_iter = mem::take(&mut update.removed_statuses).into_iter().fuse();
901    let mut is_first = true;
902    std::iter::from_fn(move || {
903        let updated_statuses = updated_statuses_iter
904            .by_ref()
905            .take(MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE)
906            .collect::<Vec<_>>();
907        let removed_statuses = removed_statuses_iter
908            .by_ref()
909            .take(MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE)
910            .collect::<Vec<_>>();
911        if updated_statuses.is_empty() && removed_statuses.is_empty() && !is_first {
912            return None;
913        }
914        is_first = false;
915        Some(UpdateRepository {
916            updated_statuses,
917            removed_statuses,
918            ..update.clone()
919        })
920    })
921}
922
923pub fn split_worktree_related_message(
924    message: WorktreeRelatedMessage,
925) -> Box<dyn Iterator<Item = WorktreeRelatedMessage> + Send> {
926    match message {
927        WorktreeRelatedMessage::UpdateWorktree(message) => {
928            Box::new(split_worktree_update(message).map(WorktreeRelatedMessage::UpdateWorktree))
929        }
930        WorktreeRelatedMessage::UpdateRepository(message) => {
931            Box::new(split_repository_update(message).map(WorktreeRelatedMessage::UpdateRepository))
932        }
933        WorktreeRelatedMessage::RemoveRepository(update) => Box::new([update.into()].into_iter()),
934    }
935}
936
937#[cfg(test)]
938mod tests {
939    use super::*;
940
941    #[test]
942    fn test_converting_peer_id_from_and_to_u64() {
943        let peer_id = PeerId {
944            owner_id: 10,
945            id: 3,
946        };
947        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
948        let peer_id = PeerId {
949            owner_id: u32::MAX,
950            id: 3,
951        };
952        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
953        let peer_id = PeerId {
954            owner_id: 10,
955            id: u32::MAX,
956        };
957        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
958        let peer_id = PeerId {
959            owner_id: u32::MAX,
960            id: u32::MAX,
961        };
962        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
963    }
964
965    #[test]
966    #[cfg(target_os = "windows")]
967    fn test_proto() {
968        fn generate_proto_path(path: PathBuf) -> PathBuf {
969            let proto = path.to_proto();
970            PathBuf::from_proto(proto)
971        }
972
973        let path = PathBuf::from("C:\\foo\\bar");
974        assert_eq!(path, generate_proto_path(path.clone()));
975
976        let path = PathBuf::from("C:/foo/bar/");
977        assert_eq!(path, generate_proto_path(path.clone()));
978
979        let path = PathBuf::from("C:/foo\\bar\\");
980        assert_eq!(path, generate_proto_path(path.clone()));
981    }
982}