@@ -39,6 +39,7 @@ crate use span_map::{collect_spans_and_sources, LinkFromSrc};
3939use std:: collections:: VecDeque ;
4040use std:: default:: Default ;
4141use std:: fmt;
42+ use std:: fs;
4243use std:: path:: PathBuf ;
4344use std:: str;
4445use std:: string:: ToString ;
@@ -68,6 +69,8 @@ use crate::html::format::{
6869 print_generic_bounds, print_where_clause, Buffer , HrefError , PrintWithSpace ,
6970} ;
7071use crate :: html:: markdown:: { HeadingOffset , Markdown , MarkdownHtml , MarkdownSummaryLine } ;
72+ use crate :: html:: sources;
73+ use crate :: scrape_examples:: FnCallLocations ;
7174
7275/// A pair of name and its optional document.
7376crate type NameDoc = ( String , Option < String > ) ;
@@ -584,6 +587,13 @@ fn document_full_inner(
584587 render_markdown ( w, cx, & s, item. links ( cx) , heading_offset) ;
585588 }
586589 }
590+
591+ match & * item. kind {
592+ clean:: ItemKind :: FunctionItem ( f) | clean:: ItemKind :: MethodItem ( f, _) => {
593+ render_call_locations ( w, cx, & f. call_locations ) ;
594+ }
595+ _ => { }
596+ }
587597}
588598
589599/// Add extra information about an item such as:
@@ -2440,3 +2450,88 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
24402450 }
24412451 out
24422452}
2453+
2454+ fn render_call_locations (
2455+ w : & mut Buffer ,
2456+ cx : & Context < ' _ > ,
2457+ call_locations : & Option < FnCallLocations > ,
2458+ ) {
2459+ let call_locations = match call_locations. as_ref ( ) {
2460+ Some ( call_locations) => call_locations,
2461+ None => {
2462+ return ;
2463+ }
2464+ } ;
2465+
2466+ let filtered_locations: Vec < _ > = call_locations
2467+ . iter ( )
2468+ . filter_map ( |( file, locs) | {
2469+ // TODO(wcrichto): file I/O should be cached
2470+ let mut contents = match fs:: read_to_string ( & file) {
2471+ Ok ( contents) => contents,
2472+ Err ( e) => {
2473+ eprintln ! ( "Failed to read file {}" , e) ;
2474+ return None ;
2475+ }
2476+ } ;
2477+
2478+ // Remove the utf-8 BOM if any
2479+ if contents. starts_with ( '\u{feff}' ) {
2480+ contents. drain ( ..3 ) ;
2481+ }
2482+
2483+ Some ( ( file, contents, locs) )
2484+ } )
2485+ . collect ( ) ;
2486+
2487+ let n_examples = filtered_locations. len ( ) ;
2488+ if n_examples == 0 {
2489+ return ;
2490+ }
2491+
2492+ let id = cx. id_map . borrow_mut ( ) . derive ( "scraped-examples" ) ;
2493+ write ! (
2494+ w,
2495+ r##"<div class="docblock scraped-example-list">
2496+ <h1 id="scraped-examples" class="small-section-header">
2497+ <a href="#{}">Uses found in <code>examples/</code></a>
2498+ </h1>"## ,
2499+ id
2500+ ) ;
2501+
2502+ let write_example = |w : & mut Buffer , ( file, contents, locs) : ( & String , String , _ ) | {
2503+ let ex_title = match cx. shared . repository_url . as_ref ( ) {
2504+ Some ( url) => format ! (
2505+ r#"<a href="{url}/{file}" target="_blank">{file}</a>"# ,
2506+ file = file,
2507+ url = url
2508+ ) ,
2509+ None => file. clone ( ) ,
2510+ } ;
2511+ let edition = cx. shared . edition ( ) ;
2512+ write ! (
2513+ w,
2514+ r#"<div class="scraped-example" data-code="{code}" data-locs="{locations}">
2515+ <strong>{title}</strong>
2516+ <div class="code-wrapper">"# ,
2517+ code = contents. replace( "\" " , """ ) ,
2518+ locations = serde_json:: to_string( & locs) . unwrap( ) ,
2519+ title = ex_title,
2520+ ) ;
2521+ write ! ( w, r#"<span class="prev">≺</span> <span class="next">≻</span>"# ) ;
2522+ write ! ( w, r#"<span class="expand">↕</span>"# ) ;
2523+ sources:: print_src ( w, & contents, edition) ;
2524+ write ! ( w, "</div></div>" ) ;
2525+ } ;
2526+
2527+ let mut it = filtered_locations. into_iter ( ) ;
2528+ write_example ( w, it. next ( ) . unwrap ( ) ) ;
2529+
2530+ if n_examples > 1 {
2531+ write ! ( w, r#"<div class="more-scraped-examples hidden">"# ) ;
2532+ it. for_each ( |ex| write_example ( w, ex) ) ;
2533+ write ! ( w, "</div>" ) ;
2534+ }
2535+
2536+ write ! ( w, "</div>" ) ;
2537+ }
0 commit comments