summaryrefslogtreecommitdiffstats
path: root/vendor/gix-object/src/object
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-object/src/object')
-rw-r--r--vendor/gix-object/src/object/convert.rs228
-rw-r--r--vendor/gix-object/src/object/mod.rs296
2 files changed, 524 insertions, 0 deletions
diff --git a/vendor/gix-object/src/object/convert.rs b/vendor/gix-object/src/object/convert.rs
new file mode 100644
index 000000000..5e6e63486
--- /dev/null
+++ b/vendor/gix-object/src/object/convert.rs
@@ -0,0 +1,228 @@
+use std::convert::TryFrom;
+
+use crate::{tree, Blob, BlobRef, Commit, CommitRef, Object, ObjectRef, Tag, TagRef, Tree, TreeRef};
+
+impl From<TagRef<'_>> for Tag {
+ fn from(other: TagRef<'_>) -> Tag {
+ let TagRef {
+ target,
+ name,
+ target_kind,
+ message,
+ tagger: signature,
+ pgp_signature,
+ } = other;
+ Tag {
+ target: gix_hash::ObjectId::from_hex(target).expect("prior parser validation"),
+ name: name.to_owned(),
+ target_kind,
+ message: message.to_owned(),
+ tagger: signature.map(Into::into),
+ pgp_signature: pgp_signature.map(ToOwned::to_owned),
+ }
+ }
+}
+
+impl From<CommitRef<'_>> for Commit {
+ fn from(other: CommitRef<'_>) -> Commit {
+ let CommitRef {
+ tree,
+ parents,
+ author,
+ committer,
+ encoding,
+ message,
+ extra_headers,
+ } = other;
+ Commit {
+ tree: gix_hash::ObjectId::from_hex(tree).expect("prior parser validation"),
+ parents: parents
+ .iter()
+ .map(|parent| gix_hash::ObjectId::from_hex(parent).expect("prior parser validation"))
+ .collect(),
+ author: author.into(),
+ committer: committer.into(),
+ encoding: encoding.map(ToOwned::to_owned),
+ message: message.to_owned(),
+ extra_headers: extra_headers
+ .into_iter()
+ .map(|(k, v)| (k.into(), v.into_owned()))
+ .collect(),
+ }
+ }
+}
+
+impl<'a> From<BlobRef<'a>> for Blob {
+ fn from(v: BlobRef<'a>) -> Self {
+ Blob {
+ data: v.data.to_owned(),
+ }
+ }
+}
+
+impl From<TreeRef<'_>> for Tree {
+ fn from(other: TreeRef<'_>) -> Tree {
+ let TreeRef { entries } = other;
+ Tree {
+ entries: entries.into_iter().map(Into::into).collect(),
+ }
+ }
+}
+
+impl From<tree::EntryRef<'_>> for tree::Entry {
+ fn from(other: tree::EntryRef<'_>) -> tree::Entry {
+ let tree::EntryRef { mode, filename, oid } = other;
+ tree::Entry {
+ mode,
+ filename: filename.to_owned(),
+ oid: oid.into(),
+ }
+ }
+}
+
+impl<'a> From<ObjectRef<'a>> for Object {
+ fn from(v: ObjectRef<'_>) -> Self {
+ match v {
+ ObjectRef::Tree(v) => Object::Tree(v.into()),
+ ObjectRef::Blob(v) => Object::Blob(v.into()),
+ ObjectRef::Commit(v) => Object::Commit(v.into()),
+ ObjectRef::Tag(v) => Object::Tag(v.into()),
+ }
+ }
+}
+
+impl From<Tag> for Object {
+ fn from(v: Tag) -> Self {
+ Object::Tag(v)
+ }
+}
+
+impl From<Commit> for Object {
+ fn from(v: Commit) -> Self {
+ Object::Commit(v)
+ }
+}
+
+impl From<Tree> for Object {
+ fn from(v: Tree) -> Self {
+ Object::Tree(v)
+ }
+}
+
+impl From<Blob> for Object {
+ fn from(v: Blob) -> Self {
+ Object::Blob(v)
+ }
+}
+
+impl TryFrom<Object> for Tag {
+ type Error = Object;
+
+ fn try_from(value: Object) -> Result<Self, Self::Error> {
+ Ok(match value {
+ Object::Tag(v) => v,
+ _ => return Err(value),
+ })
+ }
+}
+
+impl TryFrom<Object> for Commit {
+ type Error = Object;
+
+ fn try_from(value: Object) -> Result<Self, Self::Error> {
+ Ok(match value {
+ Object::Commit(v) => v,
+ _ => return Err(value),
+ })
+ }
+}
+
+impl TryFrom<Object> for Tree {
+ type Error = Object;
+
+ fn try_from(value: Object) -> Result<Self, Self::Error> {
+ Ok(match value {
+ Object::Tree(v) => v,
+ _ => return Err(value),
+ })
+ }
+}
+
+impl TryFrom<Object> for Blob {
+ type Error = Object;
+
+ fn try_from(value: Object) -> Result<Self, Self::Error> {
+ Ok(match value {
+ Object::Blob(v) => v,
+ _ => return Err(value),
+ })
+ }
+}
+
+impl<'a> From<TagRef<'a>> for ObjectRef<'a> {
+ fn from(v: TagRef<'a>) -> Self {
+ ObjectRef::Tag(v)
+ }
+}
+
+impl<'a> From<CommitRef<'a>> for ObjectRef<'a> {
+ fn from(v: CommitRef<'a>) -> Self {
+ ObjectRef::Commit(v)
+ }
+}
+
+impl<'a> From<TreeRef<'a>> for ObjectRef<'a> {
+ fn from(v: TreeRef<'a>) -> Self {
+ ObjectRef::Tree(v)
+ }
+}
+
+impl<'a> From<BlobRef<'a>> for ObjectRef<'a> {
+ fn from(v: BlobRef<'a>) -> Self {
+ ObjectRef::Blob(v)
+ }
+}
+
+impl<'a> TryFrom<ObjectRef<'a>> for TagRef<'a> {
+ type Error = ObjectRef<'a>;
+
+ fn try_from(value: ObjectRef<'a>) -> Result<Self, Self::Error> {
+ Ok(match value {
+ ObjectRef::Tag(v) => v,
+ _ => return Err(value),
+ })
+ }
+}
+
+impl<'a> TryFrom<ObjectRef<'a>> for CommitRef<'a> {
+ type Error = ObjectRef<'a>;
+
+ fn try_from(value: ObjectRef<'a>) -> Result<Self, Self::Error> {
+ Ok(match value {
+ ObjectRef::Commit(v) => v,
+ _ => return Err(value),
+ })
+ }
+}
+
+impl<'a> TryFrom<ObjectRef<'a>> for TreeRef<'a> {
+ type Error = ObjectRef<'a>;
+
+ fn try_from(value: ObjectRef<'a>) -> Result<Self, Self::Error> {
+ Ok(match value {
+ ObjectRef::Tree(v) => v,
+ _ => return Err(value),
+ })
+ }
+}
+
+impl<'a> TryFrom<ObjectRef<'a>> for BlobRef<'a> {
+ type Error = ObjectRef<'a>;
+
+ fn try_from(value: ObjectRef<'a>) -> Result<Self, Self::Error> {
+ Ok(match value {
+ ObjectRef::Blob(v) => v,
+ _ => return Err(value),
+ })
+ }
+}
diff --git a/vendor/gix-object/src/object/mod.rs b/vendor/gix-object/src/object/mod.rs
new file mode 100644
index 000000000..c0f9dcd52
--- /dev/null
+++ b/vendor/gix-object/src/object/mod.rs
@@ -0,0 +1,296 @@
+use crate::{Blob, Commit, Object, Tag, Tree};
+
+mod convert;
+
+mod write {
+ use std::io;
+
+ use crate::{Kind, Object, ObjectRef, WriteTo};
+
+ /// Serialization
+ impl<'a> WriteTo for ObjectRef<'a> {
+ /// Write the contained object to `out` in the git serialization format.
+ fn write_to(&self, out: impl io::Write) -> io::Result<()> {
+ use crate::ObjectRef::*;
+ match self {
+ Tree(v) => v.write_to(out),
+ Blob(v) => v.write_to(out),
+ Commit(v) => v.write_to(out),
+ Tag(v) => v.write_to(out),
+ }
+ }
+
+ fn size(&self) -> usize {
+ use crate::ObjectRef::*;
+ match self {
+ Tree(v) => v.size(),
+ Blob(v) => v.size(),
+ Commit(v) => v.size(),
+ Tag(v) => v.size(),
+ }
+ }
+
+ fn kind(&self) -> Kind {
+ self.kind()
+ }
+ }
+
+ /// Serialization
+ impl WriteTo for Object {
+ /// Write the contained object to `out` in the git serialization format.
+ fn write_to(&self, out: impl io::Write) -> io::Result<()> {
+ use crate::Object::*;
+ match self {
+ Tree(v) => v.write_to(out),
+ Blob(v) => v.write_to(out),
+ Commit(v) => v.write_to(out),
+ Tag(v) => v.write_to(out),
+ }
+ }
+
+ fn size(&self) -> usize {
+ use crate::Object::*;
+ match self {
+ Tree(v) => v.size(),
+ Blob(v) => v.size(),
+ Commit(v) => v.size(),
+ Tag(v) => v.size(),
+ }
+ }
+
+ fn kind(&self) -> Kind {
+ self.kind()
+ }
+ }
+}
+
+/// Convenient extraction of typed object.
+impl Object {
+ /// Turns this instance into a [`Blob`][Blob], panic otherwise.
+ pub fn into_blob(self) -> Blob {
+ match self {
+ Object::Blob(v) => v,
+ _ => panic!("BUG: not a blob"),
+ }
+ }
+ /// Turns this instance into a [`Commit`][Commit] panic otherwise.
+ pub fn into_commit(self) -> Commit {
+ match self {
+ Object::Commit(v) => v,
+ _ => panic!("BUG: not a commit"),
+ }
+ }
+ /// Turns this instance into a [`Tree`][Tree] panic otherwise.
+ pub fn into_tree(self) -> Tree {
+ match self {
+ Object::Tree(v) => v,
+ _ => panic!("BUG: not a tree"),
+ }
+ }
+ /// Turns this instance into a [`Tag`][Tag] panic otherwise.
+ pub fn into_tag(self) -> Tag {
+ match self {
+ Object::Tag(v) => v,
+ _ => panic!("BUG: not a tag"),
+ }
+ }
+ /// Turns this instance into a [`Blob`][Blob] if it is one.
+ #[allow(clippy::result_large_err)]
+ pub fn try_into_blob(self) -> Result<Blob, Self> {
+ match self {
+ Object::Blob(v) => Ok(v),
+ _ => Err(self),
+ }
+ }
+ /// Turns this instance into a [`BlobRef`][BlobRef] if it is a blob.
+ pub fn try_into_blob_ref(&self) -> Option<BlobRef<'_>> {
+ match self {
+ Object::Blob(v) => Some(v.to_ref()),
+ _ => None,
+ }
+ }
+ /// Turns this instance into a [`Commit`][Commit] if it is one.
+ #[allow(clippy::result_large_err)]
+ pub fn try_into_commit(self) -> Result<Commit, Self> {
+ match self {
+ Object::Commit(v) => Ok(v),
+ _ => Err(self),
+ }
+ }
+ /// Turns this instance into a [`Tree`][Tree] if it is one.
+ #[allow(clippy::result_large_err)]
+ pub fn try_into_tree(self) -> Result<Tree, Self> {
+ match self {
+ Object::Tree(v) => Ok(v),
+ _ => Err(self),
+ }
+ }
+ /// Turns this instance into a [`Tag`][Tag] if it is one.
+ #[allow(clippy::result_large_err)]
+ pub fn try_into_tag(self) -> Result<Tag, Self> {
+ match self {
+ Object::Tag(v) => Ok(v),
+ _ => Err(self),
+ }
+ }
+
+ /// Returns a [`Blob`][Blob] if it is one.
+ pub fn as_blob(&self) -> Option<&Blob> {
+ match self {
+ Object::Blob(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Returns a [`Commit`][Commit] if it is one.
+ pub fn as_commit(&self) -> Option<&Commit> {
+ match self {
+ Object::Commit(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Returns a [`Tree`][Tree] if it is one.
+ pub fn as_tree(&self) -> Option<&Tree> {
+ match self {
+ Object::Tree(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Returns a [`Tag`][Tag] if it is one.
+ pub fn as_tag(&self) -> Option<&Tag> {
+ match self {
+ Object::Tag(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Returns the kind of object stored in this instance.
+ pub fn kind(&self) -> crate::Kind {
+ match self {
+ Object::Tree(_) => crate::Kind::Tree,
+ Object::Blob(_) => crate::Kind::Blob,
+ Object::Commit(_) => crate::Kind::Commit,
+ Object::Tag(_) => crate::Kind::Tag,
+ }
+ }
+}
+
+use crate::{
+ decode::{loose_header, Error as DecodeError, LooseHeaderDecodeError},
+ BlobRef, CommitRef, Kind, ObjectRef, TagRef, TreeRef,
+};
+
+#[derive(Debug, thiserror::Error)]
+#[allow(missing_docs)]
+pub enum LooseDecodeError {
+ #[error(transparent)]
+ InvalidHeader(#[from] LooseHeaderDecodeError),
+ #[error(transparent)]
+ InvalidContent(#[from] DecodeError),
+}
+
+impl<'a> ObjectRef<'a> {
+ /// Deserialize an object from a loose serialisation
+ pub fn from_loose(data: &'a [u8]) -> Result<ObjectRef<'a>, LooseDecodeError> {
+ let (kind, size, offset) = loose_header(data)?;
+
+ let body = &data[offset..]
+ .get(..size)
+ .ok_or(LooseHeaderDecodeError::InvalidHeader {
+ message: "object data was shorter than its size declared in the header",
+ })?;
+
+ Ok(Self::from_bytes(kind, body)?)
+ }
+
+ /// Deserialize an object of `kind` from the given `data`.
+ pub fn from_bytes(kind: Kind, data: &'a [u8]) -> Result<ObjectRef<'a>, crate::decode::Error> {
+ Ok(match kind {
+ Kind::Tree => ObjectRef::Tree(TreeRef::from_bytes(data)?),
+ Kind::Blob => ObjectRef::Blob(BlobRef { data }),
+ Kind::Commit => ObjectRef::Commit(CommitRef::from_bytes(data)?),
+ Kind::Tag => ObjectRef::Tag(TagRef::from_bytes(data)?),
+ })
+ }
+
+ /// Convert the immutable object into a mutable version, consuming the source in the process.
+ ///
+ /// Note that this is an expensive operation.
+ pub fn into_owned(self) -> Object {
+ self.into()
+ }
+
+ /// Convert this immutable object into its mutable counterpart.
+ ///
+ /// Note that this is an expensive operation.
+ pub fn to_owned(&self) -> Object {
+ self.clone().into()
+ }
+}
+
+/// Convenient access to contained objects.
+impl<'a> ObjectRef<'a> {
+ /// Interpret this object as blob.
+ pub fn as_blob(&self) -> Option<&BlobRef<'a>> {
+ match self {
+ ObjectRef::Blob(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Interpret this object as blob, chainable.
+ pub fn into_blob(self) -> Option<BlobRef<'a>> {
+ match self {
+ ObjectRef::Blob(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Interpret this object as commit.
+ pub fn as_commit(&self) -> Option<&CommitRef<'a>> {
+ match self {
+ ObjectRef::Commit(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Interpret this object as commit, chainable.
+ pub fn into_commit(self) -> Option<CommitRef<'a>> {
+ match self {
+ ObjectRef::Commit(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Interpret this object as tree.
+ pub fn as_tree(&self) -> Option<&TreeRef<'a>> {
+ match self {
+ ObjectRef::Tree(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Interpret this object as tree, chainable
+ pub fn into_tree(self) -> Option<TreeRef<'a>> {
+ match self {
+ ObjectRef::Tree(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Interpret this object as tag.
+ pub fn as_tag(&self) -> Option<&TagRef<'a>> {
+ match self {
+ ObjectRef::Tag(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Interpret this object as tag, chainable.
+ pub fn into_tag(self) -> Option<TagRef<'a>> {
+ match self {
+ ObjectRef::Tag(v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Return the kind of object.
+ pub fn kind(&self) -> Kind {
+ match self {
+ ObjectRef::Tree(_) => Kind::Tree,
+ ObjectRef::Blob(_) => Kind::Blob,
+ ObjectRef::Commit(_) => Kind::Commit,
+ ObjectRef::Tag(_) => Kind::Tag,
+ }
+ }
+}