From 6132f7f6660c29fe3fc02422b7047246033db84f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 30 Jan 2014 11:30:21 -0800 Subject: [PATCH] rustdoc: Remove io_error usage --- src/librustdoc/html/escape.rs | 9 +- src/librustdoc/html/format.rs | 212 ++++++----- src/librustdoc/html/layout.rs | 3 +- src/librustdoc/html/markdown.rs | 13 +- src/librustdoc/html/render.rs | 648 +++++++++++++++++--------------- src/librustdoc/lib.rs | 22 +- src/librustdoc/test.rs | 4 +- 7 files changed, 495 insertions(+), 416 deletions(-) diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 1aaa446fc6c..82850dffa2b 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -20,7 +20,7 @@ pub struct Escape<'a>(&'a str); impl<'a> fmt::Show for Escape<'a> { - fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) { + fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { // Because the internet is always right, turns out there's not that many // characters to escape: http://stackoverflow.com/questions/7381974 let Escape(s) = *s; @@ -29,7 +29,7 @@ fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) { for (i, ch) in s.bytes().enumerate() { match ch as char { '<' | '>' | '&' | '\'' | '"' => { - fmt.buf.write(pile_o_bits.slice(last, i).as_bytes()); + if_ok!(fmt.buf.write(pile_o_bits.slice(last, i).as_bytes())); let s = match ch as char { '>' => ">", '<' => "<", @@ -38,7 +38,7 @@ fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) { '"' => """, _ => unreachable!() }; - fmt.buf.write(s.as_bytes()); + if_ok!(fmt.buf.write(s.as_bytes())); last = i + 1; } _ => {} @@ -46,7 +46,8 @@ fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) { } if last < s.len() { - fmt.buf.write(pile_o_bits.slice_from(last).as_bytes()); + if_ok!(fmt.buf.write(pile_o_bits.slice_from(last).as_bytes())); } + Ok(()) } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6b09072ff08..687f391c07f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -48,85 +48,105 @@ pub fn get(&self) -> ast::Purity { } impl fmt::Show for clean::Generics { - fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) { - if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return } - f.buf.write("<".as_bytes()); +impl fmt::Default for clean::Generics { + fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) -> fmt::Result { + if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return Ok(()) } + if_ok!(f.buf.write("<".as_bytes())); for (i, life) in g.lifetimes.iter().enumerate() { - if i > 0 { f.buf.write(", ".as_bytes()); } - write!(f.buf, "{}", *life); + if i > 0 { + if_ok!(f.buf.write(", ".as_bytes())); + } + if_ok!(write!(f.buf, "{}", *life)); } if g.type_params.len() > 0 { - if g.lifetimes.len() > 0 { f.buf.write(", ".as_bytes()); } + if g.lifetimes.len() > 0 { + if_ok!(f.buf.write(", ".as_bytes())); + } for (i, tp) in g.type_params.iter().enumerate() { - if i > 0 { f.buf.write(", ".as_bytes()) } - f.buf.write(tp.name.as_bytes()); + if i > 0 { + if_ok!(f.buf.write(", ".as_bytes())) + } + if_ok!(f.buf.write(tp.name.as_bytes())); if tp.bounds.len() > 0 { - f.buf.write(": ".as_bytes()); + if_ok!(f.buf.write(": ".as_bytes())); for (i, bound) in tp.bounds.iter().enumerate() { - if i > 0 { f.buf.write(" + ".as_bytes()); } - write!(f.buf, "{}", *bound); + if i > 0 { + if_ok!(f.buf.write(" + ".as_bytes())); + } + if_ok!(write!(f.buf, "{}", *bound)); } } } } - f.buf.write(">".as_bytes()); + if_ok!(f.buf.write(">".as_bytes())); + Ok(()) } } impl fmt::Show for clean::Lifetime { - fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) { - f.buf.write("'".as_bytes()); - f.buf.write(l.get_ref().as_bytes()); + fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) -> fmt::Result { + if_ok!(f.buf.write("'".as_bytes())); + if_ok!(f.buf.write(l.get_ref().as_bytes())); + Ok(()) } } impl fmt::Show for clean::TyParamBound { - fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) { + fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) -> fmt::Result { match *bound { clean::RegionBound => { f.buf.write("'static".as_bytes()) } clean::TraitBound(ref ty) => { - write!(f.buf, "{}", *ty); + write!(f.buf, "{}", *ty) } } } } impl fmt::Show for clean::Path { - fn fmt(path: &clean::Path, f: &mut fmt::Formatter) { - if path.global { f.buf.write("::".as_bytes()) } + fn fmt(path: &clean::Path, f: &mut fmt::Formatter) -> fmt::Result { + if path.global { + if_ok!(f.buf.write("::".as_bytes())) + } for (i, seg) in path.segments.iter().enumerate() { - if i > 0 { f.buf.write("::".as_bytes()) } - f.buf.write(seg.name.as_bytes()); + if i > 0 { + if_ok!(f.buf.write("::".as_bytes())) + } + if_ok!(f.buf.write(seg.name.as_bytes())); if seg.lifetimes.len() > 0 || seg.types.len() > 0 { - f.buf.write("<".as_bytes()); + if_ok!(f.buf.write("<".as_bytes())); let mut comma = false; for lifetime in seg.lifetimes.iter() { - if comma { f.buf.write(", ".as_bytes()); } + if comma { + if_ok!(f.buf.write(", ".as_bytes())); + } comma = true; - write!(f.buf, "{}", *lifetime); + if_ok!(write!(f.buf, "{}", *lifetime)); } for ty in seg.types.iter() { - if comma { f.buf.write(", ".as_bytes()); } + if comma { + if_ok!(f.buf.write(", ".as_bytes())); + } comma = true; - write!(f.buf, "{}", *ty); + if_ok!(write!(f.buf, "{}", *ty)); } - f.buf.write(">".as_bytes()); + if_ok!(f.buf.write(">".as_bytes())); } } + Ok(()) } } /// Used when rendering a `ResolvedPath` structure. This invokes the `path` /// rendering function with the necessary arguments for linking to a local path. fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path, - print_all: bool) { + print_all: bool) -> fmt::Result { path(w, p, print_all, |_cache, loc| { Some("../".repeat(loc.len())) }, |cache| { @@ -134,13 +154,14 @@ fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path, None => None, Some(&(ref fqp, shortty)) => Some((fqp.clone(), shortty)) } - }); + }) } /// Used when rendering an `ExternalPath` structure. Like `resolved_path` this /// will invoke `path` with proper linking-style arguments. fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool, - fqn: &[~str], kind: clean::TypeKind, crate: ast::CrateNum) { + fqn: &[~str], kind: clean::TypeKind, + crate: ast::CrateNum) -> fmt::Result { path(w, p, print_all, |cache, loc| { match *cache.extern_locations.get(&crate) { @@ -161,7 +182,9 @@ fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool, fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool, root: |&render::Cache, &[~str]| -> Option<~str>, - info: |&render::Cache| -> Option<(~[~str], &'static str)>) { + info: |&render::Cache| -> Option<(~[~str], &'static str)>) + -> fmt::Result +{ // The generics will get written to both the title and link let mut generics = ~""; let last = path.segments.last().unwrap(); @@ -200,20 +223,20 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool, let mut root = root; for seg in path.segments.slice_to(amt).iter() { if "super" == seg.name || "self" == seg.name { - write!(w, "{}::", seg.name); + if_ok!(write!(w, "{}::", seg.name)); } else { root.push_str(seg.name); root.push_str("/"); - write!(w, "{}::", - root, - seg.name); + if_ok!(write!(w, "{}::", + root, + seg.name)); } } } None => { for seg in path.segments.slice_to(amt).iter() { - write!(w, "{}::", seg.name); + if_ok!(write!(w, "{}::", seg.name)); } } } @@ -241,51 +264,57 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool, } } - write!(w, "{}", - shortty, url, fqp.connect("::"), last.name); + if_ok!(write!(w, "{}", + shortty, url, fqp.connect("::"), last.name)); } _ => { - write!(w, "{}", last.name); + if_ok!(write!(w, "{}", last.name)); } } - write!(w, "{}", generics); + if_ok!(write!(w, "{}", generics)); + Ok(()) }) }) } /// Helper to render type parameters -fn typarams(w: &mut io::Writer, typarams: &Option<~[clean::TyParamBound]>) { +fn typarams(w: &mut io::Writer, + typarams: &Option<~[clean::TyParamBound]>) -> fmt::Result { match *typarams { Some(ref params) => { - write!(w, "<"); + if_ok!(write!(w, "<")); for (i, param) in params.iter().enumerate() { - if i > 0 { write!(w, ", "); } - write!(w, "{}", *param); + if i > 0 { + if_ok!(write!(w, ", ")); + } + if_ok!(write!(w, "{}", *param)); } - write!(w, ">"); + if_ok!(write!(w, ">")); + Ok(()) } - None => {} + None => Ok(()) } } impl fmt::Show for clean::Type { - fn fmt(g: &clean::Type, f: &mut fmt::Formatter) { + fn fmt(g: &clean::Type, f: &mut fmt::Formatter) -> fmt::Result { match *g { clean::TyParamBinder(id) | clean::Generic(id) => { local_data::get(cache_key, |cache| { let m = cache.unwrap().get(); - f.buf.write(m.typarams.get(&id).as_bytes()); + f.buf.write(m.typarams.get(&id).as_bytes()) }) } clean::ResolvedPath{id, typarams: ref tp, path: ref path} => { - resolved_path(f.buf, id, path, false); - typarams(f.buf, tp); + if_ok!(resolved_path(f.buf, id, path, false)); + typarams(f.buf, tp) } clean::ExternalPath{path: ref path, typarams: ref tp, fqn: ref fqn, kind, crate} => { - external_path(f.buf, path, false, fqn.as_slice(), kind, crate); - typarams(f.buf, tp); + if_ok!(external_path(f.buf, path, false, fqn.as_slice(), kind, + crate)) + typarams(f.buf, tp) } clean::Self(..) => f.buf.write("Self".as_bytes()), clean::Primitive(prim) => { @@ -306,7 +335,7 @@ fn fmt(g: &clean::Type, f: &mut fmt::Formatter) { ast::TyBool => "bool", ast::TyChar => "char", }; - f.buf.write(s.as_bytes()); + f.buf.write(s.as_bytes()) } clean::Closure(ref decl) => { let region = match decl.region { @@ -322,7 +351,7 @@ fn fmt(g: &clean::Type, f: &mut fmt::Formatter) { ast::ManagedSigil => format!("@{}fn({})", region, decl.decl.inputs), }, arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" }, - ret = decl.decl.output); + ret = decl.decl.output) // FIXME: where are bounds and lifetimes printed?! } clean::BareFunction(ref decl) => { @@ -333,19 +362,21 @@ fn fmt(g: &clean::Type, f: &mut fmt::Formatter) { ref s => " " + *s + " ", }, decl.generics, - decl.decl); + decl.decl) } clean::Tuple(ref typs) => { - f.buf.write("(".as_bytes()); + if_ok!(f.buf.write("(".as_bytes())); for (i, typ) in typs.iter().enumerate() { - if i > 0 { f.buf.write(", ".as_bytes()) } - write!(f.buf, "{}", *typ); + if i > 0 { + if_ok!(f.buf.write(", ".as_bytes())) + } + if_ok!(write!(f.buf, "{}", *typ)); } - f.buf.write(")".as_bytes()); + f.buf.write(")".as_bytes()) } clean::Vector(ref t) => write!(f.buf, "[{}]", **t), clean::FixedVector(ref t, ref s) => { - write!(f.buf, "[{}, ..{}]", **t, *s); + write!(f.buf, "[{}, ..{}]", **t, *s) } clean::String => f.buf.write("str".as_bytes()), clean::Bool => f.buf.write("bool".as_bytes()), @@ -368,23 +399,23 @@ fn fmt(g: &clean::Type, f: &mut fmt::Formatter) { clean::Mutable => "mut ", clean::Immutable => "", }, - **ty); + **ty) } } } } impl fmt::Show for clean::FnDecl { - fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) { + fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}", args = d.inputs, arrow = match d.output { clean::Unit => "no", _ => "yes" }, - ret = d.output); + ret = d.output) } } impl fmt::Show for ~[clean::Argument] { - fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) { + fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) -> fmt::Result { let mut args = ~""; for (i, input) in inputs.iter().enumerate() { if i > 0 { args.push_str(", "); } @@ -393,12 +424,12 @@ fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) { } args.push_str(format!("{}", input.type_)); } - f.buf.write(args.as_bytes()); + f.buf.write(args.as_bytes()) } } impl<'a> fmt::Show for Method<'a> { - fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) { + fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) -> fmt::Result { let Method(selfty, d) = *m; let mut args = ~""; match *selfty { @@ -429,74 +460,79 @@ fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) { write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}", args = args, arrow = match d.output { clean::Unit => "no", _ => "yes" }, - ret = d.output); + ret = d.output) } } impl fmt::Show for VisSpace { - fn fmt(v: &VisSpace, f: &mut fmt::Formatter) { + fn fmt(v: &VisSpace, f: &mut fmt::Formatter) -> fmt::Result { match v.get() { - Some(ast::Public) => { write!(f.buf, "pub "); } - Some(ast::Private) => { write!(f.buf, "priv "); } - Some(ast::Inherited) | None => {} + Some(ast::Public) => write!(f.buf, "pub "), + Some(ast::Private) => write!(f.buf, "priv "), + Some(ast::Inherited) | None => Ok(()) } } } impl fmt::Show for PuritySpace { - fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) { + fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) -> fmt::Result { match p.get() { ast::UnsafeFn => write!(f.buf, "unsafe "), ast::ExternFn => write!(f.buf, "extern "), - ast::ImpureFn => {} + ast::ImpureFn => Ok(()) } } } impl fmt::Show for clean::ViewPath { - fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) { + fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) -> fmt::Result { match *v { clean::SimpleImport(ref name, ref src) => { if *name == src.path.segments.last().unwrap().name { - write!(f.buf, "use {};", *src); + write!(f.buf, "use {};", *src) } else { - write!(f.buf, "use {} = {};", *name, *src); + write!(f.buf, "use {} = {};", *name, *src) } } clean::GlobImport(ref src) => { - write!(f.buf, "use {}::*;", *src); + write!(f.buf, "use {}::*;", *src) } clean::ImportList(ref src, ref names) => { - write!(f.buf, "use {}::\\{", *src); + if_ok!(write!(f.buf, "use {}::\\{", *src)); for (i, n) in names.iter().enumerate() { - if i > 0 { write!(f.buf, ", "); } - write!(f.buf, "{}", *n); + if i > 0 { + if_ok!(write!(f.buf, ", ")); + } + if_ok!(write!(f.buf, "{}", *n)); } - write!(f.buf, "\\};"); + write!(f.buf, "\\};") } } } } impl fmt::Show for clean::ImportSource { - fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) { + fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) -> fmt::Result { match v.did { // FIXME: shouldn't be restricted to just local imports Some(did) if ast_util::is_local(did) => { - resolved_path(f.buf, did.node, &v.path, true); + resolved_path(f.buf, did.node, &v.path, true) } _ => { for (i, seg) in v.path.segments.iter().enumerate() { - if i > 0 { write!(f.buf, "::") } - write!(f.buf, "{}", seg.name); + if i > 0 { + if_ok!(write!(f.buf, "::")) + } + if_ok!(write!(f.buf, "{}", seg.name)); } + Ok(()) } } } } impl fmt::Show for clean::ViewListIdent { - fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) { + fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) -> fmt::Result { match v.source { // FIXME: shouldn't be limited to just local imports Some(did) if ast_util::is_local(did) => { @@ -508,7 +544,7 @@ fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) { types: ~[], }] }; - resolved_path(f.buf, did.node, &path, false); + resolved_path(f.buf, did.node, &path, false) } _ => write!(f.buf, "{}", v.name), } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 4565facea02..db7c882ab42 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -26,6 +26,7 @@ pub struct Page<'a> { pub fn render( dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T) + -> fmt::Result { write!(dst, " @@ -121,7 +122,7 @@ pub fn render( favicon = nonestr(layout.favicon), sidebar = *sidebar, crate = layout.crate, - ); + ) } fn nonestr<'a>(s: &'a str) -> &'a str { diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 254d65ae2f6..c2203a352c5 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -109,7 +109,7 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> { } } -pub fn render(w: &mut io::Writer, s: &str) { +pub fn render(w: &mut io::Writer, s: &str) -> fmt::Result { extern fn block(ob: *buf, text: *buf, lang: *buf, opaque: *libc::c_void) { unsafe { let my_opaque: &my_opaque = cast::transmute(opaque); @@ -159,11 +159,12 @@ pub fn render(w: &mut io::Writer, s: &str) { sd_markdown_render(ob, s.as_ptr(), s.len() as libc::size_t, markdown); sd_markdown_free(markdown); - vec::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| { - w.write(buf); + let ret = vec::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| { + w.write(buf) }); bufrelease(ob); + ret } } @@ -210,10 +211,10 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { } impl<'a> fmt::Show for Markdown<'a> { - fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) { + fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { let Markdown(md) = *md; // This is actually common enough to special-case - if md.len() == 0 { return; } - render(fmt.buf, md.as_slice()); + if md.len() == 0 { return Ok(()) } + render(fmt.buf, md.as_slice()) } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 0b2c568c723..7dc89cca745 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -195,7 +195,7 @@ struct IndexItem { local_data_key!(pub current_location_key: ~[~str]) /// Generates the documentation for `crate` into the directory `dst` -pub fn run(mut crate: clean::Crate, dst: Path) { +pub fn run(mut crate: clean::Crate, dst: Path) -> io::IoResult<()> { let mut cx = Context { dst: dst, current: ~[], @@ -208,7 +208,7 @@ pub fn run(mut crate: clean::Crate, dst: Path) { }, include_sources: true, }; - mkdir(&cx.dst); + if_ok!(mkdir(&cx.dst)); match crate.module.as_ref().map(|m| m.doc_list().unwrap_or(&[])) { Some(attrs) => { @@ -248,47 +248,55 @@ pub fn run(mut crate: clean::Crate, dst: Path) { // Add all the static files let mut dst = cx.dst.join(crate.name.as_slice()); - mkdir(&dst); - write(dst.join("jquery.js"), include_str!("static/jquery-2.0.3.min.js")); - write(dst.join("main.js"), include_str!("static/main.js")); - write(dst.join("main.css"), include_str!("static/main.css")); - write(dst.join("normalize.css"), include_str!("static/normalize.css")); + if_ok!(mkdir(&dst)); + if_ok!(write(dst.join("jquery.js"), + include_str!("static/jquery-2.0.3.min.js"))); + if_ok!(write(dst.join("main.js"), include_str!("static/main.js"))); + if_ok!(write(dst.join("main.css"), include_str!("static/main.css"))); + if_ok!(write(dst.join("normalize.css"), + include_str!("static/normalize.css"))); // Publish the search index { dst.push("search-index.js"); let mut w = BufferedWriter::new(File::create(&dst).unwrap()); let w = &mut w as &mut Writer; - write!(w, "var searchIndex = ["); + if_ok!(write!(w, "var searchIndex = [")); for (i, item) in cache.search_index.iter().enumerate() { - if i > 0 { write!(w, ","); } - write!(w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}", - item.ty, item.name, item.path, - item.desc.to_json().to_str()) + if i > 0 { + if_ok!(write!(w, ",")); + } + if_ok!(write!(w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}", + item.ty, item.name, item.path, + item.desc.to_json().to_str())); match item.parent { - Some(id) => { write!(w, ",parent:'{}'", id); } + Some(id) => { + if_ok!(write!(w, ",parent:'{}'", id)); + } None => {} } - write!(w, "\\}"); + if_ok!(write!(w, "\\}")); } - write!(w, "];"); - write!(w, "var allPaths = \\{"); + if_ok!(write!(w, "];")); + if_ok!(write!(w, "var allPaths = \\{")); for (i, (&id, &(ref fqp, short))) in cache.paths.iter().enumerate() { - if i > 0 { write!(w, ","); } - write!(w, "'{}':\\{type:'{}',name:'{}'\\}", - id, short, *fqp.last().unwrap()); + if i > 0 { + if_ok!(write!(w, ",")); + } + if_ok!(write!(w, "'{}':\\{type:'{}',name:'{}'\\}", + id, short, *fqp.last().unwrap())); } - write!(w, "\\};"); - w.flush(); + if_ok!(write!(w, "\\};")); + if_ok!(w.flush()); } // Render all source files (this may turn into a giant no-op) { info!("emitting source files"); let dst = cx.dst.join("src"); - mkdir(&dst); + if_ok!(mkdir(&dst)); let dst = dst.join(crate.name.as_slice()); - mkdir(&dst); + if_ok!(mkdir(&dst)); let mut folder = SourceCollector { dst: dst, seen: HashSet::new(), @@ -302,27 +310,23 @@ pub fn run(mut crate: clean::Crate, dst: Path) { } // And finally render the whole crate's documentation - cx.crate(crate, cache); + cx.crate(crate, cache) } /// Writes the entire contents of a string to a destination, not attempting to /// catch any errors. -fn write(dst: Path, contents: &str) { - File::create(&dst).write(contents.as_bytes()); +fn write(dst: Path, contents: &str) -> io::IoResult<()> { + File::create(&dst).write(contents.as_bytes()) } /// Makes a directory on the filesystem, failing the task if an error occurs and /// skipping if the directory already exists. -fn mkdir(path: &Path) { - io::io_error::cond.trap(|err| { - error!("Couldn't create directory `{}`: {}", - path.display(), err.desc); - fail!() - }).inside(|| { - if !path.is_dir() { - fs::mkdir(path, io::UserRWX); - } - }) +fn mkdir(path: &Path) -> io::IoResult<()> { + if !path.exists() { + fs::mkdir(path, io::UserRWX) + } else { + Ok(()) + } } /// Takes a path to a source file and cleans the path to it. This canonicalizes @@ -387,15 +391,17 @@ fn fold_item(&mut self, item: clean::Item) -> Option { // something like that), so just don't include sources for the // entire crate. The other option is maintaining this mapping on a // per-file basis, but that's probably not worth it... - self.cx.include_sources = self.emit_source(item.source.filename); + self.cx.include_sources = match self.emit_source(item.source.filename) { + Ok(()) => true, + Err(e) => { + println!("warning: source code was requested to be rendered, \ + but processing `{}` had an error: {}", + item.source.filename, e); + println!(" skipping rendering of source code"); + false + } + }; self.seen.insert(item.source.filename.clone()); - - if !self.cx.include_sources { - println!("warning: source code was requested to be rendered, \ - but `{}` is a missing source file.", - item.source.filename); - println!(" skipping rendering of source code"); - } } self.fold_item_recur(item) @@ -404,30 +410,18 @@ fn fold_item(&mut self, item: clean::Item) -> Option { impl<'a> SourceCollector<'a> { /// Renders the given filename into its corresponding HTML source file. - fn emit_source(&mut self, filename: &str) -> bool { + fn emit_source(&mut self, filename: &str) -> io::IoResult<()> { let p = Path::new(filename); - // Read the contents of the file - let mut contents = ~[]; - { - let mut buf = [0, ..1024]; - // If we couldn't open this file, then just returns because it - // probably means that it's some standard library macro thing and we - // can't have the source to it anyway. - let mut r = match io::result(|| File::open(&p)) { - Ok(r) => r, - // eew macro hacks - Err(..) => return filename == "" - }; - - // read everything - loop { - match r.read(buf) { - Some(n) => contents.push_all(buf.slice_to(n)), - None => break - } - } - } + // If we couldn't open this file, then just returns because it + // probably means that it's some standard library macro thing and we + // can't have the source to it anyway. + let contents = match File::open(&p).read_to_end() { + Ok(r) => r, + // eew macro hacks + Err(..) if filename == "" => return Ok(()), + Err(e) => return Err(e) + }; let contents = str::from_utf8_owned(contents).unwrap(); // Create the intermediate directories @@ -435,12 +429,12 @@ fn emit_source(&mut self, filename: &str) -> bool { let mut root_path = ~"../../"; clean_srcpath(p.dirname(), |component| { cur.push(component); - mkdir(&cur); + mkdir(&cur).unwrap(); root_path.push_str("../"); }); cur.push(p.filename().expect("source has no filename") + bytes!(".html")); - let mut w = BufferedWriter::new(File::create(&cur).unwrap()); + let mut w = BufferedWriter::new(if_ok!(File::create(&cur))); let title = cur.filename_display().with_str(|s| format!("{} -- source", s)); let page = layout::Page { @@ -448,10 +442,10 @@ fn emit_source(&mut self, filename: &str) -> bool { ty: "source", root_path: root_path, }; - layout::render(&mut w as &mut Writer, &self.cx.layout, - &page, &(""), &Source(contents.as_slice())); - w.flush(); - return true; + if_ok!(layout::render(&mut w as &mut Writer, &self.cx.layout, + &page, &(""), &Source(contents.as_slice()))); + if_ok!(w.flush()); + return Ok(()); } } @@ -665,7 +659,7 @@ fn recurse(&mut self, s: ~str, f: |&mut Context| -> T) -> T { info!("Recursing into {}", self.dst.display()); - mkdir(&self.dst); + mkdir(&self.dst).unwrap(); let ret = f(self); info!("Recursed; leaving {}", self.dst.display()); @@ -683,10 +677,10 @@ fn recurse(&mut self, s: ~str, f: |&mut Context| -> T) -> T { /// /// This currently isn't parallelized, but it'd be pretty easy to add /// parallelization to this function. - fn crate(self, mut crate: clean::Crate, cache: Cache) { + fn crate(self, mut crate: clean::Crate, cache: Cache) -> io::IoResult<()> { let mut item = match crate.module.take() { Some(i) => i, - None => return + None => return Ok(()) }; item.name = Some(crate.name); @@ -696,12 +690,13 @@ fn crate(self, mut crate: clean::Crate, cache: Cache) { let mut work = ~[(self, item)]; loop { match work.pop() { - Some((mut cx, item)) => cx.item(item, |cx, item| { + Some((mut cx, item)) => if_ok!(cx.item(item, |cx, item| { work.push((cx.clone(), item)); - }), + })), None => break, } } + Ok(()) } /// Non-parellelized version of rendering an item. This will take the input @@ -709,9 +704,10 @@ fn crate(self, mut crate: clean::Crate, cache: Cache) { /// all sub-items which need to be rendered. /// /// The rendering driver uses this closure to queue up more work. - fn item(&mut self, item: clean::Item, f: |&mut Context, clean::Item|) { + fn item(&mut self, item: clean::Item, + f: |&mut Context, clean::Item|) -> io::IoResult<()> { fn render(w: io::File, cx: &mut Context, it: &clean::Item, - pushname: bool) { + pushname: bool) -> io::IoResult<()> { info!("Rendering an item to {}", w.path().display()); // A little unfortunate that this is done like this, but it sure // does make formatting *a lot* nicer. @@ -733,10 +729,10 @@ fn render(w: io::File, cx: &mut Context, it: &clean::Item, // of the pain by using a buffered writer instead of invoking the // write sycall all the time. let mut writer = BufferedWriter::new(w); - layout::render(&mut writer as &mut Writer, &cx.layout, &page, - &Sidebar{ cx: cx, item: it }, - &Item{ cx: cx, item: it }); - writer.flush(); + if_ok!(layout::render(&mut writer as &mut Writer, &cx.layout, &page, + &Sidebar{ cx: cx, item: it }, + &Item{ cx: cx, item: it })); + writer.flush() } match item.inner { @@ -748,7 +744,8 @@ fn render(w: io::File, cx: &mut Context, it: &clean::Item, self.recurse(name, |this| { let item = item.take_unwrap(); let dst = this.dst.join("index.html"); - render(File::create(&dst).unwrap(), this, &item, false); + let dst = if_ok!(File::create(&dst)); + if_ok!(render(dst, this, &item, false)); let m = match item.inner { clean::ModuleItem(m) => m, @@ -758,6 +755,7 @@ fn render(w: io::File, cx: &mut Context, it: &clean::Item, for item in m.items.move_iter() { f(this,item); } + Ok(()) }) } @@ -765,10 +763,11 @@ fn render(w: io::File, cx: &mut Context, it: &clean::Item, // pages dedicated to them. _ if item.name.is_some() => { let dst = self.dst.join(item_path(&item)); - render(File::create(&dst).unwrap(), self, &item, true); + let dst = if_ok!(File::create(&dst)); + render(dst, self, &item, true) } - _ => {} + _ => Ok(()) } } } @@ -802,7 +801,7 @@ fn ismodule(&self) -> bool { } impl<'a> fmt::Show for Item<'a> { - fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) { + fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { match attr::find_stability(it.item.attrs.iter()) { Some(ref stability) => { write!(fmt.buf, @@ -826,23 +825,24 @@ fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) { } else { format!("{}-{}", it.item.source.loline, it.item.source.hiline) }; - write!(fmt.buf, - "[src]", - root = it.cx.root_path, - crate = it.cx.layout.crate, - path = path.connect("/"), - href = href); + if_ok!(write!(fmt.buf, + "\ + [src]", + root = it.cx.root_path, + crate = it.cx.layout.crate, + path = path.connect("/"), + href = href)); } // Write the breadcrumb trail header for the top - write!(fmt.buf, "

"); + if_ok!(write!(fmt.buf, "

")); match it.item.inner { - clean::ModuleItem(..) => write!(fmt.buf, "Module "), - clean::FunctionItem(..) => write!(fmt.buf, "Function "), - clean::TraitItem(..) => write!(fmt.buf, "Trait "), - clean::StructItem(..) => write!(fmt.buf, "Struct "), - clean::EnumItem(..) => write!(fmt.buf, "Enum "), + clean::ModuleItem(..) => if_ok!(write!(fmt.buf, "Module ")), + clean::FunctionItem(..) => if_ok!(write!(fmt.buf, "Function ")), + clean::TraitItem(..) => if_ok!(write!(fmt.buf, "Trait ")), + clean::StructItem(..) => if_ok!(write!(fmt.buf, "Struct ")), + clean::EnumItem(..) => if_ok!(write!(fmt.buf, "Enum ")), _ => {} } let cur = it.cx.current.as_slice(); @@ -852,11 +852,11 @@ fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) { for _ in range(0, cur.len() - i - 1) { trail.push_str("../"); } - write!(fmt.buf, "{}::", - trail, component.as_slice()); + if_ok!(write!(fmt.buf, "{}::", + trail, component.as_slice())); } - write!(fmt.buf, "{}

", - shortty(it.item), it.item.name.get_ref().as_slice()); + if_ok!(write!(fmt.buf, "{}", + shortty(it.item), it.item.name.get_ref().as_slice())); match it.item.inner { clean::ModuleItem(ref m) => item_module(fmt.buf, it.cx, @@ -867,7 +867,7 @@ fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) { clean::StructItem(ref s) => item_struct(fmt.buf, it.item, s), clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e), clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t), - _ => {} + _ => Ok(()) } } } @@ -903,18 +903,19 @@ fn shorter<'a>(s: Option<&'a str>) -> &'a str { } } -fn document(w: &mut Writer, item: &clean::Item) { +fn document(w: &mut Writer, item: &clean::Item) -> fmt::Result { match item.doc_value() { Some(s) => { - write!(w, "
{}
", Markdown(s)); + if_ok!(write!(w, "
{}
", Markdown(s))); } None => {} } + Ok(()) } fn item_module(w: &mut Writer, cx: &Context, - item: &clean::Item, items: &[clean::Item]) { - document(w, item); + item: &clean::Item, items: &[clean::Item]) -> fmt::Result { + if_ok!(document(w, item)); debug!("{:?}", items); let mut indices = vec::from_fn(items.len(), |i| i); @@ -965,10 +966,10 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { let myty = shortty(myitem); if myty != curty { if curty != "" { - write!(w, ""); + if_ok!(write!(w, "")); } curty = myty; - write!(w, "

{}

\n", match myitem.inner { + if_ok!(write!(w, "

{}

\n
", match myitem.inner { clean::ModuleItem(..) => "Modules", clean::StructItem(..) => "Structs", clean::EnumItem(..) => "Enums", @@ -984,24 +985,26 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { clean::VariantItem(..) => "Variants", clean::ForeignFunctionItem(..) => "Foreign Functions", clean::ForeignStaticItem(..) => "Foreign Statics", - }); + })); } match myitem.inner { clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => { struct Initializer<'a>(&'a str); impl<'a> fmt::Show for Initializer<'a> { - fn fmt(s: &Initializer<'a>, f: &mut fmt::Formatter) { + fn fmt(s: &Initializer<'a>, + f: &mut fmt::Formatter) -> fmt::Result { let Initializer(s) = *s; - if s.len() == 0 { return; } - write!(f.buf, " = "); + if s.len() == 0 { return Ok(()); } + if_ok!(write!(f.buf, " = ")); let tag = if s.contains("\n") { "pre" } else { "code" }; - write!(f.buf, "<{tag}>{}", - s.as_slice(), tag=tag); + if_ok!(write!(f.buf, "<{tag}>{}", + s.as_slice(), tag=tag)); + Ok(()) } } - write!(w, " + if_ok!(write!(w, " @@ -1011,27 +1014,27 @@ fn fmt(s: &Initializer<'a>, f: &mut fmt::Formatter) { *myitem.name.get_ref(), s.type_, Initializer(s.expr), - Markdown(blank(myitem.doc_value()))); + Markdown(blank(myitem.doc_value())))); } clean::ViewItemItem(ref item) => { match item.inner { clean::ExternMod(ref name, ref src, _) => { - write!(w, ""); + if_ok!(write!(w, ";")); } clean::Import(ref imports) => { for import in imports.iter() { - write!(w, "", - VisSpace(myitem.visibility), - *import); + if_ok!(write!(w, "", + VisSpace(myitem.visibility), + *import)); } } } @@ -1040,7 +1043,7 @@ fn fmt(s: &Initializer<'a>, f: &mut fmt::Formatter) { _ => { if myitem.name.is_none() { continue } - write!(w, " + if_ok!(write!(w, " @@ -1051,24 +1054,26 @@ fn fmt(s: &Initializer<'a>, f: &mut fmt::Formatter) { Markdown(shorter(myitem.doc_value())), class = shortty(myitem), href = item_path(myitem), - title = full_path(cx, myitem)); + title = full_path(cx, myitem))); } } } - write!(w, "
{}static {}: {}{} {} 
extern mod {}", - name.as_slice()); + if_ok!(write!(w, "
extern mod {}", + name.as_slice())); match *src { - Some(ref src) => write!(w, " = \"{}\"", - src.as_slice()), + Some(ref src) => if_ok!(write!(w, " = \"{}\"", + src.as_slice())), None => {} } - write!(w, ";
{}{}
{}{}
{}
"); + write!(w, "") } -fn item_function(w: &mut Writer, it: &clean::Item, f: &clean::Function) { - write!(w, "
{vis}{purity}fn {name}{generics}{decl}
", +fn item_function(w: &mut Writer, it: &clean::Item, + f: &clean::Function) -> fmt::Result { + if_ok!(write!(w, "
{vis}{purity}fn {name}{generics}{decl}
", vis = VisSpace(it.visibility), purity = PuritySpace(f.purity), name = it.name.get_ref().as_slice(), generics = f.generics, - decl = f.decl); - document(w, it); + decl = f.decl)); + document(w, it) } -fn item_trait(w: &mut Writer, it: &clean::Item, t: &clean::Trait) { +fn item_trait(w: &mut Writer, it: &clean::Item, + t: &clean::Trait) -> fmt::Result { let mut parents = ~""; if t.parents.len() > 0 { parents.push_str(": "); @@ -1079,99 +1084,102 @@ fn item_trait(w: &mut Writer, it: &clean::Item, t: &clean::Trait) { } // Output the trait definition - write!(w, "
{}trait {}{}{} ",
-           VisSpace(it.visibility),
-           it.name.get_ref().as_slice(),
-           t.generics,
-           parents);
+    if_ok!(write!(w, "
{}trait {}{}{} ",
+                  VisSpace(it.visibility),
+                  it.name.get_ref().as_slice(),
+                  t.generics,
+                  parents));
     let required = t.methods.iter().filter(|m| m.is_req()).to_owned_vec();
     let provided = t.methods.iter().filter(|m| !m.is_req()).to_owned_vec();
 
     if t.methods.len() == 0 {
-        write!(w, "\\{ \\}");
+        if_ok!(write!(w, "\\{ \\}"));
     } else {
-        write!(w, "\\{\n");
+        if_ok!(write!(w, "\\{\n"));
         for m in required.iter() {
-            write!(w, "    ");
-            render_method(w, m.item(), true);
-            write!(w, ";\n");
+            if_ok!(write!(w, "    "));
+            if_ok!(render_method(w, m.item(), true));
+            if_ok!(write!(w, ";\n"));
         }
         if required.len() > 0 && provided.len() > 0 {
-            w.write("\n".as_bytes());
+            if_ok!(w.write("\n".as_bytes()));
         }
         for m in provided.iter() {
-            write!(w, "    ");
-            render_method(w, m.item(), true);
-            write!(w, " \\{ ... \\}\n");
+            if_ok!(write!(w, "    "));
+            if_ok!(render_method(w, m.item(), true));
+            if_ok!(write!(w, " \\{ ... \\}\n"));
         }
-        write!(w, "\\}");
+        if_ok!(write!(w, "\\}"));
     }
-    write!(w, "
"); + if_ok!(write!(w, "
")); // Trait documentation - document(w, it); - - fn meth(w: &mut Writer, m: &clean::TraitMethod) { - write!(w, "

", - shortty(m.item()), - *m.item().name.get_ref()); - render_method(w, m.item(), false); - write!(w, "

"); - document(w, m.item()); + if_ok!(document(w, it)); + + fn meth(w: &mut Writer, m: &clean::TraitMethod) -> fmt::Result { + if_ok!(write!(w, "

", + shortty(m.item()), + *m.item().name.get_ref())); + if_ok!(render_method(w, m.item(), false)); + if_ok!(write!(w, "

")); + if_ok!(document(w, m.item())); + Ok(()) } // Output the documentation for each function individually if required.len() > 0 { - write!(w, " + if_ok!(write!(w, "

Required Methods

- "); + ")); for m in required.iter() { - meth(w, *m); + if_ok!(meth(w, *m)); } - write!(w, "
"); + if_ok!(write!(w, "")); } if provided.len() > 0 { - write!(w, " + if_ok!(write!(w, "

Provided Methods

- "); + ")); for m in provided.iter() { - meth(w, *m); + if_ok!(meth(w, *m)); } - write!(w, "
"); + if_ok!(write!(w, "")); } local_data::get(cache_key, |cache| { let cache = cache.unwrap().get(); match cache.implementors.find(&it.id) { Some(implementors) => { - write!(w, " + if_ok!(write!(w, "

Implementors

    - "); + ")); for i in implementors.iter() { match *i { PathType(ref ty) => { - write!(w, "
  • {}
  • ", *ty); + if_ok!(write!(w, "
  • {}
  • ", *ty)); } OtherType(ref generics, ref trait_, ref for_) => { - write!(w, "
  • impl{} {} for {}
  • ", - *generics, *trait_, *for_); + if_ok!(write!(w, "
  • impl{} {} for {}
  • ", + *generics, *trait_, *for_)); } } } - write!(w, "
"); + if_ok!(write!(w, "")); } None => {} } + Ok(()) }) } -fn render_method(w: &mut Writer, meth: &clean::Item, withlink: bool) { +fn render_method(w: &mut Writer, meth: &clean::Item, + withlink: bool) -> fmt::Result { fn fun(w: &mut Writer, it: &clean::Item, purity: ast::Purity, g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl, - withlink: bool) { + withlink: bool) -> fmt::Result { write!(w, "{}fn {withlink, select, true{{name}} @@ -1185,118 +1193,125 @@ fn fun(w: &mut Writer, it: &clean::Item, purity: ast::Purity, name = it.name.get_ref().as_slice(), generics = *g, decl = Method(selfty, d), - withlink = if withlink {"true"} else {"false"}); + withlink = if withlink {"true"} else {"false"}) } match meth.inner { clean::TyMethodItem(ref m) => { - fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink); + fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink) } clean::MethodItem(ref m) => { - fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink); + fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink) } _ => unreachable!() } } -fn item_struct(w: &mut Writer, it: &clean::Item, s: &clean::Struct) { - write!(w, "
");
-    render_struct(w, it, Some(&s.generics), s.struct_type, s.fields,
-                  s.fields_stripped, "", true);
-    write!(w, "
"); +fn item_struct(w: &mut Writer, it: &clean::Item, + s: &clean::Struct) -> fmt::Result { + if_ok!(write!(w, "
"));
+    if_ok!(render_struct(w, it, Some(&s.generics), s.struct_type, s.fields,
+                         s.fields_stripped, "", true));
+    if_ok!(write!(w, "
")); - document(w, it); + if_ok!(document(w, it)); match s.struct_type { doctree::Plain if s.fields.len() > 0 => { - write!(w, "

Fields

\n"); + if_ok!(write!(w, "

Fields

\n
")); for field in s.fields.iter() { - write!(w, ""); + if_ok!(write!(w, "")); } - write!(w, "
\ - {name}", - name = field.name.get_ref().as_slice()); - document(w, field); - write!(w, "
\ + {name}", + name = field.name.get_ref().as_slice())); + if_ok!(document(w, field)); + if_ok!(write!(w, "
"); + if_ok!(write!(w, "")); } _ => {} } - render_methods(w, it); + render_methods(w, it) } -fn item_enum(w: &mut Writer, it: &clean::Item, e: &clean::Enum) { - write!(w, "
{}enum {}{}",
-           VisSpace(it.visibility),
-           it.name.get_ref().as_slice(),
-           e.generics);
+fn item_enum(w: &mut Writer, it: &clean::Item, e: &clean::Enum) -> fmt::Result {
+    if_ok!(write!(w, "
{}enum {}{}",
+                  VisSpace(it.visibility),
+                  it.name.get_ref().as_slice(),
+                  e.generics));
     if e.variants.len() == 0 && !e.variants_stripped {
-        write!(w, " \\{\\}");
+        if_ok!(write!(w, " \\{\\}"));
     } else {
-        write!(w, " \\{\n");
+        if_ok!(write!(w, " \\{\n"));
         for v in e.variants.iter() {
-            write!(w, "    ");
+            if_ok!(write!(w, "    "));
             let name = v.name.get_ref().as_slice();
             match v.inner {
                 clean::VariantItem(ref var) => {
                     match var.kind {
-                        clean::CLikeVariant => write!(w, "{}", name),
+                        clean::CLikeVariant => if_ok!(write!(w, "{}", name)),
                         clean::TupleVariant(ref tys) => {
-                            write!(w, "{}(", name);
+                            if_ok!(write!(w, "{}(", name));
                             for (i, ty) in tys.iter().enumerate() {
-                                if i > 0 { write!(w, ", ") }
-                                write!(w, "{}", *ty);
+                                if i > 0 {
+                                    if_ok!(write!(w, ", "))
+                                }
+                                if_ok!(write!(w, "{}", *ty));
                             }
-                            write!(w, ")");
+                            if_ok!(write!(w, ")"));
                         }
                         clean::StructVariant(ref s) => {
-                            render_struct(w, v, None, s.struct_type, s.fields,
-                                          s.fields_stripped, "    ", false);
+                            if_ok!(render_struct(w, v, None, s.struct_type,
+                                                 s.fields, s.fields_stripped,
+                                                 "    ", false));
                         }
                     }
                 }
                 _ => unreachable!()
             }
-            write!(w, ",\n");
+            if_ok!(write!(w, ",\n"));
         }
 
         if e.variants_stripped {
-            write!(w, "    // some variants omitted\n");
+            if_ok!(write!(w, "    // some variants omitted\n"));
         }
-        write!(w, "\\}");
+        if_ok!(write!(w, "\\}"));
     }
-    write!(w, "
"); + if_ok!(write!(w, "
")); - document(w, it); + if_ok!(document(w, it)); if e.variants.len() > 0 { - write!(w, "

Variants

\n"); + if_ok!(write!(w, "

Variants

\n
")); for variant in e.variants.iter() { - write!(w, "
{name}", - name = variant.name.get_ref().as_slice()); - document(w, variant); + if_ok!(write!(w, "
{name}", + name = variant.name.get_ref().as_slice())); + if_ok!(document(w, variant)); match variant.inner { clean::VariantItem(ref var) => { match var.kind { clean::StructVariant(ref s) => { - write!(w, "

Fields

\n"); + if_ok!(write!(w, "

Fields

\n +
")); for field in s.fields.iter() { - write!(w, ""); + if_ok!(write!(w, "")); } - write!(w, "
\ - {f}", - v = variant.name.get_ref().as_slice(), - f = field.name.get_ref().as_slice()); - document(w, field); - write!(w, "
\ + {f}", + v = variant.name.get_ref().as_slice(), + f = field.name.get_ref().as_slice())); + if_ok!(document(w, field)); + if_ok!(write!(w, "
"); + if_ok!(write!(w, "
")); } _ => () } } _ => () } - write!(w, ""); + if_ok!(write!(w, "")); } - write!(w, ""); + if_ok!(write!(w, "")); } - render_methods(w, it); + if_ok!(render_methods(w, it)); + Ok(()) } fn render_struct(w: &mut Writer, it: &clean::Item, @@ -1305,54 +1320,59 @@ fn render_struct(w: &mut Writer, it: &clean::Item, fields: &[clean::Item], fields_stripped: bool, tab: &str, - structhead: bool) { - write!(w, "{}{}{}", - VisSpace(it.visibility), - if structhead {"struct "} else {""}, - it.name.get_ref().as_slice()); + structhead: bool) -> fmt::Result { + if_ok!(write!(w, "{}{}{}", + VisSpace(it.visibility), + if structhead {"struct "} else {""}, + it.name.get_ref().as_slice())); match g { - Some(g) => write!(w, "{}", *g), + Some(g) => if_ok!(write!(w, "{}", *g)), None => {} } match ty { doctree::Plain => { - write!(w, " \\{\n{}", tab); + if_ok!(write!(w, " \\{\n{}", tab)); for field in fields.iter() { match field.inner { clean::StructFieldItem(ref ty) => { - write!(w, " {}{}: {},\n{}", - VisSpace(field.visibility), - field.name.get_ref().as_slice(), - ty.type_, - tab); + if_ok!(write!(w, " {}{}: {},\n{}", + VisSpace(field.visibility), + field.name.get_ref().as_slice(), + ty.type_, + tab)); } _ => unreachable!() } } if fields_stripped { - write!(w, " // some fields omitted\n{}", tab); + if_ok!(write!(w, " // some fields omitted\n{}", tab)); } - write!(w, "\\}"); + if_ok!(write!(w, "\\}")); } doctree::Tuple | doctree::Newtype => { - write!(w, "("); + if_ok!(write!(w, "(")); for (i, field) in fields.iter().enumerate() { - if i > 0 { write!(w, ", ") } + if i > 0 { + if_ok!(write!(w, ", ")); + } match field.inner { clean::StructFieldItem(ref field) => { - write!(w, "{}", field.type_); + if_ok!(write!(w, "{}", field.type_)); } _ => unreachable!() } } - write!(w, ");"); + if_ok!(write!(w, ");")); + } + doctree::Unit => { + if_ok!(write!(w, ";")); } - doctree::Unit => { write!(w, ";"); } } + Ok(()) } -fn render_methods(w: &mut Writer, it: &clean::Item) { +fn render_methods(w: &mut Writer, it: &clean::Item) -> fmt::Result { local_data::get(cache_key, |cache| { let c = cache.unwrap().get(); match c.impls.find(&it.id) { @@ -1367,29 +1387,31 @@ fn render_methods(w: &mut Writer, it: &clean::Item) { let traits = traits.to_owned_vec(); if non_trait.len() > 0 { - write!(w, "

Methods

"); + if_ok!(write!(w, "

Methods

")); for &(ref i, ref dox) in non_trait.move_iter() { - render_impl(w, i, dox); + if_ok!(render_impl(w, i, dox)); } } if traits.len() > 0 { - write!(w, "

Trait \ - Implementations

"); + if_ok!(write!(w, "

Trait \ + Implementations

")); for &(ref i, ref dox) in traits.move_iter() { - render_impl(w, i, dox); + if_ok!(render_impl(w, i, dox)); } } } None => {} } + Ok(()) }) } -fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) { - write!(w, "

impl{} ", i.generics); +fn render_impl(w: &mut Writer, i: &clean::Impl, + dox: &Option<~str>) -> fmt::Result { + if_ok!(write!(w, "

impl{} ", i.generics)); let trait_id = match i.trait_ { Some(ref ty) => { - write!(w, "{} for ", *ty); + if_ok!(write!(w, "{} for ", *ty)); match *ty { clean::ResolvedPath { id, .. } => Some(id), _ => None, @@ -1397,32 +1419,32 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) { } None => None }; - write!(w, "{}

", i.for_); + if_ok!(write!(w, "{}

", i.for_)); match *dox { Some(ref dox) => { - write!(w, "
{}
", - Markdown(dox.as_slice())); + if_ok!(write!(w, "
{}
", + Markdown(dox.as_slice()))); } None => {} } - fn docmeth(w: &mut Writer, item: &clean::Item) -> bool { - write!(w, "

", - *item.name.get_ref()); - render_method(w, item, false); - write!(w, "

\n"); + fn docmeth(w: &mut Writer, item: &clean::Item) -> io::IoResult { + if_ok!(write!(w, "

", + *item.name.get_ref())); + if_ok!(render_method(w, item, false)); + if_ok!(write!(w, "

\n")); match item.doc_value() { Some(s) => { - write!(w, "
{}
", Markdown(s)); - true + if_ok!(write!(w, "
{}
", Markdown(s))); + Ok(true) } - None => false + None => Ok(false) } } - write!(w, "
"); + if_ok!(write!(w, "
")); for meth in i.methods.iter() { - if docmeth(w, meth) { + if if_ok!(docmeth(w, meth)) { continue } @@ -1431,7 +1453,7 @@ fn docmeth(w: &mut Writer, item: &clean::Item) -> bool { None => continue, Some(id) => id, }; - local_data::get(cache_key, |cache| { + if_ok!(local_data::get(cache_key, |cache| { let cache = cache.unwrap().get(); match cache.traits.find(&trait_id) { Some(t) => { @@ -1440,9 +1462,9 @@ fn docmeth(w: &mut Writer, item: &clean::Item) -> bool { Some(method) => { match method.item().doc_value() { Some(s) => { - write!(w, - "
{}
", - Markdown(s)); + if_ok!(write!(w, + "
{}
", + Markdown(s))); } None => {} } @@ -1452,7 +1474,8 @@ fn docmeth(w: &mut Writer, item: &clean::Item) -> bool { } None => {} } - }) + Ok(()) + })) } // If we've implemented a trait, then also emit documentation for all @@ -1460,7 +1483,7 @@ fn docmeth(w: &mut Writer, item: &clean::Item) -> bool { match trait_id { None => {} Some(id) => { - local_data::get(cache_key, |cache| { + if_ok!(local_data::get(cache_key, |cache| { let cache = cache.unwrap().get(); match cache.traits.find(&id) { Some(t) => { @@ -1471,50 +1494,56 @@ fn docmeth(w: &mut Writer, item: &clean::Item) -> bool { None => {} } - docmeth(w, method.item()); + if_ok!(docmeth(w, method.item())); } } None => {} } - }) + Ok(()) + })) } } - write!(w, "
"); + if_ok!(write!(w, "
")); + Ok(()) } -fn item_typedef(w: &mut Writer, it: &clean::Item, t: &clean::Typedef) { - write!(w, "
type {}{} = {};
", - it.name.get_ref().as_slice(), - t.generics, - t.type_); +fn item_typedef(w: &mut Writer, it: &clean::Item, + t: &clean::Typedef) -> fmt::Result { + if_ok!(write!(w, "
type {}{} = {};
", + it.name.get_ref().as_slice(), + t.generics, + t.type_)); - document(w, it); + document(w, it) } impl<'a> fmt::Show for Sidebar<'a> { - fn fmt(s: &Sidebar<'a>, fmt: &mut fmt::Formatter) { + fn fmt(s: &Sidebar<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { let cx = s.cx; let it = s.item; - write!(fmt.buf, "

"); + if_ok!(write!(fmt.buf, "

")); let len = cx.current.len() - if it.is_mod() {1} else {0}; for (i, name) in cx.current.iter().take(len).enumerate() { - if i > 0 { write!(fmt.buf, "&\\#8203;::") } - write!(fmt.buf, "{}", - cx.root_path.slice_to((cx.current.len() - i - 1) * 3), *name); + if i > 0 { + if_ok!(write!(fmt.buf, "&\\#8203;::")); + } + if_ok!(write!(fmt.buf, "{}", + cx.root_path.slice_to((cx.current.len() - i - 1) * 3), + *name)); } - write!(fmt.buf, "

"); + if_ok!(write!(fmt.buf, "

")); fn block(w: &mut Writer, short: &str, longty: &str, - cur: &clean::Item, cx: &Context) { + cur: &clean::Item, cx: &Context) -> fmt::Result { let items = match cx.sidebar.find_equiv(&short) { Some(items) => items.as_slice(), - None => return + None => return Ok(()) }; - write!(w, "

{}

", short, longty); + if_ok!(write!(w, "

{}

", short, longty)); for item in items.iter() { let class = if cur.name.get_ref() == item && short == shortty(cur) { "current" } else { "" }; - write!(w, " fmt::Show for Source<'a> { - fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) { + fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { let Source(s) = *s; let lines = s.lines().len(); let mut cols = 0; @@ -1566,13 +1597,14 @@ fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) { cols += 1; tmp /= 10; } - write!(fmt.buf, "
");
+        if_ok!(write!(fmt.buf, "
"));
         for i in range(1, lines + 1) {
-            write!(fmt.buf, "{0:1$u}\n", i, cols);
+            if_ok!(write!(fmt.buf, "{0:1$u}\n", i, cols));
         }
-        write!(fmt.buf, "
"); - write!(fmt.buf, "
");
-        write!(fmt.buf, "{}", Escape(s.as_slice()));
-        write!(fmt.buf, "
"); + if_ok!(write!(fmt.buf, "
")); + if_ok!(write!(fmt.buf, "
"));
+        if_ok!(write!(fmt.buf, "{}", Escape(s.as_slice())));
+        if_ok!(write!(fmt.buf, "
")); + Ok(()) } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f7a484e3d3e..fe989279e71 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -162,10 +162,16 @@ pub fn main_args(args: &[~str]) -> int { let output = matches.opt_str("o").map(|s| Path::new(s)); match matches.opt_str("w") { Some(~"html") | None => { - html::render::run(crate, output.unwrap_or(Path::new("doc"))) + match html::render::run(crate, output.unwrap_or(Path::new("doc"))) { + Ok(()) => {} + Err(e) => fail!("failed to generate documentation: {}", e), + } } Some(~"json") => { - json_output(crate, res, output.unwrap_or(Path::new("doc.json"))) + match json_output(crate, res, output.unwrap_or(Path::new("doc.json"))) { + Ok(()) => {} + Err(e) => fail!("failed to write json: {}", e), + } } Some(s) => { println!("unknown output format: {}", s); @@ -276,8 +282,8 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output { /// run over the deserialized output. fn json_input(input: &str) -> Result { let mut input = match File::open(&Path::new(input)) { - Some(f) => f, - None => return Err(format!("couldn't open {} for reading", input)), + Ok(f) => f, + Err(e) => return Err(format!("couldn't open {}: {}", input, e)), }; match json::from_reader(&mut input) { Err(s) => Err(s.to_str()), @@ -312,7 +318,8 @@ fn json_input(input: &str) -> Result { /// Outputs the crate/plugin json as a giant json blob at the specified /// destination. -fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) { +fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], + dst: Path) -> io::IoResult<()> { // { // "schema": version, // "crate": { parsed crate ... }, @@ -340,6 +347,7 @@ fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) { json.insert(~"crate", crate_json); json.insert(~"plugins", json::Object(plugins_json)); - let mut file = File::create(&dst).unwrap(); - json::Object(json).to_writer(&mut file); + let mut file = if_ok!(File::create(&dst)); + if_ok!(json::Object(json).to_writer(&mut file)); + Ok(()) } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 12874d1b502..9e3b217f69f 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -127,8 +127,8 @@ fn runtest(test: &str, cratename: &str, libs: HashSet) { let exe = outdir.path().join("rust_out"); let out = run::process_output(exe.as_str().unwrap(), []); match out { - None => fail!("couldn't run the test"), - Some(out) => { + Err(e) => fail!("couldn't run the test: {}", e), + Ok(out) => { if !out.status.success() { fail!("test executable failed:\n{}", str::from_utf8(out.error)); -- GitLab