1 //! Frontend-client library for rust. 2 /// 3 /// Rust to C++ Grpc frontend.proto for Windows, linux and mac. 4 /// 5 /// This can be replaced with grpcio native implementation when the 6 /// Windows build works. 7 8 /// Wrapper struct for application defined ClientResponseReader 9 pub struct ClientResponseReader { 10 /// Delegated handler for reading responses 11 pub handler: Box<dyn ClientResponseReadable>, 12 } 13 14 /// Delegating functions to handler 15 impl ClientResponseReader { handle_chunk(&self, chunk: &[u8])16 fn handle_chunk(&self, chunk: &[u8]) { 17 self.handler.handle_chunk(chunk); 18 } handle_error(&self, error_code: u32, error_message: &str)19 fn handle_error(&self, error_code: u32, error_message: &str) { 20 self.handler.handle_error(error_code, error_message); 21 } 22 } 23 24 /// Trait for ClientResponseReader handler functions 25 pub trait ClientResponseReadable { 26 /// Process each chunk of streaming response handle_chunk(&self, chunk: &[u8])27 fn handle_chunk(&self, chunk: &[u8]); 28 /// Process errors in response handle_error(&self, error_code: u32, error_message: &str)29 fn handle_error(&self, error_code: u32, error_message: &str); 30 } 31 32 #[cxx::bridge(namespace = "netsim::frontend")] 33 #[allow(missing_docs)] 34 pub mod ffi { 35 // Shared enum GrpcMethod 36 #[derive(Debug, PartialEq, Eq)] 37 pub enum GrpcMethod { 38 GetVersion, 39 PatchDevice, 40 GetDevices, 41 Reset, 42 ListCapture, 43 PatchCapture, 44 GetCapture, 45 } 46 47 extern "Rust" { 48 type ClientResponseReader; handle_chunk(&self, chunk: &[u8])49 fn handle_chunk(&self, chunk: &[u8]); handle_error(&self, error_code: u32, error_message: &str)50 fn handle_error(&self, error_code: u32, error_message: &str); 51 } 52 53 // C++ types and signatures exposed to Rust. 54 unsafe extern "C++" { 55 include!("frontend/frontend_client.h"); 56 57 type FrontendClient; 58 type ClientResult; 59 60 #[allow(dead_code)] 61 #[rust_name = "new_frontend_client"] NewFrontendClient() -> UniquePtr<FrontendClient>62 pub fn NewFrontendClient() -> UniquePtr<FrontendClient>; 63 64 #[allow(dead_code)] 65 #[rust_name = "get_capture"] GetCapture( self: &FrontendClient, request: &Vec<u8>, client_reader: &ClientResponseReader, ) -> UniquePtr<ClientResult>66 pub fn GetCapture( 67 self: &FrontendClient, 68 request: &Vec<u8>, 69 client_reader: &ClientResponseReader, 70 ) -> UniquePtr<ClientResult>; 71 72 #[allow(dead_code)] 73 #[rust_name = "send_grpc"] SendGrpc( self: &FrontendClient, grpc_method: &GrpcMethod, request: &Vec<u8>, ) -> UniquePtr<ClientResult>74 pub fn SendGrpc( 75 self: &FrontendClient, 76 grpc_method: &GrpcMethod, 77 request: &Vec<u8>, 78 ) -> UniquePtr<ClientResult>; 79 80 #[allow(dead_code)] 81 #[rust_name = "is_ok"] IsOk(self: &ClientResult) -> bool82 pub fn IsOk(self: &ClientResult) -> bool; 83 84 #[allow(dead_code)] 85 #[rust_name = "err"] Err(self: &ClientResult) -> String86 pub fn Err(self: &ClientResult) -> String; 87 88 #[allow(dead_code)] 89 #[rust_name = "byte_vec"] ByteVec(self: &ClientResult) -> &CxxVector<u8>90 pub fn ByteVec(self: &ClientResult) -> &CxxVector<u8>; 91 92 } 93 } 94