Skip to main content

RpcErrCodec

Trait RpcErrCodec 

Source
pub trait RpcErrCodec:
    Send
    + Sized
    + 'static
    + Unpin {
    // Required methods
    fn encode<C: Codec>(&self, codec: &C) -> EncodedErr;
    fn decode<C: Codec>(codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>;
    fn fmt(&self, f: &mut Formatter<'_>) -> Result;
}
Expand description

Serialize and Deserialize trait for custom RpcError

There is only two forms for rpc transport layer, u32 and String, choose one of them.

Because Rust does not allow overlapping impl, we only imple RpcErrCodec trait by default for the following types:

  • ()
  • from i8 to u32
  • String
  • nix::errno::Errno

If you use other type as error, you can implement manually:

§Example with serde_derive

use serde_derive::{Serialize, Deserialize};
use razor_stream::{Codec, error::{RpcErrCodec, RpcIntErr, EncodedErr}};
use strum::Display;
#[derive(Serialize, Deserialize, Debug)]
pub enum MyError {
    NoSuchFile,
    TooManyRequest,
}

impl RpcErrCodec for MyError {
    #[inline(always)]
    fn encode<C: Codec>(&self, codec: &C) -> EncodedErr {
        match codec.encode(self) {
            Ok(buf)=>EncodedErr::Buf(buf),
            Err(())=>EncodedErr::Rpc(RpcIntErr::Encode),
        }
    }

    #[inline(always)]
    fn decode<C: Codec>(codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()> {
        if let Err(b) = buf {
            return codec.decode(b);
        } else {
            Err(())
        }
    }
    #[inline(always)]
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        std::fmt::Debug::fmt(self, f)
    }
}

§Example with num_enum

use num_enum::TryFromPrimitive;
use razor_stream::{Codec, error::{RpcErrCodec, RpcIntErr, EncodedErr}};

// Define your error codes as a C-like enum with explicit values
// You can use num_enum's TryFromPrimitive for safer deserialization
#[derive(Debug, Clone, Copy, PartialEq, TryFromPrimitive)]
#[repr(u32)]
pub enum MyRpcErrorCode {
    /// Service is not available
    ServiceUnavailable = 1,
    /// Request timed out
    RequestTimeout = 2,
    /// Invalid parameter
    InvalidParameter = 3,
    /// Resource not found
    NotFound = 4,
}

impl RpcErrCodec for MyRpcErrorCode {
    #[inline(always)]
    fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr {
        // Manual conversion to u32 (no IntoPrimitive needed)
        let code: u32 = *self as u32;
        EncodedErr::Num(code)
    }

    #[inline(always)]
    fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()> {
        if let Ok(code) = buf {
            // Using num_enum for safe deserialization (TryFromPrimitive)
            return MyRpcErrorCode::try_from(code).map_err(|_| ());
        }
        Err(())
    }

    #[inline(always)]
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        std::fmt::Debug::fmt(self, f)
    }
}

Required Methods§

Source

fn encode<C: Codec>(&self, codec: &C) -> EncodedErr

Source

fn decode<C: Codec>(codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source

fn fmt(&self, f: &mut Formatter<'_>) -> Result

You can choose to use std::fmt::Debug or std::fmt::Display for the type.

NOTE that this method exists because rust does not have Display for ().

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl RpcErrCodec for Errno

Source§

fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr

Source§

fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Source§

impl RpcErrCodec for i8

Source§

fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr

Source§

fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Source§

impl RpcErrCodec for i16

Source§

fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr

Source§

fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Source§

impl RpcErrCodec for i32

Source§

fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr

Source§

fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Source§

impl RpcErrCodec for u8

Source§

fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr

Source§

fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Source§

impl RpcErrCodec for u16

Source§

fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr

Source§

fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Source§

impl RpcErrCodec for u32

Source§

fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr

Source§

fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Source§

impl RpcErrCodec for ()

Source§

fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr

Source§

fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Source§

impl RpcErrCodec for String

Source§

fn encode<C: Codec>(&self, _codec: &C) -> EncodedErr

Source§

fn decode<C: Codec>(_codec: &C, buf: Result<u32, &[u8]>) -> Result<Self, ()>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Implementors§