code-moniker-workspace 0.7.1

Workspace model, ports, snapshots, linkage, and change analysis for code-moniker.
Documentation
use std::path::{Component, Path, PathBuf};

pub(crate) fn absolute_path(path: &Path) -> PathBuf {
	let path = if path.is_absolute() {
		path.to_path_buf()
	} else {
		std::env::current_dir()
			.map(|cwd| cwd.join(path))
			.unwrap_or_else(|_| path.to_path_buf())
	};
	path.canonicalize().unwrap_or_else(|_| lexical_path(&path))
}

pub(crate) fn normalize_path(path: &Path) -> PathBuf {
	absolute_path(path)
}

pub(crate) fn portable_path(path: &Path) -> String {
	path.to_string_lossy()
		.replace(std::path::MAIN_SEPARATOR, "/")
}

pub(crate) fn portable_path_buf(path: &Path) -> PathBuf {
	PathBuf::from(portable_path(path))
}

pub(crate) fn lexical_path(path: &Path) -> PathBuf {
	let mut out = PathBuf::new();
	for component in path.components() {
		match component {
			Component::CurDir => {}
			Component::ParentDir => {
				out.pop();
			}
			_ => out.push(component.as_os_str()),
		}
	}
	out
}

#[cfg(test)]
mod tests {
	use super::*;

	#[test]
	fn portable_paths_use_forward_slashes() {
		let path = Path::new("src").join("engine").join("mod.rs");
		assert_eq!(portable_path(&path), "src/engine/mod.rs");
	}
}