1use crate::jet::Jet;
2use crate::node::{
3 CoreConstructible, DisconnectConstructible, JetConstructible, WitnessConstructible,
4};
5use crate::types::{Context, Error};
6use crate::{Cmr, FailEntropy, HasCmr, Word};
7
8#[derive(Clone, Debug, Eq, PartialEq)]
36pub struct Hiding<'brand, N> {
37 result: HidingResult<N>,
38 ctx: Context<'brand>,
46}
47
48type HidingResult<N> = Result<N, Cmr>;
49
50impl<'brand, N> Hiding<'brand, N> {
51 pub const fn hidden(cmr: Cmr, ctx: Context<'brand>) -> Self {
56 Self {
59 result: Err(cmr),
60 ctx,
61 }
62 }
63
64 fn hidden_cloned_ctx(&self, cmr: Cmr) -> Self {
65 Self {
66 result: Err(cmr),
67 ctx: self.ctx.shallow_clone(),
68 }
69 }
70
71 pub fn as_node(&self) -> Option<&N> {
75 self.result.as_ref().ok()
76 }
77
78 pub fn get_node(self) -> Option<N> {
82 self.result.ok()
83 }
84}
85
86impl<N: HasCmr> Hiding<'_, N> {
87 pub fn hide(self) -> Self {
90 match self.result {
102 Ok(node) => Self::hidden(node.cmr(), self.ctx),
103 Err(..) => self,
104 }
105 }
106}
107
108impl<N: HasCmr> HasCmr for Hiding<'_, N> {
109 fn cmr(&self) -> Cmr {
110 match &self.result {
111 Ok(node) => node.cmr(),
112 Err(cmr) => *cmr,
113 }
114 }
115}
116
117impl<'brand, N: CoreConstructible<'brand>> From<N> for Hiding<'brand, N> {
121 fn from(node: N) -> Self {
122 Self {
123 ctx: node.inference_context().shallow_clone(),
124 result: Ok(node),
125 }
126 }
127}
128
129impl<'brand, N: CoreConstructible<'brand> + HasCmr> CoreConstructible<'brand>
132 for Hiding<'brand, N>
133{
134 fn iden(inference_context: &Context<'brand>) -> Self {
135 N::iden(inference_context).into()
136 }
137
138 fn unit(inference_context: &Context<'brand>) -> Self {
139 N::unit(inference_context).into()
140 }
141
142 fn injl(child: &Self) -> Self {
143 match &child.result {
144 Ok(child) => N::injl(child).into(),
145 Err(cmr) => child.hidden_cloned_ctx(Cmr::injl(*cmr)),
146 }
147 }
148
149 fn injr(child: &Self) -> Self {
150 match &child.result {
151 Ok(child) => N::injr(child).into(),
152 Err(cmr) => child.hidden_cloned_ctx(Cmr::injr(*cmr)),
153 }
154 }
155
156 fn take(child: &Self) -> Self {
157 match &child.result {
158 Ok(child) => N::take(child).into(),
159 Err(cmr) => child.hidden_cloned_ctx(Cmr::take(*cmr)),
160 }
161 }
162
163 fn drop_(child: &Self) -> Self {
164 match &child.result {
165 Ok(child) => N::drop_(child).into(),
166 Err(cmr) => child.hidden_cloned_ctx(Cmr::drop(*cmr)),
167 }
168 }
169
170 fn comp(left: &Self, right: &Self) -> Result<Self, Error> {
171 match (&left.result, &right.result) {
172 (Ok(left), Ok(right)) => N::comp(left, right).map(Self::from),
173 _ => Ok(left.hidden_cloned_ctx(Cmr::comp(left.cmr(), right.cmr()))),
174 }
175 }
176
177 fn case(left: &Self, right: &Self) -> Result<Self, Error> {
178 match (&left.result, &right.result) {
179 (Ok(left), Ok(right)) => N::case(left, right).map(Self::from),
180 (Err(left), Ok(right)) => N::assertr(*left, right).map(Self::from),
181 (Ok(left), Err(right)) => N::assertl(left, *right).map(Self::from),
182 _ => Ok(left.hidden_cloned_ctx(Cmr::case(left.cmr(), right.cmr()))),
183 }
184 }
185
186 fn assertl(left: &Self, right: Cmr) -> Result<Self, Error> {
187 match &left.result {
188 Ok(left) => N::assertl(left, right).map(Self::from),
189 _ => Ok(left.hidden_cloned_ctx(Cmr::case(left.cmr(), right))),
190 }
191 }
192
193 fn assertr(left: Cmr, right: &Self) -> Result<Self, Error> {
194 match &right.result {
195 Ok(right) => N::assertr(left, right).map(Self::from),
196 _ => Ok(right.hidden_cloned_ctx(Cmr::case(left, right.cmr()))),
197 }
198 }
199
200 fn pair(left: &Self, right: &Self) -> Result<Self, Error> {
201 match (&left.result, &right.result) {
202 (Ok(left), Ok(right)) => N::pair(left, right).map(Self::from),
203 _ => Ok(left.hidden_cloned_ctx(Cmr::pair(left.cmr(), right.cmr()))),
204 }
205 }
206
207 fn fail(inference_context: &Context<'brand>, entropy: FailEntropy) -> Self {
208 N::fail(inference_context, entropy).into()
209 }
210
211 fn const_word(inference_context: &Context<'brand>, word: Word) -> Self {
212 N::const_word(inference_context, word).into()
213 }
214
215 fn inference_context(&self) -> &Context<'brand> {
216 &self.ctx
217 }
218}
219
220impl<'brand, N> JetConstructible<'brand> for Hiding<'brand, N>
221where
222 N: JetConstructible<'brand> + CoreConstructible<'brand>,
223{
224 fn jet(inference_context: &Context<'brand>, jet: &dyn Jet) -> Self {
225 N::jet(inference_context, jet).into()
226 }
227}
228
229impl<'brand, X, N> DisconnectConstructible<'brand, Option<X>> for Hiding<'brand, N>
230where
231 N: DisconnectConstructible<'brand, Option<X>> + CoreConstructible<'brand> + HasCmr,
232{
233 fn disconnect(left: &Self, right: &Option<X>) -> Result<Self, Error> {
234 match &left.result {
235 Ok(left) => N::disconnect(left, right).map(Self::from),
236 Err(..) => Ok(left.hidden_cloned_ctx(Cmr::disconnect(left.cmr()))),
237 }
238 }
239}
240
241impl<'brand, W, N> WitnessConstructible<'brand, W> for Hiding<'brand, N>
242where
243 N: WitnessConstructible<'brand, W> + CoreConstructible<'brand>,
244{
245 fn witness(inference_context: &Context<'brand>, witness: W) -> Self {
246 N::witness(inference_context, witness).into()
247 }
248}