proto.rs

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