use super::super::RunWasmGcHost;
use super::super::decode::{
decode_result_string, decode_result_tcp_connection, decode_result_unit,
};
use super::factories::{
host_result_err_string, host_result_err_unit_string, host_result_ok_string,
host_result_ok_unit, host_result_tcp_connection_err, host_result_tcp_connection_ok,
host_tcp_connection_id, host_tcp_connection_make,
};
use super::lm::{lm_string_from_host, lm_string_to_host, val_i64};
use super::replay_glue::{json_err, json_ok, json_record, record_effect_if_recording, try_replay};
pub(super) fn dispatch(
name: &str,
caller: &mut wasmtime::Caller<'_, RunWasmGcHost>,
params: &[wasmtime::Val],
results: &mut [wasmtime::Val],
caller_fn: &str,
) -> Result<bool, wasmtime::Error> {
use wasmtime::Val;
match name {
"tcp_connect" => {
let host = lm_string_to_host(caller, params.first())?.unwrap_or_default();
let port = params.get(1).and_then(val_i64).unwrap_or(0);
let args = vec![
aver::replay::JsonValue::String(host.clone()),
aver::replay::JsonValue::Int(port),
];
if let Some(cached) = try_replay(caller, "Tcp.connect", args.clone())? {
let r = decode_result_tcp_connection(caller, &cached)?;
results[0] = Val::AnyRef(r);
return Ok(true);
}
let (result_ref, outcome) = match aver_rt::tcp::connect(&host, port) {
Ok(conn) => {
let id_ref = lm_string_from_host(caller, conn.id.as_ref())?;
let host_ref = lm_string_from_host(caller, conn.host.as_ref())?;
let rec_ref = host_tcp_connection_make(caller, id_ref, host_ref, conn.port)?;
let conn_json = json_record(
"Tcp.Connection",
vec![
(
"id",
aver::replay::JsonValue::String(conn.id.as_ref().to_string()),
),
(
"host",
aver::replay::JsonValue::String(conn.host.as_ref().to_string()),
),
("port", aver::replay::JsonValue::Int(conn.port)),
],
);
(
host_result_tcp_connection_ok(caller, rec_ref)?,
json_ok(conn_json),
)
}
Err(e) => (host_result_tcp_connection_err(caller, &e)?, json_err(&e)),
};
results[0] = Val::AnyRef(result_ref);
record_effect_if_recording(caller, "Tcp.connect", args, outcome, caller_fn);
Ok(true)
}
"tcp_write_line" => {
let id = host_tcp_connection_id(caller, params.first())?.unwrap_or_default();
let line = lm_string_to_host(caller, params.get(1))?.unwrap_or_default();
let conn_arg = json_record(
"Tcp.Connection",
vec![
("id", aver::replay::JsonValue::String(id.clone())),
("host", aver::replay::JsonValue::String(String::new())),
("port", aver::replay::JsonValue::Int(0)),
],
);
let args = vec![
conn_arg.clone(),
aver::replay::JsonValue::String(line.clone()),
];
if let Some(cached) = try_replay(caller, "Tcp.writeLine", args.clone())? {
let r = decode_result_unit(caller, &cached)?;
results[0] = Val::AnyRef(r);
return Ok(true);
}
let conn = aver_rt::TcpConnection {
id: aver_rt::AverStr::from(id.as_str()),
host: aver_rt::AverStr::from(""),
port: 0,
};
let (result_ref, outcome) = match aver_rt::tcp::write_line(&conn, &line) {
Ok(()) => (
host_result_ok_unit(caller)?,
json_ok(aver::replay::JsonValue::Null),
),
Err(e) => (host_result_err_unit_string(caller, &e)?, json_err(&e)),
};
results[0] = Val::AnyRef(result_ref);
record_effect_if_recording(caller, "Tcp.writeLine", args, outcome, caller_fn);
Ok(true)
}
"tcp_read_line" => {
let id = host_tcp_connection_id(caller, params.first())?.unwrap_or_default();
let conn_arg = json_record(
"Tcp.Connection",
vec![
("id", aver::replay::JsonValue::String(id.clone())),
("host", aver::replay::JsonValue::String(String::new())),
("port", aver::replay::JsonValue::Int(0)),
],
);
let args = vec![conn_arg];
if let Some(cached) = try_replay(caller, "Tcp.readLine", args.clone())? {
let r = decode_result_string(caller, &cached)?;
results[0] = Val::AnyRef(r);
return Ok(true);
}
let conn = aver_rt::TcpConnection {
id: aver_rt::AverStr::from(id.as_str()),
host: aver_rt::AverStr::from(""),
port: 0,
};
let (result_ref, outcome) = match aver_rt::tcp::read_line(&conn) {
Ok(text) => (
host_result_ok_string(caller, &text)?,
json_ok(aver::replay::JsonValue::String(text)),
),
Err(e) => (host_result_err_string(caller, &e)?, json_err(&e)),
};
results[0] = Val::AnyRef(result_ref);
record_effect_if_recording(caller, "Tcp.readLine", args, outcome, caller_fn);
Ok(true)
}
"tcp_close" => {
let id = host_tcp_connection_id(caller, params.first())?.unwrap_or_default();
let conn_arg = json_record(
"Tcp.Connection",
vec![
("id", aver::replay::JsonValue::String(id.clone())),
("host", aver::replay::JsonValue::String(String::new())),
("port", aver::replay::JsonValue::Int(0)),
],
);
let args = vec![conn_arg];
if let Some(cached) = try_replay(caller, "Tcp.close", args.clone())? {
let r = decode_result_unit(caller, &cached)?;
results[0] = Val::AnyRef(r);
return Ok(true);
}
let conn = aver_rt::TcpConnection {
id: aver_rt::AverStr::from(id.as_str()),
host: aver_rt::AverStr::from(""),
port: 0,
};
let (result_ref, outcome) = match aver_rt::tcp::close(&conn) {
Ok(()) => (
host_result_ok_unit(caller)?,
json_ok(aver::replay::JsonValue::Null),
),
Err(e) => (host_result_err_unit_string(caller, &e)?, json_err(&e)),
};
results[0] = Val::AnyRef(result_ref);
record_effect_if_recording(caller, "Tcp.close", args, outcome, caller_fn);
Ok(true)
}
"tcp_send" => {
let host = lm_string_to_host(caller, params.first())?.unwrap_or_default();
let port = params.get(1).and_then(val_i64).unwrap_or(0);
let msg = lm_string_to_host(caller, params.get(2))?.unwrap_or_default();
let args = vec![
aver::replay::JsonValue::String(host.clone()),
aver::replay::JsonValue::Int(port),
aver::replay::JsonValue::String(msg.clone()),
];
if let Some(cached) = try_replay(caller, "Tcp.send", args.clone())? {
let r = decode_result_string(caller, &cached)?;
results[0] = Val::AnyRef(r);
return Ok(true);
}
let (result_ref, outcome) = match aver_rt::tcp::send(&host, port, &msg) {
Ok(text) => (
host_result_ok_string(caller, &text)?,
json_ok(aver::replay::JsonValue::String(text)),
),
Err(e) => (host_result_err_string(caller, &e)?, json_err(&e)),
};
results[0] = Val::AnyRef(result_ref);
record_effect_if_recording(caller, "Tcp.send", args, outcome, caller_fn);
Ok(true)
}
"tcp_ping" => {
let host = lm_string_to_host(caller, params.first())?.unwrap_or_default();
let port = params.get(1).and_then(val_i64).unwrap_or(0);
let args = vec![
aver::replay::JsonValue::String(host.clone()),
aver::replay::JsonValue::Int(port),
];
if let Some(cached) = try_replay(caller, "Tcp.ping", args.clone())? {
let r = decode_result_unit(caller, &cached)?;
results[0] = Val::AnyRef(r);
return Ok(true);
}
let (result_ref, outcome) = match aver_rt::tcp::ping(&host, port) {
Ok(()) => (
host_result_ok_unit(caller)?,
json_ok(aver::replay::JsonValue::Null),
),
Err(e) => (host_result_err_unit_string(caller, &e)?, json_err(&e)),
};
results[0] = Val::AnyRef(result_ref);
record_effect_if_recording(caller, "Tcp.ping", args, outcome, caller_fn);
Ok(true)
}
_ => Ok(false),
}
}