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 (GitCheckoutFiles, Background),
445 (GitShow, Background),
446 (GitCommitDetails, Background),
447 (SetIndexText, Background),
448);
449
450request_messages!(
451 (AcceptTermsOfService, AcceptTermsOfServiceResponse),
452 (ApplyCodeAction, ApplyCodeActionResponse),
453 (
454 ApplyCompletionAdditionalEdits,
455 ApplyCompletionAdditionalEditsResponse
456 ),
457 (Call, Ack),
458 (CancelCall, Ack),
459 (Commit, Ack),
460 (CopyProjectEntry, ProjectEntryResponse),
461 (ComputeEmbeddings, ComputeEmbeddingsResponse),
462 (CreateChannel, CreateChannelResponse),
463 (CreateProjectEntry, ProjectEntryResponse),
464 (CreateRoom, CreateRoomResponse),
465 (DeclineCall, Ack),
466 (DeleteChannel, Ack),
467 (DeleteProjectEntry, ProjectEntryResponse),
468 (ExpandProjectEntry, ExpandProjectEntryResponse),
469 (ExpandAllForProjectEntry, ExpandAllForProjectEntryResponse),
470 (Follow, FollowResponse),
471 (FormatBuffers, FormatBuffersResponse),
472 (FuzzySearchUsers, UsersResponse),
473 (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
474 (GetChannelMembers, GetChannelMembersResponse),
475 (GetChannelMessages, GetChannelMessagesResponse),
476 (GetChannelMessagesById, GetChannelMessagesResponse),
477 (GetCodeActions, GetCodeActionsResponse),
478 (GetCompletions, GetCompletionsResponse),
479 (GetDefinition, GetDefinitionResponse),
480 (GetDeclaration, GetDeclarationResponse),
481 (GetImplementation, GetImplementationResponse),
482 (GetDocumentHighlights, GetDocumentHighlightsResponse),
483 (GetHover, GetHoverResponse),
484 (GetLlmToken, GetLlmTokenResponse),
485 (GetNotifications, GetNotificationsResponse),
486 (GetPrivateUserInfo, GetPrivateUserInfoResponse),
487 (GetProjectSymbols, GetProjectSymbolsResponse),
488 (GetReferences, GetReferencesResponse),
489 (GetSignatureHelp, GetSignatureHelpResponse),
490 (OpenUnstagedDiff, OpenUnstagedDiffResponse),
491 (OpenUncommittedDiff, OpenUncommittedDiffResponse),
492 (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
493 (GetTypeDefinition, GetTypeDefinitionResponse),
494 (LinkedEditingRange, LinkedEditingRangeResponse),
495 (ListRemoteDirectory, ListRemoteDirectoryResponse),
496 (GetUsers, UsersResponse),
497 (IncomingCall, Ack),
498 (InlayHints, InlayHintsResponse),
499 (InviteChannelMember, Ack),
500 (JoinChannel, JoinRoomResponse),
501 (JoinChannelBuffer, JoinChannelBufferResponse),
502 (JoinChannelChat, JoinChannelChatResponse),
503 (JoinProject, JoinProjectResponse),
504 (JoinRoom, JoinRoomResponse),
505 (LeaveChannelBuffer, Ack),
506 (LeaveRoom, Ack),
507 (MarkNotificationRead, Ack),
508 (MoveChannel, Ack),
509 (OnTypeFormatting, OnTypeFormattingResponse),
510 (OpenBufferById, OpenBufferResponse),
511 (OpenBufferByPath, OpenBufferResponse),
512 (OpenBufferForSymbol, OpenBufferForSymbolResponse),
513 (OpenCommitMessageBuffer, OpenBufferResponse),
514 (OpenNewBuffer, OpenBufferResponse),
515 (PerformRename, PerformRenameResponse),
516 (Ping, Ack),
517 (PrepareRename, PrepareRenameResponse),
518 (CountLanguageModelTokens, CountLanguageModelTokensResponse),
519 (RefreshInlayHints, Ack),
520 (RejoinChannelBuffers, RejoinChannelBuffersResponse),
521 (RejoinRoom, RejoinRoomResponse),
522 (ReloadBuffers, ReloadBuffersResponse),
523 (RemoveChannelMember, Ack),
524 (RemoveChannelMessage, Ack),
525 (UpdateChannelMessage, Ack),
526 (RemoveContact, Ack),
527 (RenameChannel, RenameChannelResponse),
528 (RenameProjectEntry, ProjectEntryResponse),
529 (RequestContact, Ack),
530 (
531 ResolveCompletionDocumentation,
532 ResolveCompletionDocumentationResponse
533 ),
534 (ResolveInlayHint, ResolveInlayHintResponse),
535 (RespondToChannelInvite, Ack),
536 (RespondToContactRequest, Ack),
537 (SaveBuffer, BufferSaved),
538 (Stage, Ack),
539 (FindSearchCandidates, FindSearchCandidatesResponse),
540 (SendChannelMessage, SendChannelMessageResponse),
541 (SetChannelMemberRole, Ack),
542 (SetChannelVisibility, Ack),
543 (ShareProject, ShareProjectResponse),
544 (SynchronizeBuffers, SynchronizeBuffersResponse),
545 (TaskContextForLocation, TaskContext),
546 (Test, Test),
547 (Unstage, Ack),
548 (UpdateBuffer, Ack),
549 (UpdateParticipantLocation, Ack),
550 (UpdateProject, Ack),
551 (UpdateWorktree, Ack),
552 (LspExtExpandMacro, LspExtExpandMacroResponse),
553 (LspExtOpenDocs, LspExtOpenDocsResponse),
554 (SetRoomParticipantRole, Ack),
555 (BlameBuffer, BlameBufferResponse),
556 (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
557 (MultiLspQuery, MultiLspQueryResponse),
558 (RestartLanguageServers, Ack),
559 (OpenContext, OpenContextResponse),
560 (CreateContext, CreateContextResponse),
561 (SynchronizeContexts, SynchronizeContextsResponse),
562 (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
563 (AddWorktree, AddWorktreeResponse),
564 (ShutdownRemoteServer, Ack),
565 (RemoveWorktree, Ack),
566 (OpenServerSettings, OpenBufferResponse),
567 (GetPermalinkToLine, GetPermalinkToLineResponse),
568 (FlushBufferedMessages, Ack),
569 (LanguageServerPromptRequest, LanguageServerPromptResponse),
570 (GitBranches, GitBranchesResponse),
571 (UpdateGitBranch, Ack),
572 (ListToolchains, ListToolchainsResponse),
573 (ActivateToolchain, Ack),
574 (ActiveToolchain, ActiveToolchainResponse),
575 (GetPathMetadata, GetPathMetadataResponse),
576 (GetPanicFiles, GetPanicFilesResponse),
577 (CancelLanguageServerWork, Ack),
578 (SyncExtensions, SyncExtensionsResponse),
579 (InstallExtension, Ack),
580 (RegisterBufferWithLanguageServers, Ack),
581 (GitShow, GitCommitDetails),
582 (GitReset, Ack),
583 (GitCheckoutFiles, Ack),
584 (SetIndexText, Ack),
585);
586
587entity_messages!(
588 {project_id, ShareProject},
589 AddProjectCollaborator,
590 AddWorktree,
591 ApplyCodeAction,
592 ApplyCompletionAdditionalEdits,
593 BlameBuffer,
594 BufferReloaded,
595 BufferSaved,
596 CloseBuffer,
597 Commit,
598 CopyProjectEntry,
599 CreateBufferForPeer,
600 CreateProjectEntry,
601 DeleteProjectEntry,
602 ExpandProjectEntry,
603 ExpandAllForProjectEntry,
604 FindSearchCandidates,
605 FormatBuffers,
606 GetCodeActions,
607 GetCompletions,
608 GetDefinition,
609 GetDeclaration,
610 GetImplementation,
611 GetDocumentHighlights,
612 GetHover,
613 GetProjectSymbols,
614 GetReferences,
615 GetSignatureHelp,
616 OpenUnstagedDiff,
617 OpenUncommittedDiff,
618 GetTypeDefinition,
619 InlayHints,
620 JoinProject,
621 LeaveProject,
622 LinkedEditingRange,
623 MultiLspQuery,
624 RestartLanguageServers,
625 OnTypeFormatting,
626 OpenNewBuffer,
627 OpenBufferById,
628 OpenBufferByPath,
629 OpenBufferForSymbol,
630 OpenCommitMessageBuffer,
631 PerformRename,
632 PrepareRename,
633 RefreshInlayHints,
634 ReloadBuffers,
635 RemoveProjectCollaborator,
636 RenameProjectEntry,
637 ResolveCompletionDocumentation,
638 ResolveInlayHint,
639 SaveBuffer,
640 Stage,
641 StartLanguageServer,
642 SynchronizeBuffers,
643 TaskContextForLocation,
644 UnshareProject,
645 Unstage,
646 UpdateBuffer,
647 UpdateBufferFile,
648 UpdateDiagnosticSummary,
649 UpdateDiffBases,
650 UpdateLanguageServer,
651 UpdateProject,
652 UpdateProjectCollaborator,
653 UpdateWorktree,
654 UpdateWorktreeSettings,
655 LspExtExpandMacro,
656 LspExtOpenDocs,
657 AdvertiseContexts,
658 OpenContext,
659 CreateContext,
660 UpdateContext,
661 SynchronizeContexts,
662 LspExtSwitchSourceHeader,
663 LanguageServerLog,
664 Toast,
665 HideToast,
666 OpenServerSettings,
667 GetPermalinkToLine,
668 LanguageServerPromptRequest,
669 GitBranches,
670 UpdateGitBranch,
671 ListToolchains,
672 ActivateToolchain,
673 ActiveToolchain,
674 GetPathMetadata,
675 CancelLanguageServerWork,
676 RegisterBufferWithLanguageServers,
677 GitShow,
678 GitReset,
679 GitCheckoutFiles,
680 SetIndexText,
681);
682
683entity_messages!(
684 {channel_id, Channel},
685 ChannelMessageSent,
686 ChannelMessageUpdate,
687 RemoveChannelMessage,
688 UpdateChannelMessage,
689 UpdateChannelBuffer,
690 UpdateChannelBufferCollaborators,
691);
692
693impl From<Timestamp> for SystemTime {
694 fn from(val: Timestamp) -> Self {
695 UNIX_EPOCH
696 .checked_add(Duration::new(val.seconds, val.nanos))
697 .unwrap()
698 }
699}
700
701impl From<SystemTime> for Timestamp {
702 fn from(time: SystemTime) -> Self {
703 let duration = time.duration_since(UNIX_EPOCH).unwrap();
704 Self {
705 seconds: duration.as_secs(),
706 nanos: duration.subsec_nanos(),
707 }
708 }
709}
710
711impl From<u128> for Nonce {
712 fn from(nonce: u128) -> Self {
713 let upper_half = (nonce >> 64) as u64;
714 let lower_half = nonce as u64;
715 Self {
716 upper_half,
717 lower_half,
718 }
719 }
720}
721
722impl From<Nonce> for u128 {
723 fn from(nonce: Nonce) -> Self {
724 let upper_half = (nonce.upper_half as u128) << 64;
725 let lower_half = nonce.lower_half as u128;
726 upper_half | lower_half
727 }
728}
729
730#[cfg(any(test, feature = "test-support"))]
731pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 2;
732#[cfg(not(any(test, feature = "test-support")))]
733pub const MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE: usize = 256;
734
735pub fn split_worktree_update(mut message: UpdateWorktree) -> impl Iterator<Item = UpdateWorktree> {
736 let mut done_files = false;
737
738 let mut repository_map = message
739 .updated_repositories
740 .into_iter()
741 .map(|repo| (repo.work_directory_id, repo))
742 .collect::<HashMap<_, _>>();
743
744 iter::from_fn(move || {
745 if done_files {
746 return None;
747 }
748
749 let updated_entries_chunk_size = cmp::min(
750 message.updated_entries.len(),
751 MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
752 );
753 let updated_entries: Vec<_> = message
754 .updated_entries
755 .drain(..updated_entries_chunk_size)
756 .collect();
757
758 let removed_entries_chunk_size = cmp::min(
759 message.removed_entries.len(),
760 MAX_WORKTREE_UPDATE_MAX_CHUNK_SIZE,
761 );
762 let removed_entries = message
763 .removed_entries
764 .drain(..removed_entries_chunk_size)
765 .collect();
766
767 done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
768
769 let mut updated_repositories = Vec::new();
770
771 if !repository_map.is_empty() {
772 for entry in &updated_entries {
773 if let Some(repo) = repository_map.remove(&entry.id) {
774 updated_repositories.push(repo);
775 }
776 }
777 }
778
779 let removed_repositories = if done_files {
780 mem::take(&mut message.removed_repositories)
781 } else {
782 Default::default()
783 };
784
785 if done_files {
786 updated_repositories.extend(mem::take(&mut repository_map).into_values());
787 }
788
789 Some(UpdateWorktree {
790 project_id: message.project_id,
791 worktree_id: message.worktree_id,
792 root_name: message.root_name.clone(),
793 abs_path: message.abs_path.clone(),
794 updated_entries,
795 removed_entries,
796 scan_id: message.scan_id,
797 is_last_update: done_files && message.is_last_update,
798 updated_repositories,
799 removed_repositories,
800 })
801 })
802}
803
804#[cfg(test)]
805mod tests {
806 use super::*;
807
808 #[test]
809 fn test_converting_peer_id_from_and_to_u64() {
810 let peer_id = PeerId {
811 owner_id: 10,
812 id: 3,
813 };
814 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
815 let peer_id = PeerId {
816 owner_id: u32::MAX,
817 id: 3,
818 };
819 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
820 let peer_id = PeerId {
821 owner_id: 10,
822 id: u32::MAX,
823 };
824 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
825 let peer_id = PeerId {
826 owner_id: u32::MAX,
827 id: u32::MAX,
828 };
829 assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
830 }
831
832 #[test]
833 #[cfg(target_os = "windows")]
834 fn test_proto() {
835 fn generate_proto_path(path: PathBuf) -> PathBuf {
836 let proto = path.to_proto();
837 PathBuf::from_proto(proto)
838 }
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 let path = PathBuf::from("C:/foo\\bar\\");
847 assert_eq!(path, generate_proto_path(path.clone()));
848 }
849}