thomasarmel / socket-server-mocker

Mock socket server in Rust, for testing various network clients.
https://crates.io/crates/socket-server-mocker
MIT License
0 stars 2 forks source link

Rethinking server instantiation API #17

Open nyurik opened 4 days ago

nyurik commented 4 days ago

Currently there is a bit of a confusing API:

let server = TcpServerMocker::new();
run_with_server(server);

fn run_with_server(server: dyn ServerMocker) {
  // use server without knowing if it is UDP or TCP
}

Proposal

I think it would be better to consolidate API, while keeping the "backend" implementation different (udp or tcp-specific). There are two way to do it:

Simpler API

Introduce one struct ServerMocker that supports tcp, udp, and eventually other protocols. Note that the actual "backend" implementation could be done by different structs internally, but that's hidden from the user. The actual usage of the server is described in #15

let tcp_server = ServerMocker::tcp();  // or tcp_with_port(n)  or  with_opts(TcpOptions { .... })
let udp_server = ServerMocker::udp();  // or udp_with_port(n)  or  with_opts(UdpOptions { .... })
// use servers

Slightly more powerful API

I am not sure this is needed just yet, and it can be introduced later. This is based on the type-state pattern described in this excellent video:

let tcp_server = ServerMocker::<TcpOptions>::new();  // or  with_opts(TcpOptions { .... })
let udp_server = ServerMocker::<UdpOptions>::new();  // or  with_opts(UdpOptions { .... })

// this allows different functions to be available on different types:
impl ServerMocker<TcpOptions> {
  pub fn tcp_specific_command(...) { ... }
}
thomasarmel commented 3 days ago

Hi, Yes I really like type state pattern.

So it's actually a really good idea! Do you want to work on it?