Skip to content

Commit 81548e5

Browse files
Cheong-Laujacobgkau
authored andcommitted
chore(deps): update freedesktop-entry-parser
1 parent e053db3 commit 81548e5

File tree

6 files changed

+113
-117
lines changed

6 files changed

+113
-117
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-c
1414
cosmic-mime-apps = { git = "https://github.com/pop-os/cosmic-mime-apps.git", optional = true }
1515
dirs = "6.0.0"
1616
env_logger = "0.11"
17-
freedesktop_entry_parser = "1.3"
17+
freedesktop_entry_parser = "2.0"
1818
futures = "0.3.31"
1919
gio = { version = "0.21", optional = true }
2020
glib = { version = "0.21", optional = true }

src/app.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -838,29 +838,28 @@ impl App {
838838
fn launch_desktop_entries(paths: &[impl AsRef<Path>]) {
839839
for path in paths.iter().map(AsRef::as_ref) {
840840
match freedesktop_entry_parser::parse_entry(path) {
841-
Ok(entry) => match entry.section("Desktop Entry").attr("Exec") {
842-
Some(exec) => match mime_app::exec_to_command(exec, &[] as &[&str; 0]) {
843-
Some(commands) => {
844-
for mut command in commands {
845-
if let Err(err) = spawn_detached(&mut command) {
846-
log::warn!("failed to execute {}: {}", path.display(), err);
847-
}
848-
}
849-
}
850-
None => {
851-
log::warn!(
852-
"failed to parse {}: invalid Desktop Entry/Exec",
853-
path.display()
854-
);
841+
Ok(entry) => {
842+
let Some(exec_attr) = entry.get("Desktop Entry", "Exec") else {
843+
log::warn!("failed to parse {}: missing Desktop Entry", path.display());
844+
continue;
845+
};
846+
847+
let Some(exec) = exec_attr.first() else {
848+
log::warn!("failed to parse {}: missing Exec", path.display());
849+
continue;
850+
};
851+
852+
let Some(commands) = mime_app::exec_to_command(exec, &[] as &[&str]) else {
853+
log::warn!("failed to parse {}: invalid Exec", path.display());
854+
continue;
855+
};
856+
857+
for mut command in commands {
858+
if let Err(err) = spawn_detached(&mut command) {
859+
log::warn!("failed to execute {}: {}", path.display(), err);
855860
}
856-
},
857-
None => {
858-
log::warn!(
859-
"failed to parse {}: missing Desktop Entry/Exec",
860-
path.display()
861-
);
862861
}
863-
},
862+
}
864863
Err(err) => {
865864
log::warn!("failed to parse {}: {}", path.display(), err);
866865
}

src/mime_app.rs

Lines changed: 60 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#[cfg(feature = "desktop")]
55
use cosmic::desktop;
66
use cosmic::widget;
7+
use freedesktop_entry_parser::Section;
78
pub use mime_guess::Mime;
89
use rustc_hash::FxHashMap;
910
use std::{
@@ -48,35 +49,29 @@ pub fn exec_to_command(
4849
let field_code_pos = args_vec
4950
.iter()
5051
.position(|arg| EXEC_HANDLERS.contains(&arg.as_str()));
51-
let args_handler = field_code_pos.and_then(|i| args_vec.get(i));
52-
// msrv
53-
// .inspect(|handler| log::trace!("Found paths handler: {handler} for exec: {exec}"));
52+
let args_handler = field_code_pos
53+
.and_then(|i| args_vec.get(i))
54+
.inspect(|&handler| log::trace!("Found paths handler: {handler} for exec: {exec}"));
5455
// Number of args before the field code.
5556
// This won't be an off by one err below because take is not zero indexed.
5657
let field_code_pos = field_code_pos.unwrap_or_default();
5758
let mut processes = match args_handler.map(String::as_str) {
5859
Some("%f") => {
59-
let mut processes = Vec::with_capacity(path_opt.len());
60-
61-
for path in path_opt.iter().map(AsRef::as_ref) {
62-
// TODO: %f and %F need to handle non-file URLs (see spec)
63-
if from_file_or_dir(path).is_none() {
64-
log::warn!("Desktop file expects a file path instead of a URL: {path:?}");
65-
}
66-
67-
// Passing multiple paths to %f should open an instance per path
68-
let mut process = process::Command::new(program);
69-
process.args(
70-
args_vec
71-
.iter()
72-
.map(AsRef::as_ref)
73-
.take(field_code_pos)
74-
.chain(std::iter::once(path)),
75-
);
76-
processes.push(process);
77-
}
60+
path_opt
61+
.iter()
62+
.map(|path| {
63+
let path = path.as_ref();
64+
// TODO: %f and %F need to handle non-file URLs (see spec)
65+
if from_file_or_dir(path).is_none() {
66+
log::warn!("Desktop file expects a file path instead of a URL: {path:?}");
67+
}
7868

79-
processes
69+
// Passing multiple paths to %f should open an instance per path
70+
let mut process = process::Command::new(program);
71+
process.args(args_vec.iter().take(field_code_pos)).arg(path);
72+
process
73+
})
74+
.collect()
8075
}
8176
Some("%F") => {
8277
// TODO: %f and %F need to handle non-file URLs (see spec)
@@ -90,39 +85,25 @@ pub fn exec_to_command(
9085

9186
// Launch one instance with all args
9287
let mut process = process::Command::new(program);
93-
process.args(
94-
args_vec
95-
.iter()
96-
.map(OsStr::new)
97-
.take(field_code_pos)
98-
.chain(path_opt.iter().map(AsRef::as_ref)),
99-
);
88+
process
89+
.args(args_vec.iter().take(field_code_pos))
90+
.args(path_opt);
10091

10192
vec![process]
10293
}
10394
Some("%u") => path_opt
10495
.iter()
10596
.map(|path| {
10697
let mut process = process::Command::new(program);
107-
process.args(
108-
args_vec
109-
.iter()
110-
.map(OsStr::new)
111-
.take(field_code_pos)
112-
.chain(std::iter::once(path.as_ref())),
113-
);
98+
process.args(args_vec.iter().take(field_code_pos)).arg(path);
11499
process
115100
})
116101
.collect(),
117102
Some("%U") => {
118103
let mut process = process::Command::new(program);
119-
process.args(
120-
args_vec
121-
.iter()
122-
.map(OsStr::new)
123-
.take(field_code_pos)
124-
.chain(path_opt.iter().map(AsRef::as_ref)),
125-
);
104+
process
105+
.args(args_vec.iter().take(field_code_pos))
106+
.args(path_opt);
126107
vec![process]
127108
}
128109
Some(invalid) => unreachable!("All valid variants were checked; got: {invalid}"),
@@ -315,39 +296,42 @@ impl MimeAppCache {
315296
}
316297
};
317298

318-
for attr in entry
319-
.section("Added Associations")
320-
.attrs()
321-
.chain(entry.section("Default Applications").attrs())
299+
let added_iter = entry.section("Added Associations").map(Section::attrs);
300+
let default_iter = entry.section("Default Applications").map(Section::attrs);
301+
// TODO: replace with Option::into_flat_iter when stable and within MSRV
302+
// https://github.com/rust-lang/rust/issues/148441
303+
for attr in added_iter
304+
.into_iter()
305+
.flatten()
306+
.chain(default_iter.into_iter().flatten())
322307
{
323-
if let Ok(mime) = attr.name.parse::<Mime>() {
324-
if let Some(filenames) = attr.value {
325-
for filename in filenames.split_terminator(';') {
326-
log::trace!("add {mime}={filename}");
327-
let apps = self
328-
.cache
329-
.entry(mime.clone())
330-
.or_insert_with(|| Vec::with_capacity(1));
331-
if !apps.iter().any(|x| filename_eq(&x.path, filename)) {
332-
if let Some(app) =
333-
all_apps.iter().find(|&x| filename_eq(&x.path, filename))
334-
{
335-
apps.push(MimeApp::from(app));
336-
} else {
337-
log::info!(
338-
"failed to add association for {mime:?}: application {filename:?} not found"
339-
);
340-
}
308+
if let Ok(mime) = attr.0.key.parse::<Mime>() {
309+
let mime_str = mime.as_ref();
310+
for filename in attr.1 {
311+
log::trace!("add {mime_str}={filename}");
312+
let apps = self
313+
.cache
314+
.entry(mime.clone())
315+
.or_insert_with(|| Vec::with_capacity(1));
316+
if !apps.iter().any(|x| filename_eq(&x.path, filename)) {
317+
if let Some(app) =
318+
all_apps.iter().find(|&x| filename_eq(&x.path, filename))
319+
{
320+
apps.push(MimeApp::from(app));
321+
} else {
322+
log::info!(
323+
"failed to add association for {mime_str}: application {filename} not found"
324+
);
341325
}
342326
}
343327
}
344328
}
345329
}
346330

347-
for attr in entry.section("Removed Associations").attrs() {
348-
if let Ok(mime) = attr.name.parse::<Mime>() {
349-
if let Some(filenames) = attr.value {
350-
for filename in filenames.split_terminator(';') {
331+
if let Some(removed_associations) = entry.section("Removed Associations") {
332+
for attr in removed_associations.attrs() {
333+
if let Ok(mime) = attr.0.key.parse::<Mime>() {
334+
for filename in attr.1 {
351335
log::trace!("remove {mime}={filename}");
352336
if let Some(apps) = self.cache.get_mut(&mime) {
353337
apps.retain(|x| !filename_eq(&x.path, filename));
@@ -357,14 +341,14 @@ impl MimeAppCache {
357341
}
358342
}
359343

360-
for attr in entry.section("Default Applications").attrs() {
361-
if let Ok(mime) = attr.name.parse::<Mime>() {
362-
if let Some(filenames) = attr.value {
363-
for filename in filenames.split_terminator(';') {
344+
if let Some(default_applications) = entry.section("Default Applications") {
345+
for attr in default_applications.attrs() {
346+
if let Ok(mime) = attr.0.key.parse::<Mime>() {
347+
for filename in attr.1 {
364348
log::trace!("default {mime}={filename}");
365349
if let Some(apps) = self.cache.get_mut(&mime) {
366350
let mut found = false;
367-
for app in apps.iter_mut() {
351+
for app in apps {
368352
if filename_eq(&app.path, filename) {
369353
app.is_default = true;
370354
found = true;
@@ -376,7 +360,7 @@ impl MimeAppCache {
376360
break;
377361
}
378362
log::debug!(
379-
"failed to set default for {mime:?}: application {filename:?} not found"
363+
"failed to set default for {mime}: application {filename} not found"
380364
);
381365
}
382366
}

src/tab.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -608,9 +608,10 @@ fn get_desktop_file_display_name(path: &Path) -> Option<String> {
608608
};
609609

610610
entry
611-
.section("Desktop Entry")
611+
.section("Desktop Entry")?
612612
.attr("Name")
613-
.map(str::to_string)
613+
.first()
614+
.cloned()
614615
}
615616

616617
fn get_desktop_file_icon(path: &Path) -> Option<String> {
@@ -623,9 +624,10 @@ fn get_desktop_file_icon(path: &Path) -> Option<String> {
623624
};
624625

625626
entry
626-
.section("Desktop Entry")
627+
.section("Desktop Entry")?
627628
.attr("Icon")
628-
.map(str::to_string)
629+
.first()
630+
.cloned()
629631
}
630632

631633
pub fn parse_desktop_file(path: &Path) -> (Option<String>, Option<String>) {
@@ -636,10 +638,14 @@ pub fn parse_desktop_file(path: &Path) -> (Option<String>, Option<String>) {
636638
return (None, None);
637639
}
638640
};
639-
let section = entry.section("Desktop Entry");
641+
642+
let Some(section) = entry.section("Desktop Entry") else {
643+
return (None, None);
644+
};
645+
640646
(
641-
section.attr("Name").map(str::to_string),
642-
section.attr("Icon").map(str::to_string),
647+
section.attr("Name").first().cloned(),
648+
section.attr("Icon").first().cloned(),
643649
)
644650
}
645651

src/thumbnailer.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,30 +123,37 @@ impl ThumbnailerCache {
123123
}
124124
};
125125

126+
let Some(section) = entry.section("Thumbnailer Entry") else {
127+
log::warn!(
128+
"missing Thumbnailer Entry section for thumbnailer {}",
129+
path.display()
130+
);
131+
continue;
132+
};
133+
126134
//TODO: use TryExec?
127-
let section = entry.section("Thumbnailer Entry");
128-
let Some(exec) = section.attr("Exec") else {
135+
let Some(exec) = section.attr("Exec").first() else {
129136
log::warn!("missing Exec attribute for thumbnailer {}", path.display());
130137
continue;
131138
};
132-
let Some(mime_types) = section.attr("MimeType") else {
139+
140+
let mime_types = section.attr("MimeType");
141+
if mime_types.is_empty() {
133142
log::warn!(
134143
"missing MimeType attribute for thumbnailer {}",
135144
path.display()
136145
);
137146
continue;
138-
};
147+
}
139148

140-
for mime_type in mime_types.split_terminator(';') {
149+
for mime_type in mime_types {
141150
if let Ok(mime) = mime_type.parse::<Mime>() {
142151
log::trace!("thumbnailer {}={}", mime, path.display());
143152
let apps = self
144153
.cache
145154
.entry(mime)
146155
.or_insert_with(|| Vec::with_capacity(1));
147-
apps.push(Thumbnailer {
148-
exec: exec.to_string(),
149-
});
156+
apps.push(Thumbnailer { exec: exec.clone() });
150157
}
151158
}
152159
}

0 commit comments

Comments
 (0)