radicle_git_ext/
oid.rs

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