azure_speech/recognizer/
callback.rs

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                        // todo: improve the error with adding the request_id on it!
189                        // f(session.request_id(), e.clone())
190                    }
191                }
192            }
193        }
194    }
195}