use std::io;
#[allow(unused)]
use std::{convert::TryInto, ffi::OsStr};
use crate::{
channel::ChannelSender,
ll::{fuse_abi::fuse_notify_code as notify_code, notify::Notification},
reply::ReplySender,
};
#[derive(Debug)]
pub struct Notifier(ChannelSender);
impl Notifier {
pub(crate) fn new(cs: ChannelSender) -> Self {
Self(cs)
}
#[cfg(feature = "abi-7-11")]
pub fn poll(&self, kh: u64) -> io::Result<()> {
let notif = Notification::new_poll(kh);
self.send(notify_code::FUSE_POLL, ¬if)
}
#[cfg(feature = "abi-7-12")]
pub fn inval_entry(&self, parent: u64, name: &OsStr) -> io::Result<()> {
let notif = Notification::new_inval_entry(parent, name).map_err(Self::too_big_err)?;
self.send_inval(notify_code::FUSE_NOTIFY_INVAL_ENTRY, ¬if)
}
#[cfg(feature = "abi-7-12")]
pub fn inval_inode(&self, ino: u64, offset: i64, len: i64) -> io::Result<()> {
let notif = Notification::new_inval_inode(ino, offset, len);
self.send_inval(notify_code::FUSE_NOTIFY_INVAL_INODE, ¬if)
}
#[cfg(feature = "abi-7-15")]
pub fn store(&self, ino: u64, offset: u64, data: &[u8]) -> io::Result<()> {
let notif = Notification::new_store(ino, offset, data).map_err(Self::too_big_err)?;
self.send_inval(notify_code::FUSE_NOTIFY_STORE, ¬if)
}
#[cfg(feature = "abi-7-18")]
pub fn delete(&self, parent: u64, child: u64, name: &OsStr) -> io::Result<()> {
let notif = Notification::new_delete(parent, child, name).map_err(Self::too_big_err)?;
self.send_inval(notify_code::FUSE_NOTIFY_DELETE, ¬if)
}
#[allow(unused)]
fn send_inval(&self, code: notify_code, notification: &Notification<'_>) -> io::Result<()> {
match self.send(code, notification) {
Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(()),
x => x,
}
}
fn send(&self, code: notify_code, notification: &Notification<'_>) -> io::Result<()> {
notification
.with_iovec(code, |iov| self.0.send(iov))
.map_err(Self::too_big_err)?
}
fn too_big_err(tfie: std::num::TryFromIntError) -> io::Error {
io::Error::new(io::ErrorKind::Other, format!("Data too large: {}", tfie))
}
}