1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use crate::mutable;
use std::io;

/// A mutable object representing [`Trees`][mutable::Tree], [`Blobs`][mutable::Blob], [`Commits`][mutable::Commit] or [`Tags`][mutable::Tag].
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
#[allow(clippy::large_enum_variant, missing_docs)]
pub enum Object {
    Tree(mutable::Tree),
    Blob(mutable::Blob),
    Commit(mutable::Commit),
    Tag(mutable::Tag),
}

/// Convenient extraction of typed object.
impl Object {
    /// Returns a [`Blob`][mutable::Blob] if it is one.
    pub fn as_blob(&self) -> Option<&mutable::Blob> {
        match self {
            Object::Blob(v) => Some(v),
            _ => None,
        }
    }
    /// Returns a [`Commit`][mutable::Commit] if it is one.
    pub fn as_commit(&self) -> Option<&mutable::Commit> {
        match self {
            Object::Commit(v) => Some(v),
            _ => None,
        }
    }
    /// Returns a [`Tree`][mutable::Tree] if it is one.
    pub fn as_tree(&self) -> Option<&mutable::Tree> {
        match self {
            Object::Tree(v) => Some(v),
            _ => None,
        }
    }
    /// Returns a [`Tag`][mutable::Tag] if it is one.
    pub fn as_tag(&self) -> Option<&mutable::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,
        }
    }
}

/// Serialization
impl Object {
    /// Write the contained object to `out` in the git serialization format.
    pub fn write_to(&self, out: impl io::Write) -> io::Result<()> {
        use 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),
        }
    }
}

mod convert {
    use crate::mutable::{Blob, Commit, Object, Tag, Tree};
    use std::convert::TryFrom;

    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),
            })
        }
    }
}