sync_readme/content/rustdoc/mod.rs
1use anyhow::Context;
2use rustdoc_types::{Crate, Item};
3
4use crate::config::Package;
5
6mod code_block;
7mod heading;
8mod intra_link;
9
10pub(super) fn create(package: &Package) -> anyhow::Result<String> {
11 let doc_string = std::fs::read_to_string(&package.rustdoc_json).context("read rustdoc")?;
12 let doc: Crate = serde_json::from_str(&doc_string).context("parse rustdoc")?;
13 let root = doc.index.get(&doc.root).unwrap();
14 let local_html_root_url = package.metadata.rustdoc_html_root_url.clone().unwrap_or_else(|| {
15 format!(
16 "https://docs.rs/{}/{}",
17 package.name,
18 doc.crate_version.as_ref().unwrap_or(&package.version)
19 )
20 });
21
22 let root_doc = extract_doc(root);
23 let mut parser = intra_link::Parser::new(&doc, root, &local_html_root_url, &package.metadata.rustdoc_mappings);
24 let events = parser.events(&root_doc);
25 let events = heading::convert(events);
26 let events = code_block::convert(events);
27
28 let mut buf = String::with_capacity(root_doc.len());
29 pulldown_cmark_to_cmark::cmark(events, &mut buf).unwrap();
30
31 if !buf.is_empty() && !buf.ends_with('\n') {
32 buf.push('\n');
33 }
34
35 Ok(buf)
36}
37
38fn extract_doc(item: &Item) -> String {
39 item.docs.clone().unwrap_or_default()
40}