smb-rpc 0.11.1

MS-RPC implementations for `smb-rs`
Documentation
use binrw::prelude::*;
use maybe_async::*;

use crate::pdu::DceRpcSyntaxId;

pub trait RpcInterface<T>
where
    T: BoundRpcConnection,
{
    const SYNTAX_ID: DceRpcSyntaxId;
    fn new(bound_pipe: T) -> Self;
}

pub trait RpcCall: for<'a> BinWrite<Args<'a> = ()> {
    const OPNUM: u16;
    type ResponseType: for<'b> BinRead<Args<'b> = ()>;
    fn serialize(&self) -> Vec<u8> {
        let mut cursor = std::io::Cursor::new(vec![]);
        self.write_le(&mut cursor).unwrap();
        cursor.into_inner()
    }

    fn deserialize(data: &[u8]) -> crate::Result<Self::ResponseType>
    where
        Self: Sized,
    {
        let mut cursor = std::io::Cursor::new(data);
        Self::ResponseType::read_le(&mut cursor)
            .map_err(crate::SmbRpcError::FailedToParseRpcResponse)
    }
}

#[maybe_async(AFIT)]
#[allow(async_fn_in_trait)]
pub trait BoundRpcConnection {
    async fn send_receive<S>(&mut self, stub_input: S) -> crate::Result<S::ResponseType>
    where
        S: RpcCall,
    {
        let serialized_input = stub_input.serialize();
        let response = self.send_receive_raw(S::OPNUM, &serialized_input).await?;
        S::deserialize(&response)
    }

    async fn send_receive_raw(&mut self, opnum: u16, stub_input: &[u8]) -> crate::Result<Vec<u8>>;
}