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