diff --git a/Cargo.lock b/Cargo.lock index a6801f35ce345fa54758e8909e3e8a73d07716f6..930ecd337e6e007fdbb0b57965fb20620ede1524 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1890,7 +1890,6 @@ dependencies = [ "dirs", "libc", "log", - "pathdiff", "serde", "serde_json", "tokio", @@ -2553,12 +2552,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - [[package]] name = "percent-encoding" version = "2.3.0" diff --git a/Cargo.toml b/Cargo.toml index 43d99fff1db64252f6ea22d0d01fe4bc1d8a336d..0951ca66e618a38709a3788dd82d1c8d0d4188f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,36 +1,26 @@ [workspace] resolver = "2" members = [ - # Lektord - "lektord", - "lektor_nkdb", - "lektor_repo", - - # Common things - "kurisu_api", - "lektor_lib", - "lektor_utils", - "lektor_mpris", - "lektor_payloads", - "lektor_procmacros", - - # Clients - "amadeus", - "lkt", + "amadeus", # GUI Client + "lkt", # CLI Client + "lektord", # Lektord + "kurisu_api", # The Kurisu API + "lektor_*", # Common things ] [workspace.package] edition = "2021" authors = [ "Maël MARTIN <mael.martin@protonmail.com>", - "Louis GOYARD", - "Loïc ALLEGRE", - "Kevin COCCHI", - "Félix GOUEDARD", - "Hubert HIRTZ", - "Étienne BRATEAU", - "Tristan DEROUET", + "Louis GOYARD <elliu@hashi.re>", + "Loïc ALLEGRE <lallegre26@gmail.com>", + "Kevin COCCHI <salixor@pm.me>", + "Félix GOUEDARD <felix.gouedard@ensiie.fr>", + "Hubert HIRTZ <hubert.hirtz@laposte.net>", + "Étienne BRATEAU <etienne.brateau@gmail.com>", + "Tristan DEROUET <tristan.derouet@gmail.com>", ] +rust-version = "1.70" version = "3.0.1" license = "MIT" @@ -55,7 +45,6 @@ regex = { version = "1.9", default-features = false, features = [ ] } url = { version = "2", default-features = false } rand = "*" -libc = { version = "0.2", default-features = false } zbus = { version = "3", default-features = false, features = ["tokio"] } chrono = { version = "0.4", default-features = false, features = ["clock"] } sha256 = { version = "1", default-features = false, features = ["async"] } diff --git a/amadeus/Cargo.toml b/amadeus/Cargo.toml index 2724906007ca7ba7a7d78e0fe305eab86b632b77..e3bc99b948e794db0120d640956cedfa22a981f0 100644 --- a/amadeus/Cargo.toml +++ b/amadeus/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true description = "Amadeus-RS, graphical interface for lektord" [dependencies] diff --git a/kurisu_api/Cargo.toml b/kurisu_api/Cargo.toml index 14fa321d3e7cfb3db83b515bf759fede7ded74f3..b2d25cc338deef8e870c6bd83e7c6680d2fbc2e6 100644 --- a/kurisu_api/Cargo.toml +++ b/kurisu_api/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true description = "Crate used to deserialize what Kurisu returns" [lib] diff --git a/lektor_lib/Cargo.toml b/lektor_lib/Cargo.toml index ecf79f7d39ee27026ce88df00cac4f60d01c3117..190cd320cdd89187a4c19169c85fa9c359f3eee8 100644 --- a/lektor_lib/Cargo.toml +++ b/lektor_lib/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true description = "Client library for lektord, used to factorize the code between lkt and amadeus" [dependencies] diff --git a/lektor_mpris/Cargo.toml b/lektor_mpris/Cargo.toml index 5faa2c308dc42260900f22f9c94fdaf5e79047c7..2418277d856ed1a2a98e65810d4cebf1724b60ab 100644 --- a/lektor_mpris/Cargo.toml +++ b/lektor_mpris/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true description = "Implement the mpris spec, designed to be plugable into lektord or amadeus" [dependencies] diff --git a/lektor_nkdb/Cargo.toml b/lektor_nkdb/Cargo.toml index c6aedf352840da5a748557612af55690897f7be7..5541700811d801c26109c7aa1deb84316f442222 100644 --- a/lektor_nkdb/Cargo.toml +++ b/lektor_nkdb/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true description = "New database implementation for lektord (New Kara DataBase)" [dependencies] diff --git a/lektor_payloads/Cargo.toml b/lektor_payloads/Cargo.toml index 9a9350958343316492c97235e9513025f8acea6b..315a1e2e1011ec3d96eb7e53d13dbdc6e63a5942 100644 --- a/lektor_payloads/Cargo.toml +++ b/lektor_payloads/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true +description = "The payloads of the requests used to exchange messages between lektord and its client, this is a utility crate, you can build your own thing because they are all serialized to json under the hood" [dependencies] serde.workspace = true diff --git a/lektor_procmacros/Cargo.toml b/lektor_procmacros/Cargo.toml index e319eb760ec3adfc44de14baea4f3a87eb2170fd..11c1c252d2548021edd1ecb6e25aabac46070c74 100644 --- a/lektor_procmacros/Cargo.toml +++ b/lektor_procmacros/Cargo.toml @@ -1,10 +1,10 @@ -# Add https://crates.io/crates/derivative [package] name = "lektor_procmacros" authors.workspace = true license.workspace = true edition.workspace = true version.workspace = true +rust-version.workspace = true description = "A collection of procedural macros for the workspace" [lib] diff --git a/lektor_repo/Cargo.toml b/lektor_repo/Cargo.toml index f32c7d41a80bc04c89e474d3a1bef54c3ce45b14..2a02274e3fb0fe1f846c57bae0537afa698ed2fe 100644 --- a/lektor_repo/Cargo.toml +++ b/lektor_repo/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true description = "Structure used to update the lektord's database from a repo, can be kurisu or something else - only kurisu for now btw" [lib] diff --git a/lektor_utils/Cargo.toml b/lektor_utils/Cargo.toml index ef4f59a243bd1b39b2e3a628851901a983362c38..e3d8b4533baf5cb4c02d8e585042bd018efb61b1 100644 --- a/lektor_utils/Cargo.toml +++ b/lektor_utils/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true description = "Utilities in common for all the crates in the workspace" [lib] @@ -21,9 +22,5 @@ chrono.workspace = true serde_json.workspace = true # Some specific things for the open module. - -[target.'cfg(all(unix, not(macos)))'.dependencies] -pathdiff = "0.2.0" - [target."cfg(unix)".dependencies] libc = "0.2" diff --git a/lektor_utils/src/lib.rs b/lektor_utils/src/lib.rs index 05ec6081764adacf889f7c5c0c0de5c93e4660f1..ce8d14b283d64a1acf86c29f7188bc19e8145948 100644 --- a/lektor_utils/src/lib.rs +++ b/lektor_utils/src/lib.rs @@ -6,7 +6,7 @@ mod base64; mod iterator; mod macros; -// Import the is_wsl and is_docker code here... +/// Import the is_wsl and is_docker code here... #[cfg(any( target_os = "linux", target_os = "android", @@ -19,6 +19,9 @@ mod macros; ))] pub mod is; +/// Pathdiff to handle some errors with WSL... +pub mod pathdiff; + pub mod config; pub mod log; pub mod logger; diff --git a/lektor_utils/src/open/haiku.rs b/lektor_utils/src/open/haiku.rs index 2fbcd138d3e2bd3df733ac61eba7ab0e59f62fc1..1eb43ad8fc1a1a59bd34f33011427ed1282a886d 100644 --- a/lektor_utils/src/open/haiku.rs +++ b/lektor_utils/src/open/haiku.rs @@ -1,12 +1,12 @@ use std::{ffi::OsStr, process::Command}; -pub fn commands<T: AsRef<OsStr>>(path: T) -> Vec<Command> { +pub fn commands(path: impl AsRef<OsStr>) -> Vec<Command> { let mut cmd = Command::new("/bin/open"); cmd.arg(path.as_ref()); vec![cmd] } -pub fn with_command<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> Command { +pub fn with_command(path: impl AsRef<OsStr>, app: impl Into<String>) -> Command { let mut cmd = Command::new(app.into()); cmd.arg(path.as_ref()); cmd diff --git a/lektor_utils/src/open/ios.rs b/lektor_utils/src/open/ios.rs index e1d78f1dc46a97b696a3e5ed1a665a45be7a54bf..d1fbdbe464393ff1060194d3de5fc108d4674a92 100644 --- a/lektor_utils/src/open/ios.rs +++ b/lektor_utils/src/open/ios.rs @@ -1,12 +1,12 @@ use std::{ffi::OsStr, process::Command}; -pub fn commands<T: AsRef<OsStr>>(path: T) -> Vec<Command> { +pub fn commands(path: impl AsRef<OsStr>) -> Vec<Command> { let mut cmd = Command::new("uiopen"); cmd.arg("--url").arg(path.as_ref()); vec![cmd] } -pub fn with_command<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> Command { +pub fn with_command(path: impl AsRef<OsStr>, app: impl Into<String>) -> Command { let mut cmd = Command::new("uiopen"); cmd.arg("--url") .arg(path.as_ref()) diff --git a/lektor_utils/src/open/macos.rs b/lektor_utils/src/open/macos.rs index 6033d64c394005060cba798e63dde7d3119347ce..7c9a7aea78af72886aea2fdd5a2782895453b257 100644 --- a/lektor_utils/src/open/macos.rs +++ b/lektor_utils/src/open/macos.rs @@ -1,12 +1,12 @@ use std::{ffi::OsStr, process::Command}; -pub fn commands<T: AsRef<OsStr>>(path: T) -> Vec<Command> { +pub fn commands(path: impl AsRef<OsStr>) -> Vec<Command> { let mut cmd = Command::new("/usr/bin/open"); cmd.arg(path.as_ref()); vec![cmd] } -pub fn with_command<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> Command { +pub fn with_command(path: impl AsRef<OsStr>, app: impl Into<String>) -> Command { let mut cmd = Command::new("/usr/bin/open"); cmd.arg(path.as_ref()).arg("-a").arg(app.into()); cmd diff --git a/lektor_utils/src/open/mod.rs b/lektor_utils/src/open/mod.rs index f21897b8dc9dd6155d47b23dffa99ad5a7a54d99..20b9bdc0e44a92bf68de1018e77588428562be77 100644 --- a/lektor_utils/src/open/mod.rs +++ b/lektor_utils/src/open/mod.rs @@ -66,20 +66,25 @@ //! } //! ``` -#[cfg(target_os = "windows")] -use windows as os; +#[cfg(windows)] +#[path = "windows.rs"] +mod windows; #[cfg(target_os = "macos")] -use macos as os; +#[path = "macos.rs"] +mod os; #[cfg(target_os = "ios")] -use ios as os; +#[path = "ios.rs"] +mod os; #[cfg(target_os = "haiku")] -use haiku as os; +#[path = "haiku.rs"] +mod os; #[cfg(target_os = "redox")] -use redox as os; +#[path = "redox.rs"] +mod os; #[cfg(any( target_os = "linux", @@ -91,7 +96,8 @@ use redox as os; target_os = "illumos", target_os = "solaris" ))] -use unix as os; +#[path = "unix.rs"] +mod os; #[cfg(not(any( target_os = "linux", @@ -108,7 +114,7 @@ use unix as os; target_os = "haiku", target_os = "redox" )))] -compile_error!("open is not supported on this platform"); +compile_error!("unsupported on this platform"); use std::{ ffi::OsStr, @@ -223,8 +229,8 @@ pub fn that_in_background(path: impl AsRef<OsStr>) -> thread::JoinHandle<io::Res /// straightforward error handling. /// /// See documentation of [`with()`] for more details. -pub fn with_in_background<T: AsRef<OsStr>>( - path: T, +pub fn with_in_background( + path: impl AsRef<OsStr>, app: impl Into<String>, ) -> thread::JoinHandle<io::Result<()>> { let path = path.as_ref().to_os_string(); @@ -240,9 +246,7 @@ pub fn that_detached(path: impl AsRef<OsStr>) -> io::Result<()> { let mut last_err = None; for mut cmd in commands(path) { match cmd.spawn_detached() { - Ok(_) => { - return Ok(()); - } + Ok(_) => return Ok(()), Err(err) => last_err = Some(err), } } @@ -254,9 +258,8 @@ pub fn that_detached(path: impl AsRef<OsStr>) -> io::Result<()> { /// straightforward error handling. /// /// See documentation of [`with()`] for more details. -pub fn with_detached<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> { - let mut cmd = with_command(path, app); - cmd.spawn_detached() +pub fn with_detached(path: impl AsRef<OsStr>, app: impl Into<String>) -> io::Result<()> { + with_command(path, app).spawn_detached() } trait IntoResult<T> { @@ -292,26 +295,21 @@ impl CommandExt for Command { fn spawn_detached(&mut self) -> io::Result<()> { // This is pretty much lifted from the implementation in Alacritty: // https://github.com/alacritty/alacritty/blob/b9c886872d1202fc9302f68a0bedbb17daa35335/alacritty/src/daemon.rs - self.stdin(Stdio::null()) .stdout(Stdio::null()) .stderr(Stdio::null()); - #[cfg(unix)] unsafe { use std::os::unix::process::CommandExt as _; - self.pre_exec(move || { match libc::fork() { - -1 => return Err(io::Error::last_os_error()), + x if x < 0 => return Err(io::Error::last_os_error()), 0 => (), _ => libc::_exit(0), } - - if libc::setsid() == -1 { + if libc::setsid() < 0 { return Err(io::Error::last_os_error()); } - Ok(()) }); } @@ -322,34 +320,6 @@ impl CommandExt for Command { const CREATE_NO_WINDOW: u32 = 0x08000000; self.creation_flags(CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW); } - self.spawn().map(|_| ()) } } - -#[cfg(windows)] -mod windows; - -#[cfg(target_os = "macos")] -mod macos; - -#[cfg(target_os = "ios")] -mod ios; - -#[cfg(target_os = "haiku")] -mod haiku; - -#[cfg(target_os = "redox")] -mod redox; - -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "netbsd", - target_os = "openbsd", - target_os = "illumos", - target_os = "solaris" -))] -mod unix; diff --git a/lektor_utils/src/open/redox.rs b/lektor_utils/src/open/redox.rs index 8fab3434207ebdeb2ec1a09581105bf3e6f61743..84609e5a5b5a49f88cd1ee8ec20ae0ffca70dc98 100644 --- a/lektor_utils/src/open/redox.rs +++ b/lektor_utils/src/open/redox.rs @@ -1,12 +1,12 @@ use std::{ffi::OsStr, process::Command}; -pub fn commands<T: AsRef<OsStr>>(path: T) -> Vec<Command> { +pub fn commands(path: impl AsRef<OsStr>) -> Vec<Command> { let mut cmd = Command::new("/ui/bin/launcher"); cmd.arg(path.as_ref()); vec![cmd] } -pub fn with_command<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> Command { +pub fn with_command(path: impl AsRef<OsStr>, app: impl Into<String>) -> Command { let mut cmd = Command::new(app.into()); cmd.arg(path.as_ref()); cmd diff --git a/lektor_utils/src/open/unix.rs b/lektor_utils/src/open/unix.rs index 7cb23eebb01f36176c10ca6bcc038e7cc23f7b37..3df5e3eb161b7e4718dfe3b30874e65df86d7f75 100644 --- a/lektor_utils/src/open/unix.rs +++ b/lektor_utils/src/open/unix.rs @@ -1,11 +1,11 @@ use std::{ env, ffi::{OsStr, OsString}, - path::{Path, PathBuf}, + path::Path, process::Command, }; -pub fn commands<T: AsRef<OsStr>>(path: T) -> Vec<Command> { +pub fn commands(path: impl AsRef<OsStr>) -> Vec<Command> { let path = path.as_ref(); let mut commands: Vec<(&str, Vec<&OsStr>)> = vec![]; @@ -37,23 +37,20 @@ pub fn with_command<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> Command cmd } -// Polyfill to workaround absolute path bug in wslu(wslview). In versions before -// v3.1.1, wslview is unable to find absolute paths. `wsl_path` converts an -// absolute path into a relative path starting from the current directory. If -// the path is already a relative path or the conversion fails the original path -// is returned. -fn wsl_path<T: AsRef<OsStr>>(path: T) -> OsString { - fn path_relative_to_current_dir<T: AsRef<OsStr>>(path: T) -> Option<PathBuf> { - let path = Path::new(&path); - if path.is_relative() { - return None; - } - - pathdiff::diff_paths(path, env::current_dir().ok()?) - } - - match path_relative_to_current_dir(&path) { - None => OsString::from(&path), - Some(relative) => OsString::from(relative), +/// Polyfill to workaround absolute path bug in wslu(wslview). In versions before v3.1.1, wslview +/// is unable to find absolute paths. `wsl_path` converts an absolute path into a relative path +/// starting from the current directory. If the path is already a relative path or the conversion +/// fails the original path is returned. +fn wsl_path(path_str: impl AsRef<OsStr>) -> OsString { + let path = Path::new(path_str.as_ref()); + match env::current_dir().ok() { + Some(current) => match path + .is_relative() + .then(|| crate::pathdiff::diff_paths(path, current)) + { + Some(Some(relative)) => OsString::from(relative), + _ => path_str.as_ref().to_owned(), + }, + None => path_str.as_ref().to_owned(), } } diff --git a/lektor_utils/src/open/windows.rs b/lektor_utils/src/open/windows.rs index e44b1610fa2ae524a932cb438fc51e1c921f8983..202aefbe6861cc499a7bb3a3d7307c31fb98fa80 100644 --- a/lektor_utils/src/open/windows.rs +++ b/lektor_utils/src/open/windows.rs @@ -6,7 +6,7 @@ use std::{ const CREATE_NO_WINDOW: u32 = 0x08000000; -pub fn commands<T: AsRef<OsStr>>(path: T) -> Vec<Command> { +pub fn commands(path: impl AsRef<OsStr>) -> Vec<Command> { let mut cmd = Command::new("cmd"); cmd.arg("/c") .arg("start") @@ -16,7 +16,7 @@ pub fn commands<T: AsRef<OsStr>>(path: T) -> Vec<Command> { vec![cmd] } -pub fn with_command<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> Command { +pub fn with_command(path: impl AsRef<OsStr>, app: impl Into<String>) -> Command { let mut cmd = Command::new("cmd"); cmd.arg("/c") .arg("start") @@ -27,7 +27,7 @@ pub fn with_command<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> Command cmd } -fn wrap_in_quotes<T: AsRef<OsStr>>(path: T) -> OsString { +fn wrap_in_quotes(path: impl AsRef<OsStr>) -> OsString { let mut result = OsString::from("\""); result.push(path); result.push("\""); diff --git a/lektor_utils/src/pathdiff.rs b/lektor_utils/src/pathdiff.rs new file mode 100644 index 0000000000000000000000000000000000000000..b9a72acb3bafc171b77cf0584b32e5a889662003 --- /dev/null +++ b/lektor_utils/src/pathdiff.rs @@ -0,0 +1,144 @@ +use std::path::*; + +/// Construct a relative path from a provided base directory path to the provided path. +/// +/// ```rust +/// use pathdiff::diff_paths; +/// use std::path::*; +/// +/// let baz = "/foo/bar/baz"; +/// let bar = "/foo/bar"; +/// let quux = "/foo/bar/quux"; +/// assert_eq!(diff_paths(bar, baz), Some("../".into())); +/// assert_eq!(diff_paths(baz, bar), Some("baz".into())); +/// assert_eq!(diff_paths(quux, baz), Some("../quux".into())); +/// assert_eq!(diff_paths(baz, quux), Some("../baz".into())); +/// assert_eq!(diff_paths(bar, quux), Some("../".into())); +/// +/// assert_eq!(diff_paths(&baz, &bar.to_string()), Some("baz".into())); +/// assert_eq!(diff_paths(Path::new(baz), Path::new(bar).to_path_buf()), Some("baz".into())); +/// ``` +pub fn diff_paths<P, B>(path: P, base: B) -> Option<PathBuf> +where + P: AsRef<Path>, + B: AsRef<Path>, +{ + let path = path.as_ref(); + let base = base.as_ref(); + + if path.is_absolute() != base.is_absolute() { + if path.is_absolute() { + Some(PathBuf::from(path)) + } else { + None + } + } else { + let mut ita = path.components(); + let mut itb = base.components(); + let mut comps: Vec<Component> = vec![]; + loop { + match (ita.next(), itb.next()) { + (None, None) => break, + (Some(a), None) => { + comps.push(a); + comps.extend(ita.by_ref()); + break; + } + (None, _) => comps.push(Component::ParentDir), + (Some(a), Some(b)) if comps.is_empty() && a == b => (), + (Some(a), Some(b)) if b == Component::CurDir => comps.push(a), + (Some(_), Some(b)) if b == Component::ParentDir => return None, + (Some(a), Some(_)) => { + comps.push(Component::ParentDir); + for _ in itb { + comps.push(Component::ParentDir); + } + comps.push(a); + comps.extend(ita.by_ref()); + break; + } + } + } + Some(comps.iter().map(|c| c.as_os_str()).collect()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_absolute() { + #[cfg(windows)] + fn abs(path: &str) -> String { + format!("C:\\{}", path) + } + + #[cfg(not(windows))] + fn abs(path: &str) -> String { + format!("/{}", path) + } + + assert_diff_paths(&abs("foo"), &abs("bar"), Some("../foo")); + assert_diff_paths(&abs("foo"), "bar", Some(&abs("foo"))); + assert_diff_paths("foo", &abs("bar"), None); + assert_diff_paths("foo", "bar", Some("../foo")); + } + + #[test] + fn test_identity() { + assert_diff_paths(".", ".", Some("")); + assert_diff_paths("../foo", "../foo", Some("")); + assert_diff_paths("./foo", "./foo", Some("")); + assert_diff_paths("/foo", "/foo", Some("")); + assert_diff_paths("foo", "foo", Some("")); + + assert_diff_paths("../foo/bar/baz", "../foo/bar/baz", Some("".into())); + assert_diff_paths("foo/bar/baz", "foo/bar/baz", Some("")); + } + + #[test] + fn test_subset() { + assert_diff_paths("foo", "fo", Some("../foo")); + assert_diff_paths("fo", "foo", Some("../fo")); + } + + #[test] + fn test_empty() { + assert_diff_paths("", "", Some("")); + assert_diff_paths("foo", "", Some("foo")); + assert_diff_paths("", "foo", Some("..")); + } + + #[test] + fn test_relative() { + assert_diff_paths("../foo", "../bar", Some("../foo")); + assert_diff_paths("../foo", "../foo/bar/baz", Some("../..")); + assert_diff_paths("../foo/bar/baz", "../foo", Some("bar/baz")); + + assert_diff_paths("foo/bar/baz", "foo", Some("bar/baz")); + assert_diff_paths("foo/bar/baz", "foo/bar", Some("baz")); + assert_diff_paths("foo/bar/baz", "foo/bar/baz", Some("")); + assert_diff_paths("foo/bar/baz", "foo/bar/baz/", Some("")); + + assert_diff_paths("foo/bar/baz/", "foo", Some("bar/baz")); + assert_diff_paths("foo/bar/baz/", "foo/bar", Some("baz")); + assert_diff_paths("foo/bar/baz/", "foo/bar/baz", Some("")); + assert_diff_paths("foo/bar/baz/", "foo/bar/baz/", Some("")); + + assert_diff_paths("foo/bar/baz", "foo/", Some("bar/baz")); + assert_diff_paths("foo/bar/baz", "foo/bar/", Some("baz")); + assert_diff_paths("foo/bar/baz", "foo/bar/baz", Some("")); + } + + #[test] + fn test_current_directory() { + assert_diff_paths(".", "foo", Some("../.")); + assert_diff_paths("foo", ".", Some("foo")); + assert_diff_paths("/foo", "/.", Some("foo")); + } + + fn assert_diff_paths(path: &str, base: &str, expected: Option<&str>) { + assert_eq!(diff_paths(path, base), expected.map(|s| s.into())); + } +} diff --git a/lektord/Cargo.toml b/lektord/Cargo.toml index 45650932cd635bb6f5cf6fc4cb57189c227bd8e6..b22fcff071228ca8474f7092991c16b7c736a4b6 100644 --- a/lektord/Cargo.toml +++ b/lektord/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true description = "The lektord daemon" [dependencies] diff --git a/lkt/Cargo.toml b/lkt/Cargo.toml index e6caa3cfc02b8516a49d8add94dda50ca9a306d7..88681dfe93c97b66e6f91189a14c53db59b0eeba 100644 --- a/lkt/Cargo.toml +++ b/lkt/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +rust-version.workspace = true description = "Simple command line utility to interact with the lektord daemon" [dependencies]