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