mirror of
https://github.com/chmln/handlr.git
synced 2024-11-14 21:49:27 +01:00
impl list
This commit is contained in:
parent
0da454a557
commit
04666c5fb7
8 changed files with 204 additions and 78 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
max_width = 80
|
||||||
|
merge-imports = true
|
83
Cargo.lock
generated
83
Cargo.lock
generated
|
@ -18,12 +18,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anyhow"
|
|
||||||
version = "1.0.28"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
|
@ -36,6 +30,12 @@ version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ascii_table"
|
||||||
|
version = "3.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbcbc3963c670677e878a5253f5fef77577ef3821080cfac27779cadf224a9b5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -288,6 +288,26 @@ dependencies = [
|
||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "handlr"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"ascii_table",
|
||||||
|
"dashmap",
|
||||||
|
"derive_more",
|
||||||
|
"dirs",
|
||||||
|
"itertools",
|
||||||
|
"json",
|
||||||
|
"mime_guess",
|
||||||
|
"pest",
|
||||||
|
"pest_derive",
|
||||||
|
"rayon",
|
||||||
|
"shlex",
|
||||||
|
"structopt",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -326,6 +346,12 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "json"
|
||||||
|
version = "0.12.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -365,23 +391,6 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mime"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"dashmap",
|
|
||||||
"derive_more",
|
|
||||||
"dirs",
|
|
||||||
"itertools",
|
|
||||||
"mime_guess",
|
|
||||||
"pest",
|
|
||||||
"pest_derive",
|
|
||||||
"rayon",
|
|
||||||
"structopt",
|
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.16"
|
version = "0.3.16"
|
||||||
|
@ -394,7 +403,7 @@ version = "2.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
|
checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"mime 0.3.16",
|
"mime",
|
||||||
"unicase",
|
"unicase",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -584,6 +593,12 @@ dependencies = [
|
||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -651,6 +666,26 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54b3d3d2ff68104100ab257bb6bb0cb26c901abe4bd4ba15961f3bf867924012"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca972988113b7715266f91250ddb98070d033c62a011fa0fcc57434a649310dd"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.11.2"
|
version = "1.11.2"
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mime"
|
name = "handlr"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["greg <gregory.mkv@gmail.com>"]
|
authors = ["greg <gregory.mkv@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dirs = "2.0.2"
|
dirs = "2.0.2"
|
||||||
anyhow = "1.0.28"
|
|
||||||
pest = "2.1.3"
|
pest = "2.1.3"
|
||||||
pest_derive = "2.1.0"
|
pest_derive = "2.1.0"
|
||||||
rayon = "1.3.0"
|
rayon = "1.3.0"
|
||||||
|
@ -18,3 +15,7 @@ url = "2.1.1"
|
||||||
mime_guess = "2.0.3"
|
mime_guess = "2.0.3"
|
||||||
itertools = "0.9.0"
|
itertools = "0.9.0"
|
||||||
derive_more = {version = "0.99.5", default-features = false, features = ["display"] }
|
derive_more = {version = "0.99.5", default-features = false, features = ["display"] }
|
||||||
|
json = "0.12.4"
|
||||||
|
shlex = "0.1.1"
|
||||||
|
thiserror = "1.0.14"
|
||||||
|
ascii_table = "3.0.0"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::Result;
|
use crate::{Error, Result};
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -12,11 +12,13 @@ impl std::str::FromStr for Mime {
|
||||||
Ok(Self(s.to_owned()))
|
Ok(Self(s.to_owned()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug, derive_more::Display, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(
|
||||||
|
Debug, derive_more::Display, Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
|
||||||
|
)]
|
||||||
pub struct Handler(String);
|
pub struct Handler(String);
|
||||||
|
|
||||||
impl std::str::FromStr for Handler {
|
impl std::str::FromStr for Handler {
|
||||||
type Err = anyhow::Error;
|
type Err = Error;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
Self::resolve(s.to_owned())
|
Self::resolve(s.to_owned())
|
||||||
}
|
}
|
||||||
|
@ -41,21 +43,31 @@ impl Handler {
|
||||||
locally.or(system)
|
locally.or(system)
|
||||||
}
|
}
|
||||||
pub fn resolve(name: String) -> Result<Self> {
|
pub fn resolve(name: String) -> Result<Self> {
|
||||||
let path =
|
let path = Self::get_path(&name).ok_or(Error::NotFound)?;
|
||||||
Self::get_path(&name).ok_or_else(|| anyhow::Error::msg("Handler does not exist"))?;
|
|
||||||
DesktopEntry::try_from(path)?;
|
DesktopEntry::try_from(path)?;
|
||||||
Ok(Self(name))
|
Ok(Self(name))
|
||||||
}
|
}
|
||||||
pub fn get_entry(&self) -> Result<DesktopEntry> {
|
pub fn get_entry(&self) -> Result<DesktopEntry> {
|
||||||
DesktopEntry::try_from(Self::get_path(&self.0).unwrap())
|
DesktopEntry::try_from(Self::get_path(&self.0).unwrap())
|
||||||
}
|
}
|
||||||
pub fn run(&self, arg: &str) -> Result<()> {
|
pub fn open(&self, arg: String) -> Result<()> {
|
||||||
std::process::Command::new("gtk-launch")
|
let (cmd, args) = self.get_entry()?.get_cmd(Some(arg))?;
|
||||||
.args(&[self.0.as_str(), arg])
|
std::process::Command::new(cmd)
|
||||||
|
.args(args)
|
||||||
.stdout(std::process::Stdio::null())
|
.stdout(std::process::Stdio::null())
|
||||||
.spawn()?;
|
.spawn()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
pub fn launch(&self, args: Vec<String>) -> Result<()> {
|
||||||
|
let (cmd, mut base_args) = self.get_entry()?.get_cmd(None)?;
|
||||||
|
base_args.extend_from_slice(&args);
|
||||||
|
std::process::Command::new(cmd)
|
||||||
|
.args(base_args)
|
||||||
|
.stdout(std::process::Stdio::null())
|
||||||
|
.stderr(std::process::Stdio::null())
|
||||||
|
.spawn()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, pest_derive::Parser, Default, PartialEq, Eq)]
|
#[derive(Debug, Clone, pest_derive::Parser, Default, PartialEq, Eq)]
|
||||||
|
@ -67,8 +79,22 @@ pub struct DesktopEntry {
|
||||||
pub(crate) mimes: Vec<Mime>,
|
pub(crate) mimes: Vec<Mime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DesktopEntry {
|
||||||
|
pub fn get_cmd(
|
||||||
|
&self,
|
||||||
|
arg: Option<String>,
|
||||||
|
) -> Result<(String, Vec<String>)> {
|
||||||
|
let arg = arg.unwrap_or_default();
|
||||||
|
let arg = shlex::quote(&arg);
|
||||||
|
let replaced = self.exec.replace("%f", &arg).replace("%U", &arg);
|
||||||
|
|
||||||
|
let mut split = shlex::split(&replaced).ok_or(Error::BadCmd)?;
|
||||||
|
Ok((split.remove(0), split))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<PathBuf> for DesktopEntry {
|
impl TryFrom<PathBuf> for DesktopEntry {
|
||||||
type Error = anyhow::Error;
|
type Error = Error;
|
||||||
fn try_from(p: PathBuf) -> Result<DesktopEntry> {
|
fn try_from(p: PathBuf) -> Result<DesktopEntry> {
|
||||||
let raw = std::fs::read_to_string(&p)?;
|
let raw = std::fs::read_to_string(&p)?;
|
||||||
let file = Self::parse(Rule::file, &raw)?.next().unwrap();
|
let file = Self::parse(Rule::file, &raw)?.next().unwrap();
|
||||||
|
@ -84,10 +110,12 @@ impl TryFrom<PathBuf> for DesktopEntry {
|
||||||
let name = inner_rules.next().unwrap().as_str();
|
let name = inner_rules.next().unwrap().as_str();
|
||||||
match name {
|
match name {
|
||||||
"Name" => {
|
"Name" => {
|
||||||
entry.name = inner_rules.next().unwrap().as_str().into();
|
entry.name =
|
||||||
|
inner_rules.next().unwrap().as_str().into();
|
||||||
}
|
}
|
||||||
"Exec" => {
|
"Exec" => {
|
||||||
entry.exec = inner_rules.next().unwrap().as_str().into();
|
entry.exec =
|
||||||
|
inner_rules.next().unwrap().as_str().into();
|
||||||
}
|
}
|
||||||
"MimeType" => {
|
"MimeType" => {
|
||||||
let mut mimes = inner_rules
|
let mut mimes = inner_rules
|
||||||
|
@ -111,7 +139,7 @@ impl TryFrom<PathBuf> for DesktopEntry {
|
||||||
if !entry.name.is_empty() && !entry.exec.is_empty() {
|
if !entry.name.is_empty() && !entry.exec.is_empty() {
|
||||||
Ok(entry)
|
Ok(entry)
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow::Error::msg("Invalid desktop entry"))
|
Err(Error::BadCmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
src/error.rs
Normal file
17
src/error.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error(transparent)]
|
||||||
|
Parse(#[from] pest::error::Error<crate::common::Rule>),
|
||||||
|
#[error(transparent)]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
#[error("handler not found")]
|
||||||
|
NotFound,
|
||||||
|
#[error("Invalid desktop entry")]
|
||||||
|
BadCmd,
|
||||||
|
#[error("Could not find config dir")]
|
||||||
|
NoConfigDir,
|
||||||
|
#[error("could not guess mime type")]
|
||||||
|
Ambiguous,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
53
src/main.rs
53
src/main.rs
|
@ -1,44 +1,61 @@
|
||||||
use anyhow::Result;
|
use error::{Error, Result};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
mod error;
|
||||||
mod mimeapps;
|
mod mimeapps;
|
||||||
|
|
||||||
pub use common::{DesktopEntry, Handler, Mime};
|
pub use common::{DesktopEntry, Handler, Mime};
|
||||||
|
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
enum Options {
|
enum Cmd {
|
||||||
List,
|
List,
|
||||||
Open { path: String },
|
Open {
|
||||||
Get { mime: Mime },
|
path: String,
|
||||||
Set { mime: Mime, handler: Handler },
|
},
|
||||||
|
Get {
|
||||||
|
#[structopt(long)]
|
||||||
|
json: bool,
|
||||||
|
mime: Mime,
|
||||||
|
},
|
||||||
|
Launch {
|
||||||
|
mime: Mime,
|
||||||
|
args: Vec<String>,
|
||||||
|
},
|
||||||
|
Set {
|
||||||
|
mime: Mime,
|
||||||
|
handler: Handler,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let cmd = Options::from_args();
|
let mut apps = mimeapps::MimeApps::read()?;
|
||||||
|
|
||||||
let mut user = mimeapps::MimeApps::read()?;
|
match Cmd::from_args() {
|
||||||
|
Cmd::Set { mime, handler } => {
|
||||||
match cmd {
|
apps.set_handler(mime, handler)?;
|
||||||
Options::Set { mime, handler } => {
|
|
||||||
user.set_handler(mime, handler)?;
|
|
||||||
}
|
}
|
||||||
Options::Get { mime } => {
|
Cmd::Launch { mime, args } => {
|
||||||
println!("{}", user.get_handler(&mime)?);
|
apps.get_handler(&mime)?.launch(args)?;
|
||||||
}
|
}
|
||||||
Options::Open { path } => match url::Url::parse(&path) {
|
Cmd::Get { mime, json } => {
|
||||||
|
apps.show_handler(&mime, json)?;
|
||||||
|
}
|
||||||
|
Cmd::Open { path } => match url::Url::parse(&path) {
|
||||||
Ok(url) => {
|
Ok(url) => {
|
||||||
let mime = Mime(format!("x-scheme-handler/{}", url.scheme()));
|
let mime = Mime(format!("x-scheme-handler/{}", url.scheme()));
|
||||||
user.get_handler(&mime)?.run(&path)?;
|
apps.get_handler(&mime)?.open(path)?;
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let guess = mime_guess::from_path(&path)
|
let guess = mime_guess::from_path(&path)
|
||||||
.first_raw()
|
.first_raw()
|
||||||
.ok_or_else(|| anyhow::Error::msg("Could not determine mime type"))?;
|
.ok_or(Error::Ambiguous)?;
|
||||||
user.get_handler(&Mime(guess.to_owned()))?.run(&path)?;
|
apps.get_handler(&Mime(guess.to_owned()))?.open(path)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {}
|
Cmd::List => {
|
||||||
|
apps.print()?;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::{DesktopEntry, Handler, Mime};
|
use crate::{DesktopEntry, Error, Handler, Mime, Result};
|
||||||
use anyhow::Result;
|
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::{
|
||||||
use std::path::PathBuf;
|
collections::{HashMap, VecDeque},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, pest_derive::Parser)]
|
#[derive(Debug, pest_derive::Parser)]
|
||||||
#[grammar = "ini.pest"]
|
#[grammar = "ini.pest"]
|
||||||
|
@ -17,25 +18,40 @@ impl MimeApps {
|
||||||
pub fn set_handler(&mut self, mime: Mime, handler: Handler) -> Result<()> {
|
pub fn set_handler(&mut self, mime: Mime, handler: Handler) -> Result<()> {
|
||||||
let handlers = self.default_apps.entry(mime).or_default();
|
let handlers = self.default_apps.entry(mime).or_default();
|
||||||
handlers.push_front(handler);
|
handlers.push_front(handler);
|
||||||
self.print()?;
|
self.save()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn get_handler(&self, mime: &Mime) -> Result<Handler> {
|
pub fn get_handler(&self, mime: &Mime) -> Result<Handler> {
|
||||||
Ok(self
|
self.default_apps
|
||||||
.default_apps
|
|
||||||
.get(mime)
|
.get(mime)
|
||||||
.or_else(|| self.added_associations.get(mime))
|
.or_else(|| self.added_associations.get(mime))
|
||||||
.map(|hs| hs.get(0).unwrap().clone())
|
.map(|hs| hs.get(0).unwrap().clone())
|
||||||
.or_else(|| self.system_apps.get_handler(mime))
|
.or_else(|| self.system_apps.get_handler(mime))
|
||||||
.ok_or(anyhow::Error::msg("No handlers found"))?)
|
.ok_or(Error::NotFound)
|
||||||
|
}
|
||||||
|
pub fn show_handler(&self, mime: &Mime, output_json: bool) -> Result<()> {
|
||||||
|
let handler = self.get_handler(mime)?;
|
||||||
|
let output = if output_json {
|
||||||
|
let entry = handler.get_entry()?;
|
||||||
|
(json::object! {
|
||||||
|
handler: handler.to_string(),
|
||||||
|
name: entry.name.as_str(),
|
||||||
|
cmd: entry.get_cmd(None)?.0
|
||||||
|
})
|
||||||
|
.to_string()
|
||||||
|
} else {
|
||||||
|
handler.to_string()
|
||||||
|
};
|
||||||
|
println!("{}", output);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn path() -> Result<PathBuf> {
|
pub fn path() -> Result<PathBuf> {
|
||||||
dirs::config_dir()
|
dirs::config_dir()
|
||||||
.map(|mut data_dir| {
|
.map(|mut config_dir| {
|
||||||
data_dir.push("mimeapps.list");
|
config_dir.push("mimeapps.list");
|
||||||
data_dir
|
config_dir
|
||||||
})
|
})
|
||||||
.ok_or_else(|| anyhow::Error::msg("Could not determine xdg data dir"))
|
.ok_or(Error::NoConfigDir)
|
||||||
}
|
}
|
||||||
pub fn read() -> Result<Self> {
|
pub fn read() -> Result<Self> {
|
||||||
let raw_conf = std::fs::read_to_string(Self::path()?)?;
|
let raw_conf = std::fs::read_to_string(Self::path()?)?;
|
||||||
|
@ -80,9 +96,9 @@ impl MimeApps {
|
||||||
"Added Associations" => conf
|
"Added Associations" => conf
|
||||||
.added_associations
|
.added_associations
|
||||||
.insert(Mime(name.to_owned()), handlers),
|
.insert(Mime(name.to_owned()), handlers),
|
||||||
"Default Applications" => {
|
"Default Applications" => conf
|
||||||
conf.default_apps.insert(Mime(name.to_owned()), handlers)
|
.default_apps
|
||||||
}
|
.insert(Mime(name.to_owned()), handlers),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -93,7 +109,7 @@ impl MimeApps {
|
||||||
|
|
||||||
Ok(conf)
|
Ok(conf)
|
||||||
}
|
}
|
||||||
pub fn print(&self) -> Result<()> {
|
pub fn save(&self) -> Result<()> {
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::io::{prelude::*, BufWriter};
|
use std::io::{prelude::*, BufWriter};
|
||||||
|
|
||||||
|
@ -123,6 +139,20 @@ impl MimeApps {
|
||||||
writer.flush()?;
|
writer.flush()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
pub fn print(&self) -> Result<()> {
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
let rows = self
|
||||||
|
.default_apps
|
||||||
|
.iter()
|
||||||
|
.sorted()
|
||||||
|
.map(|(k, v)| vec![k.0.clone(), v.iter().join(", ")])
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
ascii_table::AsciiTable::default().print(rows);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
use crate::{DesktopEntry, Handler, Mime};
|
|
||||||
use anyhow::Result;
|
|
||||||
use dashmap::DashMap;
|
|
||||||
use std::convert::TryFrom;
|
|
Loading…
Reference in a new issue