pub mod sample_table;
use std::slice::IterMut;
pub use sample_table::*;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::de::Error as _;
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
#[serde(untagged)]
pub enum Value {
String(String),
Double(f64),
Integer(i64),
}
impl From<String> for Value {
fn from(value: String) -> Self {
Value::String(value)
}
}
impl From<&str> for Value {
fn from(value: &str) -> Self {
Value::String(value.to_owned())
}
}
impl From<f64> for Value {
fn from(value: f64) -> Self {
Value::Double(value)
}
}
impl From<i64> for Value {
fn from(value: i64) -> Self {
Value::Integer(value)
}
}
impl Default for Value {
fn default() -> Value {
Value::Double(0.0)
}
}
impl Value {
pub fn into_series(self) -> ValueSeries {
self.into()
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ValueRef<'value> {
String(&'value str),
Double(&'value f64),
Integer(&'value i64),
}
pub enum ValueRefMut<'value> {
String(&'value mut String),
Double(&'value mut f64),
Integer(&'value mut i64),
}
impl PartialEq<Value> for ValueRef<'_> {
fn eq(&self, other: &Value) -> bool {
match (*self, other) {
(ValueRef::String(s), Value::String(s2)) => s == s2,
(ValueRef::Double(d), Value::Double(d2)) => d == d2,
(ValueRef::Integer(i), Value::Integer(i2)) => i == i2,
_ => false,
}
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(untagged)]
pub enum ValueSeries {
String(Vec<String>),
Double(Vec<f64>),
Integer(Vec<i64>),
}
impl ValueSeries {
pub fn get(&self, index: usize) -> Option<ValueRef<'_>> {
match self {
ValueSeries::String(values) => values.get(index).map(|s| ValueRef::String(s.as_str())),
ValueSeries::Double(values) => values.get(index).map(ValueRef::Double),
ValueSeries::Integer(values) => values.get(index).map(ValueRef::Integer),
}
}
fn transpose_inner<T: Into<Value>>(values: Vec<T>) -> Vec<ValueSeries> {
values.into_iter().map(|v| v.into().into_series()).collect()
}
pub fn transpose(self) -> Vec<ValueSeries> {
match self {
Self::String(v) => Self::transpose_inner(v),
Self::Double(v) => Self::transpose_inner(v),
Self::Integer(v) => Self::transpose_inner(v),
}
}
}
#[derive(Debug)]
pub struct ValueSeriesIter<'values> {
values: &'values ValueSeries,
index: usize,
}
#[derive(Debug)]
pub enum ValueSeriesIterMut<'values> {
String(IterMut<'values, String>),
Double(IterMut<'values, f64>),
Integer(IterMut<'values, i64>),
}
impl<'values> ValueSeriesIter<'values> {
fn new(values: &'values ValueSeries) -> Self {
Self { values, index: 0 }
}
}
impl<'values> ValueSeriesIterMut<'values> {
fn new(values: &'values mut ValueSeries) -> Self {
match values {
ValueSeries::String(values) => ValueSeriesIterMut::String(values.iter_mut()),
ValueSeries::Double(values) => ValueSeriesIterMut::Double(values.iter_mut()),
ValueSeries::Integer(values) => ValueSeriesIterMut::Integer(values.iter_mut()),
}
}
}
impl<'values> Iterator for ValueSeriesIter<'values> {
type Item = ValueRef<'values>;
fn next(&mut self) -> Option<Self::Item> {
self.values.get(self.index).inspect(|_| {
self.index = self.index.saturating_add(1);
})
}
}
impl<'values> Iterator for ValueSeriesIterMut<'values> {
type Item = ValueRefMut<'values>;
fn next(&mut self) -> Option<Self::Item> {
match self {
ValueSeriesIterMut::String(values) => values.next().map(ValueRefMut::String),
ValueSeriesIterMut::Double(values) => values.next().map(ValueRefMut::Double),
ValueSeriesIterMut::Integer(values) => values.next().map(ValueRefMut::Integer),
}
}
}
impl<'values> IntoIterator for &'values ValueSeries {
type Item = ValueRef<'values>;
type IntoIter = ValueSeriesIter<'values>;
fn into_iter(self) -> Self::IntoIter {
ValueSeriesIter::new(self)
}
}
impl From<Vec<String>> for ValueSeries {
fn from(values: Vec<String>) -> Self {
ValueSeries::String(values)
}
}
impl From<Vec<&str>> for ValueSeries {
fn from(values: Vec<&str>) -> Self {
ValueSeries::String(values.into_iter().map(|s| s.to_owned()).collect())
}
}
impl From<Vec<f64>> for ValueSeries {
fn from(values: Vec<f64>) -> Self {
ValueSeries::Double(values)
}
}
impl From<Vec<i64>> for ValueSeries {
fn from(values: Vec<i64>) -> Self {
ValueSeries::Integer(values)
}
}
impl From<Value> for ValueSeries {
fn from(value: Value) -> Self {
match value {
Value::String(string) => ValueSeries::String(vec![string]),
Value::Double(double) => ValueSeries::Double(vec![double]),
Value::Integer(int) => ValueSeries::Integer(vec![int]),
}
}
}
impl Default for ValueSeries {
fn default() -> ValueSeries {
ValueSeries::Double(Vec::new())
}
}
impl ValueSeries {
pub fn iter(&self) -> ValueSeriesIter<'_> {
ValueSeriesIter::new(self)
}
pub fn iter_mut(&mut self) -> ValueSeriesIterMut<'_> {
ValueSeriesIterMut::new(self)
}
pub const fn len(&self) -> usize {
match self {
ValueSeries::String(values) => values.len(),
ValueSeries::Double(values) => values.len(),
ValueSeries::Integer(values) => values.len(),
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn iter_numeric_as_f64(&self) -> Option<Box<dyn Iterator<Item = f64> + '_>> {
match self {
ValueSeries::Double(vals) => Some(Box::new(vals.iter().copied())),
ValueSeries::Integer(vals) => Some(Box::new(vals.iter().map(|&v| v as f64))),
ValueSeries::String(_) => None,
}
}
pub fn truncate(&mut self, size: usize) {
match self {
ValueSeries::String(values) => values.truncate(size),
ValueSeries::Double(values) => values.truncate(size),
ValueSeries::Integer(values) => values.truncate(size),
}
}
}
fn usize_with_underscores<'de, D: Deserializer<'de>>(deserializer: D) -> Result<usize, D::Error> {
#[derive(Deserialize)]
#[serde(untagged)]
enum UsizeOrString {
Usize(usize),
String(String),
}
let value: UsizeOrString = serde::Deserialize::deserialize(deserializer)?;
match value {
UsizeOrString::Usize(value) => Ok(value),
UsizeOrString::String(value) => value
.replace('_', "")
.parse::<usize>()
.map_err(D::Error::custom),
}
}
#[derive(Debug, Copy, Clone, PartialEq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum BufferCapacity {
Points(#[serde(deserialize_with = "usize_with_underscores")] usize),
Duration {
unit: TimeUnit,
#[serde(deserialize_with = "usize_with_underscores")]
value: usize,
},
}
impl Default for BufferCapacity {
fn default() -> Self {
Self::Points(5000)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum TimeUnit {
#[serde(alias = "milliseconds")]
#[serde(alias = "millis")]
#[serde(alias = "ms")]
Milliseconds,
#[serde(alias = "seconds")]
#[serde(alias = "sec")]
#[serde(alias = "s")]
Seconds,
#[serde(alias = "minutes")]
#[serde(alias = "min")]
#[serde(alias = "m")]
Minutes,
#[serde(alias = "hours")]
#[serde(alias = "hr")]
#[serde(alias = "h")]
Hours,
}
impl TimeUnit {
pub fn to_duration(&self, value: usize) -> core::time::Duration {
match self {
TimeUnit::Milliseconds => core::time::Duration::from_millis(value as u64),
TimeUnit::Seconds => core::time::Duration::from_secs(value as u64),
TimeUnit::Minutes => {
core::time::Duration::from_secs(60_u64.saturating_mul(value as u64))
}
TimeUnit::Hours => {
core::time::Duration::from_secs(3600_u64.saturating_mul(value as u64))
}
}
}
}
impl BufferCapacity {
pub fn value(&self) -> usize {
match self {
BufferCapacity::Points(points) => *points,
BufferCapacity::Duration { value, unit: _ } => *value,
}
}
}