diff --git a/Cargo.toml b/Cargo.toml index 359bf368..9c6d93df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,12 +31,6 @@ lazy_static = "^1.4" libc = { version = "^0.2", optional = true } parking_lot = "^0.11" protobuf = { version = "^2.0", optional = true } -# DO NOT RELY ON THIS FEATURE TO STAY AVAILABLE! -# It doesn't change the API. -# Intended for testing/debugging only. -# It can affect the performance. -# Report any interesting findings, especially if the performance IMPROVES with `regex` turned ON. -regex = { version = "^1.3", optional = true } memchr = "^2.3" reqwest = { version = "^0.11", features = ["blocking"], optional = true } thiserror = "^1.0" diff --git a/src/desc.rs b/src/desc.rs index 58f58606..e5c0f9a0 100644 --- a/src/desc.rs +++ b/src/desc.rs @@ -10,66 +10,40 @@ use crate::errors::{Error, Result}; use crate::metrics::SEPARATOR_BYTE; use crate::proto::LabelPair; -#[cfg(not(feature = "regex"))] -mod validation { - fn matches_charset_without_colon(c: char) -> bool { - c.is_ascii_alphabetic() || c == '_' - } - - fn matches_charset_with_colon(c: char) -> bool { - matches_charset_without_colon(c) || c == ':' - } - - /// Equivalent to regex `^[?][?0-9]*$` where `?` denotes char set as validated by `charset_validator`. - fn is_valid_ident bool>(input: &str, mut charset_validator: F) -> bool { - let mut chars = input.chars(); - let zeroth = chars.next(); - zeroth - .and_then(|zeroth| { - if charset_validator(zeroth) { - Some(chars.all(|c| charset_validator(c) || c.is_digit(10))) - } else { - None - } - }) - .unwrap_or(false) - } - - // Details of required format are at - // https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels - pub(super) fn is_valid_metric_name(name: &str) -> bool { - is_valid_ident(name, matches_charset_with_colon) - } - - pub(super) fn is_valid_label_name(name: &str) -> bool { - is_valid_ident(name, matches_charset_without_colon) - } +// [a-zA-Z_] +fn matches_charset_without_colon(c: char) -> bool { + c.is_ascii_alphabetic() || c == '_' } -#[cfg(feature = "regex")] -mod validation { - use regex::Regex; - - pub(super) fn is_valid_metric_name(name: &str) -> bool { - lazy_static! { - static ref VALIDATOR: Regex = - Regex::new("^[a-zA-Z_:][a-zA-Z0-9_:]*$").expect("Regex to be valid."); - } - - VALIDATOR.is_match(name) - } +// [a-zA-Z_:] +fn matches_charset_with_colon(c: char) -> bool { + matches_charset_without_colon(c) || c == ':' +} - pub(super) fn is_valid_label_name(name: &str) -> bool { - lazy_static! { - static ref VALIDATOR: Regex = - Regex::new("^[a-zA-Z_][a-zA-Z0-9_]*$").expect("Regex to be valid."); - } +// Equivalent to regex ^[?][?0-9]*$ where ? denotes char set as validated by charset_validator +fn is_valid_ident bool>(input: &str, mut charset_validator: F) -> bool { + let mut chars = input.chars(); + let zeroth = chars.next(); + zeroth + .and_then(|zeroth| { + if charset_validator(zeroth) { + Some(chars.all(|c| charset_validator(c) || c.is_digit(10))) + } else { + None + } + }) + .unwrap_or(false) +} - VALIDATOR.is_match(name) - } +// Details of required format are at +// https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels +pub(super) fn is_valid_metric_name(name: &str) -> bool { + is_valid_ident(name, matches_charset_with_colon) } -use validation::*; +pub(super) fn is_valid_label_name(name: &str) -> bool { + is_valid_ident(name, matches_charset_without_colon) +} /// The descriptor used by every Prometheus [`Metric`](crate::core::Metric). It is essentially /// the immutable meta-data of a metric. The normal metric implementations diff --git a/src/encoder/text.rs b/src/encoder/text.rs index cb6b79cb..17516bc0 100644 --- a/src/encoder/text.rs +++ b/src/encoder/text.rs @@ -215,27 +215,6 @@ fn label_pairs_to_text( Ok(()) } -#[cfg(feature = "regex")] -fn find_first_occurence(v: &str, include_double_quote: bool) -> Option { - use regex::{Match, Regex}; - - // Regex compilation is expensive. Use `lazy_static` to compile the regexes - // once per process lifetime and not once per function invocation. - lazy_static! { - static ref ESCAPER: Regex = Regex::new("(\\\\|\n)").expect("Regex to be valid."); - static ref QUOTED_ESCAPER: Regex = Regex::new("(\\\\|\n|\")").expect("Regex to be valid."); - } - - if include_double_quote { - QUOTED_ESCAPER.find(v) - } else { - ESCAPER.find(v) - } - .as_ref() - .map(Match::start) -} - -#[cfg(not(feature = "regex"))] fn find_first_occurence(v: &str, include_double_quote: bool) -> Option { if include_double_quote { memchr::memchr3(b'\\', b'\n', b'\"', v.as_bytes())