penumbra_sdk_tct/internal/
insert.rs1use crate::prelude::*;
2
3#[derive(Clone, Copy, Eq, Derivative, Serialize, Deserialize)]
8#[derivative(Debug)]
9pub enum Insert<T> {
10 Keep(T),
12 #[derivative(Debug = "transparent")]
14 Hash(Hash),
15}
16
17#[derive(Eq, Derivative)]
20#[derivative(Debug)]
21pub enum InsertMut<'a, T> {
22 Keep(&'a mut T),
24 Hash(&'a mut Hash),
26}
27
28impl<T> Insert<T> {
29 pub fn as_ref(&self) -> Insert<&T> {
31 match self {
32 Insert::Keep(item) => Insert::Keep(item),
33 Insert::Hash(hash) => Insert::Hash(*hash),
34 }
35 }
36
37 pub fn as_mut(&mut self) -> InsertMut<'_, T> {
39 match self {
40 Insert::Keep(item) => InsertMut::Keep(item),
41 Insert::Hash(hash) => InsertMut::Hash(hash),
42 }
43 }
44
45 pub fn is_keep(&self) -> bool {
47 matches!(self, Insert::Keep(_))
48 }
49
50 pub fn is_hash(&self) -> bool {
52 matches!(self, Insert::Hash(_))
53 }
54
55 pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Insert<U> {
57 match self {
58 Insert::Keep(item) => Insert::Keep(f(item)),
59 Insert::Hash(hash) => Insert::Hash(hash),
60 }
61 }
62
63 pub fn and_then<U, F: FnOnce(T) -> Insert<U>>(self, f: F) -> Insert<U> {
65 match self {
66 Insert::Keep(item) => f(item),
67 Insert::Hash(hash) => Insert::Hash(hash),
68 }
69 }
70
71 pub fn keep(self) -> Option<T> {
73 match self {
74 Insert::Keep(item) => Some(item),
75 Insert::Hash(_) => None,
76 }
77 }
78}
79
80impl<'a, T> InsertMut<'a, T> {
81 pub fn as_ref(&self) -> Insert<&T> {
83 match self {
84 InsertMut::Keep(item) => Insert::Keep(item),
85 InsertMut::Hash(hash) => Insert::Hash(**hash),
86 }
87 }
88
89 pub fn is_keep(&self) -> bool {
91 matches!(self, InsertMut::Keep(_))
92 }
93
94 pub fn is_hash(&self) -> bool {
96 matches!(self, InsertMut::Hash(_))
97 }
98
99 pub fn map<U, F: FnOnce(&mut T) -> U>(self, f: F) -> Insert<U> {
101 match self {
102 InsertMut::Keep(item) => Insert::Keep(f(item)),
103 InsertMut::Hash(hash) => Insert::Hash(*hash),
104 }
105 }
106
107 pub fn and_then<U, F: FnOnce(&mut T) -> Insert<U>>(self, f: F) -> Insert<U> {
110 match self {
111 InsertMut::Keep(item) => f(item),
112 InsertMut::Hash(hash) => Insert::Hash(*hash),
113 }
114 }
115
116 pub fn keep(self) -> Option<&'a mut T> {
118 match self {
119 InsertMut::Keep(item) => Some(item),
120 InsertMut::Hash(_) => None,
121 }
122 }
123}
124
125impl<T: PartialEq<S>, S> PartialEq<Insert<S>> for Insert<T> {
126 fn eq(&self, other: &Insert<S>) -> bool {
127 match (self, other) {
128 (Insert::Keep(item), Insert::Keep(other)) => item == other,
129 (Insert::Hash(hash), Insert::Hash(other)) => hash == other,
130 _ => false,
131 }
132 }
133}
134
135impl<T: PartialEq<S>, S> PartialEq<InsertMut<'_, S>> for InsertMut<'_, T> {
136 fn eq(&self, other: &InsertMut<S>) -> bool {
137 match (self, other) {
138 (InsertMut::Keep(item), InsertMut::Keep(other)) => item == other,
139 (InsertMut::Hash(hash), InsertMut::Hash(other)) => hash == other,
140 _ => false,
141 }
142 }
143}
144
145impl<T: GetHash> GetHash for Insert<T> {
146 #[inline]
147 fn hash(&self) -> Hash {
148 match self {
149 Insert::Keep(item) => item.hash(),
150 Insert::Hash(hash) => *hash,
151 }
152 }
153
154 #[inline]
155 fn cached_hash(&self) -> Option<Hash> {
156 match self {
157 Insert::Keep(item) => item.cached_hash(),
158 Insert::Hash(hash) => Some(*hash),
159 }
160 }
161}
162
163impl<T: Height> Height for Insert<T> {
164 type Height = T::Height;
165}
166
167impl<T: Height + ForgetOwned> Forget for Insert<T> {
168 fn forget(&mut self, forgotten: Option<Forgotten>, index: impl Into<u64>) -> bool {
169 let this = std::mem::replace(self, Insert::Hash(Hash::zero()));
171
172 let was_forgotten;
174
175 (*self, was_forgotten) = match this {
178 Insert::Keep(item) => item.forget_owned(forgotten, index),
179 Insert::Hash(_) => (this, false),
180 };
181
182 was_forgotten
184 }
185}