risc0_zkvm/claim/
maybe_pruned.rs1use core::fmt;
18
19use borsh::{BorshDeserialize, BorshSerialize};
20use derive_more::Debug;
21use risc0_binfmt::Digestible;
22use risc0_zkp::core::digest::Digest;
23use serde::{Deserialize, Serialize};
24
25use crate::sha::{self, Sha256};
26
27#[derive(Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize)]
36pub enum MaybePruned<T> {
37 Value(T),
39
40 Pruned(Digest),
42}
43
44impl<T> MaybePruned<T> {
45 pub fn value(self) -> Result<T, PrunedValueError> {
47 match self {
48 MaybePruned::Value(value) => Ok(value),
49 MaybePruned::Pruned(digest) => Err(PrunedValueError(digest)),
50 }
51 }
52
53 pub fn as_value(&self) -> Result<&T, PrunedValueError> {
55 match self {
56 MaybePruned::Value(ref value) => Ok(value),
57 MaybePruned::Pruned(ref digest) => Err(PrunedValueError(*digest)),
58 }
59 }
60
61 pub fn as_value_mut(&mut self) -> Result<&mut T, PrunedValueError> {
63 match self {
64 MaybePruned::Value(ref mut value) => Ok(value),
65 MaybePruned::Pruned(ref digest) => Err(PrunedValueError(*digest)),
66 }
67 }
68}
69
70impl<T> From<T> for MaybePruned<T> {
71 fn from(value: T) -> Self {
72 Self::Value(value)
73 }
74}
75
76impl<T> Digestible for MaybePruned<T>
77where
78 T: Digestible,
79{
80 fn digest<S: Sha256>(&self) -> Digest {
81 match self {
82 MaybePruned::Value(ref val) => val.digest::<S>(),
83 MaybePruned::Pruned(digest) => *digest,
84 }
85 }
86}
87
88impl<T> Default for MaybePruned<T>
89where
90 T: Digestible + Default,
91{
92 fn default() -> Self {
93 MaybePruned::Value(Default::default())
94 }
95}
96
97impl<T> MaybePruned<Option<T>> {
98 pub fn is_none(&self) -> bool {
101 match self {
102 MaybePruned::Value(Some(_)) => false,
103 MaybePruned::Value(None) => true,
104 MaybePruned::Pruned(digest) => digest == &Digest::ZERO,
105 }
106 }
107
108 pub fn is_some(&self) -> bool {
111 !self.is_none()
112 }
113}
114
115#[cfg(test)]
116impl<T> PartialEq for MaybePruned<T>
117where
118 T: PartialEq,
119{
120 fn eq(&self, other: &Self) -> bool {
121 match (self, other) {
122 (Self::Value(a), Self::Value(b)) => a == b,
123 (Self::Pruned(a), Self::Pruned(b)) => a == b,
124 _ => false,
125 }
126 }
127}
128
129impl<T> fmt::Debug for MaybePruned<T>
130where
131 T: Digestible + fmt::Debug,
132{
133 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
137 let mut builder = fmt.debug_struct("MaybePruned");
138 if let MaybePruned::Value(value) = self {
139 builder.field("value", value);
140 }
141 builder
142 .field("digest", &self.digest::<sha::Impl>())
143 .finish()
144 }
145}
146
147#[derive(Debug, Clone)]
149pub struct PrunedValueError(pub Digest);
150
151impl fmt::Display for PrunedValueError {
152 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153 write!(f, "value is pruned: {}", &self.0)
154 }
155}
156
157#[cfg(feature = "std")]
158impl std::error::Error for PrunedValueError {}