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