restflow_core/models/
output.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::HashMap;
4use ts_rs::TS;
5
6/// Unified node output enum. Each variant corresponds to a node type's output structure.
7///
8/// Note: Uses `#[serde(tag = "type", content = "data")]` for O(1) deserialization (15-20% faster) at ~20 bytes overhead per output.
9#[derive(Debug, Clone, Serialize, Deserialize, TS)]
10#[ts(export)]
11#[serde(tag = "type", content = "data")]
12pub enum NodeOutput {
13    Http(HttpOutput),
14    Agent(AgentOutput),
15    Python(PythonOutput),
16    Print(PrintOutput),
17    ManualTrigger(ManualTriggerOutput),
18    WebhookTrigger(WebhookTriggerOutput),
19    ScheduleTrigger(ScheduleOutput),
20}
21
22/// HTTP Request output
23#[derive(Debug, Clone, Serialize, Deserialize, TS)]
24#[ts(export)]
25pub struct HttpOutput {
26    pub status: u16,
27    #[ts(type = "Record<string, string>")]
28    pub headers: HashMap<String, String>,
29    #[ts(type = "any")]
30    pub body: Value,
31}
32
33/// AI Agent output
34#[derive(Debug, Clone, Serialize, Deserialize, TS)]
35#[ts(export)]
36pub struct AgentOutput {
37    pub response: String,
38}
39
40/// Python script output
41#[derive(Debug, Clone, Serialize, Deserialize, TS)]
42#[ts(export)]
43pub struct PythonOutput {
44    #[ts(type = "any")]
45    pub result: Value,
46}
47
48/// Print node output
49#[derive(Debug, Clone, Serialize, Deserialize, TS)]
50#[ts(export)]
51pub struct PrintOutput {
52    pub printed: String,
53}
54
55/// Manual trigger output
56#[derive(Debug, Clone, Serialize, Deserialize, TS)]
57#[ts(export)]
58pub struct ManualTriggerOutput {
59    pub triggered_at: i64,
60    #[ts(type = "any")]
61    pub payload: Value,
62}
63
64/// Webhook trigger output - received HTTP request data
65#[derive(Debug, Clone, Serialize, Deserialize, TS)]
66#[ts(export)]
67pub struct WebhookTriggerOutput {
68    pub triggered_at: i64,
69    pub method: String,
70    #[ts(type = "Record<string, string>")]
71    pub headers: HashMap<String, String>,
72    #[ts(type = "any")]
73    pub body: Value,
74    #[ts(type = "Record<string, string>")]
75    pub query: HashMap<String, String>,
76}
77
78/// Schedule trigger output
79#[derive(Debug, Clone, Serialize, Deserialize, TS)]
80#[ts(export)]
81pub struct ScheduleOutput {
82    pub triggered_at: i64,
83    #[ts(type = "any")]
84    pub payload: Value,
85}
86
87impl NodeOutput {
88    /// Get type-safe access to HTTP output
89    pub fn as_http(&self) -> Option<&HttpOutput> {
90        match self {
91            Self::Http(output) => Some(output),
92            _ => None,
93        }
94    }
95
96    /// Get type-safe access to Agent output
97    pub fn as_agent(&self) -> Option<&AgentOutput> {
98        match self {
99            Self::Agent(output) => Some(output),
100            _ => None,
101        }
102    }
103
104    /// Get type-safe access to Python output
105    pub fn as_python(&self) -> Option<&PythonOutput> {
106        match self {
107            Self::Python(output) => Some(output),
108            _ => None,
109        }
110    }
111
112    /// Get type-safe access to Print output
113    pub fn as_print(&self) -> Option<&PrintOutput> {
114        match self {
115            Self::Print(output) => Some(output),
116            _ => None,
117        }
118    }
119
120    /// Get type-safe access to ManualTrigger output
121    pub fn as_manual_trigger(&self) -> Option<&ManualTriggerOutput> {
122        match self {
123            Self::ManualTrigger(output) => Some(output),
124            _ => None,
125        }
126    }
127
128    /// Get type-safe access to WebhookTrigger output
129    pub fn as_webhook_trigger(&self) -> Option<&WebhookTriggerOutput> {
130        match self {
131            Self::WebhookTrigger(output) => Some(output),
132            _ => None,
133        }
134    }
135
136    /// Get type-safe access to Schedule output
137    pub fn as_schedule(&self) -> Option<&ScheduleOutput> {
138        match self {
139            Self::ScheduleTrigger(output) => Some(output),
140            _ => None,
141        }
142    }
143}