@@ -39,6 +39,7 @@ crate use span_map::{collect_spans_and_sources, LinkFromSrc};
39
39
use std:: collections:: VecDeque ;
40
40
use std:: default:: Default ;
41
41
use std:: fmt;
42
+ use std:: fs;
42
43
use std:: path:: PathBuf ;
43
44
use std:: str;
44
45
use std:: string:: ToString ;
@@ -68,6 +69,8 @@ use crate::html::format::{
68
69
print_generic_bounds, print_where_clause, Buffer , HrefError , PrintWithSpace ,
69
70
} ;
70
71
use crate :: html:: markdown:: { HeadingOffset , Markdown , MarkdownHtml , MarkdownSummaryLine } ;
72
+ use crate :: html:: sources;
73
+ use crate :: scrape_examples:: FnCallLocations ;
71
74
72
75
/// A pair of name and its optional document.
73
76
crate type NameDoc = ( String , Option < String > ) ;
@@ -584,6 +587,13 @@ fn document_full_inner(
584
587
render_markdown ( w, cx, & s, item. links ( cx) , heading_offset) ;
585
588
}
586
589
}
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
+ }
587
597
}
588
598
589
599
/// 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> {
2440
2450
}
2441
2451
out
2442
2452
}
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