///|
fn is_ascii_letter(char : Char) -> Bool {
match char {
'a'..='z' | 'A'..='Z' => true
_ => false
}
}
///|
fn is_ascii_digit(char : Char) -> Bool {
match char {
'0'..='9' => true
_ => false
}
}
///|
fn is_valid_identifier(value : String, allow_colon : Bool) -> Bool {
if value.is_empty() {
return false
}
let mut index = 0
for char in value {
let valid = if index == 0 {
is_ascii_letter(char) || char == '_' || (allow_colon && char == ':')
} else {
is_ascii_letter(char) ||
is_ascii_digit(char) ||
char == '_' ||
(allow_colon && char == ':')
}
if !valid {
return false
}
index += 1
}
true
}
///|
fn is_valid_metric_name(name : String) -> Bool {
is_valid_identifier(name, true)
}
///|
pub fn validate_label_name(name : String) -> Unit raise MetricError {
if !is_valid_identifier(name, false) {
raise InvalidLabelName(name)
}
if name.has_prefix("__") {
raise ReservedLabelName(name)
}
}
///|
fn canonical_const_labels(
labels : Array[Label],
) -> Array[Label] raise MetricError {
for index, label in labels {
validate_label_name(label.name)
for previous in 0.. left.name.compare(right.name))
canonical
}
///|
fn validate_variable_label_names(
names : Array[String],
) -> Unit raise MetricError {
for index, name in names {
validate_label_name(name)
for previous in 0..