You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: request.rs
    path of file: ./repos/fuse-rs/src/ll
    
    the code of the file until where you have to start completion: //! Low-level filesystem operation request.
//!
//! A request represents information about a filesystem operation the kernel driver wants us to
//! perform.

use fuse_abi::*;
use std::convert::TryFrom;
use std::ffi::OsStr;
use std::{error, fmt, mem};

use super::argument::ArgumentIterator;


/// Error that may occur while reading and parsing a request from the kernel driver.
#[derive(Debug)]
pub enum RequestError {
    /// Not enough data for parsing header (short read).
    ShortReadHeader(usize),
    /// Kernel requested an unknown operation.
    UnknownOperation(u32),
    /// Not enough data for arguments (short read).
    ShortRead(usize, usize),
    /// Insufficient argument data.
    InsufficientData,
}

impl fmt::Display for RequestError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            RequestError::ShortReadHeader(len) => write!(f, "Short read of FUSE request header ({} < {})", len, mem::size_of::<fuse_in_header>()),
            RequestError::UnknownOperation(opcode) => write!(f, "Unknown FUSE opcode ({})", opcode),
            RequestError::ShortRead(len, total) => write!(f, "Short read of FUSE request ({} < {})", len, total),
            RequestError::InsufficientData => write!(f, "Insufficient argument data"),
        }
    }
}

impl error::Error for RequestError {}


