11use std:: {
22 borrow:: Cow ,
3+ io,
34 path:: { Path , PathBuf } ,
45 ptr,
56} ;
@@ -52,32 +53,6 @@ pub struct Shortcut {
5253 pub run_as_admin : bool ,
5354}
5455
55- /// Options for loading a [`Shortcut`], can be specified when using [`load_with_options`](Shortcut::load_with_options).
56- #[ derive( Debug , Clone , Copy ) ]
57- pub struct LoadOptions {
58- /// If true, canonicalizes paths.
59- pub canonicalize : bool ,
60- }
61-
62- impl Default for LoadOptions {
63- fn default ( ) -> Self {
64- Self { canonicalize : true } // keep current behavior as default
65- }
66- }
67-
68- /// Options for saving a [`Shortcut`], can be specified when using [`save_with_options`](Shortcut::save_with_options).
69- #[ derive( Debug , Clone , Copy ) ]
70- pub struct SaveOptions {
71- /// If true, canonicalizes paths.
72- pub canonicalize : bool ,
73- }
74-
75- impl Default for SaveOptions {
76- fn default ( ) -> Self {
77- Self { canonicalize : true }
78- }
79- }
80-
8156impl Shortcut {
8257 /// Create a new empty [`ShortcutBuilder`].
8358 #[ must_use]
@@ -100,11 +75,6 @@ impl Shortcut {
10075 }
10176 }
10277
103- /// Loads a `.lnk` file from disk and parses it into a [`Shortcut`].
104- pub fn load ( path : impl AsRef < Path > ) -> Result < Self > {
105- Self :: load_with_options ( path, LoadOptions :: default ( ) )
106- }
107-
10878 /// Canonicalizes all filesystem paths contained in this shortcut in-place.
10979 ///
11080 /// The following fields are affected:
@@ -116,27 +86,25 @@ impl Shortcut {
11686 /// If a path is **relative** and `base` is [`Some`], it is first resolved
11787 /// relative to `base` (typically the directory containing the `.lnk` file)
11888 /// and then canonicalized.
119- ///
120- /// # Errors
121- /// Errors during canonicalization are ignored.
122- pub fn canonicalize ( & mut self , base : Option < & Path > ) {
123- try_canonicalize_with_base_inplace_opt ( self . target_path . as_mut ( ) , base) ;
124- try_canonicalize_with_base_inplace_opt ( self . working_dir . as_mut ( ) , base) ;
125- try_canonicalize_with_base_inplace_opt ( self . icon . as_mut ( ) . map ( |i| & mut i. path ) , base) ;
89+ pub fn canonicalize ( & mut self , base : Option < & Path > ) -> io:: Result < ( ) > {
90+ canonicalize_with_base_inplace_opt ( self . target_path . as_mut ( ) , base) ?;
91+ canonicalize_with_base_inplace_opt ( self . working_dir . as_mut ( ) , base) ?;
92+ canonicalize_with_base_inplace_opt ( self . icon . as_mut ( ) . map ( |i| & mut i. path ) , base) ?;
93+ Ok ( ( ) )
12694 }
12795
12896 /// Returns a canonicalized clone of this shortcut.
12997 ///
13098 /// This is a non-mutating variant of [`canonicalize`](Self::canonicalize).
13199 /// The original [`Shortcut`] is left unchanged.
132- pub fn canonicalized ( & self , base : Option < & Path > ) -> Self {
100+ pub fn canonicalized ( & self , base : Option < & Path > ) -> io :: Result < Self > {
133101 let mut clone = self . clone ( ) ;
134- clone. canonicalize ( base) ;
135- clone
102+ clone. canonicalize ( base) ? ;
103+ Ok ( clone)
136104 }
137105
138- /// Loads a `.lnk` file from disk and parses it into a [`Shortcut`], considering the given [`LoadOptions`] .
139- pub fn load_with_options ( path : impl AsRef < Path > , options : LoadOptions ) -> Result < Self > {
106+ /// Loads a `.lnk` file from disk and parses it into a [`Shortcut`].
107+ pub fn load ( path : impl AsRef < Path > ) -> Result < Self > {
140108 let path = path. as_ref ( ) ;
141109 com:: ensure_initialized ( ) ?;
142110
@@ -181,7 +149,7 @@ impl Shortcut {
181149 #[ cfg( feature = "runas" ) ]
182150 let run_as_admin = runas:: read_runas_bit ( & path) ?;
183151
184- let mut shortcut = Shortcut {
152+ let shortcut = Shortcut {
185153 target_path,
186154 arguments,
187155 working_dir,
@@ -193,31 +161,19 @@ impl Shortcut {
193161 run_as_admin,
194162 } ;
195163
196- if options. canonicalize {
197- shortcut. canonicalize ( path. parent ( ) ) ;
198- }
199-
200164 Ok ( shortcut)
201165 }
202166
203167 /// Saves the shortcut to disk as a `.lnk` file.
204168 pub fn save ( & self , path : impl AsRef < Path > ) -> Result < ( ) > {
205- self . save_with_options ( path, SaveOptions :: default ( ) )
206- }
207-
208- /// Saves the shortcut to disk as a `.lnk` file, considering the given [`SaveOptions`].
209- pub fn save_with_options ( & self , path : impl AsRef < Path > , options : SaveOptions ) -> Result < ( ) > {
210169 com:: ensure_initialized ( ) ?;
211170
212- let path = maybe_try_canonicalize ( path. as_ref ( ) , options. canonicalize ) ;
213- let base = path. parent ( ) ;
171+ let path = try_canonicalize ( path. as_ref ( ) ) ;
214172
215173 let link: IShellLinkW = unsafe { CoCreateInstance ( & ShellLink , None , CLSCTX_INPROC_SERVER ) }
216174 . context ( None , "CoCreateInstance" ) ?;
217175
218176 if let Some ( target_path) = & self . target_path {
219- let target_path =
220- maybe_try_canonicalize_with_base ( target_path, base, options. canonicalize ) ;
221177 let w = U16CString :: from_os_str ( target_path. as_os_str ( ) ) ?;
222178 unsafe { link. SetPath ( PCWSTR ( w. as_ptr ( ) ) ) } . context ( Some ( "IShellLinkW" ) , "SetPath" ) ?;
223179 }
@@ -229,8 +185,6 @@ impl Shortcut {
229185 }
230186
231187 if let Some ( working_dir) = & self . working_dir {
232- let working_dir =
233- maybe_try_canonicalize_with_base ( working_dir, base, options. canonicalize ) ;
234188 let w = U16CString :: from_os_str ( working_dir. as_os_str ( ) ) ?;
235189 unsafe { link. SetWorkingDirectory ( PCWSTR ( w. as_ptr ( ) ) ) }
236190 . context ( Some ( "IShellLinkW" ) , "SetWorkingDirectory" ) ?;
@@ -243,9 +197,7 @@ impl Shortcut {
243197 }
244198
245199 if let Some ( icon) = & self . icon {
246- let icon_path =
247- maybe_try_canonicalize_with_base ( & icon. path , base, options. canonicalize ) ;
248- let w = U16CString :: from_os_str ( icon_path. as_os_str ( ) ) ?;
200+ let w = U16CString :: from_os_str ( icon. path . as_os_str ( ) ) ?;
249201 unsafe { link. SetIconLocation ( PCWSTR ( w. as_ptr ( ) ) , icon. index ) }
250202 . context ( Some ( "IShellLinkW" ) , "SetIconLocation" ) ?;
251203 }
@@ -400,76 +352,32 @@ impl ShortcutBuilder {
400352 }
401353}
402354
403- fn try_canonicalize_inplace ( path : & mut PathBuf ) -> bool {
404- if let Ok ( canon) = dunce:: canonicalize ( & path) {
405- * path = canon;
406- true
407- } else {
408- false
409- }
410- }
411- /*
412- fn try_canonicalize_inplace_opt(opt: Option<&mut PathBuf>) -> bool {
413- if let Some(path) = opt {
414- try_canonicalize_inplace(path)
415- } else {
416- false
417- }
355+ fn canonicalize_inplace ( path : & mut PathBuf ) -> io:: Result < ( ) > {
356+ * path = dunce:: canonicalize ( & path) ?;
357+ Ok ( ( ) )
418358}
419- */
420359#[ allow( clippy:: unnecessary_unwrap) ]
421- fn try_canonicalize_with_base_inplace ( path : & mut PathBuf , base : Option < & Path > ) -> bool {
360+ fn canonicalize_with_base_inplace ( path : & mut PathBuf , base : Option < & Path > ) -> io :: Result < ( ) > {
422361 if path. is_absolute ( ) || base. is_none ( ) {
423- try_canonicalize_inplace ( path)
362+ canonicalize_inplace ( path)
424363 } else {
425364 let mut absolute = base. unwrap ( ) . join ( & path) ;
426- let success = try_canonicalize_inplace ( & mut absolute) ;
427- if success {
428- * path = absolute;
429- }
430- success
365+ canonicalize_inplace ( & mut absolute) ?;
366+ * path = absolute;
367+ Ok ( ( ) )
431368 }
432369}
433- fn try_canonicalize_with_base_inplace_opt ( opt : Option < & mut PathBuf > , base : Option < & Path > ) -> bool {
370+ fn canonicalize_with_base_inplace_opt (
371+ opt : Option < & mut PathBuf > ,
372+ base : Option < & Path > ,
373+ ) -> io:: Result < ( ) > {
434374 if let Some ( path) = opt {
435- try_canonicalize_with_base_inplace ( path, base)
375+ canonicalize_with_base_inplace ( path, base)
436376 } else {
437- false
377+ Ok ( ( ) )
438378 }
439379}
440380
441381fn try_canonicalize ( path : & ' _ Path ) -> Cow < ' _ , Path > {
442382 dunce:: canonicalize ( path) . map_or_else ( |_| Cow :: Borrowed ( path) , Cow :: Owned )
443383}
444- fn maybe_try_canonicalize ( path : & ' _ Path , enabled : bool ) -> Cow < ' _ , Path > {
445- if enabled {
446- try_canonicalize ( path)
447- } else {
448- Cow :: Borrowed ( path)
449- }
450- }
451-
452- #[ allow( clippy:: unnecessary_unwrap) ]
453- fn try_canonicalize_with_base < ' a > ( path : & ' a Path , base : Option < & ' _ Path > ) -> Cow < ' a , Path > {
454- if path. is_absolute ( ) || base. is_none ( ) {
455- try_canonicalize ( path)
456- } else {
457- let mut absolute = base. unwrap ( ) . join ( path) ;
458- if try_canonicalize_inplace ( & mut absolute) {
459- Cow :: Owned ( absolute)
460- } else {
461- Cow :: Borrowed ( path)
462- }
463- }
464- }
465- fn maybe_try_canonicalize_with_base < ' a > (
466- path : & ' a Path ,
467- base : Option < & ' _ Path > ,
468- enabled : bool ,
469- ) -> Cow < ' a , Path > {
470- if enabled {
471- try_canonicalize_with_base ( path, base)
472- } else {
473- Cow :: Borrowed ( path)
474- }
475- }
0 commit comments