|
// backend.cpp (Corrected)
|
|
#include "httplib.h"
|
|
#include "wren.h"
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
// A struct to hold the response data for our foreign object
|
|
struct ResponseData {
|
|
bool isError;
|
|
int statusCode;
|
|
std::string body;
|
|
};
|
|
|
|
// --- Response Class Foreign Methods ---
|
|
|
|
void responseAllocate(WrenVM* vm) {
|
|
// This is the constructor for the Response class.
|
|
ResponseData* data = (ResponseData*)wrenSetSlotNewForeign(vm, 0, 0, sizeof(ResponseData));
|
|
data->isError = false;
|
|
data->statusCode = 0;
|
|
}
|
|
|
|
void responseIsError(WrenVM* vm) {
|
|
ResponseData* data = (ResponseData*)wrenGetSlotForeign(vm, 0);
|
|
wrenSetSlotBool(vm, 0, data->isError);
|
|
}
|
|
|
|
void responseStatusCode(WrenVM* vm) {
|
|
ResponseData* data = (ResponseData*)wrenGetSlotForeign(vm, 0);
|
|
wrenSetSlotDouble(vm, 0, data->statusCode);
|
|
}
|
|
|
|
void responseBody(WrenVM* vm) {
|
|
ResponseData* data = (ResponseData*)wrenGetSlotForeign(vm, 0);
|
|
wrenSetSlotBytes(vm, 0, data->body.c_str(), data->body.length());
|
|
}
|
|
|
|
void responseJson(WrenVM* vm) {
|
|
// For a real implementation, you would use a JSON library here.
|
|
// For this example, we just return the body text.
|
|
ResponseData* data = (ResponseData*)wrenGetSlotForeign(vm, 0);
|
|
wrenSetSlotBytes(vm, 0, data->body.c_str(), data->body.length());
|
|
}
|
|
|
|
// --- Requests Class Foreign Methods ---
|
|
|
|
void requestsGet(WrenVM* vm) {
|
|
const char* url = wrenGetSlotString(vm, 1);
|
|
// TODO: Handle headers from slot 2.
|
|
|
|
httplib::Client cli("jsonplaceholder.typicode.com");
|
|
auto res = cli.Get("/posts/1");
|
|
|
|
// CHANGED: We need two slots: one for the Response class, one for the new instance.
|
|
wrenEnsureSlots(vm, 2);
|
|
|
|
// CHANGED: Get the 'Response' class from the 'requests' module and put it in slot 1.
|
|
wrenGetVariable(vm, "requests", "Response", 1);
|
|
|
|
// CHANGED: Create a new foreign object instance of the class in slot 1.
|
|
// The new instance is placed in slot 0, which becomes the return value.
|
|
ResponseData* data = (ResponseData*)wrenSetSlotNewForeign(vm, 0, 1, sizeof(ResponseData));
|
|
|
|
if (res) {
|
|
data->isError = false;
|
|
data->statusCode = res->status;
|
|
data->body = res->body;
|
|
} else {
|
|
data->isError = true;
|
|
data->statusCode = -1;
|
|
data->body = "GET request failed.";
|
|
}
|
|
}
|
|
|
|
void requestsPost(WrenVM* vm) {
|
|
const char* url = wrenGetSlotString(vm, 1);
|
|
const char* body = wrenGetSlotString(vm, 2);
|
|
const char* contentType = wrenGetSlotString(vm, 3);
|
|
// TODO: Handle headers from slot 4.
|
|
|
|
httplib::Client cli("jsonplaceholder.typicode.com");
|
|
auto res = cli.Post("/posts", body, contentType);
|
|
|
|
// CHANGED: We need two slots: one for the Response class, one for the new instance.
|
|
wrenEnsureSlots(vm, 2);
|
|
|
|
// CHANGED: Get the 'Response' class from the 'requests' module and put it in slot 1.
|
|
wrenGetVariable(vm, "requests", "Response", 1);
|
|
|
|
// CHANGED: Create a new foreign object instance of the class in slot 1.
|
|
// The new instance is placed in slot 0, which becomes the return value.
|
|
ResponseData* data = (ResponseData*)wrenSetSlotNewForeign(vm, 0, 1, sizeof(ResponseData));
|
|
|
|
if (res) {
|
|
data->isError = false;
|
|
data->statusCode = res->status;
|
|
data->body = res->body;
|
|
} else {
|
|
data->isError = true;
|
|
data->statusCode = -1;
|
|
data->body = "POST request failed.";
|
|
}
|
|
}
|
|
|
|
|
|
// --- FFI Binding Functions ---
|
|
|
|
WrenForeignMethodFn bindForeignMethod(WrenVM* vm, const char* module,
|
|
const char* className, bool isStatic, const char* signature) {
|
|
if (strcmp(module, "requests") != 0) return NULL;
|
|
|
|
if (strcmp(className, "Requests") == 0 && isStatic) {
|
|
if (strcmp(signature, "get_(_,_)") == 0) return requestsGet;
|
|
if (strcmp(signature, "post_(_,_,_,_)") == 0) return requestsPost;
|
|
}
|
|
|
|
if (strcmp(className, "Response") == 0 && !isStatic) {
|
|
if (strcmp(signature, "isError") == 0) return responseIsError;
|
|
if (strcmp(signature, "statusCode") == 0) return responseStatusCode;
|
|
if (strcmp(signature, "body") == 0) return responseBody;
|
|
if (strcmp(signature, "json()") == 0) return responseJson;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
|
|
WrenForeignClassMethods methods = {0};
|
|
if (strcmp(module, "requests") == 0) {
|
|
if (strcmp(className, "Response") == 0) {
|
|
methods.allocate = responseAllocate;
|
|
}
|
|
}
|
|
return methods;
|
|
}
|