rsynko_manager/
navigation.rs1use crate::*;
2use alux_ext::ext;
3use ambassador::delegatable_trait;
4
5#[delegatable_trait]
7pub trait NavigationStateAlg: ManagerSorts {
8 fn page(&self) -> ManagerPage<Self::Id>;
10 fn set_page(&mut self, page: ManagerPage<Self::Id>);
12}
13
14#[delegatable_trait]
16pub trait DetailSelectionAlg {
17 fn selected_detail_control(&self) -> Option<DetailControl>;
19 fn set_selected_detail_control(&mut self, control: Option<DetailControl>);
21}
22
23#[delegatable_trait]
25pub trait ManagerStatusAlg {
26 fn manager_message(&self) -> Option<&str>;
28 fn set_manager_message(&mut self, message: Option<String>);
30}
31
32#[delegatable_trait]
34pub trait SafeExitAlg {
35 fn exit_requested(&self) -> bool;
37 fn request_safe_exit(&mut self);
39}
40
41pub const COLLECTION: &str = "Transfers";
46
47#[ext(name = BreadcrumbExt)]
49pub impl<This> This
50where
51 This: NavigationStateAlg + QueueCatalogAlg,
52 This::Entry: QueueEntryAlg + RequestOptionsAlg,
53 This::Id: Copy,
54{
55 fn breadcrumbs(&self) -> Vec<Breadcrumb> {
57 let mut breadcrumbs = vec![segment(COLLECTION)];
58 match self.page() {
59 ManagerPage::Collection => {}
60 ManagerPage::AddSources => breadcrumbs.push(segment("Add sources")),
61 ManagerPage::Details(id) => breadcrumbs.push(segment(self.entry_label(id))),
62 ManagerPage::Formats(id) => {
63 let chooses_media = self
65 .queue_entry(id)
66 .is_some_and(|entry| entry.performer() == Performer::Retrieval);
67 let choice = if chooses_media { "Formats" } else { "Transfer" };
68 breadcrumbs.extend([segment(self.entry_label(id)), segment(choice)]);
69 }
70 ManagerPage::Input(id) => {
71 breadcrumbs.extend([segment(self.entry_label(id)), segment("Input")]);
72 }
73 ManagerPage::Output(id) => {
74 let stated = self
76 .queue_entry(id)
77 .is_some_and(|entry| entry.output_naming() == OutputNaming::Stated);
78 let named = if stated { "Output" } else { "File name" };
79 breadcrumbs.extend([segment(self.entry_label(id)), segment(named)]);
80 }
81 ManagerPage::Log(id) => {
82 breadcrumbs.extend([segment(self.entry_label(id)), segment("Log")]);
83 }
84 ManagerPage::Report(id) => {
85 breadcrumbs.extend([segment(self.entry_label(id)), segment("Report")]);
86 }
87 ManagerPage::Command(id) => {
88 breadcrumbs.extend([segment(self.entry_label(id)), segment("Command")]);
89 }
90 }
91 breadcrumbs
92 }
93
94 fn entry_label(&self, id: This::Id) -> &str {
96 self.queue_entry(id)
97 .map_or("Missing entry", QueueEntryAlg::label)
98 }
99}
100
101fn segment(label: impl Into<String>) -> Breadcrumb {
103 Breadcrumb {
104 label: label.into(),
105 }
106}