casper_types/global_state/
pointer.rs1use core::fmt::Debug;
2
3use alloc::vec::Vec;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH},
8 Digest,
9};
10
11#[cfg(any(feature = "testing", test))]
12use crate::testing::TestRng;
13
14#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
16pub enum Pointer {
17 LeafPointer(Digest),
19 NodePointer(Digest),
21}
22
23impl Pointer {
24 pub fn hash(&self) -> &Digest {
26 match self {
27 Pointer::LeafPointer(hash) => hash,
28 Pointer::NodePointer(hash) => hash,
29 }
30 }
31
32 pub fn into_hash(self) -> Digest {
34 match self {
35 Pointer::LeafPointer(hash) => hash,
36 Pointer::NodePointer(hash) => hash,
37 }
38 }
39
40 pub fn update(&self, hash: Digest) -> Self {
42 match self {
43 Pointer::LeafPointer(_) => Pointer::LeafPointer(hash),
44 Pointer::NodePointer(_) => Pointer::NodePointer(hash),
45 }
46 }
47
48 fn tag(&self) -> u8 {
50 match self {
51 Pointer::LeafPointer(_) => 0,
52 Pointer::NodePointer(_) => 1,
53 }
54 }
55
56 #[cfg(any(feature = "testing", test))]
58 pub fn random(rng: &mut TestRng) -> Self {
59 use rand::Rng;
60
61 match rng.gen_range(0..2) {
62 0 => Pointer::LeafPointer(Digest::random(rng)),
63 1 => Pointer::NodePointer(Digest::random(rng)),
64 _ => unreachable!(),
65 }
66 }
67}
68
69impl ToBytes for Pointer {
70 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
71 let mut ret = bytesrepr::unchecked_allocate_buffer(self);
72 self.write_bytes(&mut ret)?;
73 Ok(ret)
74 }
75
76 #[inline(always)]
77 fn serialized_length(&self) -> usize {
78 U8_SERIALIZED_LENGTH + Digest::LENGTH
79 }
80
81 #[inline]
82 fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
83 writer.push(self.tag());
84 writer.extend_from_slice(self.hash().as_ref());
85 Ok(())
86 }
87}
88
89impl FromBytes for Pointer {
90 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
91 let (tag, rem) = u8::from_bytes(bytes)?;
92 match tag {
93 0 => {
94 let (hash, rem) = Digest::from_bytes(rem)?;
95 Ok((Pointer::LeafPointer(hash), rem))
96 }
97 1 => {
98 let (hash, rem) = Digest::from_bytes(rem)?;
99 Ok((Pointer::NodePointer(hash), rem))
100 }
101 _ => Err(bytesrepr::Error::Formatting),
102 }
103 }
104}