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