cosmic-files/src/mounter/mod.rs

138 lines
3.6 KiB
Rust

use cosmic::{iced::Subscription, widget, Task};
use once_cell::sync::Lazy;
use std::{
collections::BTreeMap,
fmt,
path::{Path, PathBuf},
sync::Arc,
};
use tokio::sync::mpsc;
use crate::{config::IconSizes, tab};
#[cfg(feature = "gvfs")]
mod gvfs;
#[derive(Clone)]
pub struct MounterAuth {
pub message: String,
pub username_opt: Option<String>,
pub domain_opt: Option<String>,
pub password_opt: Option<String>,
pub remember_opt: Option<bool>,
pub anonymous_opt: Option<bool>,
}
// Custom debug for MounterAuth to hide password
impl fmt::Debug for MounterAuth {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MounterAuth")
.field("username_opt", &self.username_opt)
.field("domain_opt", &self.domain_opt)
.field(
"password_opt",
if self.password_opt.is_some() {
&"Some(*)"
} else {
&"None"
},
)
.field("remember_opt", &self.remember_opt)
.field("anonymous_opt", &self.anonymous_opt)
.finish()
}
}
#[derive(Clone, Debug)]
pub enum MounterItem {
#[cfg(feature = "gvfs")]
Gvfs(gvfs::Item),
#[allow(dead_code)]
None,
}
impl MounterItem {
pub fn name(&self) -> String {
match self {
#[cfg(feature = "gvfs")]
Self::Gvfs(item) => item.name(),
Self::None => unreachable!(),
}
}
pub fn uri(&self) -> String {
match self {
#[cfg(feature = "gvfs")]
Self::Gvfs(item) => item.uri(),
Self::None => unreachable!(),
}
}
pub fn is_mounted(&self) -> bool {
match self {
#[cfg(feature = "gvfs")]
Self::Gvfs(item) => item.is_mounted(),
Self::None => unreachable!(),
}
}
pub fn icon(&self, symbolic: bool) -> Option<widget::icon::Handle> {
match self {
#[cfg(feature = "gvfs")]
Self::Gvfs(item) => item.icon(symbolic),
Self::None => unreachable!(),
}
}
pub fn path(&self) -> Option<PathBuf> {
match self {
#[cfg(feature = "gvfs")]
Self::Gvfs(item) => item.path(),
Self::None => unreachable!(),
}
}
}
pub type MounterItems = Vec<MounterItem>;
#[derive(Clone, Debug)]
pub enum MounterMessage {
Items(MounterItems),
MountResult(MounterItem, Result<bool, String>),
NetworkAuth(String, MounterAuth, mpsc::Sender<MounterAuth>),
NetworkResult(String, Result<bool, String>),
}
pub trait Mounter: Send + Sync {
fn items(&self, sizes: IconSizes) -> Option<MounterItems>;
//TODO: send result
fn mount(&self, item: MounterItem) -> Task<()>;
fn network_drive(&self, uri: String) -> Task<()>;
fn network_scan(
&self,
uri: &str,
sizes: IconSizes,
path: Option<&Path>,
) -> Option<Result<Vec<tab::Item>, String>>;
fn unmount(&self, item: MounterItem) -> Task<()>;
fn subscription(&self) -> Subscription<MounterMessage>;
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct MounterKey(pub &'static str);
pub type MounterMap = BTreeMap<MounterKey, Box<dyn Mounter>>;
pub type Mounters = Arc<MounterMap>;
pub fn mounters() -> Mounters {
#[allow(unused_mut)]
let mut mounters = MounterMap::new();
#[cfg(feature = "gvfs")]
{
mounters.insert(MounterKey("gvfs"), Box::new(gvfs::Gvfs::new()));
}
Mounters::new(mounters)
}
pub static MOUNTERS: Lazy<Mounters> = Lazy::new(mounters);