/// Filesystem operation (and arguments) the kernel driver wants us to perform. The fields of each
/// variant needs to match the actual arguments the kernel driver sends for the specific operation.
#[derive(Debug)]
pub enum Operation<'a> {
    Lookup {
        name: &'a OsStr,
    },
    Forget {
        arg: &'a fuse_forget_in,
    },
    GetAttr,
    SetAttr {
        arg: &'a fuse_setattr_in,
    },
    ReadLink,
    SymLink {
        name: &'a OsStr,
        link: &'a OsStr,
    },
    MkNod {
        arg: &'a fuse_mknod_in,
        name: &'a OsStr,
    },
    MkDir {
        arg: &'a fuse_mkdir_in,
        name: &'a OsStr,
    },
    Unlink {
        name: &'a OsStr,
    },
    RmDir {
        name: &'a OsStr,
    },
    Rename {
        arg: &'a fuse_rename_in,
        name: &'a OsStr,
        newname: &'a OsStr,
    },
    Link {
        arg: &'a fuse_link_in,
        name: &'a OsStr,
    },
    Open {
        arg: &'a fuse_open_in,
    },
    Read {
        arg: &'a fuse_read_in,
    },
    Write {
        arg: &'a fuse_write_in,
        data: &'a [u8],
    },
    StatFs,
    Release {
        arg: &'a fuse_release_in,
    },
    FSync {
        arg: &'a fuse_fsync_in,
    },
    SetXAttr {
        arg: &'a fuse_setxattr_in,
        name: &'a OsStr,
        value: &'a [u8],
    },
    GetXAttr {
        arg: &'a fuse_getxattr_in,
        name: &'a OsStr,
    },
    ListXAttr {
        arg: &'a fuse_getxattr_in,
    },
    RemoveXAttr {
        name: &'a OsStr,
    },
    Flush {
        arg: &'a fuse_flush_in,
    },
    Init {
        arg: &'a fuse_init_in,
    },
    OpenDir {
        arg: &'a fuse_open_in,
    },
    ReadDir {
        arg: &'a fuse_read_in,
    },
    ReleaseDir {
        arg: &'a fuse_release_in,
    },
    FSyncDir {
        arg: &'a fuse_fsync_in,
    },
    GetLk {
        arg: &'a fuse_lk_in,
    },
    SetLk {
        a
    
    fn parse(opcode: &fuse_opcode, data: &mut ArgumentIterator<'a>) -> Option<Self> {
        unsafe {
            Some(match opcode {
                fuse_opcode::FUSE_LOOKUP => Operation::Lookup {
                    name: data.fetch_str()?,
                },
                fuse_opcode::FUSE_FORGET => Operation::Forget { arg: data.fetch()? },
                fuse_opcode::FUSE_GETATTR => Operation::GetAttr,
                fuse_opcode::FUSE_SETATTR => Operation::SetAttr { arg: data.fetch()? },
                fuse_opcode::FUSE_READLINK => Operation::ReadLink,
                fuse_opcode::FUSE_SYMLINK => Operation::SymLink {
                    name: data.fetch_str()?,
                    link: data.fetch_str()?,
                },
                fuse_opcode::FUSE_MKNOD => Operation::MkNod {
                    arg: data.fetch()?,
                    name: data.fetch_str()?,
                },
                fuse_opcode::FUSE_MKDIR => Operation::MkDir {
                    arg: data.fetch()?,
                    name: data.fetch_str()?,
                },
                fuse_opcode::FUSE_UNLINK => Operation::Unlink {
                    name: data.fetch_str()?,
                },
                fuse_opcode::FUSE_RMDIR => Operation::RmDir {
                    name: data.fetch_str()?,
                },
                fuse_opcode::FUSE_RENAME => Operation::Rename {
                    arg: data.fetch()?,
                    name: data.fetch_str()?,
                    newname: data.fetch_str()?,
                },
                fuse_opcode::FUSE_LINK => Operation::Link {
                    arg: data.fetch()?,
                    name: data.fetch_str()?,
                },
                fuse_opcode::FUSE_OPEN => Operation::Open { arg: data.fetch()? },
                fuse_opcode::FUSE_READ => Operation::Read { arg: data.fetch()? },
                fuse_opcode::FUSE_WRITE => Operation::Write {
                    arg: data.fetch()?,
                    data: data.fetch_all(),
                },
                fuse_opcode::FUSE_STATFS => Operation::StatFs,
                fuse_opcode::FUSE_RELEASE => Operation::Release { arg: data.fetch()? },
                fuse_opcode::FUSE_FSYNC => Operation::FSync { arg: data.fetch()? },
                fuse_opcode::FUSE_SETXATTR => Operation::SetXAttr {
                    arg: data.fetch()?,
                    name: data.fetch_str()?,
                    value: data.fetch_all(),
                },
                fuse_opcode::FUSE_GETXATTR => Operation::GetXAttr {
                    arg: data.fetch()?,
                    name: data.fetch_str()?,
                },
                fuse_opcode::FUSE_LISTXATTR => Operation::ListXAttr { arg: data.fetch()? },
                fuse_opcode::FUSE_REMOVEXATTR => Operation::RemoveXAttr {
                    name: data.fetch_str()?,
                },
                fuse_opcode::FUSE_FLUSH => Operation::Flush { arg: data.fetch()? },
                fuse_opcode::FUSE_INIT => Operation::Init { arg: data.fetch()? },
                fuse_opcode::FUSE_OPENDIR => Operation::OpenDir { arg: data.fetch()? },
                fuse_opcode::FUSE_READDIR => Operation::ReadDir { arg: data.fetch()? },
                fuse_opcode::FUSE_RELEASEDIR => Operation::ReleaseDir { arg: data.fetch()? },
                fuse_opcode::FUSE_FSYNCDIR => Operation::FSyncDir { arg: data.fetch()? },
                fuse_opcode::FUSE_GETLK => Operation::GetLk { arg: data.fetch()? },
                fuse_opcode::FUSE_SETLK => Operation::SetLk { arg: data.fetch()? },
                fuse_opcode::FUSE_SETLKW => Operation::SetLkW { arg: data.fetch()? },
                fuse_opcode::FUSE_ACCESS => Operation::Access { arg: data.fetch()? },
                fuse_opcode::FUSE_CREATE => Operation::Create {
                    arg: data.fetch()?,
                    name: data.fetch_str()?,
                },
                fuse_opcode::FUSE_INTERRUPT => Operation::Interrupt { arg: data.fetch()? },
                fuse_opcode::FUSE_BMAP => Operation::BMap { arg: data.fetch()? },
                fuse_opcode::FUSE_DESTROY => Operation::Destroy,

                #[cfg(target_os = "macos")]
                fuse_opcode::FUSE_SETVOLNAME => Operation::SetVolName {
                    name: data.fetch_str()?,
                },
                #[cfg(target_os = "macos")]
                fuse_opcode::FUSE_GETXTIMES => Operation::GetXTimes,
                #[cfg(target_os = "macos")]
                fuse_opcode::FUSE_EXCHANGE => Operation::Exchange {
                    arg: data.fetch()?,
                    oldname: data.fetch_str()?,
                    newname: data.fetch_str()?,
                },
            })
        }
    }