Skip to content

Commit

Permalink
feat: all logic done, test cases need to be done
Browse files Browse the repository at this point in the history
  • Loading branch information
yuanbohan committed Jul 18, 2023
1 parent 9216c26 commit 2fa6659
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 124 deletions.
9 changes: 5 additions & 4 deletions src/label/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl Labels {
impl fmt::Display for Labels {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let labels = self.labels.join(", ");
write!(f, "({labels})")
write!(f, "{labels}")
}
}

Expand All @@ -67,9 +67,10 @@ mod tests {
#[test]
fn test_to_string() {
let cases = vec![
(vec!["foo"], "(foo)"),
(vec!["foo", "bar"], "(foo, bar)"),
(vec!["foo", "foo", "bar"], "(foo, foo, bar)"),
(vec![], ""),
(vec!["foo"], "foo"),
(vec!["foo", "bar"], "foo, bar"),
(vec!["foo", "foo", "bar"], "foo, foo, bar"),
];

for (ls, expect) in cases {
Expand Down
10 changes: 4 additions & 6 deletions src/label/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use std::collections::HashSet;
use std::fmt;
use std::hash::{Hash, Hasher};

use crate::label::METRIC_NAME;
use crate::parser::token::{TokenId, T_EQL, T_EQL_REGEX, T_NEQ, T_NEQ_REGEX};
use regex::Regex;

Expand Down Expand Up @@ -158,14 +157,13 @@ impl Matchers {

impl fmt::Display for Matchers {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let matchers_str = self
let mut v = self
.matchers
.iter()
.filter(|m| !m.name.eq_ignore_ascii_case(METRIC_NAME))
.map(|Matcher { op, name, value }| format!("{name}{op}\"{value}\""))
.collect::<Vec<String>>()
.join(", ");
write!(f, "{matchers_str}")
.collect::<Vec<String>>();
v.sort();
write!(f, "{}", v.join(", "))
}
}

Expand Down
218 changes: 104 additions & 114 deletions src/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,24 +65,6 @@ impl LabelModifier {
}
}

// impl fmt::Display for LabelModifier {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// if self.is_on() && self.labels().is_empty() {
// write!(f, "")
// } else {
// let op = if self.is_on() { "by" } else { "without" };
// let labels = self
// .labels()
// .0
// .iter()
// .map(|e| e.to_string())
// .collect::<Vec<String>>()
// .join(", ");
// write!(f, "{op} ({labels})")
// }
// }
// }

/// The label list provided with the group_left or group_right modifier contains
/// additional labels from the "one"-side to be included in the result metrics.
#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -128,32 +110,28 @@ pub struct BinModifier {

impl fmt::Display for BinModifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = String::from(self.bool_string());
if let Some(matching) = &self.matching {
match matching {
LabelModifier::Include(labels) => write!(f, " on ({})", labels.labels.join(", "))?,
LabelModifier::Exclude(labels) => {
let labels = labels.labels.join(", ");
if !labels.is_empty() {
write!(f, " ignoring ({labels})",)?;
LabelModifier::Include(ls) => s.push_str(&format!("on ({ls})")),
LabelModifier::Exclude(ls) => {
if !ls.is_empty() {
s.push_str(&format!("ignoring ({ls})"));
}
}
}
}

match &self.card {
VectorMatchCardinality::ManyToOne(labels) => {
write!(f, " group_left ({})", labels.labels.join(", "))?
VectorMatchCardinality::ManyToOne(ls) => {
s.push_str(&format!(" group_left ({ls})"));
}
VectorMatchCardinality::OneToMany(labels) => {
write!(f, " group_right ({})", labels.labels.join(", "))?
VectorMatchCardinality::OneToMany(ls) => {
s.push_str(&format!(" group_right ({ls})"));
}
_ => {}
}

if self.return_bool {
write!(f, " bool")?;
}
write!(f, " ")
write!(f, "{s}")
}
}

Expand Down Expand Up @@ -206,6 +184,14 @@ impl BinModifier {
pub fn is_matching_labels_not_empty(&self) -> bool {
matches!(&self.matching, Some(matching) if !matching.labels().is_empty())
}

pub fn bool_string(&self) -> &str {
if self.return_bool {
"bool "
} else {
""
}
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -344,33 +330,33 @@ pub struct AggregateExpr {

impl fmt::Display for AggregateExpr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut v: Vec<String> = vec![token_display(self.op.id()).into()];
write!(f, "{}", token_display(self.op.id()))?;
// let mut v: Vec<String> = vec![token_display(self.op.id()).into()];

// modifier
{
if let Some(modifier) = &self.modifier {
match modifier {
LabelModifier::Include(ls) => {
if !ls.is_empty() {
v.push(format!("by {ls}"))
write!(f, " by ({ls})")?;
}
}
LabelModifier::Exclude(ls) => v.push(format!("without {ls}")),
LabelModifier::Exclude(ls) => write!(f, " without ({ls})")?,
}
}
}

// body
{
let mut body = String::from("(");
write!(f, "(")?;
if let Some(param) = &self.param {
body.push_str(&format!("{param}, "));
write!(f, "{param}, ")?;
}
body.push_str(&format!("{})", self.expr));
v.push(body)
write!(f, "{})", self.expr)?;
}

write!(f, "{}", v.join(" "))
Ok(())
}
}

Expand Down Expand Up @@ -425,6 +411,16 @@ impl BinaryExpr {
}
}

impl fmt::Display for BinaryExpr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let op = token_display(self.op.id());
match &self.modifier {
Some(modifier) => write!(f, "{} {} {} {}", self.lhs, op, modifier, self.rhs),
None => write!(f, "{} {} {}", self.lhs, op, self.rhs),
}
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParenExpr {
pub expr: Box<Expr>,
Expand All @@ -446,24 +442,21 @@ pub struct SubqueryExpr {

impl fmt::Display for SubqueryExpr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.step {
Some(step) => write!(
f,
"{}[{}:{}]",
self.expr,
display_duration(&self.range),
display_duration(step)
)?,
None => write!(f, "{}[{}]", self.expr, display_duration(&self.range))?,
}
let step = match &self.step {
Some(step) => display_duration(step),
None => String::from(""),
};
let range = display_duration(&self.range);
write!(f, "{}[{range}:{step}]", self.expr)?;

if let Some(offset) = &self.offset {
write!(f, " offset {offset}")?;
}
if let Some(at) = &self.at {
write!(f, " {at}")
} else {
Ok(())
write!(f, " {at}")?;
}

Ok(())
}
}

Expand Down Expand Up @@ -494,11 +487,31 @@ impl Neg for NumberLiteral {
}
}

impl fmt::Display for NumberLiteral {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.val == f64::INFINITY {
write!(f, "Inf")
} else if self.val == f64::NEG_INFINITY {
write!(f, "-Inf")
} else if f64::is_nan(self.val) {
write!(f, "NaN")
} else {
write!(f, "{}", self.val)
}
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StringLiteral {
pub val: String,
}

impl fmt::Display for StringLiteral {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\"{}\"", self.val)
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VectorSelector {
pub name: Option<String>,
Expand Down Expand Up @@ -552,12 +565,38 @@ impl Neg for VectorSelector {
}
}

impl fmt::Display for VectorSelector {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(name) = &self.name {
write!(f, "{name}")?;
}
let matchers = &self.matchers.to_string();
if !matchers.is_empty() {
write!(f, "{{{matchers}}}")?;
}
if let Some(offset) = &self.offset {
write!(f, " offset {offset}")?;
}
if let Some(at) = &self.at {
write!(f, " {at}")?;
}
Ok(())
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MatrixSelector {
pub vector_selector: VectorSelector,
pub range: Duration,
}

impl fmt::Display for MatrixSelector {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let range = display_duration(&self.range);
write!(f, "{}[{range}]", self.vector_selector)
}
}

/// Call represents Prometheus Function.
/// Some functions have special cases:
///
Expand Down Expand Up @@ -603,6 +642,12 @@ pub struct Call {
pub args: FunctionArgs,
}

impl fmt::Display for Call {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}({})", self.func.name, self.args)
}
}

/// Node for extending the AST. [Extension] won't be generate by this parser itself.
#[derive(Debug, Clone)]
pub struct Extension {
Expand Down Expand Up @@ -938,69 +983,14 @@ impl fmt::Display for Expr {
match self {
Expr::Aggregate(agg) => write!(f, "{agg}"),
Expr::Unary(UnaryExpr { expr }) => write!(f, "- {expr}"),
Expr::Binary(binary) => {
let lhs = binary.lhs.as_ref();
let rhs = binary.rhs.as_ref();
let op = token_display(binary.op.id());
if let Some(modifier) = &binary.modifier {
write!(f, "{lhs} {op}{modifier}{rhs}")
} else {
write!(f, "{lhs} {op} {rhs}")
}
}
Expr::Binary(bin) => write!(f, "{bin}"),
Expr::Paren(ParenExpr { expr }) => write!(f, "({expr})"),
Expr::Subquery(subquery) => write!(f, "{subquery}"),
Expr::NumberLiteral(NumberLiteral { val }) => {
if *val == f64::INFINITY {
write!(f, "Inf")
} else if *val == f64::NEG_INFINITY {
write!(f, "-Inf")
} else if f64::is_nan(*val) {
write!(f, "NaN")
} else {
write!(f, "{val}")
}
}
Expr::StringLiteral(StringLiteral { val }) => write!(f, "\"{val}\""),
Expr::VectorSelector(vector_selector) => {
if let Some(name) = &vector_selector.name {
write!(f, "{name}")?;
}
let matchers = &vector_selector.matchers.to_string();
if !matchers.is_empty() {
write!(f, "{{{matchers}}}")?;
}
if let Some(offset) = &vector_selector.offset {
write!(f, " offset {offset}")?;
}
if let Some(at) = &vector_selector.at {
write!(f, " {at}")
} else {
Ok(())
}
}
Expr::MatrixSelector(MatrixSelector {
vector_selector,
range,
}) => {
if let Some(name) = &vector_selector.name {
write!(f, "{name}")?;
}
let matchers = &vector_selector.matchers.to_string();
if !matchers.is_empty() {
write!(f, "{{{matchers}}}")?;
}
write!(f, "[{}]", display_duration(range))?;
if let Some(offset) = &vector_selector.offset {
write!(f, " offset {offset}")?;
}
if let Some(at) = &vector_selector.at {
write!(f, " {at}")
} else {
Ok(())
}
}
Expr::Call(call) => write!(f, "{call:?}"),
Expr::NumberLiteral(nl) => write!(f, "{nl}"),
Expr::StringLiteral(sl) => write!(f, "{sl}"),
Expr::VectorSelector(vs) => write!(f, "{vs}"),
Expr::MatrixSelector(ms) => write!(f, "{ms}"),
Expr::Call(call) => write!(f, "{call}"),
Expr::Extension(ext) => write!(f, "{ext:?}"),
}
}
Expand Down
Loading

0 comments on commit 2fa6659

Please sign in to comment.