1use std::ffi::CStr;
9use std::os::raw::c_char;
10
11use transcribe_cpp_sys as sys;
12
13use crate::types::TimestampKind;
14
15#[derive(Debug, Clone, Default, PartialEq)]
17pub struct Transcript {
18 pub text: String,
20 pub raw_text: String,
24 pub language: Option<String>,
27 pub timestamp_kind: TimestampKind,
29 pub segments: Vec<Segment>,
32 pub speaker_segments: Vec<SpeakerSegment>,
34 pub words: Vec<Word>,
36 pub tokens: Vec<Token>,
38 pub timings: Timings,
40}
41
42#[derive(Debug, Clone, Default, PartialEq)]
44pub struct Segment {
45 pub t0_ms: i64,
46 pub t1_ms: i64,
47 pub first_word: i32,
48 pub n_words: i32,
49 pub first_token: i32,
50 pub n_tokens: i32,
51 pub text: String,
52 pub speaker_id: i32,
54}
55
56#[derive(Debug, Clone, Default, PartialEq)]
59pub struct SpeakerSegment {
60 pub t0_ms: i64,
61 pub t1_ms: i64,
62 pub speaker_id: i32,
63 pub p: f32,
64}
65
66#[derive(Debug, Clone, Default, PartialEq)]
68pub struct Word {
69 pub t0_ms: i64,
70 pub t1_ms: i64,
71 pub seg_index: i32,
72 pub first_token: i32,
73 pub n_tokens: i32,
74 pub text: String,
75}
76
77#[derive(Debug, Clone, Default, PartialEq)]
80pub struct Token {
81 pub id: i32,
82 pub p: f32,
83 pub t0_ms: i64,
84 pub t1_ms: i64,
85 pub seg_index: i32,
86 pub word_index: i32,
87 pub text: String,
88}
89
90#[derive(Debug, Clone, Copy, Default, PartialEq)]
92pub struct Timings {
93 pub load_ms: f32,
94 pub mel_ms: f32,
95 pub encode_ms: f32,
96 pub decode_ms: f32,
97}
98
99pub(crate) fn owned_str(ptr: *const c_char) -> String {
101 if ptr.is_null() {
102 return String::new();
103 }
104 unsafe { CStr::from_ptr(ptr) }
105 .to_string_lossy()
106 .into_owned()
107}
108
109pub(crate) fn owned_opt_str(ptr: *const c_char) -> Option<String> {
111 if ptr.is_null() {
112 return None;
113 }
114 let s = unsafe { CStr::from_ptr(ptr) }
115 .to_string_lossy()
116 .into_owned();
117 if s.is_empty() {
118 None
119 } else {
120 Some(s)
121 }
122}
123
124impl Segment {
125 pub(crate) fn from_raw(raw: &sys::transcribe_segment) -> Self {
126 Segment {
127 t0_ms: raw.t0_ms,
128 t1_ms: raw.t1_ms,
129 first_word: raw.first_word,
130 n_words: raw.n_words,
131 first_token: raw.first_token,
132 n_tokens: raw.n_tokens,
133 text: owned_str(raw.text),
134 speaker_id: raw.speaker_id,
135 }
136 }
137}
138
139impl SpeakerSegment {
140 pub(crate) fn from_raw(raw: &sys::transcribe_speaker_segment) -> Self {
141 SpeakerSegment {
142 t0_ms: raw.t0_ms,
143 t1_ms: raw.t1_ms,
144 speaker_id: raw.speaker_id,
145 p: raw.p,
146 }
147 }
148}
149
150impl Word {
151 pub(crate) fn from_raw(raw: &sys::transcribe_word) -> Self {
152 Word {
153 t0_ms: raw.t0_ms,
154 t1_ms: raw.t1_ms,
155 seg_index: raw.seg_index,
156 first_token: raw.first_token,
157 n_tokens: raw.n_tokens,
158 text: owned_str(raw.text),
159 }
160 }
161}
162
163impl Token {
164 pub(crate) fn from_raw(raw: &sys::transcribe_token) -> Self {
165 Token {
166 id: raw.id,
167 p: raw.p,
168 t0_ms: raw.t0_ms,
169 t1_ms: raw.t1_ms,
170 seg_index: raw.seg_index,
171 word_index: raw.word_index,
172 text: owned_str(raw.text),
173 }
174 }
175}
176
177impl Timings {
178 pub(crate) fn from_raw(raw: &sys::transcribe_timings) -> Self {
179 Timings {
180 load_ms: raw.load_ms,
181 mel_ms: raw.mel_ms,
182 encode_ms: raw.encode_ms,
183 decode_ms: raw.decode_ms,
184 }
185 }
186}