domasi/src/alert.rs

114 lines
2.9 KiB
Rust

use rodio::{decoder::DecoderError, Decoder, OutputStream, PlayError, Sink, StreamError};
use std::fs::File;
use std::io::BufReader;
use std::path::PathBuf;
use std::thread;
use std::{error::Error, fmt::Display, fmt::Formatter, fmt::Result as FmtResult};
#[derive(Debug, Clone)]
pub struct Alert {
path: PathBuf,
}
impl Alert {
pub fn new(path: PathBuf) -> Self {
Self { path }
}
pub fn load(&mut self, path: PathBuf) {
self.path = path;
}
// pub fn play(&self) -> Result<(), Box<dyn Error>> {
// let file = File::open(&self.path).unwrap();
// thread::Builder::new()
// .name("Audio Thread".to_string())
// .spawn(|| -> Result<(), Error> {
// let (_stream, handle) = OutputStream::try_default()?;
// let source = Decoder::new(BufReader::new(file))?;
// let sink = Sink::try_new(&handle)?;
// sink.append(source);
// loop {
// if sink.len() == 0 {
// break;
// }
// }
// Ok(())
// })?;
// Ok(())
// }
pub fn play(&self) -> Result<(), Box<dyn Error>> {
let file = File::open(&self.path).unwrap();
thread::Builder::new()
.name("Alert Playback Thread".to_string())
.spawn(move || -> Result<(), PlaybackError> {
let (_stream, handle) = OutputStream::try_default()?;
let source = Decoder::new(BufReader::new(file))?;
let sink = Sink::try_new(&handle)?;
sink.append(source);
loop {
if sink.len() == 0 {
break;
}
}
Ok(())
})?;
Ok(())
}
}
#[derive(Debug)]
enum PlaybackError {
StreamError(StreamError),
DecoderError(DecoderError),
SinkError(PlayError),
}
impl From<DecoderError> for PlaybackError {
fn from(err: DecoderError) -> Self {
Self::DecoderError(err)
}
}
impl From<StreamError> for PlaybackError {
fn from(err: StreamError) -> Self {
Self::StreamError(err)
}
}
impl From<PlayError> for PlaybackError {
fn from(err: PlayError) -> Self {
Self::SinkError(err)
}
}
impl Error for PlaybackError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match &self {
Self::StreamError(err) => Some(err),
Self::DecoderError(err) => Some(err),
Self::SinkError(err) => Some(err),
}
}
}
impl Display for PlaybackError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match &self {
Self::StreamError(err) => write!(f, "{}", err),
Self::DecoderError(err) => write!(f, "{}", err),
Self::SinkError(err) => write!(f, "{}", err),
}
}
}