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    (RefreshInlayHints, Foreground),
257    (RejoinChannelBuffers, Foreground),
258    (RejoinChannelBuffersResponse, Foreground),
259    (RejoinRoom, Foreground),
260    (RejoinRoomResponse, Foreground),
261    (ReloadBuffers, Foreground),
262    (ReloadBuffersResponse, Foreground),
263    (RemoveChannelMember, Foreground),
264    (RemoveChannelMessage, Foreground),
265    (UpdateChannelMessage, Foreground),
266    (RemoveContact, Foreground),
267    (RemoveProjectCollaborator, Foreground),
268    (RenameChannel, Foreground),
269    (RenameChannelResponse, Foreground),
270    (RenameProjectEntry, Foreground),
271    (RequestContact, Foreground),
272    (ResolveCompletionDocumentation, Background),
273    (ResolveCompletionDocumentationResponse, Background),
274    (ResolveInlayHint, Background),
275    (ResolveInlayHintResponse, Background),
276    (RespondToChannelInvite, Foreground),
277    (RespondToContactRequest, Foreground),
278    (RoomUpdated, Foreground),
279    (SaveBuffer, Foreground),
280    (SetChannelMemberRole, Foreground),
281    (SetChannelVisibility, Foreground),
282    (SearchProject, Background),
283    (SearchProjectResponse, Background),
284    (SendChannelMessage, Background),
285    (SendChannelMessageResponse, Background),
286    (ShareProject, Foreground),
287    (ShareProjectResponse, Foreground),
288    (ShowContacts, Foreground),
289    (StartLanguageServer, Foreground),
290    (SubscribeToChannels, Foreground),
291    (SynchronizeBuffers, Foreground),
292    (SynchronizeBuffersResponse, Foreground),
293    (TaskContextForLocation, Background),
294    (TaskContext, Background),
295    (TaskTemplates, Background),
296    (TaskTemplatesResponse, Background),
297    (Test, Foreground),
298    (Unfollow, Foreground),
299    (UnshareProject, Foreground),
300    (UpdateBuffer, Foreground),
301    (UpdateBufferFile, Foreground),
302    (UpdateChannelBuffer, Foreground),
303    (UpdateChannelBufferCollaborators, Foreground),
304    (UpdateChannels, Foreground),
305    (UpdateUserChannels, Foreground),
306    (UpdateContacts, Foreground),
307    (UpdateDiagnosticSummary, Foreground),
308    (UpdateDiffBase, Foreground),
309    (UpdateFollowers, Foreground),
310    (UpdateInviteInfo, Foreground),
311    (UpdateLanguageServer, Foreground),
312    (UpdateParticipantLocation, Foreground),
313    (UpdateProject, Foreground),
314    (UpdateProjectCollaborator, Foreground),
315    (UpdateUserPlan, Foreground),
316    (UpdateWorktree, Foreground),
317    (UpdateWorktreeSettings, Foreground),
318    (UsersResponse, Foreground),
319    (LspExtExpandMacro, Background),
320    (LspExtExpandMacroResponse, Background),
321    (SetRoomParticipantRole, Foreground),
322    (BlameBuffer, Foreground),
323    (BlameBufferResponse, Foreground),
324    (CreateDevServerProject, Background),
325    (CreateDevServerProjectResponse, Foreground),
326    (CreateDevServer, Foreground),
327    (CreateDevServerResponse, Foreground),
328    (DevServerInstructions, Foreground),
329    (ShutdownDevServer, Foreground),
330    (ReconnectDevServer, Foreground),
331    (ReconnectDevServerResponse, Foreground),
332    (ShareDevServerProject, Foreground),
333    (JoinDevServerProject, Foreground),
334    (RejoinRemoteProjects, Foreground),
335    (RejoinRemoteProjectsResponse, Foreground),
336    (MultiLspQuery, Background),
337    (MultiLspQueryResponse, Background),
338    (DevServerProjectsUpdate, Foreground),
339    (ValidateDevServerProjectRequest, Background),
340    (ListRemoteDirectory, Background),
341    (ListRemoteDirectoryResponse, Background),
342    (UpdateDevServerProject, Background),
343    (DeleteDevServer, Foreground),
344    (DeleteDevServerProject, Foreground),
345    (RegenerateDevServerToken, Foreground),
346    (RegenerateDevServerTokenResponse, Foreground),
347    (RenameDevServer, Foreground),
348    (OpenNewBuffer, Foreground),
349    (RestartLanguageServers, Foreground),
350    (LinkedEditingRange, Background),
351    (LinkedEditingRangeResponse, Background),
352    (AdvertiseContexts, Foreground),
353    (OpenContext, Foreground),
354    (OpenContextResponse, Foreground),
355    (CreateContext, Foreground),
356    (CreateContextResponse, Foreground),
357    (UpdateContext, Foreground),
358    (SynchronizeContexts, Foreground),
359    (SynchronizeContextsResponse, Foreground),
360    (LspExtSwitchSourceHeader, Background),
361    (LspExtSwitchSourceHeaderResponse, Background),
362    (AddWorktree, Foreground),
363    (AddWorktreeResponse, Foreground),
364    (FindSearchCandidates, Background),
365    (FindSearchCandidatesResponse, Background),
366    (CloseBuffer, Foreground),
367    (UpdateUserSettings, Foreground),
368    (CreateLanguageServer, Foreground),
369    (WhichCommand, Foreground),
370    (WhichCommandResponse, Foreground),
371    (ShellEnv, Foreground),
372    (ShellEnvResponse, Foreground),
373    (TryExec, Foreground),
374    (ReadTextFile, Foreground),
375    (ReadTextFileResponse, Foreground),
376    (CheckFileExists, Background),
377    (CheckFileExistsResponse, Background)
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    (SearchProject, SearchProjectResponse),
466    (FindSearchCandidates, FindSearchCandidatesResponse),
467    (SendChannelMessage, SendChannelMessageResponse),
468    (SetChannelMemberRole, Ack),
469    (SetChannelVisibility, Ack),
470    (ShareProject, ShareProjectResponse),
471    (SynchronizeBuffers, SynchronizeBuffersResponse),
472    (TaskContextForLocation, TaskContext),
473    (TaskTemplates, TaskTemplatesResponse),
474    (Test, Test),
475    (UpdateBuffer, Ack),
476    (UpdateParticipantLocation, Ack),
477    (UpdateProject, Ack),
478    (UpdateWorktree, Ack),
479    (LspExtExpandMacro, LspExtExpandMacroResponse),
480    (SetRoomParticipantRole, Ack),
481    (BlameBuffer, BlameBufferResponse),
482    (CreateDevServerProject, CreateDevServerProjectResponse),
483    (CreateDevServer, CreateDevServerResponse),
484    (ShutdownDevServer, Ack),
485    (ShareDevServerProject, ShareProjectResponse),
486    (JoinDevServerProject, JoinProjectResponse),
487    (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
488    (ReconnectDevServer, ReconnectDevServerResponse),
489    (ValidateDevServerProjectRequest, Ack),
490    (MultiLspQuery, MultiLspQueryResponse),
491    (DeleteDevServer, Ack),
492    (DeleteDevServerProject, Ack),
493    (RegenerateDevServerToken, RegenerateDevServerTokenResponse),
494    (RenameDevServer, Ack),
495    (RestartLanguageServers, Ack),
496    (OpenContext, OpenContextResponse),
497    (CreateContext, CreateContextResponse),
498    (SynchronizeContexts, SynchronizeContextsResponse),
499    (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse),
500    (AddWorktree, AddWorktreeResponse),
501    (CreateLanguageServer, Ack),
502    (WhichCommand, WhichCommandResponse),
503    (ShellEnv, ShellEnvResponse),
504    (ReadTextFile, ReadTextFileResponse),
505    (TryExec, Ack),
506    (CheckFileExists, CheckFileExistsResponse)
507);
508
509entity_messages!(
510    {project_id, ShareProject},
511    AddProjectCollaborator,
512    AddWorktree,
513    ApplyCodeAction,
514    ApplyCompletionAdditionalEdits,
515    BlameBuffer,
516    BufferReloaded,
517    BufferSaved,
518    CloseBuffer,
519    CopyProjectEntry,
520    CreateBufferForPeer,
521    CreateProjectEntry,
522    DeleteProjectEntry,
523    ExpandProjectEntry,
524    FindSearchCandidates,
525    FormatBuffers,
526    GetCodeActions,
527    GetCompletions,
528    GetDefinition,
529    GetDeclaration,
530    GetImplementation,
531    GetDocumentHighlights,
532    GetHover,
533    GetProjectSymbols,
534    GetReferences,
535    GetSignatureHelp,
536    GetTypeDefinition,
537    InlayHints,
538    JoinProject,
539    LeaveProject,
540    LinkedEditingRange,
541    MultiLspQuery,
542    RestartLanguageServers,
543    OnTypeFormatting,
544    OpenNewBuffer,
545    OpenBufferById,
546    OpenBufferByPath,
547    OpenBufferForSymbol,
548    PerformRename,
549    PrepareRename,
550    RefreshInlayHints,
551    ReloadBuffers,
552    RemoveProjectCollaborator,
553    RenameProjectEntry,
554    ResolveCompletionDocumentation,
555    ResolveInlayHint,
556    SaveBuffer,
557    SearchProject,
558    StartLanguageServer,
559    SynchronizeBuffers,
560    TaskContextForLocation,
561    TaskTemplates,
562    UnshareProject,
563    UpdateBuffer,
564    UpdateBufferFile,
565    UpdateDiagnosticSummary,
566    UpdateDiffBase,
567    UpdateLanguageServer,
568    UpdateProject,
569    UpdateProjectCollaborator,
570    UpdateWorktree,
571    UpdateWorktreeSettings,
572    LspExtExpandMacro,
573    AdvertiseContexts,
574    OpenContext,
575    CreateContext,
576    UpdateContext,
577    SynchronizeContexts,
578    LspExtSwitchSourceHeader,
579    UpdateUserSettings,
580    CreateLanguageServer,
581    WhichCommand,
582    ShellEnv,
583    TryExec,
584    ReadTextFile,
585    CheckFileExists,
586);
587
588entity_messages!(
589    {channel_id, Channel},
590    ChannelMessageSent,
591    ChannelMessageUpdate,
592    RemoveChannelMessage,
593    UpdateChannelMessage,
594    UpdateChannelBuffer,
595    UpdateChannelBufferCollaborators,
596);
597
598impl From<Timestamp> for SystemTime {
599    fn from(val: Timestamp) -> Self {
600        UNIX_EPOCH
601            .checked_add(Duration::new(val.seconds, val.nanos))
602            .unwrap()
603    }
604}
605
606impl From<SystemTime> for Timestamp {
607    fn from(time: SystemTime) -> Self {
608        let duration = time.duration_since(UNIX_EPOCH).unwrap();
609        Self {
610            seconds: duration.as_secs(),
611            nanos: duration.subsec_nanos(),
612        }
613    }
614}
615
616impl From<u128> for Nonce {
617    fn from(nonce: u128) -> Self {
618        let upper_half = (nonce >> 64) as u64;
619        let lower_half = nonce as u64;
620        Self {
621            upper_half,
622            lower_half,
623        }
624    }
625}
626
627impl From<Nonce> for u128 {
628    fn from(nonce: Nonce) -> Self {
629        let upper_half = (nonce.upper_half as u128) << 64;
630        let lower_half = nonce.lower_half as u128;
631        upper_half | lower_half
632    }
633}
634
635pub fn split_worktree_update(
636    mut message: UpdateWorktree,
637    max_chunk_size: usize,
638) -> impl Iterator<Item = UpdateWorktree> {
639    let mut done_files = false;
640
641    let mut repository_map = message
642        .updated_repositories
643        .into_iter()
644        .map(|repo| (repo.work_directory_id, repo))
645        .collect::<HashMap<_, _>>();
646
647    iter::from_fn(move || {
648        if done_files {
649            return None;
650        }
651
652        let updated_entries_chunk_size = cmp::min(message.updated_entries.len(), max_chunk_size);
653        let updated_entries: Vec<_> = message
654            .updated_entries
655            .drain(..updated_entries_chunk_size)
656            .collect();
657
658        let removed_entries_chunk_size = cmp::min(message.removed_entries.len(), max_chunk_size);
659        let removed_entries = message
660            .removed_entries
661            .drain(..removed_entries_chunk_size)
662            .collect();
663
664        done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
665
666        let mut updated_repositories = Vec::new();
667
668        if !repository_map.is_empty() {
669            for entry in &updated_entries {
670                if let Some(repo) = repository_map.remove(&entry.id) {
671                    updated_repositories.push(repo)
672                }
673            }
674        }
675
676        let removed_repositories = if done_files {
677            mem::take(&mut message.removed_repositories)
678        } else {
679            Default::default()
680        };
681
682        if done_files {
683            updated_repositories.extend(mem::take(&mut repository_map).into_values());
684        }
685
686        Some(UpdateWorktree {
687            project_id: message.project_id,
688            worktree_id: message.worktree_id,
689            root_name: message.root_name.clone(),
690            abs_path: message.abs_path.clone(),
691            updated_entries,
692            removed_entries,
693            scan_id: message.scan_id,
694            is_last_update: done_files && message.is_last_update,
695            updated_repositories,
696            removed_repositories,
697        })
698    })
699}
700
701#[cfg(test)]
702mod tests {
703    use super::*;
704
705    #[test]
706    fn test_converting_peer_id_from_and_to_u64() {
707        let peer_id = PeerId {
708            owner_id: 10,
709            id: 3,
710        };
711        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
712        let peer_id = PeerId {
713            owner_id: u32::MAX,
714            id: 3,
715        };
716        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
717        let peer_id = PeerId {
718            owner_id: 10,
719            id: u32::MAX,
720        };
721        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
722        let peer_id = PeerId {
723            owner_id: u32::MAX,
724            id: u32::MAX,
725        };
726        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
727    }
728}