#ifndef MACROS_H #define MACROS_H #include "app.h" #include "context.h" #include #include #include // Global app instance for simplified API extern app_t *_global_app; // Initialize the simplified API #define APP_INIT() do { \ _global_app = app_new(); \ if (!_global_app) { \ fprintf(stderr, "Failed to create app\n"); \ exit(1); \ } \ } while(0) // Simple route registration without app parameter #define GET(path, handler) app_get(_global_app, path, handler) #define POST(path, handler) app_post(_global_app, path, handler) #define PUT(path, handler) app_put(_global_app, path, handler) #define DELETE(path, handler) app_delete(_global_app, path, handler) // Configuration #define WORKERS(n) app_set_workers(_global_app, n) #define PORT(p) app_listen(_global_app, p) #define RUN() app_run(_global_app) #define SERVE(port_num) do { \ PORT(port_num); \ printf("🚀 Server running on http://localhost:%d\n", port_num); \ RUN(); \ } while(0) // Route parameter syntax helpers - make parameters explicit // Usage: GET(app, ROUTE_PATH("/users/" ROUTE_PARAM("id") "/posts/" ROUTE_PARAM("post_id")), handler) #define ROUTE_PARAM(name) ":" name #define ROUTE_PATH(...) __VA_ARGS__ #define ROUTE_WILDCARD "*" // Alternative clearer syntax for routes with parameters #define GET_PARAM(app, base_path, param_name, handler) \ GET(app, base_path ":" param_name, handler) #define GET_PARAMS(app, base_path, param1, param2, handler) \ GET(app, base_path ":" param1 "/" ":" param2, handler) // Builder-style route definitions for maximum clarity #define ROUTE_WITH_PARAMS(method, app, ...) method(app, __VA_ARGS__) #define STATIC_PATH(path) path #define PARAM_PATH(name) ":" name #define ANY_PATH "*" // Examples: // ROUTE_WITH_PARAMS(GET, app, STATIC_PATH("/users/"), PARAM_PATH("id"), handler) // ROUTE_WITH_PARAMS(GET, app, STATIC_PATH("/api/"), PARAM_PATH("version"), STATIC_PATH("/users"), handler) // Documentation macros for route definitions #define ROUTE_DOC(description) /* description */ #define PARAMS(...) /* Parameters: __VA_ARGS__ */ #define RETURNS(type) /* Returns: type */ // Handler definition macros #define HANDLER(name) void name(context_t *ctx) #define ASYNC_HANDLER(name) void name(context_t *ctx, void (*done)(context_t*)) // Response macros - simplified (ctx is implicit in handlers) #define OK(text) ctx_text(ctx, 200, text) #define CREATED(text) ctx_text(ctx, 201, text) #define JSON(json) ctx_json(ctx, 200, json) #define HTML(html) ctx_html(ctx, 200, html) #define ERROR(code, msg) ctx_error(ctx, code, msg) #define FILE(path) ctx_file(ctx, path) // Error responses #define BAD_REQUEST(msg) ctx_error(ctx, 400, msg) #define UNAUTHORIZED(msg) ctx_error(ctx, 401, msg) #define FORBIDDEN(msg) ctx_error(ctx, 403, msg) #define NOT_FOUND(msg) ctx_error(ctx, 404, msg) #define SERVER_ERROR(msg) ctx_error(ctx, 500, msg) // JSON response macros #define JSON_OK(ctx, ...) ctx_json(ctx, 200, __VA_ARGS__) #define JSON_CREATED(ctx, ...) ctx_json(ctx, 201, __VA_ARGS__) #define JSON_ERROR(ctx, code, msg) ctx_json(ctx, code, "{\"error\":\"" msg "\"}") // HTML response macros #define HTML_OK(ctx, ...) ctx_html(ctx, 200, __VA_ARGS__) #define HTML_PAGE(ctx, title, body) \ ctx_html(ctx, 200, \ "" title "" \ "" body "") // Redirect macros #define REDIRECT(ctx, url) ctx_redirect(ctx, url) #define REDIRECT_PERMANENT(ctx, url) do { \ ctx_status(ctx, 301); \ ctx_header_set(ctx, "Location", url); \ ctx_send(ctx); \ } while(0) // Request accessor macros - simplified (ctx is implicit in handlers) #define PARAM(name) ctx_param(ctx, name) #define QUERY(name) ctx_query(ctx, name) #define HEADER(name) ctx_header(ctx, name) #define COOKIE(name) ctx_cookie(ctx, name) #define BODY() ctx_body(ctx) #define METHOD() ((ctx)->request ? (ctx)->request->method : NULL) #define PATH() ((ctx)->request ? (ctx)->request->path : NULL) // Middleware-style macros #define NEXT(ctx, next) next(ctx) #define ABORT(ctx, code, msg) do { \ ctx_error(ctx, code, msg); \ return; \ } while(0) // Common patterns - simplified (ctx is implicit) #define REQUIRE_AUTH() do { \ if (!HEADER("Authorization")) { \ UNAUTHORIZED("Authentication required"); \ return; \ } \ } while(0) #define REQUIRE_JSON() do { \ const char *ct = HEADER("Content-Type"); \ if (!ct || strstr(ct, "application/json") == NULL) { \ BAD_REQUEST("Content-Type must be application/json"); \ return; \ } \ } while(0) #define CORS() do { \ ctx_header_set(ctx, "Access-Control-Allow-Origin", "*"); \ ctx_header_set(ctx, "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); \ ctx_header_set(ctx, "Access-Control-Allow-Headers", "Content-Type, Authorization"); \ } while(0) // Utility macros for building responses #define JSON_BEGIN(buf, size) char buf[size]; int _json_pos = 0; _json_pos += snprintf(buf, size, "{") #define JSON_FIELD(buf, size, key, fmt, val) \ _json_pos += snprintf(buf + _json_pos, size - _json_pos, \ "%s\"%s\":" fmt, (_json_pos > 1 ? "," : ""), key, val) #define JSON_STRING(buf, size, key, val) JSON_FIELD(buf, size, key, "\"%s\"", val) #define JSON_NUMBER(buf, size, key, val) JSON_FIELD(buf, size, key, "%d", val) #define JSON_BOOL(buf, size, key, val) JSON_FIELD(buf, size, key, "%s", (val) ? "true" : "false") #define JSON_END(buf, size) snprintf(buf + _json_pos, size - _json_pos, "}") // App configuration macros #define APP_CONFIG(app, ...) do { \ struct { \ int workers; \ int max_conns; \ size_t read_buf; \ size_t write_buf; \ int cpu_affinity; \ } config = {0, 10000, 8192, 8192, 1, ##__VA_ARGS__}; \ if (config.workers > 0) app_set_workers(app, config.workers); \ app_set_max_conns(app, config.max_conns); \ app_set_buffer_sizes(app, config.read_buf, config.write_buf); \ app_set_cpu_affinity(app, config.cpu_affinity); \ } while(0) // Quick app setup macro #define QUICK_APP(port, ...) ({ \ app_t *_app = app_new(); \ if (_app) { \ APP_CONFIG(_app, ##__VA_ARGS__); \ __VA_ARGS__; \ app_listen(_app, port); \ } \ _app; \ }) #endif // MACROS_H