@@ -221,6 +221,40 @@ impl<T, E, L: Loss> Imperfect<T, E, L> {
221221 self . eh ( f)
222222 }
223223
224+ /// Attempt recovery from Failure. The loss carries forward.
225+ ///
226+ /// Success and Partial pass through unchanged.
227+ /// Failure → recovery function → result carries the failure's accumulated loss.
228+ ///
229+ /// Recovery from Failure never produces Success — because the failure happened.
230+ /// The loss is real. The best you can do is recover a value and carry the cost.
231+ pub fn recover ( self , f : impl FnOnce ( E ) -> Imperfect < T , E , L > ) -> Imperfect < T , E , L > {
232+ match self {
233+ Imperfect :: Success ( v) => Imperfect :: Success ( v) ,
234+ Imperfect :: Partial ( v, l) => Imperfect :: Partial ( v, l) ,
235+ Imperfect :: Failure ( e, loss) => match f ( e) {
236+ Imperfect :: Success ( v) => Imperfect :: Partial ( v, loss) ,
237+ Imperfect :: Partial ( v, l2) => Imperfect :: Partial ( v, loss. combine ( l2) ) ,
238+ Imperfect :: Failure ( e2, l2) => Imperfect :: Failure ( e2, loss. combine ( l2) ) ,
239+ } ,
240+ }
241+ }
242+
243+ /// Recover a default value from Failure. Always produces Partial.
244+ /// You can't un-fail. But you can get something back. The loss survives.
245+ pub fn unwrap_or_else ( self , f : impl FnOnce ( E ) -> T ) -> Imperfect < T , E , L > {
246+ match self {
247+ Imperfect :: Success ( v) => Imperfect :: Success ( v) ,
248+ Imperfect :: Partial ( v, l) => Imperfect :: Partial ( v, l) ,
249+ Imperfect :: Failure ( e, loss) => Imperfect :: Partial ( f ( e) , loss) ,
250+ }
251+ }
252+
253+ /// Recover with a static default. Always produces Partial on Failure.
254+ pub fn unwrap_or ( self , default : T ) -> Imperfect < T , E , L > {
255+ self . unwrap_or_else ( |_| default)
256+ }
257+
224258 /// Propagate accumulated loss from `self` through `next`.
225259 ///
226260 /// Deprecated in favor of [`eh`](Self::eh) / [`imp`](Self::imp) / [`tri`](Self::tri).
0 commit comments