Skip to content

Commit

Permalink
Add into_{objtype} methods on Object
Browse files Browse the repository at this point in the history
Similar to the into_object methods elsewhere
  • Loading branch information
alexcrichton committed Feb 26, 2016
1 parent 6573ca4 commit e286949
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/blob.rs
Expand Up @@ -87,6 +87,7 @@ mod tests {
assert!(blob.is_binary());

repo.find_object(id, None).unwrap().as_blob().unwrap();
repo.find_object(id, None).unwrap().into_blob().ok().unwrap();
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions src/commit.rs
Expand Up @@ -334,6 +334,7 @@ mod tests {
new_head.into_object();

repo.find_object(target, None).unwrap().as_commit().unwrap();
repo.find_object(target, None).unwrap().into_commit().ok().unwrap();
}
}

42 changes: 42 additions & 0 deletions src/object.rs
@@ -1,5 +1,6 @@
use std::marker;
use std::mem;
use std::ptr;

use {raw, Oid, ObjectType, Error, Buf, Commit, Tag, Blob, Tree, Repository};
use {Describe, DescribeOptions};
Expand Down Expand Up @@ -62,27 +63,55 @@ impl<'repo> Object<'repo> {
self.cast(ObjectType::Commit)
}

/// Attempt to consume this object and return a commit.
///
/// Returns `Err(self)` if this object is not actually a commit.
pub fn into_commit(self) -> Result<Commit<'repo>, Object<'repo>> {
self.cast_into(ObjectType::Commit)
}

/// Attempt to view this object as a tag.
///
/// Returns `None` if the object is not actually a tag.
pub fn as_tag(&self) -> Option<&Tag<'repo>> {
self.cast(ObjectType::Tag)
}

/// Attempt to consume this object and return a tag.
///
/// Returns `Err(self)` if this object is not actually a tag.
pub fn into_tag(self) -> Result<Tag<'repo>, Object<'repo>> {
self.cast_into(ObjectType::Tag)
}

/// Attempt to view this object as a tree.
///
/// Returns `None` if the object is not actually a tree.
pub fn as_tree(&self) -> Option<&Tree<'repo>> {
self.cast(ObjectType::Tree)
}

/// Attempt to consume this object and return a tree.
///
/// Returns `Err(self)` if this object is not actually a tree.
pub fn into_tree(self) -> Result<Tree<'repo>, Object<'repo>> {
self.cast_into(ObjectType::Tree)
}

/// Attempt to view this object as a blob.
///
/// Returns `None` if the object is not actually a blob.
pub fn as_blob(&self) -> Option<&Blob<'repo>> {
self.cast(ObjectType::Blob)
}

/// Attempt to consume this object and return a blob.
///
/// Returns `Err(self)` if this object is not actually a blob.
pub fn into_blob(self) -> Result<Blob<'repo>, Object<'repo>> {
self.cast_into(ObjectType::Blob)
}

/// Describes a commit
///
/// Performs a describe operation on this commitish object.
Expand All @@ -103,6 +132,19 @@ impl<'repo> Object<'repo> {
None
}
}

fn cast_into<T>(self, kind: ObjectType) -> Result<T, Object<'repo>> {
assert_eq!(mem::size_of_val(&self), mem::size_of::<T>());
if self.kind() == Some(kind) {
Ok(unsafe {
let other = ptr::read(&self as *const _ as *const T);
mem::forget(self);
other
})
} else {
Err(self)
}
}
}

impl<'repo> Clone for Object<'repo> {
Expand Down
1 change: 1 addition & 0 deletions src/tag.rs
Expand Up @@ -150,6 +150,7 @@ mod tests {
tag.into_object();

repo.find_object(tag_id, None).unwrap().as_tag().unwrap();
repo.find_object(tag_id, None).unwrap().into_tag().ok().unwrap();

repo.tag_delete("foo").unwrap();
}
Expand Down
1 change: 1 addition & 0 deletions src/tree.rs
Expand Up @@ -375,5 +375,6 @@ mod tests {
tree.into_object();

repo.find_object(commit.tree_id(), None).unwrap().as_tree().unwrap();
repo.find_object(commit.tree_id(), None).unwrap().into_tree().ok().unwrap();
}
}

0 comments on commit e286949

Please sign in to comment.