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 #[allow(unsafe_op_in_unsafe_fn)] 35 pub mod frontend_client_ffi { 36 // Shared enum GrpcMethod 37 #[derive(Debug, PartialEq, Eq)] 38 pub enum GrpcMethod { 39 GetVersion, 40 CreateDevice, 41 DeleteChip, 42 PatchDevice, 43 ListDevice, 44 Reset, 45 ListCapture, 46 PatchCapture, 47 GetCapture, 48 } 49 50 extern "Rust" { 51 type ClientResponseReader; handle_chunk(&self, chunk: &[u8])52 fn handle_chunk(&self, chunk: &[u8]); handle_error(&self, error_code: u32, error_message: &str)53 fn handle_error(&self, error_code: u32, error_message: &str); 54 } 55 56 // C++ types and signatures exposed to Rust. 57 unsafe extern "C++" { 58 include!("frontend/frontend_client.h"); 59 60 type FrontendClient; 61 type ClientResult; 62 63 #[allow(dead_code)] 64 #[rust_name = "new_frontend_client"] NewFrontendClient(server: &CxxString) -> UniquePtr<FrontendClient>65 pub fn NewFrontendClient(server: &CxxString) -> UniquePtr<FrontendClient>; 66 67 #[allow(dead_code)] 68 #[rust_name = "get_capture"] GetCapture( self: &FrontendClient, request: &Vec<u8>, client_reader: &ClientResponseReader, ) -> UniquePtr<ClientResult>69 pub fn GetCapture( 70 self: &FrontendClient, 71 request: &Vec<u8>, 72 client_reader: &ClientResponseReader, 73 ) -> UniquePtr<ClientResult>; 74 75 #[allow(dead_code)] 76 #[rust_name = "send_grpc"] SendGrpc( self: &FrontendClient, grpc_method: &GrpcMethod, request: &Vec<u8>, ) -> UniquePtr<ClientResult>77 pub fn SendGrpc( 78 self: &FrontendClient, 79 grpc_method: &GrpcMethod, 80 request: &Vec<u8>, 81 ) -> UniquePtr<ClientResult>; 82 83 #[allow(dead_code)] 84 #[rust_name = "is_ok"] IsOk(self: &ClientResult) -> bool85 pub fn IsOk(self: &ClientResult) -> bool; 86 87 #[allow(dead_code)] 88 #[rust_name = "err"] Err(self: &ClientResult) -> String89 pub fn Err(self: &ClientResult) -> String; 90 91 #[allow(dead_code)] 92 #[rust_name = "byte_vec"] ByteVec(self: &ClientResult) -> &CxxVector<u8>93 pub fn ByteVec(self: &ClientResult) -> &CxxVector<u8>; 94 95 } 96 } 97