1use crate::callback::{BoxFuture, OnError, OnSessionEnded, OnSessionStarted};
2use crate::recognizer::{Duration, Event, Offset, RawMessage, Recognized};
3use crate::RequestId;
4use std::future::Future;
5use std::sync::Arc;
6
7pub(crate) type OnRecognizing =
8 Box<dyn Fn(RequestId, Recognized, Offset, Duration, RawMessage) -> BoxFuture>;
9pub(crate) type OnRecognized =
10 Box<dyn Fn(RequestId, Recognized, Offset, Duration, RawMessage) -> BoxFuture>;
11pub(crate) type OnUnMatch = Box<dyn Fn(RequestId, Offset, Duration, RawMessage) -> BoxFuture>;
12pub(crate) type OnStartDetected = Box<dyn Fn(RequestId, Offset) -> BoxFuture>;
13pub(crate) type OnEndDetected = Box<dyn Fn(RequestId, Offset) -> BoxFuture>;
14
15#[derive(Default, Clone)]
16pub struct Callback {
17 pub(crate) on_session_started: Option<Arc<OnSessionStarted>>,
18 pub(crate) on_error: Option<Arc<OnError>>,
19 pub(crate) on_session_ended: Option<Arc<OnSessionEnded>>,
20
21 pub(crate) on_recognizing: Option<Arc<OnRecognizing>>,
22 pub(crate) on_recognized: Option<Arc<OnRecognized>>,
23 pub(crate) on_un_match: Option<Arc<OnUnMatch>>,
24 pub(crate) on_start_detected: Option<Arc<OnStartDetected>>,
25 pub(crate) on_end_detected: Option<Arc<OnEndDetected>>,
26}
27
28impl Callback {
29 pub fn on_session_start<F, Fut>(mut self, func: F) -> Self
30 where
31 F: Fn(RequestId) -> Fut + 'static,
32 Fut: Future<Output = ()> + Send + Sync + 'static,
33 {
34 self.on_session_started = Some(Arc::new(Box::new(move |str| Box::pin(func(str)))));
35 self
36 }
37
38 pub fn on_session_end<F, Fut>(mut self, func: F) -> Self
39 where
40 F: Fn(RequestId) -> Fut + Send + Sync + 'static,
41 Fut: Future<Output = ()> + Send + 'static,
42 {
43 self.on_session_ended = Some(Arc::new(Box::new(move |str| Box::pin(func(str)))));
44 self
45 }
46
47 pub fn on_error<F, Fut>(mut self, func: F) -> Self
48 where
49 F: Fn(RequestId, crate::Error) -> Fut + Send + Sync + 'static,
50 Fut: Future<Output = ()> + Send + 'static,
51 {
52 self.on_error = Some(Arc::new(Box::new(move |request, err| {
53 Box::pin(func(request, err))
54 })));
55 self
56 }
57
58 pub fn on_recognizing<F, Fut>(mut self, func: F) -> Self
59 where
60 F: Fn(RequestId, Recognized, Offset, Duration, RawMessage) -> Fut + Send + Sync + 'static,
61 Fut: Future<Output = ()> + Send + 'static,
62 {
63 self.on_recognizing = Some(Arc::new(Box::new(
64 move |request_id, recognized, offset, duration, raw_message| {
65 Box::pin(func(request_id, recognized, offset, duration, raw_message))
66 },
67 )));
68 self
69 }
70
71 pub fn on_recognized<F, Fut>(mut self, func: F) -> Self
72 where
73 F: Fn(RequestId, Recognized, Offset, Duration, RawMessage) -> Fut + Send + Sync + 'static,
74 Fut: Future<Output = ()> + Send + 'static,
75 {
76 self.on_recognized = Some(Arc::new(Box::new(
77 move |request_id, recognized, offset, duration, raw_message| {
78 Box::pin(func(request_id, recognized, offset, duration, raw_message))
79 },
80 )));
81 self
82 }
83
84 pub fn on_un_match<F, Fut>(mut self, func: F) -> Self
85 where
86 F: Fn(RequestId, Offset, Duration, RawMessage) -> Fut + Send + Sync + 'static,
87 Fut: Future<Output = ()> + Send + 'static,
88 {
89 self.on_un_match = Some(Arc::new(Box::new(
90 move |request_id, offset, duration, raw_message| {
91 Box::pin(func(request_id, offset, duration, raw_message))
92 },
93 )));
94 self
95 }
96
97 pub fn on_start_detected<F, Fut>(mut self, func: F) -> Self
98 where
99 F: Fn(RequestId, Offset) -> Fut + Send + Sync + 'static,
100 Fut: Future<Output = ()> + Send + 'static,
101 {
102 self.on_start_detected = Some(Arc::new(Box::new(move |request, offset| {
103 Box::pin(func(request, offset))
104 })));
105 self
106 }
107
108 pub fn on_end_detected<F, Fut>(mut self, func: F) -> Self
109 where
110 F: Fn(RequestId, Offset) -> Fut + Send + Sync + 'static,
111 Fut: Future<Output = ()> + Send + 'static,
112 {
113 self.on_end_detected = Some(Arc::new(Box::new(move |request, offset| {
114 Box::pin(func(request, offset))
115 })));
116 self
117 }
118}
119
120#[async_trait::async_trait]
121impl crate::callback::Callback for Callback {
122 type Item = crate::Result<Event>;
123
124 #[allow(clippy::manual_async_fn)]
125 fn on_event(&self, item: Self::Item) -> impl Future<Output = ()> {
126 async move {
127 match &item {
128 Ok(Event::SessionStarted(request_id)) => {
129 tracing::debug!("Session started");
130 if let Some(f) = self.on_session_started.as_ref() {
131 f(*request_id).await
132 }
133 }
134 Ok(Event::SessionEnded(request_id)) => {
135 tracing::debug!("Session ended");
136 if let Some(f) = self.on_session_ended.as_ref() {
137 f(*request_id).await
138 }
139 }
140
141 Ok(Event::Recognizing(request_id, recognized, offset, duration, raw)) => {
142 if let Some(f) = self.on_recognizing.as_ref() {
143 f(
144 *request_id,
145 recognized.clone(),
146 *offset,
147 *duration,
148 raw.clone(),
149 )
150 .await
151 }
152 }
153
154 Ok(Event::Recognized(request_id, recognized, offset, duration, raw)) => {
155 if let Some(f) = self.on_recognized.as_ref() {
156 f(
157 *request_id,
158 recognized.clone(),
159 *offset,
160 *duration,
161 raw.clone(),
162 )
163 .await
164 }
165 }
166
167 Ok(Event::UnMatch(request_id, offset, duration, raw)) => {
168 if let Some(f) = self.on_un_match.as_ref() {
169 f(*request_id, *offset, *duration, raw.clone()).await
170 }
171 }
172
173 Ok(Event::EndDetected(request_id, offset)) => {
174 if let Some(f) = self.on_end_detected.as_ref() {
175 f(*request_id, *offset).await
176 }
177 }
178
179 Ok(Event::StartDetected(request_id, offset)) => {
180 if let Some(f) = self.on_start_detected.as_ref() {
181 f(*request_id, *offset).await
182 }
183 }
184
185 Err(e) => {
186 tracing::error!("Error: {:?}", e);
187 if let Some(_f) = self.on_error.as_ref() {
188 }
191 }
192 }
193 }
194 }
195}