use super::newtypes::{ArgName, BindingName};
use serde_json::Value;
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum DataSource {
PromptArg(ArgName),
StepOutput {
step: BindingName,
field: Option<String>,
},
Constant(Value),
}
impl DataSource {
pub fn prompt_arg(name: impl Into<ArgName>) -> Self {
Self::PromptArg(name.into())
}
pub fn from_step(step: impl Into<BindingName>) -> Self {
Self::StepOutput {
step: step.into(),
field: None,
}
}
pub fn from_step_field(step: impl Into<BindingName>, field: impl Into<String>) -> Self {
Self::StepOutput {
step: step.into(),
field: Some(field.into()),
}
}
pub fn constant(value: Value) -> Self {
Self::Constant(value)
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn test_prompt_arg_source() {
let source = DataSource::prompt_arg("input");
match source {
DataSource::PromptArg(name) => {
assert_eq!(name.as_str(), "input");
},
_ => panic!("Expected PromptArg variant"),
}
}
#[test]
fn test_from_step_source() {
let source = DataSource::from_step("step1");
match source {
DataSource::StepOutput { step, field } => {
assert_eq!(step.as_str(), "step1");
assert!(field.is_none());
},
_ => panic!("Expected StepOutput variant"),
}
}
#[test]
fn test_from_step_field_source() {
let source = DataSource::from_step_field("step1", "result");
match source {
DataSource::StepOutput { step, field } => {
assert_eq!(step.as_str(), "step1");
assert_eq!(field.as_deref(), Some("result"));
},
_ => panic!("Expected StepOutput variant"),
}
}
#[test]
fn test_constant_source() {
let value = json!({"key": "value"});
let source = DataSource::constant(value.clone());
match source {
DataSource::Constant(v) => {
assert_eq!(v, value);
},
_ => panic!("Expected Constant variant"),
}
}
#[test]
fn test_constant_with_primitives() {
let source = DataSource::constant(json!(42));
assert!(matches!(source, DataSource::Constant(_)));
let source = DataSource::constant(json!("hello"));
assert!(matches!(source, DataSource::Constant(_)));
let source = DataSource::constant(json!(true));
assert!(matches!(source, DataSource::Constant(_)));
}
#[test]
fn test_data_source_equality() {
let s1 = DataSource::prompt_arg("input");
let s2 = DataSource::prompt_arg("input");
let s3 = DataSource::prompt_arg("output");
assert_eq!(s1, s2);
assert_ne!(s1, s3);
}
#[test]
fn test_data_source_clone() {
let source = DataSource::from_step_field("step1", "result");
let cloned = source.clone();
assert_eq!(source, cloned);
}
#[test]
fn test_data_source_is_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<DataSource>();
}
#[test]
fn test_data_source_debug() {
let source = DataSource::prompt_arg("input");
let debug = format!("{:?}", source);
assert!(debug.contains("PromptArg"));
}
}