use crate::host::with_host;
use fusevm::Value;
pub const METHODS: &[&str] = &["text", "json", "arrayBuffer", "buffer", "bytes", "blob"];
const CONSUMER_SRC: &str = "(function (stream, kind) {\n\
var B = require('buffer');\n\
return new Promise(function (resolve, reject) {\n\
var chunks = [];\n\
stream.on('data', function (c) {\n\
chunks.push(typeof c === 'string' ? B.Buffer.from(c) : c);\n\
});\n\
stream.on('error', function (e) { reject(e); });\n\
stream.on('end', function () {\n\
try {\n\
var buf = B.Buffer.concat(chunks);\n\
if (kind === 'text') return resolve(buf.toString('utf8'));\n\
if (kind === 'json') return resolve(JSON.parse(buf.toString('utf8')));\n\
if (kind === 'blob') return resolve(new B.Blob([buf]));\n\
return resolve(buf);\n\
} catch (err) { reject(err); }\n\
});\n\
});\n\
})";
fn run_completion(src: &str) -> Result<Value, String> {
let prog = crate::compile_completion(src)?;
let chunk = crate::load_merged(prog);
crate::host::run_chunk_on(chunk)
}
pub fn call(method: &str, args: &[Value]) -> Option<Result<Value, String>> {
let kind = match method {
"text" | "json" | "arrayBuffer" | "buffer" | "bytes" | "blob" => method,
_ => return None,
};
let stream = args.first().cloned().unwrap_or(Value::Undef);
Some(consume(stream, kind))
}
fn consume(stream: Value, kind: &str) -> Result<Value, String> {
let factory = run_completion(CONSUMER_SRC)?;
let kv = with_host(|h| h.new_str(kind.to_string()));
crate::host::invoke(&factory, vec![stream, kv], None)
}