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