use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
iter::{FromIterator, Iterator},
slice::Iter,
};
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(untagged)]
pub enum Value {
String(String),
Integer(i64),
Float(f64),
Boolean(bool),
}
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Point {
pub measurement: String,
pub tags: HashMap<String, Value>,
pub fields: HashMap<String, Value>,
pub timestamp: Option<i64>,
}
impl Point {
pub fn new(measurement: &str) -> Point {
Point {
measurement: String::from(measurement),
tags: HashMap::new(),
fields: HashMap::new(),
timestamp: None,
}
}
pub fn add_tag<T: Into<String>, F: Into<Value>>(mut self, tag: T, value: F) -> Self {
self.tags.insert(tag.into(), value.into());
self
}
pub fn add_field<T: Into<String>, F: Into<Value>>(mut self, field: T, value: F) -> Self {
self.fields.insert(field.into(), value.into());
self
}
pub fn add_timestamp(mut self, timestamp: i64) -> Self {
self.timestamp = Some(timestamp);
self
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct Points {
pub point: Vec<Point>,
}
impl Points {
pub fn new(point: Point) -> Points {
Points { point: vec![point] }
}
pub fn push(mut self, point: Point) -> Self {
self.point.push(point);
self
}
pub fn create_new(points: Vec<Point>) -> Points {
Points { point: points }
}
}
impl<'a> IntoIterator for &'a Points {
type Item = &'a Point;
type IntoIter = Iter<'a, Point>;
fn into_iter(self) -> Iter<'a, Point> {
self.point.iter()
}
}
impl FromIterator<Point> for Points {
fn from_iter<T: IntoIterator<Item = Point>>(iter: T) -> Self {
let mut points = Vec::new();
for point in iter {
points.push(point);
}
Points { point: points }
}
}
impl Iterator for Points {
type Item = Point;
fn next(&mut self) -> Option<Point> {
self.point.pop()
}
}
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Query {
pub results: Option<Vec<Node>>,
pub error: Option<String>,
}
pub type ChunkedQuery<'de, T> = serde_json::StreamDeserializer<'de, T, Query>;
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Node {
pub statement_id: Option<u64>,
pub series: Option<Vec<Series>>,
}
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Series {
pub name: Option<String>,
pub tags: Option<serde_json::Map<String, serde_json::Value>>,
pub columns: Vec<String>,
pub values: Option<Vec<Vec<serde_json::Value>>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Precision {
Nanoseconds,
Microseconds,
Milliseconds,
Seconds,
Minutes,
Hours,
}
impl Precision {
pub fn to_str(&self) -> &str {
match *self {
Precision::Nanoseconds => "n",
Precision::Microseconds => "u",
Precision::Milliseconds => "ms",
Precision::Seconds => "s",
Precision::Minutes => "m",
Precision::Hours => "h",
}
}
}
#[macro_export]
macro_rules! points {
($($x:expr),+) => {
{
let mut temp_vec = Vec::new();
$(temp_vec.push($x);)*
Points { point: temp_vec }
}
};
}
#[macro_export]
macro_rules! point {
($x:expr) => {{
Point::new($x)
}};
($x:expr, $y:expr, $z:expr) => {{
Point {
measurement: String::from($x),
tags: $y,
fields: $z,
timestamp: None,
}
}};
($x:expr, $y:expr, $z:expr, $a:expr) => {{
Point {
measurement: String::from($x),
tags: $y,
fields: $z,
timestamp: Some($a),
}
}};
}
impl From<String> for Value {
fn from(v: String) -> Value {
Value::String(v)
}
}
impl From<&str> for Value {
fn from(v: &str) -> Value {
Value::String(v.to_string())
}
}
impl From<i64> for Value {
fn from(v: i64) -> Value {
Value::Integer(v)
}
}
impl From<f64> for Value {
fn from(v: f64) -> Value {
Value::Float(v)
}
}
impl From<bool> for Value {
fn from(v: bool) -> Value {
Value::Boolean(v)
}
}