nfs3_client 0.8.0

Provides an implementation of NFS3 client
Documentation
//! Error types

use std::error::Error as StdError;
use std::fmt;

use nfs3_types::rpc::{accept_stat_data, rejected_reply};

#[derive(Debug)]
pub enum Error {
    Io(std::io::Error),
    Xdr(nfs3_types::xdr_codec::Error),
    Rpc(RpcError),
    Portmap(PortmapError),
    MountError(nfs3_types::mount::mountstat3),
    NfsError(nfs3_types::nfs3::nfsstat3),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Io(e) => e.fmt(f),
            Self::Xdr(e) => e.fmt(f),
            Self::Rpc(e) => e.fmt(f),
            Self::Portmap(e) => e.fmt(f),
            Self::MountError(e) => (*e as u32).fmt(f),
            Self::NfsError(e) => (*e as u32).fmt(f),
        }
    }
}

impl StdError for Error {}

impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Self {
        Self::Io(e)
    }
}

impl From<nfs3_types::xdr_codec::Error> for Error {
    fn from(e: nfs3_types::xdr_codec::Error) -> Self {
        Self::Xdr(e)
    }
}

impl From<RpcError> for Error {
    fn from(e: RpcError) -> Self {
        Self::Rpc(e)
    }
}

impl From<rejected_reply> for Error {
    fn from(e: rejected_reply) -> Self {
        Self::Rpc(e.into())
    }
}

#[derive(Debug)]
pub enum RpcError {
    UnexpectedCall,
    Auth,
    RpcMismatch,
    WrongLength,
    UnexpectedXid,
    NotFullyParsed { buf: Vec<u8>, pos: u64 },
    ProgUnavail,
    ProgMismatch,
    ProcUnavail,
    GarbageArgs,
    SystemErr,
}

impl fmt::Display for RpcError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::UnexpectedCall => write!(f, "Unexpected CALL request"),
            Self::Auth => write!(f, "Authentication error"),
            Self::RpcMismatch => write!(f, "RPC version mismatch"),
            Self::WrongLength => write!(f, "Wrong length in RPC message"),
            Self::UnexpectedXid => write!(f, "Unexpected XID in RPC reply"),
            Self::NotFullyParsed { .. } => write!(f, "Not fully parsed"),
            Self::ProgUnavail => write!(f, "Program unavailable"),
            Self::ProgMismatch => write!(f, "Program mismatch"),
            Self::ProcUnavail => write!(f, "Procedure unavailable"),
            Self::GarbageArgs => write!(f, "Garbage arguments"),
            Self::SystemErr => write!(f, "System error"),
        }
    }
}

impl StdError for RpcError {}

impl From<rejected_reply> for RpcError {
    fn from(e: rejected_reply) -> Self {
        match e {
            rejected_reply::RPC_MISMATCH { .. } => Self::RpcMismatch,
            rejected_reply::AUTH_ERROR(_) => Self::Auth,
        }
    }
}

impl TryFrom<accept_stat_data> for RpcError {
    type Error = ();

    fn try_from(value: accept_stat_data) -> Result<Self, Self::Error> {
        match value {
            accept_stat_data::SUCCESS => Err(()),
            accept_stat_data::PROG_UNAVAIL => Ok(Self::ProgUnavail),
            accept_stat_data::PROG_MISMATCH { .. } => Ok(Self::ProgMismatch),
            accept_stat_data::PROC_UNAVAIL => Ok(Self::ProcUnavail),
            accept_stat_data::GARBAGE_ARGS => Ok(Self::GarbageArgs),
            accept_stat_data::SYSTEM_ERR => Ok(Self::SystemErr),
        }
    }
}

#[derive(Debug)]
pub enum PortmapError {
    ProgramUnavailable,
    InvalidPortValue(u32),
}

impl fmt::Display for PortmapError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::ProgramUnavailable => write!(f, "Program unavailable"),
            Self::InvalidPortValue(value) => write!(f, "Invalid port value: {value}"),
        }
    }
}

impl StdError for PortmapError {}

impl From<PortmapError> for Error {
    fn from(e: PortmapError) -> Self {
        Self::Portmap(e)
    }
}