use std::mem::ManuallyDrop;
use std::ptr::null_mut;
use windows as Windows;
use Windows::Win32::Media::Speech::{
ISpRecoGrammar, SPGRAMMARSTATE, SPGS_DISABLED, SPGS_ENABLED, SPRS_ACTIVE, SPRS_INACTIVE,
SPRULESTATE,
};
use crate::com_util::Intf;
use crate::Result;
use super::RecognitionPauser;
mod builder;
mod rule;
pub use builder::GrammarBuilder;
pub use rule::{RepeatRange, Rule, RuleArena};
pub struct Grammar {
intf: ManuallyDrop<Intf<ISpRecoGrammar>>,
pauser: RecognitionPauser,
}
impl Grammar {
pub fn set_enabled(&self, enabled: bool) -> Result<()> {
let _pause = self.pauser.pause()?;
unsafe { self.intf.SetGrammarState(grammar_state(enabled)) }
}
pub fn set_rule_enabled<S: AsRef<str>>(&self, name: S, enabled: bool) -> Result<()> {
let _pause = self.pauser.pause()?;
unsafe {
self.intf
.SetRuleState(name.as_ref(), null_mut(), rule_state(enabled))
}
}
}
impl Drop for Grammar {
fn drop(&mut self) {
let _pause = self.pauser.pause();
unsafe { ManuallyDrop::drop(&mut self.intf) };
}
}
fn grammar_state(enabled: bool) -> SPGRAMMARSTATE {
if enabled {
SPGS_ENABLED
} else {
SPGS_DISABLED
}
}
fn rule_state(enabled: bool) -> SPRULESTATE {
if enabled {
SPRS_ACTIVE
} else {
SPRS_INACTIVE
}
}