fuse2rs 0.0.3

FUSE2 bindings for Rust (mainly for OpenBSD)
Documentation
use std::{
	fmt::{self, Display, Formatter},
	process::{Child, Command},
	thread::sleep,
	time::{Duration, Instant},
};

use cfg_if::cfg_if;
use tempfile::{tempdir, TempDir};

struct Harness {
	dir:   TempDir,
	child: Child,
}

#[derive(Debug, Clone, Copy)]
struct WaitForError;

impl Display for WaitForError {
	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
		write!(f, "timeout waiting for condition")
	}
}

impl std::error::Error for WaitForError {}

fn waitfor<C>(timeout: Duration, condition: C) -> Result<(), WaitForError>
where
	C: Fn() -> bool,
{
	let start = Instant::now();
	loop {
		if condition() {
			break Ok(());
		}
		if start.elapsed() > timeout {
			break (Err(WaitForError));
		}
		sleep(Duration::from_millis(50));
	}
}
impl Harness {
	fn new() -> Self {
		let dir = tempdir().unwrap();

		let child = Command::new("doas")
			.arg("target/debug/examples/testfs")
			.arg(dir.path())
			.spawn()
			.unwrap();

		waitfor(Duration::from_secs(5), || {
			let s = nix::sys::statfs::statfs(dir.path()).unwrap();

			cfg_if! {
				if #[cfg(target_os = "openbsd")] {
					s.filesystem_type_name() == "fuse"
				} else if #[cfg(target_os = "freebsd")] {
					s.filesystem_type_name() == "fusefs"
				} else if #[cfg(target_os = "linux")] {
										s.filesystem_type() == nix::sys::statfs::FUSE_SUPER_MAGIC
								}
			}
		})
		.unwrap();

		Self { dir, child }
	}
}

#[test]
fn testfs() {
	let h = Harness::new();
	drop(h);
}