prodigy/cook/input/
provider.rs1use super::types::{ExecutionInput, InputType, VariableDefinition};
2use anyhow::Result;
3use async_trait::async_trait;
4use serde_json::Value;
5use std::collections::HashMap;
6
7#[derive(Debug, Clone)]
8pub struct ValidationIssue {
9 pub field: String,
10 pub message: String,
11 pub severity: ValidationSeverity,
12}
13
14#[derive(Debug, Clone, PartialEq)]
15pub enum ValidationSeverity {
16 Error,
17 Warning,
18 Info,
19}
20
21pub struct InputConfig {
22 values: HashMap<String, Value>,
23}
24
25impl Default for InputConfig {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31impl InputConfig {
32 pub fn new() -> Self {
33 Self {
34 values: HashMap::new(),
35 }
36 }
37
38 pub fn from_values(values: HashMap<String, Value>) -> Self {
39 Self { values }
40 }
41
42 pub fn get_string(&self, key: &str) -> Result<String> {
43 self.values
44 .get(key)
45 .and_then(|v| v.as_str())
46 .map(|s| s.to_string())
47 .ok_or_else(|| anyhow::anyhow!("Missing or invalid string value for key: {}", key))
48 }
49
50 pub fn get_array(&self, key: &str) -> Result<Vec<Value>> {
51 self.values
52 .get(key)
53 .and_then(|v| v.as_array())
54 .cloned()
55 .ok_or_else(|| anyhow::anyhow!("Missing or invalid array value for key: {}", key))
56 }
57
58 pub fn get_bool(&self, key: &str) -> Result<bool> {
59 self.values
60 .get(key)
61 .and_then(|v| v.as_bool())
62 .ok_or_else(|| anyhow::anyhow!("Missing or invalid boolean value for key: {}", key))
63 }
64
65 pub fn set(&mut self, key: String, value: Value) {
66 self.values.insert(key, value);
67 }
68}
69
70#[async_trait]
71pub trait InputProvider: Send + Sync {
72 fn input_type(&self) -> InputType;
74
75 async fn validate(&self, config: &InputConfig) -> Result<Vec<ValidationIssue>>;
77
78 async fn generate_inputs(&self, config: &InputConfig) -> Result<Vec<ExecutionInput>>;
80
81 fn available_variables(&self, config: &InputConfig) -> Result<Vec<VariableDefinition>>;
83
84 fn supports(&self, config: &InputConfig) -> bool;
86}