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