mod client_object;
pub(crate) mod client_socket;
mod server_spec;
use crate::implementation;
use implementation::client::ProtocolImplementations;
use std::os::fd;
use std::{io, path, rc};
pub struct Client(pub(crate) rc::Rc<client_socket::ClientSocket>);
impl Client {
pub fn open<T>(path: T) -> io::Result<Self>
where
T: AsRef<path::Path>,
{
Ok(Self(client_socket::ClientSocket::open(path)?))
}
pub fn from_fd<T>(fd: T) -> io::Result<Self>
where
T: Into<fd::OwnedFd>,
{
Ok(Self(client_socket::ClientSocket::from_fd(fd)?))
}
pub fn add_implementation<T>(&mut self, p_impl: T)
where
T: ProtocolImplementations + 'static,
{
self.0.add_implementation(Box::new(p_impl));
}
pub fn wait_for_handshake<D>(&mut self, state: &mut D) -> Result<(), io::Error> {
self.0.wait_for_handshake(state)
}
pub fn dispatch_events<D>(&self, state: &mut D, block: bool) -> Result<(), io::Error> {
self.0.dispatch_events(state, block)
}
pub fn roundtrip<D>(&self, state: &mut D) -> Result<(), io::Error> {
self.0.roundtrip(state)
}
#[must_use]
pub fn extract_loop_fd(&self) -> fd::BorrowedFd<'_> {
self.0.extract_loop_fd()
}
#[must_use]
pub fn is_handshake_done(&self) -> bool {
self.0.handshake_done.get()
}
pub fn bind<T: crate::Object, D: crate::Dispatch<T>>(
&self,
spec: &dyn implementation::types::ProtocolSpec,
version: u32,
state: &mut D,
) -> Result<T, io::Error> {
let obj = self.0.bind_protocol(spec, version)?;
let raw_obj: rc::Rc<dyn implementation::object::RawObject> = obj.clone();
let typed = T::from_object::<D>(raw_obj);
self.0.wait_for_object(&obj, state)?;
Ok(typed)
}
#[must_use]
pub fn get_spec(&self, name: &str) -> Option<server_spec::ServerSpec> {
self.0.get_spec(name)
}
#[must_use]
pub fn object_for_seq(
&self,
seq: u32,
) -> Option<rc::Rc<dyn implementation::object::RawObject>> {
self.0
.object_for_seq(seq)
.map(|obj| obj as rc::Rc<dyn implementation::object::RawObject>)
}
#[must_use]
pub fn object_for_id(&self, id: u32) -> Option<rc::Rc<dyn implementation::object::RawObject>> {
self.0
.object_for_id(id)
.map(|obj| obj as rc::Rc<dyn implementation::object::RawObject>)
}
}