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