1use rustc_span::RemapPathScopeComponents;
7use rustc_span::edition::Edition;
8use serde::Serialize;
9
10use super::make::DocTestWrapResult;
11use super::{BuildDocTestBuilder, ScrapedDocTest};
12use crate::config::Options as RustdocOptions;
13use crate::html::markdown;
14
15const FORMAT_VERSION: u32 = 2;
21
22#[derive(Serialize)]
23pub(crate) struct ExtractedDocTests {
24 format_version: u32,
25 doctests: Vec<ExtractedDocTest>,
26}
27
28impl ExtractedDocTests {
29 pub(crate) fn new() -> Self {
30 Self { format_version: FORMAT_VERSION, doctests: Vec::new() }
31 }
32
33 pub(crate) fn add_test(
34 &mut self,
35 scraped_test: ScrapedDocTest,
36 opts: &super::GlobalTestOptions,
37 options: &RustdocOptions,
38 ) {
39 let edition = scraped_test.edition(options);
40 self.add_test_with_edition(scraped_test, opts, edition)
41 }
42
43 pub(crate) fn add_test_with_edition(
45 &mut self,
46 scraped_test: ScrapedDocTest,
47 opts: &super::GlobalTestOptions,
48 edition: Edition,
49 ) {
50 let ScrapedDocTest { filename, line, langstr, text, name, global_crate_attrs, .. } =
51 scraped_test;
52
53 let doctest = BuildDocTestBuilder::new(&text)
54 .crate_name(&opts.crate_name)
55 .global_crate_attrs(global_crate_attrs)
56 .edition(edition)
57 .lang_str(&langstr)
58 .build(None);
59 let (wrapped, _size) = doctest.generate_unique_doctest(
60 &text,
61 langstr.test_harness,
62 opts,
63 Some(&opts.crate_name),
64 );
65 self.doctests.push(ExtractedDocTest {
66 file: filename.display(RemapPathScopeComponents::DOCUMENTATION).to_string(),
67 line,
68 doctest_attributes: langstr.into(),
69 doctest_code: match wrapped {
70 DocTestWrapResult::Valid { crate_level_code, wrapper, code } => Some(DocTest {
71 crate_level: crate_level_code,
72 code,
73 wrapper: wrapper.map(
74 |super::make::WrapperInfo { before, after, returns_result, .. }| {
75 WrapperInfo { before, after, returns_result }
76 },
77 ),
78 }),
79 DocTestWrapResult::SyntaxError { .. } => None,
80 },
81 original_code: text,
82 name,
83 });
84 }
85
86 #[cfg(test)]
87 pub(crate) fn doctests(&self) -> &[ExtractedDocTest] {
88 &self.doctests
89 }
90}
91
92#[derive(Serialize)]
93pub(crate) struct WrapperInfo {
94 before: String,
95 after: String,
96 returns_result: bool,
97}
98
99#[derive(Serialize)]
100pub(crate) struct DocTest {
101 crate_level: String,
102 code: String,
103 pub(crate) wrapper: Option<WrapperInfo>,
109}
110
111#[derive(Serialize)]
112pub(crate) struct ExtractedDocTest {
113 file: String,
114 line: usize,
115 doctest_attributes: LangString,
116 original_code: String,
117 pub(crate) doctest_code: Option<DocTest>,
119 name: String,
120}
121
122#[derive(Serialize)]
123pub(crate) enum Ignore {
124 All,
125 None,
126 Some(Vec<String>),
127}
128
129impl From<markdown::Ignore> for Ignore {
130 fn from(original: markdown::Ignore) -> Self {
131 match original {
132 markdown::Ignore::All => Self::All,
133 markdown::Ignore::None => Self::None,
134 markdown::Ignore::Some(values) => Self::Some(values),
135 }
136 }
137}
138
139#[derive(Serialize)]
140struct LangString {
141 pub(crate) original: String,
142 pub(crate) should_panic: bool,
143 pub(crate) no_run: bool,
144 pub(crate) ignore: Ignore,
145 pub(crate) rust: bool,
146 pub(crate) test_harness: bool,
147 pub(crate) compile_fail: bool,
148 pub(crate) standalone_crate: bool,
149 pub(crate) error_codes: Vec<String>,
150 pub(crate) edition: Option<String>,
151 pub(crate) added_css_classes: Vec<String>,
152 pub(crate) unknown: Vec<String>,
153}
154
155impl From<markdown::LangString> for LangString {
156 fn from(original: markdown::LangString) -> Self {
157 let markdown::LangString {
158 original,
159 should_panic,
160 no_run,
161 ignore,
162 rust,
163 test_harness,
164 compile_fail,
165 standalone_crate,
166 error_codes,
167 edition,
168 added_classes,
169 unknown,
170 } = original;
171
172 Self {
173 original,
174 should_panic,
175 no_run,
176 ignore: ignore.into(),
177 rust,
178 test_harness,
179 compile_fail,
180 standalone_crate,
181 error_codes,
182 edition: edition.map(|edition| edition.to_string()),
183 added_css_classes: added_classes,
184 unknown,
185 }
186 }
187}