12#ifndef __CWIST_VALIDATION_BIND_H__
13#define __CWIST_VALIDATION_BIND_H__
18#include <cjson/cJSON.h>
54 bool (*
fn)(
const char *value,
size_t len,
void *
ctx);
94#define CWIST_BIND_MAX_ERRORS 32
95#define CWIST_BIND_MSG_MAX 256
96#define CWIST_BIND_KEY_MAX 64
187#define CWIST_BIND_TYPEOF(x) \
189 bool: CWIST_BIND_BOOL, \
190 char *: CWIST_BIND_STRING, \
191 const char *: CWIST_BIND_STRING, \
192 int: CWIST_BIND_INT, \
193 unsigned int: CWIST_BIND_UINT, \
194 long: CWIST_BIND_INT, \
195 unsigned long: CWIST_BIND_UINT, \
196 long long: CWIST_BIND_INT, \
197 unsigned long long: CWIST_BIND_UINT, \
198 float: CWIST_BIND_FLOAT, \
199 double: CWIST_BIND_DOUBLE, \
200 long double: CWIST_BIND_DOUBLE, \
201 cwist_sstring *: CWIST_BIND_SSTRING, \
202 cJSON *: CWIST_BIND_JSON_OBJECT, \
203 default: CWIST_BIND_STRING)
208#define CWIST_BIND_OFFSET(st, m) offsetof(st, m)
213#define CWIST_BIND_SIZEOF(st, m) sizeof(((st *)0)->m)
228#define CWIST_BIND_RULES(name, ...) \
229 static const cwist_bind_rule_t name[] = {__VA_ARGS__, {-1, {0}, NULL}}
253#define CWIST_BIND_FIELD(StructType, MemberName, JsonKey, RulesArray) \
254 {.json_key = (JsonKey), \
255 .target_type = CWIST_BIND_TYPEOF(((StructType *)0)->MemberName), \
256 .target_offset = CWIST_BIND_OFFSET(StructType, MemberName), \
257 .target_size = CWIST_BIND_SIZEOF(StructType, MemberName), \
258 .rules = (RulesArray)}
263#define CWIST_BIND_SCHEMA(StructType, FieldArray) \
264 (cwist_bind_schema_t) { \
265 .fields = (FieldArray), .field_count = sizeof(FieldArray) / sizeof((FieldArray)[0]), \
266 .struct_size = sizeof(StructType) \
273#define CWIST_RULE_REQUIRED() \
274 (cwist_bind_rule_t) { \
275 CWIST_BIND_RULE_REQUIRED, {0}, NULL \
278#define CWIST_RULE_MIN_LEN(n) \
279 (cwist_bind_rule_t) { \
280 CWIST_BIND_RULE_MIN_LEN, {.min_len = (n)}, NULL \
283#define CWIST_RULE_MAX_LEN(n) \
284 (cwist_bind_rule_t) { \
285 CWIST_BIND_RULE_MAX_LEN, {.max_len = (n)}, NULL \
288#define CWIST_RULE_MIN_VAL(v) \
289 (cwist_bind_rule_t) { \
290 CWIST_BIND_RULE_MIN_VAL, {.min_val = (v)}, NULL \
293#define CWIST_RULE_MAX_VAL(v) \
294 (cwist_bind_rule_t) { \
295 CWIST_BIND_RULE_MAX_VAL, {.max_val = (v)}, NULL \
298#define CWIST_RULE_REGEX(pat) \
299 (cwist_bind_rule_t) { \
300 CWIST_BIND_RULE_REGEX, {.pattern = (pat)}, NULL \
303#define CWIST_RULE_EMAIL() \
304 (cwist_bind_rule_t) { \
305 CWIST_BIND_RULE_EMAIL, {0}, NULL \
308#define CWIST_RULE_CUSTOM(fn_ptr, ctx_ptr) \
309 (cwist_bind_rule_t) { \
310 CWIST_BIND_RULE_CUSTOM, {.custom = {.fn = (fn_ptr), .ctx = (ctx_ptr)}}, NULL \
struct cwist_bind_schema cwist_bind_schema_t
Complete schema descriptor for a struct.
bool cwist_app_req_bind_json_or_400(cwist_http_request *req, cwist_http_response *res, const cwist_bind_schema_t *schema, void *out)
Convenience wrapper: bind JSON and auto-respond 400 on failure.
#define CWIST_BIND_MAX_ERRORS
bool cwist_app_req_bind_form(cwist_http_request *req, const cwist_bind_schema_t *schema, void *out, cwist_bind_result_t *result)
Bind URL-encoded form data to a user struct.
#define CWIST_BIND_MSG_MAX
#define CWIST_BIND_KEY_MAX
struct cwist_bind_rule cwist_bind_rule_t
Single validation rule attached to a field.
cwist_bind_field_type
Logical type of a bind target field.
@ CWIST_BIND_JSON_OBJECT
cJSON * (ownership transferred to caller).
@ CWIST_BIND_STRING
Null-terminated C string (copied).
@ CWIST_BIND_SSTRING
cwist_sstring target.
enum cwist_bind_field_type cwist_bind_field_type_t
Logical type of a bind target field.
bool cwist_app_req_bind_json(cwist_http_request *req, const cwist_bind_schema_t *schema, void *out, cwist_bind_result_t *result)
Bind a JSON payload to a user struct according to a schema.
enum cwist_bind_rule_type cwist_bind_rule_type_t
Supported validation constraint types.
struct cwist_bind_error cwist_bind_error_t
A single bind/validation failure.
struct cwist_bind_result cwist_bind_result_t
Result of a bind operation.
void cwist_bind_write_error_response(cwist_http_response *res, const cwist_bind_result_t *result)
Populate a response with 400 Bad Request and a JSON error payload.
cwist_bind_rule_type
Supported validation constraint types.
@ CWIST_BIND_RULE_CUSTOM
User-supplied predicate.
@ CWIST_BIND_RULE_MAX_LEN
Maximum string length.
@ CWIST_BIND_RULE_MAX_VAL
Maximum numeric value.
@ CWIST_BIND_RULE_EMAIL
Must conform to RFC 5322 simplified email shape.
@ CWIST_BIND_RULE_REQUIRED
Field must be present and non-empty.
@ CWIST_BIND_RULE_REGEX
Must match POSIX extended regular expression.
@ CWIST_BIND_RULE_MIN_VAL
Minimum numeric value.
@ CWIST_BIND_RULE_MIN_LEN
Minimum string length.
struct cwist_bind_field cwist_bind_field_t
Per-field binding descriptor.
Safe string type with helper methods.
Simple JSON string builder utility.
HTTP Protocol Definitions and Helpers.
A single bind/validation failure.
char key[CWIST_BIND_KEY_MAX]
char message[CWIST_BIND_MSG_MAX]
Per-field binding descriptor.
cwist_bind_field_type_t target_type
Destination C type.
size_t target_size
sizeof(destination) for bounds checking.
const cwist_bind_rule_t * rules
Array of rules (NULL-terminated by type == -1).
size_t rule_count
Number of rules (optional, for static arrays).
const char * json_key
Source key in JSON/Form payload.
size_t target_offset
Byte offset inside the user struct.
Result of a bind operation.
cwist_bind_error_t errors[CWIST_BIND_MAX_ERRORS]
Single validation rule attached to a field.
long double min_val
For MIN_VAL.
struct cwist_bind_rule::@0::@1 custom
For CUSTOM.
union cwist_bind_rule::@0 u
long double max_val
For MAX_VAL.
const char * pattern
For REGEX (static string, compiled once).
cwist_bind_rule_type_t type
const char * error_message
Optional override for the default error text.
size_t max_len
For MAX_LEN.
bool(* fn)(const char *value, size_t len, void *ctx)
size_t min_len
For MIN_LEN.
Complete schema descriptor for a struct.
const cwist_bind_field_t * fields
size_t struct_size
sizeof(user_struct) for bounds checking.
HTTP Response Object. Supports standard string body or Zero-Copy pointer body.