use crate::{
frame::AsPtr, timestamp::CanTimestamps, CanAddr, CanAnyFrame, CanFrame, Error, Socket,
SocketOptions,
};
use futures::{ready, sink::Sink, stream::Stream};
use std::{
io,
os::unix::io::{AsRawFd, RawFd},
pin::Pin,
task::{Context, Poll},
time::{Duration, SystemTime},
};
#[cfg(any(feature = "async-io", feature = "async-std"))]
use async_io::Async;
#[cfg(all(
feature = "smol",
not(any(feature = "async-io", feature = "async-std"))
))]
use smol::Async;
#[derive(Debug)]
pub struct CanSocket(Async<crate::CanSocket>);
impl CanSocket {
pub fn open(ifname: &str) -> io::Result<Self> {
crate::CanSocket::open(ifname)?.try_into()
}
pub fn open_if(ifindex: u32) -> io::Result<Self> {
crate::CanSocket::open_iface(ifindex)?.try_into()
}
pub fn open_addr(addr: &CanAddr) -> io::Result<Self> {
crate::CanSocket::open_addr(addr)?.try_into()
}
pub async fn write_frame<F>(&self, frame: &F) -> io::Result<()>
where
F: Into<CanFrame> + AsPtr,
{
self.0.write_with(|fd| fd.write_frame(frame)).await
}
pub fn try_write_frame<F>(&self, frame: &F) -> io::Result<()>
where
F: Into<CanFrame> + AsPtr,
{
self.0.get_ref().write_frame(frame)
}
pub async fn read_frame(&self) -> io::Result<CanFrame> {
self.0.read_with(|fd| fd.read_frame()).await
}
pub fn try_read_frame(&self) -> io::Result<CanFrame> {
self.0.get_ref().read_frame()
}
pub fn has_hw_timestamps(&self) -> bool {
self.0.get_ref().has_hw_timestamps()
}
pub async fn read_frame_with_timestamp(&self) -> io::Result<(CanFrame, SystemTime)> {
self.0.read_with(|fd| fd.read_frame_with_timestamp()).await
}
pub async fn read_frame_with_timestamps(&self) -> io::Result<(CanFrame, CanTimestamps)> {
self.0.read_with(|fd| fd.read_frame_with_timestamps()).await
}
pub async fn read_frame_with_hw_timestamp(&self) -> io::Result<(CanFrame, Duration)> {
self.0
.read_with(|fd| fd.read_frame_with_hw_timestamp())
.await
}
}
impl SocketOptions for CanSocket {}
impl TryFrom<crate::CanSocket> for CanSocket {
type Error = io::Error;
fn try_from(sock: crate::CanSocket) -> Result<Self, Self::Error> {
Ok(Self(Async::new(sock)?))
}
}
impl AsRawFd for CanSocket {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
impl Stream for CanSocket {
type Item = crate::Result<CanFrame>;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
loop {
ready!(self.0.poll_readable(cx))?;
match self.0.get_ref().read_frame() {
Ok(frame) => return Poll::Ready(Some(Ok(frame))),
Err(e) if e.kind() == io::ErrorKind::WouldBlock => continue,
Err(e) => return Poll::Ready(Some(Err(e.into()))),
}
}
}
}
impl Sink<CanFrame> for CanSocket {
type Error = Error;
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<crate::Result<()>> {
ready!(self.0.poll_writable(cx))?;
Poll::Ready(Ok(()))
}
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<crate::Result<()>> {
Poll::Ready(Ok(()))
}
fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<crate::Result<()>> {
Poll::Ready(Ok(()))
}
fn start_send(self: Pin<&mut Self>, item: CanFrame) -> crate::Result<()> {
self.0.get_ref().write_frame(&item)?;
Ok(())
}
}
#[derive(Debug)]
pub struct CanFdSocket(Async<crate::CanFdSocket>);
impl CanFdSocket {
pub fn open(ifname: &str) -> io::Result<Self> {
crate::CanFdSocket::open(ifname)?.try_into()
}
pub fn open_if(ifindex: u32) -> io::Result<Self> {
crate::CanFdSocket::open_iface(ifindex)?.try_into()
}
pub fn open_addr(addr: &CanAddr) -> io::Result<Self> {
crate::CanFdSocket::open_addr(addr)?.try_into()
}
pub async fn write_frame<F>(&self, frame: &F) -> io::Result<()>
where
F: Into<CanAnyFrame> + AsPtr,
{
self.0.write_with(|fd| fd.write_frame(frame)).await
}
pub fn try_write_frame<F>(&self, frame: &F) -> io::Result<()>
where
F: Into<CanAnyFrame> + AsPtr,
{
self.0.get_ref().write_frame(frame)
}
pub async fn read_frame(&self) -> io::Result<CanAnyFrame> {
self.0.read_with(|fd| fd.read_frame()).await
}
pub fn try_read_frame(&self) -> io::Result<CanAnyFrame> {
self.0.get_ref().read_frame()
}
pub fn has_hw_timestamps(&self) -> bool {
self.0.get_ref().has_hw_timestamps()
}
pub async fn read_frame_with_timestamp(&self) -> io::Result<(CanAnyFrame, SystemTime)> {
self.0.read_with(|fd| fd.read_frame_with_timestamp()).await
}
pub async fn read_frame_with_timestamps(&self) -> io::Result<(CanAnyFrame, CanTimestamps)> {
self.0.read_with(|fd| fd.read_frame_with_timestamps()).await
}
pub async fn read_frame_with_hw_timestamp(&self) -> io::Result<(CanAnyFrame, Duration)> {
self.0
.read_with(|fd| fd.read_frame_with_hw_timestamp())
.await
}
}
impl SocketOptions for CanFdSocket {}
impl TryFrom<crate::CanFdSocket> for CanFdSocket {
type Error = io::Error;
fn try_from(sock: crate::CanFdSocket) -> Result<Self, Self::Error> {
Ok(Self(Async::new(sock)?))
}
}
impl AsRawFd for CanFdSocket {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
impl Stream for CanFdSocket {
type Item = crate::Result<CanAnyFrame>;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
loop {
ready!(self.0.poll_readable(cx))?;
match self.0.get_ref().read_frame() {
Ok(frame) => return Poll::Ready(Some(Ok(frame))),
Err(e) if e.kind() == io::ErrorKind::WouldBlock => continue,
Err(e) => return Poll::Ready(Some(Err(e.into()))),
}
}
}
}
impl Sink<CanAnyFrame> for CanFdSocket {
type Error = Error;
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<crate::Result<()>> {
ready!(self.0.poll_writable(cx))?;
Poll::Ready(Ok(()))
}
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<crate::Result<()>> {
Poll::Ready(Ok(()))
}
fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<crate::Result<()>> {
Poll::Ready(Ok(()))
}
fn start_send(self: Pin<&mut Self>, item: CanAnyFrame) -> crate::Result<()> {
self.0.get_ref().write_frame(&item)?;
Ok(())
}
}