#![allow(dead_code, deprecated, unused_variables, unused_mut)] #![feature(error_generic_member_access)] use core::error::Request; use core::error::request_ref; #[derive(Debug)] struct Parent(Option); impl std::fmt::Display for Parent { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "a parent failed") } } impl std::error::Error for Parent { fn provide<'a>(&'a self, request: &mut Request<'a>) { if let Some(v) = &self.0 { request.provide_ref::(v); } } } #[derive(Debug)] struct Child { parent: Parent, name: String, } impl Child { fn an_expensive_computation(&self) -> Option<&str> { Some(&self.name) } } impl std::fmt::Display for Child { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{} failed: \n {}", self.name, self.parent) } } impl std::error::Error for Child { fn provide<'a>(&'a self, request: &mut Request<'a>) { self.parent.provide(request); if request.would_be_satisfied_by_ref_of::() { if let Some(v) = self.an_expensive_computation() { request.provide_ref::(v); } } assert!(! request.would_be_satisfied_by_ref_of::< str > ()); } } fn main() { let parent = Parent(Some("parent".into())); let child = Child { parent, name: "child".into(), }; assert_eq!(Some("parent"), request_ref::< str > (& child)); let parent = Parent(None); let child = Child { parent, name: "child".into(), }; assert_eq!(Some("child"), request_ref::< str > (& child)); }