cosmic_files/mounter/
mod.rs1use cosmic::iced::Subscription;
2use cosmic::{Task, widget};
3use std::collections::BTreeMap;
4use std::fmt;
5use std::path::PathBuf;
6use std::sync::{Arc, LazyLock};
7use tokio::sync::mpsc;
8
9use crate::config::IconSizes;
10use crate::tab;
11
12#[cfg(feature = "gvfs")]
13mod gvfs;
14
15#[derive(Clone)]
16pub struct MounterAuth {
17 pub message: String,
18 pub username_opt: Option<String>,
19 pub domain_opt: Option<String>,
20 pub password_opt: Option<String>,
21 pub remember_opt: Option<bool>,
22 pub anonymous_opt: Option<bool>,
23}
24
25impl fmt::Debug for MounterAuth {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 f.debug_struct("MounterAuth")
29 .field("username_opt", &self.username_opt)
30 .field("domain_opt", &self.domain_opt)
31 .field(
32 "password_opt",
33 if self.password_opt.is_some() {
34 &"Some(*)"
35 } else {
36 &"None"
37 },
38 )
39 .field("remember_opt", &self.remember_opt)
40 .field("anonymous_opt", &self.anonymous_opt)
41 .finish()
42 }
43}
44
45#[derive(Clone, Debug)]
46pub enum MounterItem {
47 #[cfg(feature = "gvfs")]
48 Gvfs(gvfs::Item),
49 #[allow(dead_code)]
50 None,
51}
52
53impl MounterItem {
54 pub fn name(&self) -> String {
55 match self {
56 #[cfg(feature = "gvfs")]
57 Self::Gvfs(item) => item.name(),
58 Self::None => unreachable!(),
59 }
60 }
61
62 pub fn uri(&self) -> String {
63 match self {
64 #[cfg(feature = "gvfs")]
65 Self::Gvfs(item) => item.uri(),
66 Self::None => unreachable!(),
67 }
68 }
69
70 pub fn is_mounted(&self) -> bool {
71 match self {
72 #[cfg(feature = "gvfs")]
73 Self::Gvfs(item) => item.is_mounted(),
74 Self::None => unreachable!(),
75 }
76 }
77
78 pub fn icon(&self, _symbolic: bool) -> Option<widget::icon::Handle> {
79 match self {
80 #[cfg(feature = "gvfs")]
81 Self::Gvfs(item) => item.icon(symbolic),
82 Self::None => unreachable!(),
83 }
84 }
85
86 pub fn path(&self) -> Option<PathBuf> {
87 match self {
88 #[cfg(feature = "gvfs")]
89 Self::Gvfs(item) => item.path(),
90 Self::None => unreachable!(),
91 }
92 }
93
94 pub fn is_remote(&self) -> bool {
95 match self {
96 #[cfg(feature = "gvfs")]
97 Self::Gvfs(item) => item.is_remote(),
98 Self::None => unreachable!(),
99 }
100 }
101}
102
103pub type MounterItems = Vec<MounterItem>;
104
105#[derive(Clone, Debug)]
106#[allow(dead_code)]
107pub enum MounterMessage {
108 Items(MounterItems),
109 MountResult(MounterItem, Result<bool, String>),
110 NetworkAuth(String, MounterAuth, mpsc::Sender<MounterAuth>),
111 NetworkResult(String, Result<bool, String>),
112}
113
114pub trait Mounter: Send + Sync {
115 fn items(&self, sizes: IconSizes) -> Option<MounterItems>;
116 fn mount(&self, item: MounterItem) -> Task<()>;
118 fn network_drive(&self, uri: String) -> Task<()>;
119 fn network_scan(&self, uri: &str, sizes: IconSizes) -> Option<Result<Vec<tab::Item>, String>>;
120 fn dir_info(&self, uri: &str) -> Option<(String, String, Option<PathBuf>)>;
121 fn unmount(&self, item: MounterItem) -> Task<()>;
122 fn subscription(&self) -> Subscription<MounterMessage>;
123}
124
125#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
126pub struct MounterKey(pub &'static str);
127pub type MounterMap = BTreeMap<MounterKey, Box<dyn Mounter>>;
128pub type Mounters = Arc<MounterMap>;
129
130pub fn mounters() -> Mounters {
131 #[allow(unused_mut)]
132 let mut mounters = MounterMap::new();
133
134 #[cfg(feature = "gvfs")]
135 {
136 mounters.insert(MounterKey("gvfs"), Box::new(gvfs::Gvfs::new()));
137 }
138
139 Mounters::new(mounters)
140}
141
142pub static MOUNTERS: LazyLock<Mounters> = LazyLock::new(mounters);