use crate::{error::Error, Revision};
pub fn parse_revision(arg: &str) -> Result<(Revision, Revision), Error<'static>> {
let pool = apr::Pool::new();
let arg_cstr = std::ffi::CString::new(arg)?;
let mut start_rev = subversion_sys::svn_opt_revision_t::default();
let mut end_rev = subversion_sys::svn_opt_revision_t::default();
unsafe {
let result = subversion_sys::svn_opt_parse_revision(
&mut start_rev,
&mut end_rev,
arg_cstr.as_ptr(),
pool.as_mut_ptr(),
);
if result != 0 {
return Err(Error::from_message("Failed to parse revision"));
}
Ok((Revision::from(start_rev), Revision::from(end_rev)))
}
}
pub fn parse_path(path: &str) -> Result<(String, Revision), Error<'static>> {
let pool = apr::Pool::new();
let path_cstr = std::ffi::CString::new(path)?;
let mut revision = subversion_sys::svn_opt_revision_t::default();
let mut true_path = std::ptr::null();
unsafe {
let err = subversion_sys::svn_opt_parse_path(
&mut revision,
&mut true_path,
path_cstr.as_ptr(),
pool.as_mut_ptr(),
);
Error::from_raw(err)?;
let path_str = if true_path.is_null() {
path.to_string()
} else {
let true_path_str = std::ffi::CStr::from_ptr(true_path);
true_path_str.to_string_lossy().into_owned()
};
Ok((path_str, Revision::from(revision)))
}
}
pub fn resolve_revisions(
peg_revision: &Revision,
op_revision: &Revision,
is_url: bool,
notice_local_mods: bool,
) -> Result<(Revision, Revision), Error<'static>> {
let pool = apr::Pool::new();
let mut peg_rev = (*peg_revision).into();
let mut op_rev = (*op_revision).into();
unsafe {
let err = subversion_sys::svn_opt_resolve_revisions(
&mut peg_rev,
&mut op_rev,
is_url as i32,
notice_local_mods as i32,
pool.as_mut_ptr(),
);
Error::from_raw(err)?;
Ok((Revision::from(peg_rev), Revision::from(op_rev)))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Revision;
#[test]
fn test_parse_revision_number() {
let (start, end) = parse_revision("123").unwrap();
assert!(matches!(start, Revision::Number(_)));
assert!(matches!(end, Revision::Unspecified));
}
#[test]
fn test_parse_revision_keywords() {
let (start, end) = parse_revision("HEAD").unwrap();
assert!(matches!(start, Revision::Head));
assert!(matches!(end, Revision::Unspecified));
let (start2, end2) = parse_revision("BASE").unwrap();
assert!(matches!(start2, Revision::Base));
assert!(matches!(end2, Revision::Unspecified));
}
#[test]
fn test_parse_path_with_revision() {
let (path, revision) = parse_path("src/main.rs@123").unwrap();
assert_eq!(path, "src/main.rs");
assert!(matches!(revision, Revision::Number(_)));
}
#[test]
fn test_parse_path_without_revision() {
let (path, revision) = parse_path("src/main.rs").unwrap();
assert_eq!(path, "src/main.rs");
assert!(matches!(revision, Revision::Unspecified));
}
}