1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
use std::env;

#[derive(Debug,PartialEq)]
pub enum Error { Empty, Unknown }

impl std::fmt::Display for Error {
	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
		match self {
			Error::Empty => f.write_str("Cannot parse empty string as a boolean."),
			Error::Unknown => f.write_str("Could not recognize string as a boolean."),
		}
	}
}

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

/** Parse a human config string as a boolean.
	
	```rust
	use humanbool::parse;
	assert!(parse("y") == Ok(true));
	```
	
	Currently the following are supported:
	- 1/0
	- yes/no/y/n
	- true/false/t/f
	- on/off
 */
pub fn parse(s: &str) -> Result<bool, Error> {
	match s {
		"1" | "y" | "yes" | "on" | "t" | "true" => Ok(true),
		"0" | "n" | "no" | "off" | "f" | "false" => Ok(false),
		"" => Err(Error::Empty),
		_ => Err(Error::Unknown),
	}
}

/** Parse a setting from the environment.
	
	```rust
	use humanbool::*;
	assert_eq!(env("ENABLE_KITTENS", "f"), Ok(false));
	std::env::set_var("ENABLE_KITTENS", "1");
	assert!(env("ENABLE_KITTENS", "f") == Ok(true));
	
	assert!(env("ENABLE_TURBO", "") == Err(Error::Empty));
	```
 */
pub fn env(k: &str, default: &str) -> Result<bool, Error> {
	match env::var(k) {
		Ok(s) => parse(&s),
		Err(env::VarError::NotPresent) => parse(default),
		Err(env::VarError::NotUnicode(_)) => {
			panic!("The environemnt variable {:?} isn't valid UTF8", k)
		},
	}
}

#[cfg(test)]
mod tests {
	use super::*;
	
	#[test]
	fn yn() {
		assert!(parse("y") == Ok(true));
		assert!(parse("n") == Ok(false));
	}
	
	#[test]
	fn tf() {
		assert!(parse("t") == Ok(true));
		assert!(parse("f") == Ok(false));
	}
	
	#[test]
	fn _10() {
		assert!(parse("1") == Ok(true));
		assert!(parse("0") == Ok(false));
	}
	
	#[test]
	fn yesno() {
		assert!(parse("yes") == Ok(true));
		assert!(parse("no") == Ok(false));
	}
	
	#[test]
	fn onoff() {
		assert!(parse("on") == Ok(true));
		assert!(parse("off") == Ok(false));
	}
	
	#[test]
	fn unknown() {
		assert!(parse("foo") == Err(Error::Unknown));
		assert!(parse("bar") == Err(Error::Unknown));
		assert!(parse("ye") == Err(Error::Unknown));
		assert!(parse("noway") == Err(Error::Unknown));
	}
	
	#[test]
	fn empty() {
		assert!(parse("") == Err(Error::Empty));
	}
}