use std::os::fd::OwnedFd;
use std::os::unix::net::UnixStream;
use std::sync::{Mutex, MutexGuard};
use crate::dbus::*;
use crate::error::*;
pub trait LoaderImplementation: Send {
fn init(
&self,
stream: UnixStream,
mime_type: String,
details: InitializationDetails,
) -> Result<ImageInfo, ProcessError>;
fn frame(&self, frame_request: FrameRequest) -> Result<Frame, ProcessError>;
}
pub struct Loader {
pub loader: Mutex<Box<dyn LoaderImplementation>>,
}
impl Loader {
pub fn get_loader(&self) -> Result<MutexGuard<Box<dyn LoaderImplementation>>, RemoteError> {
self.loader.lock().map_err(|err| {
RemoteError::InternalLoaderError(format!("Failed to lock decoder for operation: {err}"))
})
}
}
#[zbus::interface(name = "org.gnome.glycin.Loader")]
impl Loader {
async fn init(&self, init_request: InitRequest) -> Result<ImageInfo, RemoteError> {
let fd = OwnedFd::from(init_request.fd);
let stream = UnixStream::from(fd);
let image_info = self
.get_loader()?
.init(stream, init_request.mime_type, init_request.details)
.map_err(|x| x.into_loader_error())?;
Ok(image_info)
}
async fn frame(&self, frame_request: FrameRequest) -> Result<Frame, RemoteError> {
self.get_loader()?
.frame(frame_request)
.map_err(|x| x.into_loader_error())
}
}