screencapturekit/stream/
delegate_trait.rs

1//! Delegate trait for stream lifecycle events
2//!
3//! Defines the interface for receiving stream state change notifications.
4
5use crate::error::SCError;
6
7/// Trait for handling stream lifecycle events
8///
9/// Implement this trait to receive notifications about stream state changes,
10/// errors, and video effects.
11///
12/// # Examples
13///
14/// ```
15/// use screencapturekit::stream::delegate_trait::SCStreamDelegateTrait;
16/// use screencapturekit::error::SCError;
17///
18/// struct MyDelegate;
19///
20/// impl SCStreamDelegateTrait for MyDelegate {
21///     fn stream_did_stop(&self, error: Option<String>) {
22///         if let Some(err) = error {
23///             eprintln!("Stream stopped with error: {}", err);
24///         } else {
25///             println!("Stream stopped normally");
26///         }
27///     }
28///
29///     fn did_stop_with_error(&self, error: SCError) {
30///         eprintln!("Stream error: {}", error);
31///     }
32/// }
33/// ```
34pub trait SCStreamDelegateTrait: Send {
35    /// Called when video effects start
36    fn output_video_effect_did_start_for_stream(&self) {}
37
38    /// Called when video effects stop
39    fn output_video_effect_did_stop_for_stream(&self) {}
40
41    /// Called when stream stops with an error
42    fn did_stop_with_error(&self, _error: SCError) {}
43
44    /// Called when stream stops
45    ///
46    /// # Parameters
47    ///
48    /// - `error`: Optional error message if the stream stopped due to an error
49    fn stream_did_stop(&self, _error: Option<String>) {}
50}
51
52/// A simple error handler wrapper for closures
53///
54/// Allows using a closure as a stream delegate that only handles errors.
55///
56/// # Examples
57///
58/// ```rust,no_run
59/// use screencapturekit::prelude::*;
60/// use screencapturekit::stream::delegate_trait::ErrorHandler;
61///
62/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
63/// # let content = SCShareableContent::get()?;
64/// # let display = &content.displays()[0];
65/// # let filter = SCContentFilter::build().display(display).exclude_windows(&[]).build();
66/// # let config = SCStreamConfiguration::default();
67///
68/// let error_handler = ErrorHandler::new(|error| {
69///     eprintln!("Stream error: {}", error);
70/// });
71///
72/// let stream = SCStream::new_with_delegate(&filter, &config, error_handler);
73/// # Ok(())
74/// # }
75/// ```
76pub struct ErrorHandler<F>
77where
78    F: Fn(SCError) + Send + 'static,
79{
80    handler: F,
81}
82
83impl<F> ErrorHandler<F>
84where
85    F: Fn(SCError) + Send + 'static,
86{
87    /// Create a new error handler from a closure
88    pub fn new(handler: F) -> Self {
89        Self { handler }
90    }
91}
92
93impl<F> SCStreamDelegateTrait for ErrorHandler<F>
94where
95    F: Fn(SCError) + Send + 'static,
96{
97    fn did_stop_with_error(&self, error: SCError) {
98        (self.handler)(error);
99    }
100}