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);
377
378request_messages!(
379    (AcceptTermsOfService, AcceptTermsOfServiceResponse),
380    (ApplyCodeAction, ApplyCodeActionResponse),
381    (
382        ApplyCompletionAdditionalEdits,
383        ApplyCompletionAdditionalEditsResponse
384    ),
385    (Call, Ack),
386    (CancelCall, Ack),
387    (CopyProjectEntry, ProjectEntryResponse),
388    (ComputeEmbeddings, ComputeEmbeddingsResponse),
389    (CreateChannel, CreateChannelResponse),
390    (CreateProjectEntry, ProjectEntryResponse),
391    (CreateRoom, CreateRoomResponse),
392    (DeclineCall, Ack),
393    (DeleteChannel, Ack),
394    (DeleteProjectEntry, ProjectEntryResponse),
395    (ExpandProjectEntry, ExpandProjectEntryResponse),
396    (Follow, FollowResponse),
397    (FormatBuffers, FormatBuffersResponse),
398    (FuzzySearchUsers, UsersResponse),
399    (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
400    (GetChannelMembers, GetChannelMembersResponse),
401    (GetChannelMessages, GetChannelMessagesResponse),
402    (GetChannelMessagesById, GetChannelMessagesResponse),
403    (GetCodeActions, GetCodeActionsResponse),
404    (GetCompletions, GetCompletionsResponse),
405    (GetDefinition, GetDefinitionResponse),
406    (GetDeclaration, GetDeclarationResponse),
407    (GetImplementation, GetImplementationResponse),
408    (GetDocumentHighlights, GetDocumentHighlightsResponse),
409    (GetHover, GetHoverResponse),
410    (GetLlmToken, GetLlmTokenResponse),
411    (GetNotifications, GetNotificationsResponse),
412    (GetPrivateUserInfo, GetPrivateUserInfoResponse),
413    (GetProjectSymbols, GetProjectSymbolsResponse),
414    (GetReferences, GetReferencesResponse),
415    (GetSignatureHelp, GetSignatureHelpResponse),
416    (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
417    (GetTypeDefinition, GetTypeDefinitionResponse),
418    (LinkedEditingRange, LinkedEditingRangeResponse),
419    (ListRemoteDirectory, ListRemoteDirectoryResponse),
420    (UpdateDevServerProject, Ack),
421    (GetUsers, UsersResponse),
422    (IncomingCall, Ack),
423    (InlayHints, InlayHintsResponse),
424    (InviteChannelMember, Ack),
425    (JoinChannel, JoinRoomResponse),
426    (JoinChannelBuffer, JoinChannelBufferResponse),
427    (JoinChannelChat, JoinChannelChatResponse),
428    (JoinHostedProject, JoinProjectResponse),
429    (JoinProject, JoinProjectResponse),
430    (JoinRoom, JoinRoomResponse),
431    (LeaveChannelBuffer, Ack),
432    (LeaveRoom, Ack),
433    (MarkNotificationRead, Ack),
434    (MoveChannel, Ack),
435    (OnTypeFormatting, OnTypeFormattingResponse),
436    (OpenBufferById, OpenBufferResponse),
437    (OpenBufferByPath, OpenBufferResponse),
438    (OpenBufferForSymbol, OpenBufferForSymbolResponse),
439    (OpenNewBuffer, OpenBufferResponse),
440    (PerformRename, PerformRenameResponse),
441    (Ping, Ack),
442    (PrepareRename, PrepareRenameResponse),
443    (CountLanguageModelTokens, CountLanguageModelTokensResponse),
444    (RefreshInlayHints, Ack),
445    (RejoinChannelBuffers, RejoinChannelBuffersResponse),
446    (RejoinRoom, RejoinRoomResponse),
447    (ReloadBuffers, ReloadBuffersResponse),
448    (RemoveChannelMember, Ack),
449    (RemoveChannelMessage, Ack),
450    (UpdateChannelMessage, Ack),
451    (RemoveContact, Ack),
452    (RenameChannel, RenameChannelResponse),
453    (RenameProjectEntry, ProjectEntryResponse),
454    (RequestContact, Ack),
455    (
456        ResolveCompletionDocumentation,
457        ResolveCompletionDocumentationResponse
458    ),
459    (ResolveInlayHint, ResolveInlayHintResponse),
460    (RespondToChannelInvite, Ack),
461    (RespondToContactRequest, Ack),
462    (SaveBuffer, BufferSaved),
463    (SearchProject, SearchProjectResponse),
464    (FindSearchCandidates, FindSearchCandidatesResponse),
465    (SendChannelMessage, SendChannelMessageResponse),
466    (SetChannelMemberRole, Ack),
467    (SetChannelVisibility, Ack),
468    (ShareProject, ShareProjectResponse),
469    (SynchronizeBuffers, SynchronizeBuffersResponse),
470    (TaskContextForLocation, TaskContext),
471    (TaskTemplates, TaskTemplatesResponse),
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    (CreateLanguageServer, Ack),
500    (WhichCommand, WhichCommandResponse),
501    (ShellEnv, ShellEnvResponse),
502    (ReadTextFile, ReadTextFileResponse),
503    (TryExec, Ack),
504);
505
506entity_messages!(
507    {project_id, ShareProject},
508    AddProjectCollaborator,
509    AddWorktree,
510    ApplyCodeAction,
511    ApplyCompletionAdditionalEdits,
512    BlameBuffer,
513    BufferReloaded,
514    BufferSaved,
515    CloseBuffer,
516    CopyProjectEntry,
517    CreateBufferForPeer,
518    CreateProjectEntry,
519    DeleteProjectEntry,
520    ExpandProjectEntry,
521    FindSearchCandidates,
522    FormatBuffers,
523    GetCodeActions,
524    GetCompletions,
525    GetDefinition,
526    GetDeclaration,
527    GetImplementation,
528    GetDocumentHighlights,
529    GetHover,
530    GetProjectSymbols,
531    GetReferences,
532    GetSignatureHelp,
533    GetTypeDefinition,
534    InlayHints,
535    JoinProject,
536    LeaveProject,
537    LinkedEditingRange,
538    MultiLspQuery,
539    RestartLanguageServers,
540    OnTypeFormatting,
541    OpenNewBuffer,
542    OpenBufferById,
543    OpenBufferByPath,
544    OpenBufferForSymbol,
545    PerformRename,
546    PrepareRename,
547    RefreshInlayHints,
548    ReloadBuffers,
549    RemoveProjectCollaborator,
550    RenameProjectEntry,
551    ResolveCompletionDocumentation,
552    ResolveInlayHint,
553    SaveBuffer,
554    SearchProject,
555    StartLanguageServer,
556    SynchronizeBuffers,
557    TaskContextForLocation,
558    TaskTemplates,
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    CreateLanguageServer,
578    WhichCommand,
579    ShellEnv,
580    TryExec,
581    ReadTextFile
582);
583
584entity_messages!(
585    {channel_id, Channel},
586    ChannelMessageSent,
587    ChannelMessageUpdate,
588    RemoveChannelMessage,
589    UpdateChannelMessage,
590    UpdateChannelBuffer,
591    UpdateChannelBufferCollaborators,
592);
593
594impl From<Timestamp> for SystemTime {
595    fn from(val: Timestamp) -> Self {
596        UNIX_EPOCH
597            .checked_add(Duration::new(val.seconds, val.nanos))
598            .unwrap()
599    }
600}
601
602impl From<SystemTime> for Timestamp {
603    fn from(time: SystemTime) -> Self {
604        let duration = time.duration_since(UNIX_EPOCH).unwrap();
605        Self {
606            seconds: duration.as_secs(),
607            nanos: duration.subsec_nanos(),
608        }
609    }
610}
611
612impl From<u128> for Nonce {
613    fn from(nonce: u128) -> Self {
614        let upper_half = (nonce >> 64) as u64;
615        let lower_half = nonce as u64;
616        Self {
617            upper_half,
618            lower_half,
619        }
620    }
621}
622
623impl From<Nonce> for u128 {
624    fn from(nonce: Nonce) -> Self {
625        let upper_half = (nonce.upper_half as u128) << 64;
626        let lower_half = nonce.lower_half as u128;
627        upper_half | lower_half
628    }
629}
630
631pub fn split_worktree_update(
632    mut message: UpdateWorktree,
633    max_chunk_size: usize,
634) -> impl Iterator<Item = UpdateWorktree> {
635    let mut done_files = false;
636
637    let mut repository_map = message
638        .updated_repositories
639        .into_iter()
640        .map(|repo| (repo.work_directory_id, repo))
641        .collect::<HashMap<_, _>>();
642
643    iter::from_fn(move || {
644        if done_files {
645            return None;
646        }
647
648        let updated_entries_chunk_size = cmp::min(message.updated_entries.len(), max_chunk_size);
649        let updated_entries: Vec<_> = message
650            .updated_entries
651            .drain(..updated_entries_chunk_size)
652            .collect();
653
654        let removed_entries_chunk_size = cmp::min(message.removed_entries.len(), max_chunk_size);
655        let removed_entries = message
656            .removed_entries
657            .drain(..removed_entries_chunk_size)
658            .collect();
659
660        done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
661
662        let mut updated_repositories = Vec::new();
663
664        if !repository_map.is_empty() {
665            for entry in &updated_entries {
666                if let Some(repo) = repository_map.remove(&entry.id) {
667                    updated_repositories.push(repo)
668                }
669            }
670        }
671
672        let removed_repositories = if done_files {
673            mem::take(&mut message.removed_repositories)
674        } else {
675            Default::default()
676        };
677
678        if done_files {
679            updated_repositories.extend(mem::take(&mut repository_map).into_values());
680        }
681
682        Some(UpdateWorktree {
683            project_id: message.project_id,
684            worktree_id: message.worktree_id,
685            root_name: message.root_name.clone(),
686            abs_path: message.abs_path.clone(),
687            updated_entries,
688            removed_entries,
689            scan_id: message.scan_id,
690            is_last_update: done_files && message.is_last_update,
691            updated_repositories,
692            removed_repositories,
693        })
694    })
695}
696
697#[cfg(test)]
698mod tests {
699    use super::*;
700
701    #[test]
702    fn test_converting_peer_id_from_and_to_u64() {
703        let peer_id = PeerId {
704            owner_id: 10,
705            id: 3,
706        };
707        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
708        let peer_id = PeerId {
709            owner_id: u32::MAX,
710            id: 3,
711        };
712        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
713        let peer_id = PeerId {
714            owner_id: 10,
715            id: u32::MAX,
716        };
717        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
718        let peer_id = PeerId {
719            owner_id: u32::MAX,
720            id: u32::MAX,
721        };
722        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
723    }
724}