diff --git a/Cargo.toml b/Cargo.toml index b18c80654a0..032b9b54810 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ dirs = "4.0" getopts = "0.2" ignore = "0.4" itertools = "0.11" +lazy_static = "1.4" regex = "1.7" serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0" diff --git a/src/comment.rs b/src/comment.rs index 099e12f86dd..7d1b0384431 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -3,6 +3,8 @@ use std::{borrow::Cow, iter}; use itertools::{multipeek, MultiPeek}; +use lazy_static::lazy_static; +use regex::Regex; use rustc_span::Span; use crate::config::Config; @@ -15,6 +17,17 @@ use crate::utils::{ }; use crate::{ErrorKind, FormattingError}; +lazy_static! { + /// A regex matching reference doc links. + /// + /// ```markdown + /// /// An [example]. + /// /// + /// /// [example]: this::is::a::link + /// ``` + static ref REFERENCE_LINK_URL: Regex = Regex::new(r"^\[.+\]\s?:").unwrap(); +} + fn is_custom_comment(comment: &str) -> bool { if !comment.starts_with("//") { false @@ -967,16 +980,11 @@ fn trim_custom_comment_prefix(s: &str) -> String { /// Returns `true` if the given string MAY include URLs or alike. fn has_url(s: &str) -> bool { // This function may return false positive, but should get its job done in most cases. - // The regex is indended to capture text such as the below. - // - // /// An [example]. - // /// - // /// [example]: this::is::a::link s.contains("https://") || s.contains("http://") || s.contains("ftp://") || s.contains("file://") - || static_regex!(r"^\[.+\]\s?:").is_match(s) + || REFERENCE_LINK_URL.is_match(s) } /// Returns true if the given string may be part of a Markdown table. diff --git a/src/lib.rs b/src/lib.rs index e07720f30ca..877d057a34b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,9 @@ #![allow(clippy::match_like_matches_macro)] #![allow(unreachable_pub)] +#[cfg(test)] +#[macro_use] +extern crate lazy_static; #[macro_use] extern crate tracing; @@ -59,13 +62,6 @@ pub use crate::rustfmt_diff::{ModifiedChunk, ModifiedLines}; #[macro_use] mod utils; -macro_rules! static_regex { - ($re:literal) => {{ - static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new(); - RE.get_or_init(|| ::regex::Regex::new($re).unwrap()) - }}; -} - mod attr; mod chains; mod closures; diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs index a195b306da3..80b61c88a00 100644 --- a/src/test/configuration_snippet.rs +++ b/src/test/configuration_snippet.rs @@ -24,6 +24,19 @@ impl ConfigurationSection { fn get_section>( file: &mut Enumerate, ) -> Option { + lazy_static! { + static ref CONFIG_NAME_REGEX: regex::Regex = + regex::Regex::new(r"^## `([^`]+)`").expect("failed creating configuration pattern"); + // Configuration values, which will be passed to `from_str`: + // + // - must be prefixed with `####` + // - must be wrapped in backticks + // - may by wrapped in double quotes (which will be stripped) + static ref CONFIG_VALUE_REGEX: regex::Regex = + regex::Regex::new(r#"^#### `"?([^`]+?)"?`"#) + .expect("failed creating configuration value pattern"); + } + loop { match file.next() { Some((i, line)) => { @@ -40,14 +53,9 @@ impl ConfigurationSection { let start_line = (i + 2) as u32; return Some(ConfigurationSection::CodeBlock((block, start_line))); - } else if let Some(c) = static_regex!(r"^## `([^`]+)`").captures(&line) { + } else if let Some(c) = CONFIG_NAME_REGEX.captures(&line) { return Some(ConfigurationSection::ConfigName(String::from(&c[1]))); - } else if let Some(c) = static_regex!(r#"^#### `"?([^`]+?)"?`"#).captures(&line) { - // Configuration values, which will be passed to `from_str` - // - // - must be prefixed with `####` - // - must be wrapped in backticks - // - may by wrapped in double quotes (which will be stripped) + } else if let Some(c) = CONFIG_VALUE_REGEX.captures(&line) { return Some(ConfigurationSection::ConfigValue(String::from(&c[1]))); } }