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