use std::kinds::marker;
use std::str;
use {raw, Error, Oid, Object, Signature, ObjectType};
pub struct Tag<'repo> {
raw: *mut raw::git_tag,
marker: marker::ContravariantLifetime<'repo>,
}
impl<'repo> Tag<'repo> {
pub unsafe fn from_raw(raw: *mut raw::git_tag) -> Tag<'repo> {
Tag {
raw: raw,
marker: marker::ContravariantLifetime,
}
}
pub fn id(&self) -> Oid {
unsafe { Oid::from_raw(raw::git_tag_id(&*self.raw)) }
}
pub fn message(&self) -> Option<&str> {
self.message_bytes().and_then(|s| str::from_utf8(s).ok())
}
pub fn message_bytes(&self) -> Option<&[u8]> {
unsafe { ::opt_bytes(self, raw::git_tag_message(&*self.raw)) }
}
pub fn name(&self) -> Option<&str> {
str::from_utf8(self.name_bytes()).ok()
}
pub fn name_bytes(&self) -> &[u8] {
unsafe { ::opt_bytes(self, raw::git_tag_name(&*self.raw)).unwrap() }
}
pub fn peel(&self) -> Result<Object<'repo>, Error> {
let mut ret = 0 as *mut raw::git_object;
unsafe {
try_call!(raw::git_tag_peel(&mut ret, &*self.raw));
Ok(Object::from_raw(ret))
}
}
pub fn tagger(&self) -> Option<Signature> {
unsafe {
let ptr = raw::git_tag_tagger(&*self.raw);
if ptr.is_null() {
None
} else {
Some(Signature::from_raw_const(self, ptr))
}
}
}
pub fn target(&self) -> Result<Object<'repo>, Error> {
let mut ret = 0 as *mut raw::git_object;
unsafe {
try_call!(raw::git_tag_target(&mut ret, &*self.raw));
Ok(Object::from_raw(ret))
}
}
pub fn target_id(&self) -> Oid {
unsafe { Oid::from_raw(raw::git_tag_target_id(&*self.raw)) }
}
pub fn target_type(&self) -> Option<ObjectType> {
unsafe { ObjectType::from_raw(raw::git_tag_target_type(&*self.raw)) }
}
pub fn raw(&self) -> *mut raw::git_tag { self.raw }
}
#[unsafe_destructor]
impl<'repo> Drop for Tag<'repo> {
fn drop(&mut self) {
unsafe { raw::git_tag_free(self.raw) }
}
}
#[cfg(test)]
mod tests {
#[test]
fn smoke() {
let (_td, repo) = ::test::repo_init();
let head = repo.head().unwrap();
let id = head.target().unwrap();
assert!(repo.find_tag(id).is_err());
let obj = repo.find_object(id, None).unwrap();
let sig = repo.signature().unwrap();
let tag_id = repo.tag("foo", &obj, &sig, "msg", false).unwrap();
let tag = repo.find_tag(tag_id).unwrap();
assert_eq!(tag.id(), tag_id);
let tags = repo.tag_names(None).unwrap();
assert_eq!(tags.len(), 1);
assert_eq!(tags.get(0), Some("foo"));
assert_eq!(tag.name(), Some("foo"));
assert_eq!(tag.message(), Some("msg"));
assert_eq!(tag.peel().unwrap().id(), obj.id());
assert_eq!(tag.target_id(), obj.id());
assert_eq!(tag.target_type(), Some(::ObjectType::Commit));
assert_eq!(tag.tagger().unwrap().name(), sig.name());
tag.target().unwrap();
repo.tag_delete("foo").unwrap();
}
}