Skip to content

Commit

Permalink
Removed regex entirely
Browse files Browse the repository at this point in the history
This removes `regex` as suggested in the PR.

Signed-off-by: Martin Habovstiak <[email protected]>
  • Loading branch information
Kixunil committed Feb 2, 2021
1 parent 657f61f commit 7a3936d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 81 deletions.
6 changes: 0 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
82 changes: 28 additions & 54 deletions src/desc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<F: FnMut(char) -> 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<F: FnMut(char) -> 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
Expand Down
21 changes: 0 additions & 21 deletions src/encoder/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,27 +215,6 @@ fn label_pairs_to_text(
Ok(())
}

#[cfg(feature = "regex")]
fn find_first_occurence(v: &str, include_double_quote: bool) -> Option<usize> {
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<usize> {
if include_double_quote {
memchr::memchr3(b'\\', b'\n', b'\"', v.as_bytes())
Expand Down

0 comments on commit 7a3936d

Please sign in to comment.