Skip to main content

sapi_lite/stt/
phrase.rs

1use std::ffi::OsString;
2use std::ptr::null_mut;
3
4use windows as Windows;
5use Windows::Win32::Media::Speech::{ISpRecoResult, SPPHRASE_50, SPPR_ALL_ELEMENTS};
6
7use crate::com_util::{from_wide, out_to_ret, ComBox};
8use crate::Result;
9
10use super::SemanticTree;
11
12/// A successfully recognized phrase.
13#[derive(Debug, PartialEq, Clone)]
14pub struct Phrase {
15    /// The text of the recognized phrase.
16    pub text: OsString,
17    /// The semantic information associated with the phrase.
18    pub semantics: Vec<SemanticTree>,
19}
20
21impl Phrase {
22    // Note: must be a recognized phrase, not a hypothesis or a false recognition
23    pub(crate) fn from_sapi(sapi_result: ISpRecoResult) -> Result<Self> {
24        let text = unsafe {
25            ComBox::from_raw(out_to_ret(|out| {
26                sapi_result.GetText(
27                    SPPR_ALL_ELEMENTS.0 as u32,
28                    SPPR_ALL_ELEMENTS.0 as u32,
29                    true,
30                    out,
31                    null_mut(),
32                )
33            })?)
34        };
35        let phrase_info =
36            unsafe { ComBox::from_raw(sapi_result.GetPhrase()? as *const SPPHRASE_50) };
37        let first_prop = unsafe { (*phrase_info).as_ref() }
38            .and_then(|info| unsafe { info.pProperties.as_ref() });
39        Ok(Self {
40            text: unsafe { from_wide(&text) },
41            semantics: SemanticTree::from_sapi(first_prop),
42        })
43    }
44}