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