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