cmdpal/cmd/common/
open_url.rs1use crate::{
4 cmd::{BaseCommand, BaseCommandBuilder, CommandResult, InvokableCommand},
5 icon::{IconData, IconInfo},
6 utils::ComBuilder,
7};
8use windows_core::ComObject;
9
10pub struct OpenUrlCommandBuilder {
12 base: ComObject<BaseCommand>,
13 target_fn: Box<dyn Send + Sync + Fn() -> String>,
14 result: CommandResult,
15}
16
17fn open_url_base_cmd() -> ComObject<BaseCommand> {
18 BaseCommandBuilder::new()
19 .name("Open")
20 .icon(IconInfo::new(IconData::from("\u{E8A7}")))
21 .build()
22}
23
24impl OpenUrlCommandBuilder {
25 pub fn new(target: String) -> Self {
27 Self {
28 base: open_url_base_cmd(),
29 target_fn: Box::new(move || target.clone()),
30 result: CommandResult::Dismiss,
31 }
32 }
33
34 pub fn new_dyn<F>(target_fn: F) -> Self
36 where
37 F: Send + Sync + Fn() -> String + 'static,
38 {
39 Self {
40 base: open_url_base_cmd(),
41 target_fn: Box::new(target_fn),
42 result: CommandResult::Dismiss,
43 }
44 }
45
46 pub fn base(mut self, base: ComObject<BaseCommand>) -> Self {
50 self.base = base;
51 self
52 }
53
54 pub fn result(mut self, result: CommandResult) -> Self {
58 self.result = result;
59 self
60 }
61}
62
63impl ComBuilder for OpenUrlCommandBuilder {
64 type Output = InvokableCommand;
65 fn build_unmanaged(self) -> InvokableCommand {
66 InvokableCommand {
67 base: self.base,
68 func: Box::new(move |_| {
69 shell_helper::open_in_shell(&(self.target_fn)())?;
70 Ok(self.result.clone())
71 }),
72 }
73 }
74}
75
76mod shell_helper {
77 use windows::Win32::UI::Shell::{SHELLEXECUTEINFOW, ShellExecuteExW};
78 use windows::Win32::UI::{Shell::SEE_MASK_NOCLOSEPROCESS, WindowsAndMessaging::SW_SHOWNORMAL};
79
80 pub(super) fn open_in_shell(target: &str) -> windows_core::Result<()> {
81 let mut sei = SHELLEXECUTEINFOW::default();
82 sei.cbSize = std::mem::size_of::<SHELLEXECUTEINFOW>() as u32;
83 sei.fMask = SEE_MASK_NOCLOSEPROCESS;
84 sei.lpFile = windows_core::PCWSTR::from_raw(windows_core::HSTRING::from(target).as_ptr());
85 sei.nShow = SW_SHOWNORMAL.0;
86
87 unsafe { ShellExecuteExW(&mut sei) }
88 }
89}