use crate::resp;
use luna_core::runtime::Table;
use luna_core::runtime::heap::Gc;
use luna_core::runtime::value::Value;
use luna_core::vm::exec::Vm;
pub(crate) fn value(vm: &mut Vm, v: Value) -> Vec<u8> {
match v {
Value::Nil => resp::nil_bulk(),
Value::Bool(true) => resp::integer(1),
Value::Bool(false) => resp::nil_bulk(),
Value::Int(n) => resp::integer(n),
Value::Float(f) => resp::float(f),
Value::Str(s) => resp::bulk(s.as_bytes()),
Value::Table(t) => table(vm, t),
Value::Closure(_)
| Value::Native(_)
| Value::Coro(_)
| Value::Userdata(_)
| Value::LightUserdata(_) => resp::nil_bulk(),
}
}
fn table(vm: &mut Vm, t: Gc<Table>) -> Vec<u8> {
let err_key = Value::Str(vm.heap.intern(b"err"));
if let Value::Str(s) = t.get(err_key) {
return resp::err(s.as_bytes());
}
let ok_key = Value::Str(vm.heap.intern(b"ok"));
if let Value::Str(s) = t.get(ok_key) {
return resp::simple_string(s.as_bytes());
}
let mut items: Vec<Vec<u8>> = Vec::new();
let mut i: i64 = 1;
loop {
let v = t.get_int(i);
if matches!(v, Value::Nil) {
break;
}
items.push(value(vm, v));
i += 1;
}
let mut out = resp::array_header(items.len() as i64);
for item in items {
out.extend_from_slice(&item);
}
out
}