1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// --- Transcription Service ---
// This Tower service takes WAV audio requests and returns transcription results.
// It wraps the configured TranscriptionProvider and handles all provider errors.
use Arc;
use ;
use Pin;
use Future;
use Mutex;
use Service;
use crate;
use crateTranscriptionProvider;
/// Tower Service that handles transcription of WAV audio data.
// #[cfg(test)]
// mod tests {
// use super::*;
// use crate::pipeline::types::{WavAudioRequest, AudioResponse, ProcessedData, PipelineError};
// use crate::providers::TranscriptionProvider;
// use std::sync::Arc;
// use tokio::sync::Mutex;
// use tower::Service;
// use futures::executor::block_on;
// struct MockTranscriptionProvider {
// result: Option<String>,
// fail: bool,
// }
// #[async_trait::async_trait]
// impl TranscriptionProvider for MockTranscriptionProvider {
// fn name(&self) -> &'static str {
// "MockTranscriptionProvider"
// }
// fn min_chunk_duration(&self) -> std::time::Duration {
// std::time::Duration::from_secs(1)
// }
// async fn transcribe(&self, _wav_data: &[u8]) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
// if self.fail {
// Err("mock provider error".into())
// } else {
// Ok(self.result.clone().unwrap_or_else(|| "mocked transcription".to_string()))
// }
// }
// }
// fn make_service(provider: MockTranscriptionProvider) -> TranscriptionService {
// let boxed: Box<dyn TranscriptionProvider + Send + Sync> = Box::new(provider);
// TranscriptionService::new(Arc::new(Mutex::new(boxed)))
// }
// #[tokio::test]
// async fn test_transcription_service_success() {
// // Test normal transcription path with valid WAV data
// let provider = MockTranscriptionProvider { result: Some("hello world".to_string()), fail: false };
// let mut service = make_service(provider);
// let req = WavAudioRequest { wav_data: vec![1, 2, 3], timestamp: std::time::SystemTime::now() };
// service.poll_ready(&mut std::task::Context::from_waker(futures::task::noop_waker_ref())).unwrap();
// let resp = service.call(req).await.unwrap();
// match resp.result_data {
// ProcessedData::Transcription(text) => assert_eq!(text, "hello world"),
// }
// }
// #[tokio::test]
// async fn test_transcription_service_empty_audio() {
// // Test transcription with empty WAV data (should still return mocked transcription)
// let provider = MockTranscriptionProvider { result: Some("empty input".to_string()), fail: false };
// let mut service = make_service(provider);
// let req = WavAudioRequest { wav_data: vec![], timestamp: std::time::SystemTime::now() };
// service.poll_ready(&mut std::task::Context::from_waker(futures::task::noop_waker_ref())).unwrap();
// let resp = service.call(req).await.unwrap();
// match resp.result_data {
// ProcessedData::Transcription(text) => assert_eq!(text, "empty input"),
// }
// }
// #[tokio::test]
// async fn test_transcription_service_provider_error() {
// // Test that provider error is mapped to PipelineError::Transcription
// let provider = MockTranscriptionProvider { result: None, fail: true };
// let mut service = make_service(provider);
// let req = WavAudioRequest { wav_data: vec![1, 2, 3], timestamp: std::time::SystemTime::now() };
// service.poll_ready(&mut std::task::Context::from_waker(futures::task::noop_waker_ref())).unwrap();
// let err = service.call(req).await.unwrap_err();
// match err {
// PipelineError::Transcription(msg) => assert!(msg.contains("mock provider error")),
// _ => panic!("Expected PipelineError::Transcription, got {:?}", err),
// }
// }
// // Optionally, test concurrency if desired
// #[tokio::test]
// async fn test_transcription_service_concurrent_calls() {
// // Service should be usable from multiple tasks concurrently
// let provider = MockTranscriptionProvider { result: Some("concurrent".to_string()), fail: false };
// let service = Arc::new(Mutex::new(make_service(provider)));
// let req = WavAudioRequest { wav_data: vec![1, 2, 3], timestamp: std::time::SystemTime::now() };
// let handles: Vec<_> = (0..4).map(|_| {
// let service = service.clone();
// let req = req.clone();
// tokio::spawn(async move {
// let mut svc = service.lock().await;
// svc.poll_ready(&mut std::task::Context::from_waker(futures::task::noop_waker_ref())).unwrap();
// let resp = svc.call(req).await.unwrap();
// match resp.result_data {
// ProcessedData::Transcription(text) => assert_eq!(text, "concurrent"),
// }
// })
// }).collect();
// for h in handles {
// h.await.unwrap();
// }
// }
// }