1#[derive(Debug, Clone)]
6pub enum HyphaEvent {
7 Progress {
9 current: u32,
10 total: u32,
11 message: String,
12 },
13 DownloadProgress {
15 downloaded_bytes: u64,
16 total_bytes: Option<u64>,
17 },
18 Log { message: String },
20 Warn { message: String },
22}
23
24pub trait EventSink: Send + Sync {
26 fn emit(&self, event: HyphaEvent);
27}
28
29pub struct NoopSink;
31
32impl EventSink for NoopSink {
33 fn emit(&self, _: HyphaEvent) {}
34}
35
36#[derive(Debug, Clone)]
42pub struct HyphaError {
43 pub code: String,
44 pub message: String,
45 pub hint: Option<String>,
46}
47
48impl HyphaError {
49 pub fn new(code: impl Into<String>, message: impl Into<String>) -> Self {
50 Self {
51 code: code.into(),
52 message: message.into(),
53 hint: None,
54 }
55 }
56
57 pub fn with_hint(
58 code: impl Into<String>,
59 message: impl Into<String>,
60 hint: impl Into<String>,
61 ) -> Self {
62 Self {
63 code: code.into(),
64 message: message.into(),
65 hint: Some(hint.into()),
66 }
67 }
68}
69
70impl std::fmt::Display for HyphaError {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 write!(f, "{}: {}", self.code, self.message)
73 }
74}
75
76impl std::error::Error for HyphaError {}
77
78impl From<String> for HyphaError {
79 fn from(msg: String) -> Self {
80 Self {
81 code: "error".to_string(),
82 message: msg,
83 hint: None,
84 }
85 }
86}
87
88impl From<&str> for HyphaError {
89 fn from(msg: &str) -> Self {
90 Self::from(msg.to_string())
91 }
92}
93
94pub struct AfDataSink;
96
97impl EventSink for AfDataSink {
98 #[allow(clippy::print_stdout)]
99 fn emit(&self, event: HyphaEvent) {
100 match event {
101 HyphaEvent::Progress {
102 current,
103 total,
104 message,
105 } => {
106 let v = agent_first_data::build_json(
107 "progress",
108 serde_json::json!({
109 "current": current,
110 "total": total,
111 "message": message,
112 }),
113 None,
114 );
115 println!("{}", agent_first_data::output_json(&v));
116 }
117 HyphaEvent::DownloadProgress {
118 downloaded_bytes,
119 total_bytes,
120 } => {
121 let v = agent_first_data::build_json(
122 "download_progress",
123 serde_json::json!({
124 "downloaded_bytes": downloaded_bytes,
125 "total_bytes": total_bytes,
126 }),
127 None,
128 );
129 println!("{}", agent_first_data::output_json(&v));
130 }
131 HyphaEvent::Log { message } => {
132 let v = agent_first_data::build_json(
133 "log",
134 serde_json::json!({ "message": message }),
135 None,
136 );
137 println!("{}", agent_first_data::output_json(&v));
138 }
139 HyphaEvent::Warn { message } => {
140 let v = agent_first_data::build_json(
141 "warn",
142 serde_json::json!({ "message": message }),
143 None,
144 );
145 println!("{}", agent_first_data::output_json(&v));
146 }
147 }
148 }
149}