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