Skip to content

Commit e624e30

Browse files
committed
try Cow<'static, str> for Text nodes.
This mostly just applies to smart quotes, which are unlikely to benefit hugely (small String optimisation?), but I'm interested in seeing how far we can go with Cow; what if we can avoid allocations entirely in some cases by referring to the input?
1 parent 067d417 commit e624e30

File tree

12 files changed

+90
-108
lines changed

12 files changed

+90
-108
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ fn replace_text(document: &str, orig_string: &str, replacement: &str) -> String
202202
for node in root.descendants() {
203203
if let NodeValue::Text(ref mut text) = node.data.borrow_mut().value {
204204
// If the node is a text node, perform the string replacement.
205-
*text = text.replace(orig_string, replacement)
205+
*text = text.to_mut().replace(orig_string, replacement).into()
206206
}
207207
}
208208

examples/iterator_replace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn replace_text(document: &str, orig_string: &str, replacement: &str) -> String
1313
for node in root.descendants() {
1414
if let NodeValue::Text(ref mut text) = node.data.borrow_mut().value {
1515
// If the node is a text node, replace `orig_string` with `replacement`.
16-
*text = text.replace(orig_string, replacement)
16+
*text = text.to_mut().replace(orig_string, replacement).into()
1717
}
1818
}
1919

