use std::os::unix::net::UnixStream;
use std::path::{Path, PathBuf};
use crate::error::Result;
use crate::model::{Interface, InterfaceDetails};
use crate::subscription::Subscription;
use crate::transport::{self, HmsgType};
use crate::wire;
pub const DEFAULT_SOCKET_PATH: &str = "/var/run/lldpd.socket";
#[derive(Debug)]
pub struct Client {
stream: UnixStream,
socket_path: PathBuf,
}
impl Client {
pub fn connect() -> Result<Self> {
Self::connect_to(DEFAULT_SOCKET_PATH)
}
pub fn connect_to<P: AsRef<Path>>(path: P) -> Result<Self> {
let stream = UnixStream::connect(path.as_ref())?;
Ok(Self {
stream,
socket_path: path.as_ref().to_path_buf(),
})
}
pub fn interfaces(&mut self) -> Result<Vec<Interface>> {
let payload = transport::request(&mut self.stream, HmsgType::GetInterfaces, &[])?;
wire::decode_interfaces(&payload)
}
pub fn interface(&mut self, ifname: &str) -> Result<InterfaceDetails> {
let request_payload = wire::encode_interface_name_request(ifname);
let payload =
transport::request(&mut self.stream, HmsgType::GetInterface, &request_payload)?;
wire::decode_hardware(&payload)
}
pub fn all_interfaces(&mut self) -> Result<Vec<InterfaceDetails>> {
let mut out = Vec::new();
for iface in self.interfaces()? {
match self.interface(&iface.name) {
Ok(details) => out.push(details),
Err(crate::error::Error::RequestRejected) => continue,
Err(e) => return Err(e),
}
}
Ok(out)
}
pub fn socket_path(&self) -> &Path {
&self.socket_path
}
pub fn subscribe(mut self) -> Result<Subscription> {
transport::request(&mut self.stream, HmsgType::Subscribe, &[])?;
Ok(Subscription {
stream: self.stream,
})
}
}