sapi_lite/stt/context/
sync.rs1use std::ops::Deref;
2use std::time::Duration;
3
4use windows as Windows;
5use Windows::core::Interface;
6
7use crate::event::{Event, EventSource};
8use crate::stt::{Phrase, Recognizer};
9use crate::Result;
10
11use super::Context;
12
13pub struct SyncContext {
15 base: Context,
16 event_src: EventSource,
17}
18
19impl SyncContext {
20 pub fn new(recognizer: &Recognizer) -> Result<Self> {
22 let intf = unsafe { recognizer.intf.CreateRecoContext() }?;
23 unsafe { intf.SetNotifyWin32Event() }?;
24 Ok(SyncContext {
25 event_src: EventSource::from_sapi(intf.cast()?),
26 base: Context::new(intf, recognizer.pauser.clone()),
27 })
28 }
29
30 pub fn recognize(&self, timeout: Duration) -> Result<Option<Phrase>> {
33 let result = self.next_phrase()?;
34 if result.is_some() {
35 return Ok(result);
36 }
37
38 let timeout_ms: u32 = timeout.as_millis().try_into().unwrap_or(u32::MAX - 1);
39 unsafe { self.base.intf.WaitForNotifyEvent(timeout_ms) }?;
40
41 return self.next_phrase();
42 }
43
44 fn next_phrase(&self) -> Result<Option<Phrase>> {
45 while let Some(event) = self.event_src.next_event()? {
46 if let Event::Recognition(result) = event {
47 let phrase = Phrase::from_sapi(result)?;
48 return Ok(Some(phrase));
49 }
50 }
51 Ok(None)
52 }
53}
54
55impl Deref for SyncContext {
56 type Target = Context;
57 fn deref(&self) -> &Self::Target {
58 &self.base
59 }
60}