radicle_git_ext/
oid.rs

1use std::{
2    convert::TryFrom,
3    fmt::{self, Display},
4    ops::Deref,
5    str::FromStr,
6};
7
8/// Serializable [`git2::Oid`]
9#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
10pub struct Oid(git2::Oid);
11
12#[cfg(feature = "serde")]
13mod serde_impls {
14    use super::*;
15    use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
16
17    impl Serialize for Oid {
18        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
19        where
20            S: Serializer,
21        {
22            self.0.to_string().serialize(serializer)
23        }
24    }
25
26    impl<'de> Deserialize<'de> for Oid {
27        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
28        where
29            D: Deserializer<'de>,
30        {
31            struct OidVisitor;
32
33            impl Visitor<'_> for OidVisitor {
34                type Value = Oid;
35
36                fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
37                    write!(f, "a hexidecimal git2::Oid")
38                }
39
40                fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
41                where
42                    E: serde::de::Error,
43                {
44                    s.parse().map_err(serde::de::Error::custom)
45                }
46            }
47
48            deserializer.deserialize_str(OidVisitor)
49        }
50    }
51}
52
53impl Deref for Oid {
54    type Target = git2::Oid;
55
56    fn deref(&self) -> &Self::Target {
57        &self.0
58    }
59}
60
61impl AsRef<git2::Oid> for Oid {
62    fn as_ref(&self) -> &git2::Oid {
63        self
64    }
65}
66
67impl AsRef<[u8]> for Oid {
68    fn as_ref(&self) -> &[u8] {
69        self.as_bytes()
70    }
71}
72
73impl From<git2::Oid> for Oid {
74    fn from(oid: git2::Oid) -> Self {
75        Self(oid)
76    }
77}
78
79impl From<Oid> for git2::Oid {
80    fn from(oid: Oid) -> Self {
81        oid.0
82    }
83}
84
85impl Display for Oid {
86    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87        self.0.fmt(f)
88    }
89}
90
91impl TryFrom<&str> for Oid {
92    type Error = git2::Error;
93
94    fn try_from(s: &str) -> Result<Self, Self::Error> {
95        s.parse().map(Self)
96    }
97}
98
99impl FromStr for Oid {
100    type Err = git2::Error;
101
102    fn from_str(s: &str) -> Result<Self, Self::Err> {
103        Self::try_from(s)
104    }
105}
106
107impl TryFrom<&[u8]> for Oid {
108    type Error = git2::Error;
109
110    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
111        git2::Oid::from_bytes(bytes).map(Self)
112    }
113}