Skip to main content

transcribe_cpp/
streaming.rs

1//! Streaming data types and the stream-params builder.
2//!
3//! The [`Stream`](crate::Stream) handle itself lives in `session.rs` (it needs
4//! the session internals); this module holds the owned option/result types it
5//! exchanges.
6
7use transcribe_cpp_sys as sys;
8
9use crate::family::{StreamExtRaw, StreamExtension};
10use crate::result::owned_str;
11use crate::types::CommitPolicy;
12
13/// Options for beginning a stream.
14#[derive(Debug, Clone, PartialEq, Eq, Default)]
15pub struct StreamOptions {
16    /// When committed text grows. Default [`CommitPolicy::Auto`].
17    pub commit_policy: CommitPolicy,
18    /// Consecutive agreeing hypotheses required before a prefix commits
19    /// (stable-prefix policies). 0 selects the library default (3).
20    pub stable_prefix_agreement_n: u32,
21    /// Optional family-specific stream extension.
22    pub family: Option<StreamExtension>,
23}
24
25/// Per-call change metadata from `feed`/`finalize`.
26#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
27pub struct StreamUpdate {
28    /// Any observable property of the snapshot changed this call.
29    pub result_changed: bool,
30    /// True only on the `finalize` call's update.
31    pub is_final: bool,
32    /// Monotonic snapshot revision; diff against the previous value.
33    pub revision: i32,
34    /// Total audio received since begin (ms).
35    pub input_received_ms: i64,
36    /// Family-reported audio progress / drain hint (ms).
37    pub audio_committed_ms: i64,
38    /// Audio still buffered inside the family's streaming state (ms).
39    pub buffered_ms: i64,
40    /// `committed_text` changed this call.
41    pub committed_changed: bool,
42    /// `tentative_text` changed this call.
43    pub tentative_changed: bool,
44}
45
46impl StreamUpdate {
47    pub(crate) fn from_raw(raw: &sys::transcribe_stream_update) -> Self {
48        StreamUpdate {
49            result_changed: raw.result_changed,
50            is_final: raw.is_final,
51            revision: raw.revision,
52            input_received_ms: raw.input_received_ms,
53            audio_committed_ms: raw.audio_committed_ms,
54            buffered_ms: raw.buffered_ms,
55            committed_changed: raw.committed_changed,
56            tentative_changed: raw.tentative_changed,
57        }
58    }
59}
60
61/// A UI-facing snapshot of the stream's text, fully owned.
62#[derive(Debug, Clone, Default, PartialEq, Eq)]
63pub struct StreamText {
64    /// The raw current model hypothesis (authoritative; may rewrite anywhere).
65    pub full: String,
66    /// The append-only, flicker-free display/input prefix.
67    pub committed: String,
68    /// The volatile raw suffix after the committed prefix.
69    pub tentative: String,
70}
71
72impl StreamText {
73    /// `committed + tentative` — the flicker-free render most UIs want.
74    pub fn display(&self) -> String {
75        format!("{}{}", self.committed, self.tentative)
76    }
77
78    pub(crate) fn from_raw(raw: &sys::transcribe_stream_text) -> Self {
79        StreamText {
80            full: owned_str(raw.full_text),
81            committed: owned_str(raw.committed_text),
82            tentative: owned_str(raw.tentative_text),
83        }
84    }
85}
86
87/// Build `transcribe_stream_params`, returning the family-ext keepalive so its
88/// backing struct outlives the `transcribe_stream_begin` call.
89pub(crate) fn build_stream_params(
90    o: &StreamOptions,
91) -> (sys::transcribe_stream_params, Option<StreamExtRaw>) {
92    let mut params: sys::transcribe_stream_params = unsafe { std::mem::zeroed() };
93    unsafe { sys::transcribe_stream_params_init(&mut params) };
94    params.commit_policy = o.commit_policy.to_raw();
95    params.stable_prefix_agreement_n = o.stable_prefix_agreement_n;
96
97    let family = o.family.as_ref().map(StreamExtension::materialize);
98    params.family = family.as_ref().map_or(std::ptr::null(), |f| f.ext_ptr());
99    (params, family)
100}