examples/sample.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn large() {
2424
for node in root.descendants() {
2525
if let NodeValue::Text(ref mut text) = node.data.borrow_mut().value {
2626
// If the node is a text node, perform the string replacement.
27-
*text = text.replace(orig_string, replacement)
27+
*text = text.to_mut().replace(orig_string, replacement).into()
2828
}
2929
}
3030

examples/update-readme.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ fn main() -> Result<(), Box<dyn Error>> {
7474
}
7575
NodeValue::Text(ref mut t) => {
7676
if in_msrv {
77-
std::mem::swap(t, &mut msrv.to_string());
77+
std::mem::swap(t, &mut msrv.to_string().into());
7878
}
7979
}
8080
_ => {}

src/html.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,10 @@ pub fn format_document_with_formatter<'a, 'o, 'c: 'o, T>(
354354
let new_cr = match child_rendering {
355355
ChildRendering::Plain => {
356356
match node.data.borrow().value {
357-
NodeValue::Text(ref literal)
358-
| NodeValue::Code(NodeCode { ref literal, .. })
357+
NodeValue::Text(ref literal) => {
358+
context.escape(literal)?;
359+
}
360+
NodeValue::Code(NodeCode { ref literal, .. })
359361
| NodeValue::HtmlInline(ref literal) => {
360362
context.escape(literal)?;
361363
}
@@ -1609,9 +1611,8 @@ pub fn collect_text<'a>(node: &'a AstNode<'a>) -> String {
16091611
/// whitespace character.
16101612
pub fn collect_text_append<'a>(node: &'a AstNode<'a>, output: &mut String) {
16111613
match node.data.borrow().value {
1612-
NodeValue::Text(ref literal) | NodeValue::Code(NodeCode { ref literal, .. }) => {
1613-
output.push_str(literal)
1614-
}
1614+
NodeValue::Text(ref literal) => output.push_str(literal),
1615+
NodeValue::Code(NodeCode { ref literal, .. }) => output.push_str(literal),
16151616
NodeValue::LineBreak | NodeValue::SoftBreak => output.push(' '),
16161617
NodeValue::Math(NodeMath { ref literal, .. }) => output.push_str(literal),
16171618
_ => {

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
//!
3131
//! for node in root.descendants() {
3232
//! if let NodeValue::Text(ref mut text) = node.data.borrow_mut().value {
33-
//! *text = text.replace("pretty", "beautiful");
33+
//! *text = text.to_mut().replace("pretty", "beautiful").into()
3434
//! }
3535
//! }
3636
//!

src/nodes.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
//! The CommonMark AST.
22
3-
use crate::arena_tree::Node;
3+
use std::borrow::Cow;
44
use std::cell::RefCell;
55
use std::convert::TryFrom;
66

7-
#[cfg(feature = "shortcodes")]
8-
pub use crate::parser::shortcodes::NodeShortCode;
9-
7+
use crate::arena_tree::Node;
108
pub use crate::parser::alert::{AlertType, NodeAlert};
119
pub use crate::parser::math::NodeMath;
1210
pub use crate::parser::multiline_block_quote::NodeMultilineBlockQuote;
11+
#[cfg(feature = "shortcodes")]
12+
pub use crate::parser::shortcodes::NodeShortCode;
1313

1414
/// The core AST node enum.
1515
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -112,7 +112,7 @@ pub enum NodeValue {
112112

113113
/// **Inline**. [Textual content](https://github.github.com/gfm/#textual-content). All text
114114
/// in a document will be contained in a `Text` node.
115-
Text(String),
115+
Text(Cow<'static, str>),
116116

117117
/// **Block**. [Task list item](https://github.github.com/gfm/#task-list-items-extension-).
118118
/// The value is the symbol that was used in the brackets to mark a task item as checked, or
@@ -474,7 +474,7 @@ impl NodeValue {
474474
/// Return a reference to the text of a `Text` inline, if this node is one.
475475
///
476476
/// Convenience method.
477-
pub fn text(&self) -> Option<&String> {
477+
pub fn text(&self) -> Option<&Cow<'static, str>> {
478478
match *self {
479479
NodeValue::Text(ref t) => Some(t),
480480
_ => None,
@@ -484,7 +484,7 @@ impl NodeValue {
484484
/// Return a mutable reference to the text of a `Text` inline, if this node is one.
485485
///
486486
/// Convenience method.
487-
pub fn text_mut(&mut self) -> Option<&mut String> {
487+
pub fn text_mut(&mut self) -> Option<&mut Cow<'static, str>> {
488488
match *self {
489489
NodeValue::Text(ref mut t) => Some(t),
490490
_ => None,

src/parser/autolink.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,15 @@ pub(crate) fn process_email_autolinks<'a>(
9191
initial_end_col,
9292
)
9393
.into();
94-
let after = make_inline(arena, NodeValue::Text(remain.to_string()), asp);
94+
let after = make_inline(arena, NodeValue::Text(remain.into()), asp);
9595
post.insert_after(after);
9696

9797
let after_ast = &mut after.data.borrow_mut();
9898
process_email_autolinks(
9999
arena,
100100
after,
101101
match after_ast.value {
102-
NodeValue::Text(ref mut t) => t,
102+
NodeValue::Text(ref mut t) => t.to_mut(),
103103
_ => unreachable!(),
104104
},
105105
relaxed_autolinks,
@@ -209,7 +209,7 @@ fn email_match<'a>(
209209

210210
inl.append(make_inline(
211211
arena,
212-
NodeValue::Text(text.to_string()),
212+
NodeValue::Text(text.to_string().into()),
213213
(0, 1, 0, 1).into(),
214214
));
215215
Some((inl, rewind, rewind + link_end))
@@ -270,7 +270,7 @@ pub fn www_match<'a>(
270270

271271
inl.append(make_inline(
272272
subject.arena,
273-
NodeValue::Text(subject.input[i..link_end + i].into()),
273+
NodeValue::Text(subject.input[i..link_end + i].to_string().into()),
274274
(0, 1, 0, 1).into(),
275275
));
276276
Some((inl, 0, link_end))
@@ -436,7 +436,7 @@ pub fn url_match<'a>(
436436

437437
inl.append(make_inline(
438438
subject.arena,
439-
NodeValue::Text(url.to_string()),
439+
NodeValue::Text(url.to_string().into()),
440440
(0, 1, 0, 1).into(),
441441
));
442442
Some((inl, rewind, rewind + link_end))

0 commit comments

Comments
 (0)