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                work_directory_id: repo.work_directory_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    let mut is_first = true;
889    std::iter::from_fn(move || {
890        let updated_statuses = updated_statuses_iter
891            .by_ref()
892            .take(MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE)
893            .collect::<Vec<_>>();
894        let removed_statuses = removed_statuses_iter
895            .by_ref()
896            .take(MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE)
897            .collect::<Vec<_>>();
898        if updated_statuses.is_empty() && removed_statuses.is_empty() && !is_first {
899            return None;
900        }
901        is_first = false;
902        Some(UpdateRepository {
903            updated_statuses,
904            removed_statuses,
905            ..update.clone()
906        })
907    })
908}
909
910#[cfg(test)]
911mod tests {
912    use super::*;
913
914    #[test]
915    fn test_converting_peer_id_from_and_to_u64() {
916        let peer_id = PeerId {
917            owner_id: 10,
918            id: 3,
919        };
920        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
921        let peer_id = PeerId {
922            owner_id: u32::MAX,
923            id: 3,
924        };
925        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
926        let peer_id = PeerId {
927            owner_id: 10,
928            id: u32::MAX,
929        };
930        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
931        let peer_id = PeerId {
932            owner_id: u32::MAX,
933            id: u32::MAX,
934        };
935        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
936    }
937
938    #[test]
939    #[cfg(target_os = "windows")]
940    fn test_proto() {
941        fn generate_proto_path(path: PathBuf) -> PathBuf {
942            let proto = path.to_proto();
943            PathBuf::from_proto(proto)
944        }
945
946        let path = PathBuf::from("C:\\foo\\bar");
947        assert_eq!(path, generate_proto_path(path.clone()));
948
949        let path = PathBuf::from("C:/foo/bar/");
950        assert_eq!(path, generate_proto_path(path.clone()));
951
952        let path = PathBuf::from("C:/foo\\bar\\");
953        assert_eq!(path, generate_proto_path(path.clone()));
954    }
955}