use std::fs::File;
use std::io::{self, Read};
use std::result;
use itertools::join;
use semver_parser::range::{Op, VersionReq};
use semver_parser::version::Version;
pub type Result<T> = result::Result<T, String>;
pub fn read_file(path: &str) -> io::Result<String> {
let mut file = File::open(path)?;
let mut buf = String::new();
file.read_to_string(&mut buf)?;
Ok(buf)
}
pub fn indent(text: &str) -> String {
join(text.lines().map(|line| String::from(" ") + line), "\n")
}
pub fn version_matches_request(version: &Version, request: &VersionReq) -> Result<()> {
if request.predicates.len() != 1 {
return Ok(());
}
let pred = &request.predicates[0];
match pred.op {
Op::Tilde | Op::Compatible => {
if pred.major != version.major {
return Err(format!(
"expected major version {}, found {}",
version.major, pred.major,
));
}
if let Some(minor) = pred.minor {
if minor != version.minor {
return Err(format!(
"expected minor version {}, found {}",
version.minor, minor
));
}
}
if let Some(patch) = pred.patch {
if patch != version.patch {
return Err(format!(
"expected patch version {}, found {}",
version.patch, patch
));
}
}
if pred.pre != version.pre {
return Err(format!(
"expected pre-release {:?}, found {:?}",
join(&version.pre, "."),
join(&pred.pre, ".")
));
}
}
_ => return Ok(()), }
Ok(())
}
#[cfg(test)]
mod tests {
use semver_parser::range::parse as parse_request;
use semver_parser::version::parse as parse_version;
use super::*;
mod test_version_matches_request {
use super::*;
#[test]
fn implicit_compatible() {
let version = parse_version("1.2.3").unwrap();
let request = parse_request("1.2.3").unwrap();
assert_eq!(version_matches_request(&version, &request), Ok(()));
}
#[test]
fn compatible() {
let version = parse_version("1.2.3").unwrap();
let request = parse_request("^1.2.3").unwrap();
assert_eq!(version_matches_request(&version, &request), Ok(()));
}
#[test]
fn tilde() {
let version = parse_version("1.2.3").unwrap();
let request = parse_request("~1.2.3").unwrap();
assert_eq!(version_matches_request(&version, &request), Ok(()));
}
#[test]
fn no_patch() {
let version = parse_version("1.2.3").unwrap();
let request = parse_request("1.2").unwrap();
assert_eq!(version_matches_request(&version, &request), Ok(()));
}
#[test]
fn no_minor() {
let version = parse_version("1.2.3").unwrap();
let request = parse_request("1").unwrap();
assert_eq!(version_matches_request(&version, &request), Ok(()));
}
#[test]
fn multiple_predicates() {
let version = parse_version("1.2.3").unwrap();
let request = parse_request(">= 1.2.3, < 2.0").unwrap();
assert_eq!(version_matches_request(&version, &request), Ok(()));
}
#[test]
fn unhandled_operator() {
let version = parse_version("1.2.3").unwrap();
let request = parse_request("< 2.0").unwrap();
assert_eq!(version_matches_request(&version, &request), Ok(()));
}
#[test]
fn bad_major() {
let version = parse_version("2.0.0").unwrap();
let request = parse_request("1.2.3").unwrap();
assert_eq!(
version_matches_request(&version, &request),
Err(String::from("expected major version 2, found 1"))
);
}
#[test]
fn bad_minor() {
let version = parse_version("1.3.0").unwrap();
let request = parse_request("1.2.3").unwrap();
assert_eq!(
version_matches_request(&version, &request),
Err(String::from("expected minor version 3, found 2"))
);
}
#[test]
fn bad_patch() {
let version = parse_version("1.2.4").unwrap();
let request = parse_request("1.2.3").unwrap();
assert_eq!(
version_matches_request(&version, &request),
Err(String::from("expected patch version 4, found 3"))
);
}
#[test]
fn bad_pre_release() {
let version = parse_version("1.2.3-rc2").unwrap();
let request = parse_request("1.2.3-rc1").unwrap();
assert_eq!(
version_matches_request(&version, &request),
Err(String::from("expected pre-release \"rc2\", found \"rc1\""))
);
}
}
}