use alloc::{string::String, vec::Vec};
use futures_core::Stream;
pub type Data = Vec<u8>;
pub trait AudioGenerator {
fn generate(&self, prompt: &str) -> impl Stream<Item = Data> + Send;
}
pub trait AudioTranscriber {
fn transcribe(&self, audio: &[u8]) -> impl Stream<Item = String> + Send;
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::{string::ToString, vec};
use futures_lite::StreamExt;
struct MockAudioGenerator;
impl AudioGenerator for MockAudioGenerator {
fn generate(&self, prompt: &str) -> impl Stream<Item = Data> + Send {
let chunks = if prompt.is_empty() {
vec![]
} else if prompt.len() < 10 {
vec![vec![0x01; 512]] } else {
vec![
vec![0x01; 512], vec![0x02; 1024], vec![0x03; 256], ]
};
futures_lite::stream::iter(chunks)
}
}
struct MockAudioTranscriber;
impl AudioTranscriber for MockAudioTranscriber {
fn transcribe(&self, audio: &[u8]) -> impl Stream<Item = String> + Send {
let text_chunks = if audio.is_empty() {
vec![]
} else if audio.len() < 100 {
vec!["Short".to_string()]
} else if audio.len() < 1000 {
vec!["Hello".to_string(), " world".to_string()]
} else {
vec![
"This".to_string(),
" is".to_string(),
" a".to_string(),
" longer".to_string(),
" transcription".to_string(),
]
};
futures_lite::stream::iter(text_chunks)
}
}
#[tokio::test]
async fn audio_generator_short_prompt() {
let generator = MockAudioGenerator;
let mut stream = generator.generate("Hi");
let mut chunks = Vec::new();
while let Some(chunk) = stream.next().await {
chunks.push(chunk);
}
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].len(), 512);
assert_eq!(chunks[0][0], 0x01);
}
#[tokio::test]
async fn audio_generator_long_prompt() {
let generator = MockAudioGenerator;
let mut stream = generator
.generate("This is a longer prompt that should generate multiple audio chunks");
let mut chunks = Vec::new();
while let Some(chunk) = stream.next().await {
chunks.push(chunk);
}
assert_eq!(chunks.len(), 3);
assert_eq!(chunks[0].len(), 512);
assert_eq!(chunks[1].len(), 1024);
assert_eq!(chunks[2].len(), 256);
assert_eq!(chunks[0][0], 0x01);
assert_eq!(chunks[1][0], 0x02);
assert_eq!(chunks[2][0], 0x03);
}
#[tokio::test]
async fn audio_generator_empty_prompt() {
let generator = MockAudioGenerator;
let mut stream = generator.generate("");
let mut chunks = Vec::new();
while let Some(chunk) = stream.next().await {
chunks.push(chunk);
}
assert!(chunks.is_empty());
}
#[tokio::test]
async fn audio_transcriber_short_audio() {
let transcriber = MockAudioTranscriber;
let audio_data = vec![0x01; 50]; let mut stream = transcriber.transcribe(&audio_data);
let mut text_chunks = Vec::new();
while let Some(chunk) = stream.next().await {
text_chunks.push(chunk);
}
assert_eq!(text_chunks.len(), 1);
assert_eq!(text_chunks[0], "Short");
}
#[tokio::test]
async fn audio_transcriber_medium_audio() {
let transcriber = MockAudioTranscriber;
let audio_data = vec![0x01; 500]; let mut stream = transcriber.transcribe(&audio_data);
let mut text_chunks = Vec::new();
while let Some(chunk) = stream.next().await {
text_chunks.push(chunk);
}
assert_eq!(text_chunks.len(), 2);
assert_eq!(text_chunks[0], "Hello");
assert_eq!(text_chunks[1], " world");
}
#[tokio::test]
async fn audio_transcriber_long_audio() {
let transcriber = MockAudioTranscriber;
let audio_data = vec![0x01; 2000]; let mut stream = transcriber.transcribe(&audio_data);
let mut text_chunks = Vec::new();
while let Some(chunk) = stream.next().await {
text_chunks.push(chunk);
}
assert_eq!(text_chunks.len(), 5);
let full_text: String = text_chunks.join("");
assert_eq!(full_text, "This is a longer transcription");
}
#[tokio::test]
async fn audio_transcriber_empty_audio() {
let transcriber = MockAudioTranscriber;
let audio_data = vec![]; let mut stream = transcriber.transcribe(&audio_data);
let mut text_chunks = Vec::new();
while let Some(chunk) = stream.next().await {
text_chunks.push(chunk);
}
assert!(text_chunks.is_empty());
}
#[test]
fn data_type_alias() {
let data: Data = vec![1, 2, 3, 4, 5];
assert_eq!(data.len(), 5);
assert_eq!(data[0], 1);
assert_eq!(data[4], 5);
}
#[test]
fn data_operations() {
let mut data: Data = vec![0xFF; 1024];
assert_eq!(data.len(), 1024);
data.push(0x00);
assert_eq!(data.len(), 1025);
assert_eq!(data[1024], 0x00);
data.extend_from_slice(&[0x01, 0x02, 0x03]);
assert_eq!(data.len(), 1028);
assert_eq!(data[1025], 0x01);
assert_eq!(data[1026], 0x02);
assert_eq!(data[1027], 0x03);
data.clear();
assert!(data.is_empty());
}
#[test]
fn data_creation() {
let empty_data: Data = Vec::new();
assert!(empty_data.is_empty());
let filled_data: Data = vec![42; 100];
assert_eq!(filled_data.len(), 100);
assert!(filled_data.iter().all(|&x| x == 42));
}
#[tokio::test]
async fn audio_workflow() {
let generator = MockAudioGenerator;
let transcriber = MockAudioTranscriber;
let prompt = "Hello world";
let mut audio_stream = generator.generate(prompt);
let mut all_audio_data = Vec::new();
while let Some(chunk) = audio_stream.next().await {
all_audio_data.extend_from_slice(&chunk);
}
let mut transcription_stream = transcriber.transcribe(&all_audio_data);
let mut transcription_chunks = Vec::new();
while let Some(chunk) = transcription_stream.next().await {
transcription_chunks.push(chunk);
}
assert!(!all_audio_data.is_empty());
assert!(!transcription_chunks.is_empty());
let full_transcription: String = transcription_chunks.join("");
assert_eq!(full_transcription, "This is a longer transcription");
}
}