use std::ffi::CString;
use std::ptr;
use crate::util::Binding;
use crate::{raw, Error, Signature};
pub struct Mailmap {
raw: *mut raw::git_mailmap,
}
impl Binding for Mailmap {
type Raw = *mut raw::git_mailmap;
unsafe fn from_raw(ptr: *mut raw::git_mailmap) -> Mailmap {
Mailmap { raw: ptr }
}
fn raw(&self) -> *mut raw::git_mailmap {
self.raw
}
}
impl Drop for Mailmap {
fn drop(&mut self) {
unsafe {
raw::git_mailmap_free(self.raw);
}
}
}
impl Mailmap {
pub fn new() -> Result<Mailmap, Error> {
crate::init();
let mut ret = ptr::null_mut();
unsafe {
try_call!(raw::git_mailmap_new(&mut ret));
Ok(Binding::from_raw(ret))
}
}
pub fn from_buffer(buf: &str) -> Result<Mailmap, Error> {
crate::init();
let mut ret = ptr::null_mut();
let len = buf.len();
let buf = CString::new(buf)?;
unsafe {
try_call!(raw::git_mailmap_from_buffer(&mut ret, buf, len));
Ok(Binding::from_raw(ret))
}
}
pub fn add_entry(
&mut self,
real_name: Option<&str>,
real_email: Option<&str>,
replace_name: Option<&str>,
replace_email: &str,
) -> Result<(), Error> {
let real_name = crate::opt_cstr(real_name)?;
let real_email = crate::opt_cstr(real_email)?;
let replace_name = crate::opt_cstr(replace_name)?;
let replace_email = CString::new(replace_email)?;
unsafe {
try_call!(raw::git_mailmap_add_entry(
self.raw,
real_name,
real_email,
replace_name,
replace_email
));
Ok(())
}
}
pub fn resolve_signature(&self, sig: &Signature<'_>) -> Result<Signature<'static>, Error> {
let mut ret = ptr::null_mut();
unsafe {
try_call!(raw::git_mailmap_resolve_signature(
&mut ret,
&*self.raw,
sig.raw()
));
Ok(Binding::from_raw(ret))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn smoke() {
let sig_name = "name";
let sig_email = "email";
let sig = t!(Signature::now(sig_name, sig_email));
let mut mm = t!(Mailmap::new());
let mailmapped_sig = t!(mm.resolve_signature(&sig));
assert_eq!(mailmapped_sig.name(), Some(sig_name));
assert_eq!(mailmapped_sig.email(), Some(sig_email));
t!(mm.add_entry(None, None, None, sig_email));
t!(mm.add_entry(
Some("real name"),
Some("real@email"),
Some(sig_name),
sig_email,
));
let mailmapped_sig = t!(mm.resolve_signature(&sig));
assert_eq!(mailmapped_sig.name(), Some("real name"));
assert_eq!(mailmapped_sig.email(), Some("real@email"));
}
#[test]
fn from_buffer() {
let buf = "<prøper@emæil> <email>";
let mm = t!(Mailmap::from_buffer(&buf));
let sig = t!(Signature::now("name", "email"));
let mailmapped_sig = t!(mm.resolve_signature(&sig));
assert_eq!(mailmapped_sig.name(), Some("name"));
assert_eq!(mailmapped_sig.email(), Some("prøper@emæil"));
}
}