Skip to content

Commit 09b51fc

Browse files
authored
Merge pull request #589 from kivikakk/push-tyympltyqtwm
html: remove some panics on unusual ASTs, and document others.
2 parents 8f76b4d + 7e99334 commit 09b51fc

File tree

4 files changed

+170
-48
lines changed

4 files changed

+170
-48
lines changed

flake.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
pkgs.rust-analyzer
9898
pkgs.clippy
9999
pkgs.cargo-fuzz
100+
pkgs.cargo-nextest
100101
pkgs.python3
101102
pkgs.re2c
102103
pkgs.hyperfine

src/html.rs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ fn render_code<'a, T>(
495495
entering: bool,
496496
) -> io::Result<ChildRendering> {
497497
let NodeValue::Code(NodeCode { ref literal, .. }) = node.data.borrow().value else {
498-
panic!()
498+
unreachable!()
499499
};
500500

501501
if entering {
@@ -515,7 +515,7 @@ fn render_code_block<'a, T>(
515515
entering: bool,
516516
) -> io::Result<ChildRendering> {
517517
let NodeValue::CodeBlock(ref ncb) = node.data.borrow().value else {
518-
panic!()
518+
unreachable!()
519519
};
520520

521521
if entering {
@@ -623,7 +623,7 @@ fn render_heading<'a, T>(
623623
entering: bool,
624624
) -> io::Result<ChildRendering> {
625625
let NodeValue::Heading(ref nch) = node.data.borrow().value else {
626-
panic!()
626+
unreachable!()
627627
};
628628

629629
match context.plugins.render.heading_adapter {
@@ -682,7 +682,7 @@ fn render_html_block<'a, T>(
682682
entering: bool,
683683
) -> io::Result<ChildRendering> {
684684
let NodeValue::HtmlBlock(ref nhb) = node.data.borrow().value else {
685-
panic!()
685+
unreachable!()
686686
};
687687

688688
// No sourcepos.
@@ -710,7 +710,7 @@ fn render_html_inline<'a, T>(
710710
entering: bool,
711711
) -> io::Result<ChildRendering> {
712712
let NodeValue::HtmlInline(ref literal) = node.data.borrow().value else {
713-
panic!()
713+
unreachable!()
714714
};
715715

716716
// No sourcepos.
@@ -737,7 +737,7 @@ fn render_image<'a, T>(
737737
entering: bool,
738738
) -> io::Result<ChildRendering> {
739739
let NodeValue::Image(ref nl) = node.data.borrow().value else {
740-
panic!()
740+
unreachable!()
741741
};
742742

743743
if entering {
@@ -813,7 +813,7 @@ fn render_link<'a, T>(
813813
entering: bool,
814814
) -> io::Result<ChildRendering> {
815815
let NodeValue::Link(ref nl) = node.data.borrow().value else {
816-
panic!()
816+
unreachable!()
817817
};
818818

819819
let parent_node = node.parent();
@@ -856,7 +856,7 @@ fn render_list<'a, T>(
856856
entering: bool,
857857
) -> io::Result<ChildRendering> {
858858
let NodeValue::List(ref nl) = node.data.borrow().value else {
859-
panic!()
859+
unreachable!()
860860
};
861861

862862
if entering {
@@ -920,7 +920,8 @@ fn render_paragraph<'a, T>(
920920
render_sourcepos(context, node)?;
921921
context.write_all(b">")?;
922922
} else {
923-
if let NodeValue::FootnoteDefinition(nfd) = &node.parent().unwrap().data.borrow().value
923+
if let Some(NodeValue::FootnoteDefinition(nfd)) =
924+
&node.parent().map(|n| n.data.borrow().value.clone())
924925
{
925926
if node.next_sibling().is_none() {
926927
context.write_all(b" ")?;
@@ -980,7 +981,7 @@ fn render_text<'a, T>(
980981
entering: bool,
981982
) -> io::Result<ChildRendering> {
982983
let NodeValue::Text(ref literal) = node.data.borrow().value else {
983-
panic!()
984+
unreachable!()
984985
};
985986

986987
// Nowhere to put sourcepos.
@@ -1014,7 +1015,7 @@ fn render_footnote_definition<'a, T>(
10141015
entering: bool,
10151016
) -> io::Result<ChildRendering> {
10161017
let NodeValue::FootnoteDefinition(ref nfd) = node.data.borrow().value else {
1017-
panic!()
1018+
unreachable!()
10181019
};
10191020

10201021
if entering {
@@ -1045,7 +1046,7 @@ fn render_footnote_reference<'a, T>(
10451046
entering: bool,
10461047
) -> io::Result<ChildRendering> {
10471048
let NodeValue::FootnoteReference(ref nfr) = node.data.borrow().value else {
1048-
panic!()
1049+
unreachable!()
10491050
};
10501051

10511052
if entering {
@@ -1093,10 +1094,10 @@ fn render_table<'a, T>(
10931094
render_sourcepos(context, node)?;
10941095
context.write_all(b">\n")?;
10951096
} else {
1096-
if !node
1097+
if let Some(true) = node
10971098
.last_child()
1098-
.unwrap()
1099-
.same_node(node.first_child().unwrap())
1099+
.map(|n| !n.same_node(node.first_child().unwrap()))
1100+
// node.first_child() guaranteed to exist in block since last_child does!
11001101
{
11011102
context.cr()?;
11021103
context.write_all(b"</tbody>\n")?;
@@ -1113,16 +1114,24 @@ fn render_table_cell<'a, T>(
11131114
node: &'a AstNode<'a>,
11141115
entering: bool,
11151116
) -> io::Result<ChildRendering> {
1116-
let row = &node.parent().unwrap().data.borrow().value;
1117+
let Some(row_node) = node.parent() else {
1118+
panic!("rendered a table cell without a containing table row");
1119+
};
1120+
let row = &row_node.data.borrow().value;
11171121
let in_header = match *row {
11181122
NodeValue::TableRow(header) => header,
1119-
_ => panic!(),
1123+
_ => panic!("rendered a table cell contained by something other than a table row"),
11201124
};
11211125

1122-
let table = &node.parent().unwrap().parent().unwrap().data.borrow().value;
1126+
let Some(table_node) = row_node.parent() else {
1127+
panic!("rendered a table cell without a containing table");
1128+
};
1129+
let table = &table_node.data.borrow().value;
11231130
let alignments = match *table {
11241131
NodeValue::Table(NodeTable { ref alignments, .. }) => alignments,
1125-
_ => panic!(),
1132+
_ => {
1133+
panic!("rendered a table cell in a table row contained by something other than a table")
1134+
}
11261135
};
11271136

11281137
if entering {
@@ -1135,7 +1144,7 @@ fn render_table_cell<'a, T>(
11351144
render_sourcepos(context, node)?;
11361145
}
11371146

1138-
let mut start = node.parent().unwrap().first_child().unwrap();
1147+
let mut start = row_node.first_child().unwrap(); // guaranteed to exist because `node' itself does!
11391148
let mut i = 0;
11401149
while !start.same_node(node) {
11411150
i += 1;
@@ -1171,7 +1180,7 @@ fn render_table_row<'a, T>(
11711180
entering: bool,
11721181
) -> io::Result<ChildRendering> {
11731182
let NodeValue::TableRow(header) = node.data.borrow().value else {
1174-
panic!()
1183+
unreachable!()
11751184
};
11761185

11771186
if entering {
@@ -1204,7 +1213,7 @@ fn render_task_item<'a, T>(
12041213
entering: bool,
12051214
) -> io::Result<ChildRendering> {
12061215
let NodeValue::TaskItem(symbol) = node.data.borrow().value else {
1207-
panic!()
1216+
unreachable!()
12081217
};
12091218

12101219
if entering {
@@ -1238,7 +1247,7 @@ fn render_alert<'a, T>(
12381247
entering: bool,
12391248
) -> io::Result<ChildRendering> {
12401249
let NodeValue::Alert(ref alert) = node.data.borrow().value else {
1241-
panic!()
1250+
unreachable!()
12421251
};
12431252

12441253
if entering {
@@ -1345,7 +1354,7 @@ fn render_escaped_tag<'a, T>(
13451354
_entering: bool,
13461355
) -> io::Result<ChildRendering> {
13471356
let NodeValue::EscapedTag(ref net) = node.data.borrow().value else {
1348-
panic!()
1357+
unreachable!()
13491358
};
13501359

13511360
// Nowhere to put sourcepos.
@@ -1376,7 +1385,7 @@ pub fn render_math<'a, T>(
13761385
..
13771386
}) = node.data.borrow().value
13781387
else {
1379-
panic!()
1388+
unreachable!()
13801389
};
13811390

13821391
if entering {
@@ -1460,7 +1469,7 @@ fn render_raw<'a, T>(
14601469
entering: bool,
14611470
) -> io::Result<ChildRendering> {
14621471
let NodeValue::Raw(ref literal) = node.data.borrow().value else {
1463-
panic!()
1472+
unreachable!()
14641473
};
14651474

14661475
// No sourcepos.
@@ -1478,7 +1487,7 @@ fn render_short_code<'a, T>(
14781487
entering: bool,
14791488
) -> io::Result<ChildRendering> {
14801489
let NodeValue::ShortCode(ref nsc) = node.data.borrow().value else {
1481-
panic!()
1490+
unreachable!()
14821491
};
14831492

14841493
// Nowhere to put sourcepos.
@@ -1559,7 +1568,7 @@ fn render_wiki_link<'a, T>(
15591568
entering: bool,
15601569
) -> io::Result<ChildRendering> {
15611570
let NodeValue::WikiLink(ref nl) = node.data.borrow().value else {
1562-
panic!()
1571+
unreachable!()
15631572
};
15641573

15651574
if entering {

src/tests.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ mod front_matter;
1818
mod fuzz;
1919
mod greentext;
2020
mod header_ids;
21+
#[path = "tests/html.rs"]
22+
mod html_;
2123
mod math;
2224
mod multiline_block_quotes;
2325
mod options;
@@ -146,37 +148,37 @@ fn remove_sourcepos(i: &str) -> String {
146148
}
147149

148150
macro_rules! html_opts {
149-
([$($optclass:ident.$optname:ident),*], $lhs:expr, $rhs:expr) => {
150-
html_opts!([$($optclass.$optname),*], $lhs, $rhs,)
151+
([$($optclass:ident.$optname:ident),*], $input:expr, $expected:expr) => {
152+
html_opts!([$($optclass.$optname),*], $input, $expected,)
151153
};
152-
([$($optclass:ident.$optname:ident = $val:expr),*], $lhs:expr, $rhs:expr) => {
153-
html_opts!([$($optclass.$optname = $val),*], $lhs, $rhs,)
154+
([$($optclass:ident.$optname:ident = $val:expr),*], $input:expr, $expected:expr) => {
155+
html_opts!([$($optclass.$optname = $val),*], $input, $expected,)
154156
};
155-
([$($optclass:ident.$optname:ident),*], $lhs:expr, $rhs:expr,) => {
156-
html_opts!([$($optclass.$optname),*], $lhs, $rhs, roundtrip)
157+
([$($optclass:ident.$optname:ident),*], $input:expr, $expected:expr,) => {
158+
html_opts!([$($optclass.$optname),*], $input, $expected, roundtrip)
157159
};
158-
([$($optclass:ident.$optname:ident = $val:expr),*], $lhs:expr, $rhs:expr,) => {
159-
html_opts!([$($optclass.$optname = $val),*], $lhs, $rhs, roundtrip)
160+
([$($optclass:ident.$optname:ident = $val:expr),*], $input:expr, $expected:expr,) => {
161+
html_opts!([$($optclass.$optname = $val),*], $input, $expected, roundtrip)
160162
};
161-
([$($optclass:ident.$optname:ident),*], $lhs:expr, $rhs:expr, $rt:ident) => {
162-
html_opts!([$($optclass.$optname),*], $lhs, $rhs, $rt,)
163+
([$($optclass:ident.$optname:ident),*], $input:expr, $expected:expr, $rt:ident) => {
164+
html_opts!([$($optclass.$optname),*], $input, $expected, $rt,)
163165
};
164-
([$($optclass:ident.$optname:ident = $val:expr),*], $lhs:expr, $rhs:expr, $rt:ident) => {
165-
html_opts!([$($optclass.$optname = $val),*], $lhs, $rhs, $rt,)
166+
([$($optclass:ident.$optname:ident = $val:expr),*], $input:expr, $expected:expr, $rt:ident) => {
167+
html_opts!([$($optclass.$optname = $val),*], $input, $expected, $rt,)
166168
};
167-
([$($optclass:ident.$optname:ident),*], $lhs:expr, $rhs:expr, roundtrip,) => {
168-
html_opts!([$($optclass.$optname = true),*], $lhs, $rhs, roundtrip,)
169+
([$($optclass:ident.$optname:ident),*], $input:expr, $expected:expr, roundtrip,) => {
170+
html_opts!([$($optclass.$optname = true),*], $input, $expected, roundtrip,)
169171
};
170-
([$($optclass:ident.$optname:ident = $val:expr),*], $lhs:expr, $rhs:expr, roundtrip,) => {
171-
$crate::tests::html_opts_i($lhs, $rhs, true, |opts| {
172+
([$($optclass:ident.$optname:ident = $val:expr),*], $input:expr, $expected:expr, roundtrip,) => {
173+
$crate::tests::html_opts_i($input, $expected, true, |opts| {
172174
$(opts.$optclass.$optname = $val;)*
173175
});
174176
};
175-
([$($optclass:ident.$optname:ident),*], $lhs:expr, $rhs:expr, no_roundtrip,) => {
176-
html_opts!([$($optclass.$optname = true),*], $lhs, $rhs, no_roundtrip,)
177+
([$($optclass:ident.$optname:ident),*], $input:expr, $expected:expr, no_roundtrip,) => {
178+
html_opts!([$($optclass.$optname = true),*], $input, $expected, no_roundtrip,)
177179
};
178-
([$($optclass:ident.$optname:ident = $val:expr),*], $lhs:expr, $rhs:expr, no_roundtrip,) => {
179-
$crate::tests::html_opts_i($lhs, $rhs, false, |opts| {
180+
([$($optclass:ident.$optname:ident = $val:expr),*], $input:expr, $expected:expr, no_roundtrip,) => {
181+
$crate::tests::html_opts_i($input, $expected, false, |opts| {
180182
$(opts.$optclass.$optname = $val;)*
181183
});
182184
};

0 commit comments

Comments
 (0)