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    (AddNotification, Foreground),
204    (AddProjectCollaborator, Foreground),
205    (ApplyCodeAction, Background),
206    (ApplyCodeActionResponse, Background),
207    (ApplyCompletionAdditionalEdits, Background),
208    (ApplyCompletionAdditionalEditsResponse, Background),
209    (BufferReloaded, Foreground),
210    (BufferSaved, Foreground),
211    (Call, Foreground),
212    (CallCanceled, Foreground),
213    (CancelCall, Foreground),
214    (ChannelMessageSent, Foreground),
215    (ChannelMessageUpdate, Foreground),
216    (Commit, Background),
217    (ComputeEmbeddings, Background),
218    (ComputeEmbeddingsResponse, Background),
219    (CopyProjectEntry, Foreground),
220    (CreateBufferForPeer, Foreground),
221    (CreateChannel, Foreground),
222    (CreateChannelResponse, Foreground),
223    (CreateProjectEntry, Foreground),
224    (CreateRoom, Foreground),
225    (CreateRoomResponse, Foreground),
226    (DeclineCall, Foreground),
227    (DeleteChannel, Foreground),
228    (DeleteNotification, Foreground),
229    (UpdateNotification, Foreground),
230    (DeleteProjectEntry, Foreground),
231    (EndStream, Foreground),
232    (Error, Foreground),
233    (ExpandProjectEntry, Foreground),
234    (ExpandProjectEntryResponse, Foreground),
235    (ExpandAllForProjectEntry, Foreground),
236    (ExpandAllForProjectEntryResponse, Foreground),
237    (Follow, Foreground),
238    (FollowResponse, Foreground),
239    (ApplyCodeActionKind, Foreground),
240    (ApplyCodeActionKindResponse, Foreground),
241    (FormatBuffers, Foreground),
242    (FormatBuffersResponse, Foreground),
243    (FuzzySearchUsers, Foreground),
244    (GetCachedEmbeddings, Background),
245    (GetCachedEmbeddingsResponse, Background),
246    (GetChannelMembers, Foreground),
247    (GetChannelMembersResponse, Foreground),
248    (GetChannelMessages, Background),
249    (GetChannelMessagesById, Background),
250    (GetChannelMessagesResponse, Background),
251    (GetCodeActions, Background),
252    (GetCodeActionsResponse, Background),
253    (GetCompletions, Background),
254    (GetCompletionsResponse, Background),
255    (GetDefinition, Background),
256    (GetDefinitionResponse, Background),
257    (GetDeclaration, Background),
258    (GetDeclarationResponse, Background),
259    (GetDocumentHighlights, Background),
260    (GetDocumentHighlightsResponse, Background),
261    (GetHover, Background),
262    (GetHoverResponse, Background),
263    (GetNotifications, Foreground),
264    (GetNotificationsResponse, Foreground),
265    (GetPrivateUserInfo, Foreground),
266    (GetPrivateUserInfoResponse, Foreground),
267    (GetProjectSymbols, Background),
268    (GetProjectSymbolsResponse, Background),
269    (GetReferences, Background),
270    (GetReferencesResponse, Background),
271    (GetSignatureHelp, Background),
272    (GetSignatureHelpResponse, Background),
273    (GetSupermavenApiKey, Background),
274    (GetSupermavenApiKeyResponse, Background),
275    (GetTypeDefinition, Background),
276    (GetTypeDefinitionResponse, Background),
277    (GetImplementation, Background),
278    (GetImplementationResponse, Background),
279    (GetLlmToken, Background),
280    (GetLlmTokenResponse, Background),
281    (OpenUnstagedDiff, Foreground),
282    (OpenUnstagedDiffResponse, Foreground),
283    (OpenUncommittedDiff, Foreground),
284    (OpenUncommittedDiffResponse, Foreground),
285    (GetUsers, Foreground),
286    (Hello, Foreground),
287    (IncomingCall, Foreground),
288    (InlayHints, Background),
289    (InlayHintsResponse, Background),
290    (InviteChannelMember, Foreground),
291    (JoinChannel, Foreground),
292    (JoinChannelBuffer, Foreground),
293    (JoinChannelBufferResponse, Foreground),
294    (JoinChannelChat, Foreground),
295    (JoinChannelChatResponse, Foreground),
296    (JoinProject, Foreground),
297    (JoinProjectResponse, Foreground),
298    (JoinRoom, Foreground),
299    (JoinRoomResponse, Foreground),
300    (LeaveChannelBuffer, Background),
301    (LeaveChannelChat, Foreground),
302    (LeaveProject, Foreground),
303    (LeaveRoom, Foreground),
304    (MarkNotificationRead, Foreground),
305    (MoveChannel, Foreground),
306    (OnTypeFormatting, Background),
307    (OnTypeFormattingResponse, Background),
308    (OpenBufferById, Background),
309    (OpenBufferByPath, Background),
310    (OpenBufferForSymbol, Background),
311    (OpenBufferForSymbolResponse, Background),
312    (OpenBufferResponse, Background),
313    (OpenCommitMessageBuffer, Background),
314    (PerformRename, Background),
315    (PerformRenameResponse, Background),
316    (Ping, Foreground),
317    (PrepareRename, Background),
318    (PrepareRenameResponse, Background),
319    (ProjectEntryResponse, Foreground),
320    (CountLanguageModelTokens, Background),
321    (CountLanguageModelTokensResponse, Background),
322    (RefreshLlmToken, Background),
323    (RefreshInlayHints, Foreground),
324    (RejoinChannelBuffers, Foreground),
325    (RejoinChannelBuffersResponse, Foreground),
326    (RejoinRoom, Foreground),
327    (RejoinRoomResponse, Foreground),
328    (ReloadBuffers, Foreground),
329    (ReloadBuffersResponse, Foreground),
330    (RemoveChannelMember, Foreground),
331    (RemoveChannelMessage, Foreground),
332    (UpdateChannelMessage, Foreground),
333    (RemoveContact, Foreground),
334    (RemoveProjectCollaborator, Foreground),
335    (RenameChannel, Foreground),
336    (RenameChannelResponse, Foreground),
337    (RenameProjectEntry, Foreground),
338    (RequestContact, Foreground),
339    (ResolveCompletionDocumentation, Background),
340    (ResolveCompletionDocumentationResponse, Background),
341    (ResolveInlayHint, Background),
342    (ResolveInlayHintResponse, Background),
343    (RespondToChannelInvite, Foreground),
344    (RespondToContactRequest, Foreground),
345    (RoomUpdated, Foreground),
346    (SaveBuffer, Foreground),
347    (SetChannelMemberRole, Foreground),
348    (SetChannelVisibility, Foreground),
349    (SendChannelMessage, Background),
350    (SendChannelMessageResponse, Background),
351    (ShareProject, Foreground),
352    (ShareProjectResponse, Foreground),
353    (ShowContacts, Foreground),
354    (Stage, Background),
355    (StartLanguageServer, Foreground),
356    (SubscribeToChannels, Foreground),
357    (SynchronizeBuffers, Foreground),
358    (SynchronizeBuffersResponse, Foreground),
359    (TaskContextForLocation, Background),
360    (TaskContext, Background),
361    (Test, Foreground),
362    (Unfollow, Foreground),
363    (UnshareProject, Foreground),
364    (Unstage, Background),
365    (UpdateBuffer, Foreground),
366    (UpdateBufferFile, Foreground),
367    (UpdateChannelBuffer, Foreground),
368    (UpdateChannelBufferCollaborators, Foreground),
369    (UpdateChannels, Foreground),
370    (UpdateUserChannels, Foreground),
371    (UpdateContacts, Foreground),
372    (UpdateDiagnosticSummary, Foreground),
373    (UpdateDiffBases, Foreground),
374    (UpdateFollowers, Foreground),
375    (UpdateInviteInfo, Foreground),
376    (UpdateLanguageServer, Foreground),
377    (UpdateParticipantLocation, Foreground),
378    (UpdateProject, Foreground),
379    (UpdateProjectCollaborator, Foreground),
380    (UpdateUserPlan, Foreground),
381    (UpdateWorktree, Foreground),
382    (UpdateWorktreeSettings, Foreground),
383    (UsersResponse, Foreground),
384    (LspExtExpandMacro, Background),
385    (LspExtExpandMacroResponse, Background),
386    (LspExtOpenDocs, Background),
387    (LspExtOpenDocsResponse, Background),
388    (SetRoomParticipantRole, Foreground),
389    (BlameBuffer, Foreground),
390    (BlameBufferResponse, Foreground),
391    (RejoinRemoteProjects, Foreground),
392    (RejoinRemoteProjectsResponse, Foreground),
393    (MultiLspQuery, Background),
394    (MultiLspQueryResponse, Background),
395    (ListRemoteDirectory, Background),
396    (ListRemoteDirectoryResponse, Background),
397    (OpenNewBuffer, Foreground),
398    (RestartLanguageServers, Foreground),
399    (LinkedEditingRange, Background),
400    (LinkedEditingRangeResponse, Background),
401    (AdvertiseContexts, Foreground),
402    (OpenContext, Foreground),
403    (OpenContextResponse, Foreground),
404    (CreateContext, Foreground),
405    (CreateContextResponse, Foreground),
406    (UpdateContext, Foreground),
407    (SynchronizeContexts, Foreground),
408    (SynchronizeContextsResponse, Foreground),
409    (LspExtSwitchSourceHeader, Background),
410    (LspExtSwitchSourceHeaderResponse, Background),
411    (AddWorktree, Foreground),
412    (AddWorktreeResponse, Foreground),
413    (FindSearchCandidates, Background),
414    (FindSearchCandidatesResponse, Background),
415    (CloseBuffer, Foreground),
416    (ShutdownRemoteServer, Foreground),
417    (RemoveWorktree, Foreground),
418    (LanguageServerLog, Foreground),
419    (Toast, Background),
420    (HideToast, Background),
421    (OpenServerSettings, Foreground),
422    (GetPermalinkToLine, Foreground),
423    (GetPermalinkToLineResponse, Foreground),
424    (FlushBufferedMessages, Foreground),
425    (LanguageServerPromptRequest, Foreground),
426    (LanguageServerPromptResponse, Foreground),
427    (GitGetBranches, Background),
428    (GitBranchesResponse, Background),
429    (UpdateGitBranch, Background),
430    (ListToolchains, Foreground),
431    (ListToolchainsResponse, Foreground),
432    (ActivateToolchain, Foreground),
433    (ActiveToolchain, Foreground),
434    (ActiveToolchainResponse, Foreground),
435    (GetPathMetadata, Background),
436    (GetPathMetadataResponse, Background),
437    (GetPanicFiles, Background),
438    (GetPanicFilesResponse, Background),
439    (CancelLanguageServerWork, Foreground),
440    (SyncExtensions, Background),
441    (SyncExtensionsResponse, Background),
442    (InstallExtension, Background),
443    (RegisterBufferWithLanguageServers, Background),
444    (GitReset, Background),
445    (GitCheckoutFiles, Background),
446    (GitShow, Background),
447    (GitCommitDetails, Background),
448    (SetIndexText, Background),
449    (Push, Background),
450    (Fetch, Background),
451    (GetRemotes, Background),
452    (GetRemotesResponse, Background),
453    (Pull, Background),
454    (RemoteMessageResponse, Background),
455    (GitCreateBranch, Background),
456    (GitChangeBranch, Background),
457    (CheckForPushedCommits, Background),
458    (CheckForPushedCommitsResponse, Background),
459);
460
461request_messages!(
462    (AcceptTermsOfService, AcceptTermsOfServiceResponse),
463    (ApplyCodeAction, ApplyCodeActionResponse),
464    (
465        ApplyCompletionAdditionalEdits,
466        ApplyCompletionAdditionalEditsResponse
467    ),
468    (Call, Ack),
469    (CancelCall, Ack),
470    (Commit, Ack),
471    (CopyProjectEntry, ProjectEntryResponse),
472    (ComputeEmbeddings, ComputeEmbeddingsResponse),
473    (CreateChannel, CreateChannelResponse),
474    (CreateProjectEntry, ProjectEntryResponse),
475    (CreateRoom, CreateRoomResponse),
476    (DeclineCall, Ack),
477    (DeleteChannel, Ack),
478    (DeleteProjectEntry, ProjectEntryResponse),
479    (ExpandProjectEntry, ExpandProjectEntryResponse),
480    (ExpandAllForProjectEntry, ExpandAllForProjectEntryResponse),
481    (Follow, FollowResponse),
482    (ApplyCodeActionKind, ApplyCodeActionKindResponse),
483    (FormatBuffers, FormatBuffersResponse),
484    (FuzzySearchUsers, UsersResponse),
485    (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
486    (GetChannelMembers, GetChannelMembersResponse),
487    (GetChannelMessages, GetChannelMessagesResponse),
488    (GetChannelMessagesById, GetChannelMessagesResponse),
489    (GetCodeActions, GetCodeActionsResponse),
490    (GetCompletions, GetCompletionsResponse),
491    (GetDefinition, GetDefinitionResponse),
492    (GetDeclaration, GetDeclarationResponse),
493    (GetImplementation, GetImplementationResponse),
494    (GetDocumentHighlights, GetDocumentHighlightsResponse),
495    (GetHover, GetHoverResponse),
496    (GetLlmToken, GetLlmTokenResponse),
497    (GetNotifications, GetNotificationsResponse),
498    (GetPrivateUserInfo, GetPrivateUserInfoResponse),
499    (GetProjectSymbols, GetProjectSymbolsResponse),
500    (GetReferences, GetReferencesResponse),
501    (GetSignatureHelp, GetSignatureHelpResponse),
502    (OpenUnstagedDiff, OpenUnstagedDiffResponse),
503    (OpenUncommittedDiff, OpenUncommittedDiffResponse),
504    (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
505    (GetTypeDefinition, GetTypeDefinitionResponse),
506    (LinkedEditingRange, LinkedEditingRangeResponse),
507    (ListRemoteDirectory, ListRemoteDirectoryResponse),
508    (GetUsers, UsersResponse),
509    (IncomingCall, Ack),
510    (InlayHints, InlayHintsResponse),
511    (InviteChannelMember, Ack),
512    (JoinChannel, JoinRoomResponse),
513    (JoinChannelBuffer, JoinChannelBufferResponse),
514    (JoinChannelChat, JoinChannelChatResponse),
515    (JoinProject, JoinProjectResponse),
516    (JoinRoom, JoinRoomResponse),
517    (LeaveChannelBuffer, Ack),
518    (LeaveRoom, Ack),
519    (MarkNotificationRead, Ack),
520    (MoveChannel, Ack),
521    (OnTypeFormatting, OnTypeFormattingResponse),
522    (OpenBufferById, OpenBufferResponse),
523    (OpenBufferByPath, OpenBufferResponse),
524    (OpenBufferForSymbol, OpenBufferForSymbolResponse),
525    (OpenCommitMessageBuffer, OpenBufferResponse),
526    (OpenNewBuffer, OpenBufferResponse),
527    (PerformRename, PerformRenameResponse),
528    (Ping, Ack),
529    (PrepareRename, PrepareRenameResponse),
530    (CountLanguageModelTokens, CountLanguageModelTokensResponse),
531    (RefreshInlayHints, Ack),
532    (RejoinChannelBuffers, RejoinChannelBuffersResponse),
533    (RejoinRoom, RejoinRoomResponse),
534    (ReloadBuffers, ReloadBuffersResponse),
535    (RemoveChannelMember, Ack),
536    (RemoveChannelMessage, Ack),
537    (UpdateChannelMessage, Ack),
538    (RemoveContact, Ack),
539    (RenameChannel, RenameChannelResponse),
540    (RenameProjectEntry, ProjectEntryResponse),
541    (RequestContact, Ack),
542    (
543        ResolveCompletionDocumentation,
544        ResolveCompletionDocumentationResponse
545    ),
546    (ResolveInlayHint, ResolveInlayHintResponse),
547    (RespondToChannelInvite, Ack),
548    (RespondToContactRequest, Ack),
549    (SaveBuffer, BufferSaved),
550    (Stage, Ack),
551    (FindSearchCandidates, FindSearchCandidatesResponse),
552    (SendChannelMessage, SendChannelMessageResponse),
553    (SetChannelMemberRole, Ack),
554    (SetChannelVisibility, Ack),
555    (ShareProject, ShareProjectResponse),
556    (SynchronizeBuffers, SynchronizeBuffersResponse),
557    (TaskContextForLocation, TaskContext),
558    (Test, Test),
559    (Unstage, Ack),
560    (UpdateBuffer, Ack),
561    (UpdateParticipantLocation, Ack),
562    (UpdateProject, Ack),
563    (UpdateWorktree, Ack),
564    (LspExtExpandMacro, LspExtExpandMacroResponse),
565    (LspExtOpenDocs, LspExtOpenDocsResponse),
566    (SetRoomParticipantRole, Ack),
567    (BlameBuffer, BlameBufferResponse),
568    (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
569    (MultiLspQuery, MultiLspQueryResponse),
570    (RestartLanguageServers, Ack),
571    (OpenContext, OpenContextResponse),
572    (CreateContext, CreateContextResponse),
573    (SynchronizeContexts, SynchronizeContextsResponse),
574    (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
575    (AddWorktree, AddWorktreeResponse),
576    (ShutdownRemoteServer, Ack),
577    (RemoveWorktree, Ack),
578    (OpenServerSettings, OpenBufferResponse),
579    (GetPermalinkToLine, GetPermalinkToLineResponse),
580    (FlushBufferedMessages, Ack),
581    (LanguageServerPromptRequest, LanguageServerPromptResponse),
582    (GitGetBranches, GitBranchesResponse),
583    (UpdateGitBranch, Ack),
584    (ListToolchains, ListToolchainsResponse),
585    (ActivateToolchain, Ack),
586    (ActiveToolchain, ActiveToolchainResponse),
587    (GetPathMetadata, GetPathMetadataResponse),
588    (GetPanicFiles, GetPanicFilesResponse),
589    (CancelLanguageServerWork, Ack),
590    (SyncExtensions, SyncExtensionsResponse),
591    (InstallExtension, Ack),
592    (RegisterBufferWithLanguageServers, Ack),
593    (GitShow, GitCommitDetails),
594    (GitReset, Ack),
595    (GitCheckoutFiles, Ack),
596    (SetIndexText, Ack),
597    (Push, RemoteMessageResponse),
598    (Fetch, RemoteMessageResponse),
599    (GetRemotes, GetRemotesResponse),
600    (Pull, RemoteMessageResponse),
601    (GitCreateBranch, Ack),
602    (GitChangeBranch, Ack),
603    (CheckForPushedCommits, CheckForPushedCommitsResponse),
604);
605
606entity_messages!(
607    {project_id, ShareProject},
608    AddProjectCollaborator,
609    AddWorktree,
610    ApplyCodeAction,
611    ApplyCompletionAdditionalEdits,
612    BlameBuffer,
613    BufferReloaded,
614    BufferSaved,
615    CloseBuffer,
616    Commit,
617    CopyProjectEntry,
618    CreateBufferForPeer,
619    CreateProjectEntry,
620    DeleteProjectEntry,
621    ExpandProjectEntry,
622    ExpandAllForProjectEntry,
623    FindSearchCandidates,
624    ApplyCodeActionKind,
625    FormatBuffers,
626    GetCodeActions,
627    GetCompletions,
628    GetDefinition,
629    GetDeclaration,
630    GetImplementation,
631    GetDocumentHighlights,
632    GetHover,
633    GetProjectSymbols,
634    GetReferences,
635    GetSignatureHelp,
636    OpenUnstagedDiff,
637    OpenUncommittedDiff,
638    GetTypeDefinition,
639    InlayHints,
640    JoinProject,
641    LeaveProject,
642    LinkedEditingRange,
643    MultiLspQuery,
644    RestartLanguageServers,
645    OnTypeFormatting,
646    OpenNewBuffer,
647    OpenBufferById,
648    OpenBufferByPath,
649    OpenBufferForSymbol,
650    OpenCommitMessageBuffer,
651    PerformRename,
652    PrepareRename,
653    RefreshInlayHints,
654    ReloadBuffers,
655    RemoveProjectCollaborator,
656    RenameProjectEntry,
657    ResolveCompletionDocumentation,
658    ResolveInlayHint,
659    SaveBuffer,
660    Stage,
661    StartLanguageServer,
662    SynchronizeBuffers,
663    TaskContextForLocation,
664    UnshareProject,
665    Unstage,
666    UpdateBuffer,
667    UpdateBufferFile,
668    UpdateDiagnosticSummary,
669    UpdateDiffBases,
670    UpdateLanguageServer,
671    UpdateProject,
672    UpdateProjectCollaborator,
673    UpdateWorktree,
674    UpdateWorktreeSettings,
675    LspExtExpandMacro,
676    LspExtOpenDocs,
677    AdvertiseContexts,
678    OpenContext,
679    CreateContext,
680    UpdateContext,
681    SynchronizeContexts,
682    LspExtSwitchSourceHeader,
683    LanguageServerLog,
684    Toast,
685    HideToast,
686    OpenServerSettings,
687    GetPermalinkToLine,
688    LanguageServerPromptRequest,
689    GitGetBranches,
690    UpdateGitBranch,
691    ListToolchains,
692    ActivateToolchain,
693    ActiveToolchain,
694    GetPathMetadata,
695    CancelLanguageServerWork,
696    RegisterBufferWithLanguageServers,
697    GitShow,
698    GitReset,
699    GitCheckoutFiles,
700    SetIndexText,
701    Push,
702    Fetch,
703    GetRemotes,
704    Pull,
705    GitChangeBranch,
706    GitCreateBranch,
707    CheckForPushedCommits,
708);
709
710entity_messages!(
711    {channel_id, Channel},
712    ChannelMessageSent,
713    ChannelMessageUpdate,
714    RemoveChannelMessage,
715    UpdateChannelMessage,
716    UpdateChannelBuffer,
717    UpdateChannelBufferCollaborators,
718);
719
720impl From<Timestamp> for SystemTime {
721    fn from(val: Timestamp) -> Self {
722        UNIX_EPOCH
723            .checked_add(Duration::new(val.seconds, val.nanos))
724            .unwrap()
725    }
726}
727
728impl From<SystemTime> for Timestamp {
729    fn from(time: SystemTime) -> Self {
730        let duration = time.duration_since(UNIX_EPOCH).unwrap();
731        Self {
732            seconds: duration.as_secs(),
733            nanos: duration.subsec_nanos(),
734        }
735    }
736}
737
738impl From<u128> for Nonce {
739    fn from(nonce: u128) -> Self {
740        let upper_half = (nonce >> 64) as u64;
741        let lower_half = nonce as u64;
742        Self {
743            upper_half,
744            lower_half,
745        }
746    }
747}
748
749impl From<Nonce> for u128 {
750    fn from(nonce: Nonce) -> Self {
751        let upper_half = (nonce.upper_half as u128) << 64;
752        let lower_half = nonce.lower_half as u128;
753        upper_half | lower_half
754    }
755}
756
757#[cfg(any(test, feature = "test-support"))]
758pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 2;
759#[cfg(not(any(test, feature = "test-support")))]
760pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 256;
761
762pub fn split_worktree_update(mut message: UpdateWorktree) -> impl Iterator<Item = UpdateWorktree> {
763    let mut done = false;
764
765    iter::from_fn(move || {
766        if done {
767            return None;
768        }
769
770        let updated_entries_chunk_size = cmp::min(
771            message.updated_entries.len(),
772            MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
773        );
774        let updated_entries: Vec<_> = message
775            .updated_entries
776            .drain(..updated_entries_chunk_size)
777            .collect();
778
779        let removed_entries_chunk_size = cmp::min(
780            message.removed_entries.len(),
781            MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
782        );
783        let removed_entries = message
784            .removed_entries
785            .drain(..removed_entries_chunk_size)
786            .collect();
787
788        let mut updated_repositories = Vec::new();
789        let mut limit = MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE;
790        while let Some(repo) = message.updated_repositories.first_mut() {
791            let updated_statuses_limit = cmp::min(repo.updated_statuses.len(), limit);
792            let removed_statuses_limit = cmp::min(repo.removed_statuses.len(), limit);
793
794            updated_repositories.push(RepositoryEntry {
795                work_directory_id: repo.work_directory_id,
796                branch: repo.branch.clone(),
797                branch_summary: repo.branch_summary.clone(),
798                updated_statuses: repo
799                    .updated_statuses
800                    .drain(..updated_statuses_limit)
801                    .collect(),
802                removed_statuses: repo
803                    .removed_statuses
804                    .drain(..removed_statuses_limit)
805                    .collect(),
806                current_merge_conflicts: repo.current_merge_conflicts.clone(),
807            });
808            if repo.removed_statuses.is_empty() && repo.updated_statuses.is_empty() {
809                message.updated_repositories.remove(0);
810            }
811            limit = limit.saturating_sub(removed_statuses_limit + updated_statuses_limit);
812            if limit == 0 {
813                break;
814            }
815        }
816
817        done = message.updated_entries.is_empty()
818            && message.removed_entries.is_empty()
819            && message.updated_repositories.is_empty();
820
821        let removed_repositories = if done {
822            mem::take(&mut message.removed_repositories)
823        } else {
824            Default::default()
825        };
826
827        Some(UpdateWorktree {
828            project_id: message.project_id,
829            worktree_id: message.worktree_id,
830            root_name: message.root_name.clone(),
831            abs_path: message.abs_path.clone(),
832            updated_entries,
833            removed_entries,
834            scan_id: message.scan_id,
835            is_last_update: done && message.is_last_update,
836            updated_repositories,
837            removed_repositories,
838        })
839    })
840}
841
842#[cfg(test)]
843mod tests {
844    use super::*;
845
846    #[test]
847    fn test_converting_peer_id_from_and_to_u64() {
848        let peer_id = PeerId {
849            owner_id: 10,
850            id: 3,
851        };
852        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
853        let peer_id = PeerId {
854            owner_id: u32::MAX,
855            id: 3,
856        };
857        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
858        let peer_id = PeerId {
859            owner_id: 10,
860            id: u32::MAX,
861        };
862        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
863        let peer_id = PeerId {
864            owner_id: u32::MAX,
865            id: u32::MAX,
866        };
867        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
868    }
869
870    #[test]
871    #[cfg(target_os = "windows")]
872    fn test_proto() {
873        fn generate_proto_path(path: PathBuf) -> PathBuf {
874            let proto = path.to_proto();
875            PathBuf::from_proto(proto)
876        }
877
878        let path = PathBuf::from("C:\\foo\\bar");
879        assert_eq!(path, generate_proto_path(path.clone()));
880
881        let path = PathBuf::from("C:/foo/bar/");
882        assert_eq!(path, generate_proto_path(path.clone()));
883
884        let path = PathBuf::from("C:/foo\\bar\\");
885        assert_eq!(path, generate_proto_path(path.clone()));
886    }
887}