pub mod controllers;
mod error;
use pulse::{
context::{introspect::Introspector, Context},
mainloop::standard::{IterateResult, Mainloop},
operation::{Operation, State},
proplist::Proplist,
};
use std::cell::RefCell;
use std::ops::Deref;
use std::rc::Rc;
pub use crate::controllers::error::ControllerError;
pub use crate::error::Error;
pub struct Handler {
pub mainloop: Rc<RefCell<Mainloop>>,
pub context: Rc<RefCell<Context>>,
pub introspect: Introspector,
}
impl Handler {
pub fn connect(name: &str) -> Result<Handler, Error> {
let mut proplist = Proplist::new().unwrap();
proplist
.set_str(pulse::proplist::properties::APPLICATION_NAME, name)
.unwrap();
let mainloop = match Mainloop::new() {
Some(mainloop) => Rc::new(RefCell::new(mainloop)),
None => return Err(Error::Connect("Failed to create mainloop".to_string())),
};
let context =
match Context::new_with_proplist(mainloop.borrow().deref(), "MainConn", &proplist) {
Some(context) => Rc::new(RefCell::new(context)),
None => return Err(Error::Connect("Failed to create new context".to_string())),
};
context
.borrow_mut()
.connect(None, pulse::context::FlagSet::NOFLAGS, None)
.map_err(|_| Error::Connect("Failed to connect context".to_string()))?;
loop {
match mainloop.borrow_mut().iterate(false) {
IterateResult::Err(e) => {
eprintln!("iterate state was not success, quitting...");
return Err(e.into());
}
IterateResult::Success(_) => {}
IterateResult::Quit(_) => {
eprintln!("iterate state was not success, quitting...");
return Err(Error::Connect(
"Iterate state quit without an error".to_string(),
));
}
}
match context.borrow().get_state() {
pulse::context::State::Ready => break,
pulse::context::State::Failed | pulse::context::State::Terminated => {
eprintln!("context state failed/terminated, quitting...");
return Err(Error::Connect(
"Context state failed/terminated without an error".to_string(),
));
}
_ => {}
}
}
let introspect = context.borrow_mut().introspect();
Ok(Handler {
mainloop,
context,
introspect,
})
}
pub fn wait_for_operation<G: ?Sized>(&mut self, op: Operation<G>) -> Result<(), Error> {
loop {
match self.mainloop.borrow_mut().iterate(false) {
IterateResult::Err(e) => return Err(e.into()),
IterateResult::Success(_) => {}
IterateResult::Quit(_) => {
return Err(Error::Operation(
"Iterate state quit without an error".to_string(),
));
}
}
match op.get_state() {
State::Done => {
break;
}
State::Running => {}
State::Cancelled => {
return Err(Error::Operation(
"Operation cancelled without an error".to_string(),
));
}
}
}
Ok(())
}
}
impl Drop for Handler {
fn drop(&mut self) {
self.context.borrow_mut().disconnect();
self.mainloop.borrow_mut().quit(pulse::def::Retval(0));
}
}