wink 0.3.1

Windows link tools with NTFS junctions support.
Documentation
#![cfg(windows)]

use std::{
	fs,
	io,
	os::windows::fs as winfs,
	path::PathBuf,
	process,
};

use wink::app_ln;

enum LinkType {
	Symbolic,
	Hard,
	Junction,
	Infer,
}

struct Cmd {
	target: PathBuf,
	path: PathBuf,
	link_type: LinkType,
}

impl Cmd {
	fn from_args() -> Self {
		use LinkType::*;
		let m = app_ln().get_matches_from(wild::args());
		let path = m.value_of("path").map(PathBuf::from).unwrap();
		let target = m.value_of("target").map(PathBuf::from).unwrap();

		let link_type = if m.is_present("symbolic") {
			Symbolic
		} else if m.is_present("hard") {
			Hard
		} else if m.is_present("junction") {
			Junction
		} else {
			Infer
		};

		Self {
			path,
			target,
			link_type,
		}
	}

	fn run(mut self) -> io::Result<()> {
		if self.path.is_dir() {
			if let Some(name) = self.target.file_name() {
				self.path.push(name);
			}
		}
		match self.link_type {
			LinkType::Symbolic => {
				let md = fs::symlink_metadata(&self.target)?;
				if md.is_dir() {
					winfs::symlink_dir(&self.target, &self.path)
				} else {
					winfs::symlink_file(&self.target, &self.path)
				}
			}
			LinkType::Hard => fs::hard_link(&self.target, &self.path),
			LinkType::Junction => junction::create(&self.target, &self.path),
			LinkType::Infer => {
				let md = fs::symlink_metadata(&self.target)?;
				if md.is_dir() {
					winfs::symlink_dir(&self.target, &self.path)
				} else {
					fs::hard_link(&self.target, &self.path)
				}
			}
		}
	}
}

fn main() {
	if let Err(e) = Cmd::from_args().run() {
		eprintln!("error: {}", &e);
		process::exit(2);
	}
}