jay-compositor 1.15.0

The Jay compositor
use crate::utils::box_cache::BoxReset;
use crate::utils::box_cache::CachedBox;
use crate::utils::fuse::fuse_out::Fov;
use crate::utils::fuse::fuse_out::FuseOut;
use crate::utils::fuse::fuse_out::FuseOutNew;
use crate::utils::fuse::fuse_sys::fuse_attr_out;
use crate::utils::fuse::fuse_sys::fuse_entry_out;
use crate::utils::fuse::fuse_sys::fuse_init_out;
use crate::utils::fuse::fuse_sys::fuse_open_out;
use crate::utils::fuse::fuse_sys::fuse_statfs_out;
use jay_proc::Pod;
use std::rc::Rc;
use uapi::c::iovec;

#[derive(Pod)]
pub struct ErrorOut;

unsafe impl FuseOut for ErrorOut {
    const NUM_IOVECS: usize = 1;
}

unsafe impl FuseOut for fuse_init_out {
    const NUM_IOVECS: usize = 2;
}

unsafe impl FuseOut for fuse_attr_out {
    const NUM_IOVECS: usize = 2;
}

unsafe impl FuseOut for fuse_entry_out {
    const NUM_IOVECS: usize = 2;
}

unsafe impl FuseOut for fuse_open_out {
    const NUM_IOVECS: usize = 2;
}

unsafe impl FuseOut for fuse_statfs_out {
    const NUM_IOVECS: usize = 2;
}

#[derive(Pod)]
pub struct EmptyOut;

unsafe impl FuseOut for EmptyOut {
    const NUM_IOVECS: usize = 1;
}

#[derive(Default)]
pub struct BytesOut {
    pub buf: Vec<u8>,
}

impl FuseOutNew for BytesOut {
    fn new() -> Self {
        Self::default()
    }
}

unsafe impl FuseOut for BytesOut {
    const NUM_IOVECS: usize = 2;

    fn fini(v: &mut Box<Fov<Self>>) {
        v.iovecs[1] = iovec {
            iov_base: v.t.buf.as_mut_ptr().cast(),
            iov_len: v.t.buf.len(),
        };
    }

    fn reset(&mut self) {
        self.buf.clear();
    }
}

#[derive(Default)]
pub struct FileReadOut {
    pub data: Option<Rc<CachedBox<String, BoxReset>>>,
    pub offset: usize,
    pub len: usize,
}

impl FuseOutNew for FileReadOut {
    fn new() -> Self {
        Self::default()
    }
}

unsafe impl FuseOut for FileReadOut {
    const NUM_IOVECS: usize = 2;

    fn fini(v: &mut Box<Fov<Self>>) {
        let s = v.t.data.as_ref().map(|v| v.as_str()).unwrap_or_default();
        let offset = v.t.offset.min(s.len());
        let len = v.t.len.min(s.len() - offset);
        unsafe {
            v.iovecs[1] = iovec {
                iov_base: s.as_ptr().add(offset).cast_mut().cast(),
                iov_len: len as _,
            };
        }
    }

    fn reset(&mut self) {
        self.data.take();
    }
}