use std::collections::HashMap;
use crate::DatumType;
#[derive(Debug, Clone)]
pub struct TransformSpec(String);
impl TransformSpec {
pub fn to_transform_string(&self) -> String {
self.0.clone()
}
}
impl From<&str> for TransformSpec {
fn from(s: &str) -> Self {
TransformSpec(s.to_string())
}
}
impl From<String> for TransformSpec {
fn from(s: String) -> Self {
TransformSpec(s)
}
}
impl From<&String> for TransformSpec {
fn from(s: &String) -> Self {
TransformSpec(s.clone())
}
}
pub trait TransformConfig: serde::Serialize {
fn name(&self) -> &'static str;
fn to_transform_string(&self) -> String {
let mut obj: serde_json::Map<String, serde_json::Value> = serde_json::to_value(self)
.expect("TransformConfig serialization cannot fail")
.as_object()
.expect("TransformConfig must serialize to a JSON object")
.clone();
obj.insert("name".into(), serde_json::Value::String(self.name().to_string()));
serde_json::to_string(&obj).expect("serialization cannot fail")
}
}
macro_rules! transform_config {
($ty:ty, $name:expr) => {
impl TransformConfig for $ty {
fn name(&self) -> &'static str {
$name
}
}
impl From<$ty> for TransformSpec {
fn from(config: $ty) -> Self {
TransformSpec(config.to_transform_string())
}
}
};
}
#[derive(Debug, Clone, Default, serde::Serialize)]
pub struct ConcretizeSymbols {
values: HashMap<String, i64>,
}
impl ConcretizeSymbols {
pub fn new() -> Self {
Self::default()
}
pub fn value(mut self, symbol: impl Into<String>, val: i64) -> Self {
self.values.insert(symbol.into(), val);
self
}
}
transform_config!(ConcretizeSymbols, "concretize_symbols");
#[derive(Debug, Clone, serde::Serialize)]
pub struct Pulse {
pulse: String,
#[serde(skip_serializing_if = "Option::is_none")]
symbol: Option<String>,
}
impl Pulse {
pub fn new(pulse: impl Into<String>) -> Self {
Self { pulse: pulse.into(), symbol: None }
}
pub fn symbol(mut self, symbol: impl Into<String>) -> Self {
self.symbol = Some(symbol.into());
self
}
}
transform_config!(Pulse, "pulse");
#[derive(Debug, Clone, serde::Serialize)]
pub struct FloatPrecision {
from: String,
to: String,
#[serde(skip_serializing_if = "Option::is_none")]
include: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
exclude: Option<Vec<String>>,
}
fn datum_type_to_str(dt: DatumType) -> &'static str {
match dt {
DatumType::F16 => "f16",
DatumType::F32 => "f32",
DatumType::F64 => "f64",
_ => panic!("FloatPrecision only supports float datum types (F16, F32, F64)"),
}
}
impl FloatPrecision {
pub fn new(from: DatumType, to: DatumType) -> Self {
Self {
from: datum_type_to_str(from).to_string(),
to: datum_type_to_str(to).to_string(),
include: None,
exclude: None,
}
}
pub fn include(mut self, patterns: Vec<String>) -> Self {
self.include = Some(patterns);
self
}
pub fn exclude(mut self, patterns: Vec<String>) -> Self {
self.exclude = Some(patterns);
self
}
}
transform_config!(FloatPrecision, "float_precision");