+#[derive(Debug, Clone, Copy)]
+pub enum ErrorSource {
+ Input,
+ Output,
+ Ptt,
+}
+
+pub trait ErrorHandler: Send + Sync + 'static {
+ fn soundmodem_error(&mut self, source: ErrorSource, err: SoundmodemError);
+}
+
+impl<F> ErrorHandler for F
+where
+ F: FnMut(ErrorSource, SoundmodemError) + Send + Sync + 'static,
+{
+ fn soundmodem_error(&mut self, source: ErrorSource, err: SoundmodemError) {
+ self(source, err)
+ }
+}
+
+pub struct NullErrorHandler;
+
+impl NullErrorHandler {
+ pub fn new() -> Self {
+ Self {}
+ }
+}
+
+impl Default for NullErrorHandler {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl ErrorHandler for NullErrorHandler {
+ fn soundmodem_error(&mut self, source: ErrorSource, err: SoundmodemError) {
+ let _ = source;
+ let _ = err;
+ }
+}
+
+type ErrorHandlerInternal = Arc<Mutex<Box<dyn ErrorHandler>>>;
+
+#[derive(Clone)]
+pub struct SoundmodemErrorSender {
+ source: ErrorSource,
+ event_tx: SyncSender<SoundmodemEvent>,
+}
+
+impl SoundmodemErrorSender {
+ pub fn send_error<E: Into<SoundmodemError>>(&self, err: E) {
+ let _ = self
+ .event_tx
+ .send(SoundmodemEvent::RuntimeError(self.source, err.into()));
+ }
+}
+