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