use can_hal::driver::{ChannelBuilder, Driver, DriverFd};
use crate::channel::SocketCanChannel;
use crate::error::SocketCanError;
enum InterfaceSpec {
Index(u32),
Name(String),
}
pub struct SocketCanDriver;
impl SocketCanDriver {
#[must_use]
pub const fn new() -> Self {
Self
}
pub fn channel_by_name(&self, name: &str) -> Result<SocketCanChannelBuilder, SocketCanError> {
Ok(SocketCanChannelBuilder {
interface: InterfaceSpec::Name(name.to_string()),
bitrate: None,
data_bitrate: None,
sample_point: None,
})
}
}
impl Default for SocketCanDriver {
fn default() -> Self {
Self::new()
}
}
impl DriverFd for SocketCanDriver {}
impl Driver for SocketCanDriver {
type Channel = SocketCanChannel;
type Builder = SocketCanChannelBuilder;
type Error = SocketCanError;
fn channel(&self, index: u32) -> Result<Self::Builder, Self::Error> {
Ok(SocketCanChannelBuilder {
interface: InterfaceSpec::Index(index),
bitrate: None,
data_bitrate: None,
sample_point: None,
})
}
}
pub struct SocketCanChannelBuilder {
interface: InterfaceSpec,
bitrate: Option<u32>,
data_bitrate: Option<u32>,
sample_point: Option<f32>,
}
impl ChannelBuilder for SocketCanChannelBuilder {
type Channel = SocketCanChannel;
type Error = SocketCanError;
fn bitrate(mut self, bitrate: u32) -> Result<Self, Self::Error> {
self.bitrate = Some(bitrate);
Ok(self)
}
fn data_bitrate(mut self, bitrate: u32) -> Result<Self, Self::Error> {
self.data_bitrate = Some(bitrate);
Ok(self)
}
fn sample_point(mut self, sample_point: f32) -> Result<Self, Self::Error> {
self.sample_point = Some(sample_point);
Ok(self)
}
fn connect(self) -> Result<Self::Channel, Self::Error> {
match self.interface {
InterfaceSpec::Index(idx) => SocketCanChannel::open_iface(idx),
InterfaceSpec::Name(ref name) => SocketCanChannel::open(name),
}
}
}