use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Phase {
Map {
#[serde(rename = "name")]
fn_name: String,
#[serde(default)]
arg: Option<Value>,
#[serde(default)]
keep: bool,
},
Reduce {
#[serde(rename = "name")]
fn_name: String,
#[serde(default)]
arg: Option<Value>,
#[serde(default)]
keep: bool,
},
Link {
#[serde(default)]
bucket: Option<String>,
#[serde(default)]
tag: Option<String>,
#[serde(default)]
keep: bool,
},
WasmModule {
module_id: String,
fn_name: String,
#[serde(default)]
arg: Option<Value>,
#[serde(default)]
keep: bool,
},
}
impl Phase {
#[must_use]
pub fn keep(&self) -> bool {
match self {
Self::Map { keep, .. }
| Self::Reduce { keep, .. }
| Self::Link { keep, .. }
| Self::WasmModule { keep, .. } => *keep,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn keep_is_per_variant() {
let p = Phase::Map {
fn_name: "f".into(),
arg: None,
keep: true,
};
assert!(p.keep());
let p = Phase::Reduce {
fn_name: "f".into(),
arg: None,
keep: false,
};
assert!(!p.keep());
}
#[test]
fn map_phase_round_trips_through_json() {
let p = Phase::Map {
fn_name: "map_object_value".into(),
arg: Some(serde_json::json!({"k": "v"})),
keep: true,
};
let s = serde_json::to_string(&p).expect("encode");
let back: Phase = serde_json::from_str(&s).expect("decode");
assert_eq!(back, p);
}
#[test]
fn reduce_phase_round_trips_through_json() {
let p = Phase::Reduce {
fn_name: "reduce_sum".into(),
arg: None,
keep: false,
};
let s = serde_json::to_string(&p).expect("encode");
let back: Phase = serde_json::from_str(&s).expect("decode");
assert_eq!(back, p);
}
#[test]
fn link_phase_round_trips_through_json() {
let p = Phase::Link {
bucket: Some("friends".into()),
tag: Some("knows".into()),
keep: true,
};
let s = serde_json::to_string(&p).expect("encode");
let back: Phase = serde_json::from_str(&s).expect("decode");
assert_eq!(back, p);
}
#[test]
fn wasm_phase_is_present_in_enum() {
let p = Phase::WasmModule {
module_id: "m".into(),
fn_name: "f".into(),
arg: None,
keep: false,
};
let s = serde_json::to_string(&p).expect("encode");
let back: Phase = serde_json::from_str(&s).expect("decode");
assert_eq!(back, p);
}
}