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
use super::parts;
use crate::{
error::Error,
hash::{Algorithm, Hash},
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::{
fmt::{self, Display},
str::{self, FromStr},
};
pub const PREFIX_LENGTH: usize = 10;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
pub struct Id {
pub hash: Hash,
pub parts: Option<parts::Header>,
}
impl Id {
pub fn new(hash: Hash, parts: Option<parts::Header>) -> Self {
Self { hash, parts }
}
pub fn prefix(&self) -> String {
let mut result = self.to_string();
result.truncate(PREFIX_LENGTH);
result
}
}
impl Display for Id {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", &self.hash)
}
}
impl FromStr for Id {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
Ok(Self::new(Hash::from_hex_upper(Algorithm::Sha256, s)?, None))
}
}
pub trait ParseId {
fn parse_block_id(&self) -> Result<Id, Error>;
}
#[cfg(test)]
mod tests {
use super::*;
const EXAMPLE_SHA256_ID: &str =
"26C0A41F3243C6BCD7AD2DFF8A8D83A71D29D307B5326C227F734A1A512FE47D";
#[test]
fn parses_hex_strings() {
let id = Id::from_str(EXAMPLE_SHA256_ID).unwrap();
assert_eq!(
id.hash.as_bytes().unwrap(),
b"\x26\xC0\xA4\x1F\x32\x43\xC6\xBC\xD7\xAD\x2D\xFF\x8A\x8D\x83\xA7\
\x1D\x29\xD3\x07\xB5\x32\x6C\x22\x7F\x73\x4A\x1A\x51\x2F\xE4\x7D"
.as_ref()
);
}
#[test]
fn serializes_hex_strings() {
let id = Id::from_str(EXAMPLE_SHA256_ID).unwrap();
assert_eq!(&id.to_string(), EXAMPLE_SHA256_ID)
}
}