1 //! A small, cross-platform crate for creating symlinks.
3 //! For efficiency, you should prefer to use [`symlink_file`] or [`symlink_dir`]—whichever is
4 //! appropriate—rather than [`symlink_auto`].
6 // Building docs produces rustdoc::broken_intra_doc_links warnings on std::os::{windows, unix},
7 // depending on your platform. This is unfortunate because I then can’t RUSTDOCFLAGS="-D warnings"
8 // unless I suppress those, but suppressing those ones alone is messy, and suppressing all harmful,
9 // so I’m just leaving it at spurious square brackets being left in the output.
11 // It’s generally nicer to produce an empty crate on unsupported platforms than to explode.
18 #[path = "windows/mod.rs"]
23 pub use std
::fs
::remove_file
as remove_symlink_dir
;
24 pub use std
::fs
::remove_file
as remove_symlink_auto
;
25 // Look, frankly, std::fs::soft_link and std::os::unix::fs::symlink call the same function,
26 // so this probably whole separate mod probably isn’t even warranted.
27 // But deprecated blah blah blah so I decided to use the std::os one anyway.
29 pub use std
::os
::unix
::fs
::{symlink
as symlink_auto
,
30 symlink
as symlink_file
,
31 symlink
as symlink_dir
};
33 // The compiler claims that std::fs::soft_link has been “replaced with
34 // std::os::unix::fs::symlink and std::os::windows::fs::{symlink_file, symlink_dir}”
35 // (rustc nightly 2021-12-26 deprecation warning message), but although that was true enough
36 // when it was deprecated, it’s no longer quite true because of the wasm32-wasi target, which
37 // supports symlinks through std::fs::soft_link but has no stable alternative (as I write,
38 // std::os::wasi::fs::symlink_path is behind feature(wasi_ext)). Frankly, I think that’s a fair
39 // (though imperfect) reason to *undeprecate* soft_link. Who knows what other platforms may in
40 // the future stop returning std::io::ErrorKind::Unsupported errors and start supporting
41 // std::fs::soft_link? (And for clarity, I note that no others do at the time of writing.)
43 pub use std
::fs
::{soft_link
as symlink_auto
,
44 soft_link
as symlink_file
,
45 soft_link
as symlink_dir
};
48 /// Create a symlink (non-preferred way).
50 /// On Windows, file and directory symlinks are created by distinct methods; to cope with that,
51 /// this function checks whether the destination is a file or a folder and creates the appropriate
52 /// type of symlink based on that result. Therefore, if the destination does not exist or if you do
53 /// not have permission to fetch its metadata, this will return an error on Windows.
55 /// On other platforms there is no distinction, so this isn’t magic: it’s precisely equivalent to
56 /// calling [`std::os::unix::fs::symlink`] or [`std::fs::soft_link`].
58 /// # A note on using this function
60 /// Because this is slightly less efficient and more hazardous on Windows, you should prefer to use
61 /// [`symlink_file`] or [`symlink_dir`] instead. Only use this if you don’t know or care whether
62 /// the destination is a file or a directory (but even then, you do need to know that it exists).
66 /// An error will be returned if the symlink cannot be created, or—on Windows—if the destination
67 /// does not exist or cannot be read.
69 pub fn symlink_auto
<P
: AsRef
<Path
>, Q
: AsRef
<Path
>>(src
: P
, dst
: Q
) -> io
::Result
<()> {
70 internal
::symlink_auto(src
.as_ref(), dst
.as_ref())
73 /// Create a symlink to a file.
75 /// On Windows, this is equivalent to [`std::os::windows::fs::symlink_file`]. If you call it with a
76 /// directory as the destination, [something may happen; you never know what][fow].
78 /// On Unix, this is equivalent to [`std::os::unix::fs::symlink`], and on other platforms it’s
79 /// equivalent to [`std::fs::soft_link`]. If you call it with a directory as the destination,
80 /// nothing bad will happen, but you’re ruining your cross-platform technique and ruining the point
81 /// of this crate, so please don’t.
85 /// An error will be returned if the symlink cannot be created.
87 /// [fow]: https://en.wikipedia.org/wiki/A_Fish_Out_of_Water_(book)
89 pub fn symlink_file
<P
: AsRef
<Path
>, Q
: AsRef
<Path
>>(src
: P
, dst
: Q
) -> io
::Result
<()> {
90 internal
::symlink_file(src
.as_ref(), dst
.as_ref())
93 /// Create a symlink to a directory.
95 /// On Windows, this is equivalent to [`std::os::windows::fs::symlink_dir`]. If you call it with a
96 /// directory as the destination, [something may happen; you never know what][fow].
98 /// On Unix, this is equivalent to [`std::os::unix::fs::symlink`], and on other platforms it’s
99 /// equivalent to [`std::fs::soft_link`]. If you call it with a directory as the destination,
100 /// nothing bad will happen, but you’re ruining your cross-platform technique and ruining the point
101 /// of this crate, so please don’t.
105 /// An error will be returned if the symlink cannot be created.
107 /// [fow]: https://en.wikipedia.org/wiki/A_Fish_Out_of_Water_(book)
109 pub fn symlink_dir
<P
: AsRef
<Path
>, Q
: AsRef
<Path
>>(src
: P
, dst
: Q
) -> io
::Result
<()> {
110 internal
::symlink_dir(src
.as_ref(), dst
.as_ref())
113 /// Remove a symlink (non-preferred way).
115 /// This inspects the path metadata to remove the symlink as a file or directory, whichever is
118 /// # A note on using this function
120 /// Because this is slightly less efficient on Windows, you should prefer to use
121 /// [`remove_symlink_file`] or [`remove_symlink_dir`] instead. Only use this if you don’t know or
122 /// care whether the destination is a file or a directory (but even then, you do need to know that
127 /// An error will be returned if the symlink cannot be removed.
129 pub fn remove_symlink_auto
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<()> {
130 internal
::remove_symlink_auto(path
)
133 /// Remove a directory symlink.
135 /// On Windows, this corresponds to [`std::fs::remove_dir`].
137 /// On Unix, this corresponds to [`std::fs::remove_file`].
139 pub fn remove_symlink_dir
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<()> {
140 internal
::remove_symlink_dir(path
)
143 /// Remove a file symlink.
145 /// This just calls [`std::fs::remove_file`], but the function is provided here to correspond to
146 /// [`remove_symlink_dir`].
148 pub fn remove_symlink_file
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<()> {
149 fs
::remove_file(path
)