use crate::{BrpcError, BrpcResult};
use brpc_sys::ffi::{self, BrpcServer, BrpcServerOptions};
use libc::{c_int, c_void};
#[repr(C)]
pub enum ServiceOwnership {
ServerOwnsService = 0,
ServerDoesntOwnService = 1,
}
#[doc(hidden)]
pub trait Service {
fn get_service_ptr(&self) -> *mut c_void;
}
pub struct Server {
inner: *mut BrpcServer, }
impl Server {
pub fn new() -> Self {
Server {
inner: unsafe { ffi::brpc_server_new() },
}
}
pub fn add_service<T: Service + Sized>(
&mut self,
service: &T,
ownership: ServiceOwnership,
) -> BrpcResult<()> {
let ret = unsafe {
ffi::brpc_server_add_service(self.inner, service.get_service_ptr(), ownership as c_int)
};
if ret == 0 {
Ok(())
} else {
Err(BrpcError::EINTERNAL)
}
}
pub fn start(&mut self, port: u16, opt: &ServerOptions) -> BrpcResult<()> {
let ret = unsafe { ffi::brpc_server_start(self.inner, i32::from(port), opt.inner) };
if ret == 0 {
Ok(())
} else {
Err(BrpcError::EINTERNAL)
}
}
pub fn run(&mut self) {
unsafe { ffi::brpc_server_run_until_asked_to_quit(self.inner) };
}
}
impl Drop for Server {
fn drop(&mut self) {
unsafe {
ffi::brpc_server_destroy(self.inner);
}
}
}
impl Default for Server {
fn default() -> Self {
Self::new()
}
}
pub struct ServerOptions {
#[doc(hidden)]
pub(crate) inner: *mut BrpcServerOptions, }
impl ServerOptions {
pub fn new() -> Self {
ServerOptions {
inner: unsafe { ffi::brpc_server_options_new() },
}
}
pub fn set_idle_timeout_ms(&mut self, timeout: i32) {
unsafe { ffi::brpc_server_options_set_idle_timeout_ms(self.inner, timeout as c_int) }
}
}
impl Drop for ServerOptions {
fn drop(&mut self) {
unsafe {
ffi::brpc_server_options_destroy(self.inner);
}
}
}
impl Default for ServerOptions {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::ptr;
struct NullService {}
impl Service for NullService {
fn get_service_ptr(&self) -> *mut c_void {
ptr::null_mut()
}
}
#[test]
fn server_options_new() {
let opt = ServerOptions::new();
assert_ne!(opt.inner, ptr::null_mut());
}
#[test]
fn server_options_set_idle_timeout_ms() {
let mut opt = ServerOptions::new();
opt.set_idle_timeout_ms(0);
}
#[test]
fn server_new() {
let server = Server::new();
assert_ne!(server.inner, ptr::null_mut());
}
#[test]
fn server_add_null_service() {
let service = NullService {};
let mut server = Server::new();
let ret = server.add_service(&service, ServiceOwnership::ServerDoesntOwnService);
assert_eq!(false, ret.is_ok()); }
#[test]
fn server_start_null_service() {
let service = NullService {};
let mut server = Server::new();
let _ = server.add_service(&service, ServiceOwnership::ServerDoesntOwnService);
let opt = ServerOptions::new();
let ret = server.start(50000, &opt);
assert_eq!(true, ret.is_ok()); }
}