rust - How can I wrap any impl of std::error::Error to ease error propagation? -


i'm trying simplify error flow in webapp i'm working on, , plan make struct implements std::error::error , forwards result of description() whatever kind of error it's wrapped around. i've implemented from types of errors want wrap, struct makes easy use try! uniform error result. here's have far struct:

#![feature(convert)] use std::error::{error}; use std::fmt::{self,display,formatter}; use std::io::{self,read}; use std::ops::deref; use std::fs::{file};  #[derive(debug)] pub struct strerr{     desc:string,     c: option<box<error>> } impl strerr{     pub fn new(msg:string) ->self{         strerr{desc:msg, c:none}     } }  impl error strerr{     fn description(&self) -> &str{         self.desc.as_str()     }     fn cause(& self) -> option<& error> {         self.c.map(|e| e.deref())     } }  impl display strerr {     fn fmt(&self, f:&mut formatter) -> result<(),fmt::error> {         f.write_str(self.desc.as_str())     }  }  impl from<io::error> strerr {     fn from(o:io::error) -> self {         strerr{desc: string::from(o.description()),c:some(box::new(o))}     } }   fn main(){     let contrived = some("foo.txt")         .ok_or_else(|| strerr::new(string::from("error message")))         .and_then(|filename| ok(try!(file::open(filename))))         .and_then(|mut file| {             let mut content = string::new();             try!(file.read_to_string(&mut content));             ok(content)         });     if let ok(content) = contrived {         println!("got content: {}", content);     } else {         println!("got error");     } } 

playground

the problem cause() method - can't return reference inner error instance because e doesn't live long enough. there different way can structure can keep generic reference implements error (which putting in box) can still implement error trait (which expecting ref parent error)?

i've worked around punting on cause() , having return none, i'd rather conform intent of trait.

rustc 1.2.0-nightly (613e57b44 2015-06-01) (built 2015-06-02) 

this 1 way can convert option<box<trait>> option<&trait>. i'm avoiding of trait implementation show interesting code:

use std::error::error;  pub struct strerr {     c: option<box<error>> }  impl strerr {     fn cause(&self) -> option<&error> {         self.c.as_ref().map(|e| &**e)     } }  fn main() {} 

we use option::as_ref avoid consuming self.c item. map closure provided &box<trait>, dereference twice trait, , reference once &trait.


Comments

Popular posts from this blog

javascript - oscilloscope of speaker input stops rendering after a few seconds -

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -