cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
bind.h
Go to the documentation of this file.
1
12#ifndef __CWIST_VALIDATION_BIND_H__
13#define __CWIST_VALIDATION_BIND_H__
14
15#include <cwist/net/http/http.h>
18#include <cjson/cJSON.h>
19#include <stdbool.h>
20#include <stddef.h>
21#include <stdint.h>
22#include <regex.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/* -------------------------------------------------------------------------
29 * Validation rule descriptors
30 * ---------------------------------------------------------------------- */
31
43
45typedef struct cwist_bind_rule {
47 union {
48 size_t min_len;
49 size_t max_len;
50 long double min_val;
51 long double max_val;
52 const char *pattern;
53 struct {
54 bool (*fn)(const char *value, size_t len, void *ctx);
55 void *ctx;
57 } u;
58 const char *error_message;
60
72
82
89
90/* -------------------------------------------------------------------------
91 * Result types
92 * ---------------------------------------------------------------------- */
93
94#define CWIST_BIND_MAX_ERRORS 32
95#define CWIST_BIND_MSG_MAX 256
96#define CWIST_BIND_KEY_MAX 64
97
103
110
111/* -------------------------------------------------------------------------
112 * Public API
113 * ---------------------------------------------------------------------- */
114
131bool cwist_app_req_bind_json(cwist_http_request *req, const cwist_bind_schema_t *schema, void *out,
132 cwist_bind_result_t *result);
133
145bool cwist_app_req_bind_form(cwist_http_request *req, const cwist_bind_schema_t *schema, void *out,
146 cwist_bind_result_t *result);
147
160
175 const cwist_bind_schema_t *schema, void *out);
176
177/* -------------------------------------------------------------------------
178 * _Generic type-safe dispatch macros
179 * ---------------------------------------------------------------------- */
180
187#define CWIST_BIND_TYPEOF(x) \
188 _Generic((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)
204
208#define CWIST_BIND_OFFSET(st, m) offsetof(st, m)
209
213#define CWIST_BIND_SIZEOF(st, m) sizeof(((st *)0)->m)
214
228#define CWIST_BIND_RULES(name, ...) \
229 static const cwist_bind_rule_t name[] = {__VA_ARGS__, {-1, {0}, NULL}}
230
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)}
259
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) \
267 }
268
269/* -------------------------------------------------------------------------
270 * Rule construction helpers
271 * ---------------------------------------------------------------------- */
272
273#define CWIST_RULE_REQUIRED() \
274 (cwist_bind_rule_t) { \
275 CWIST_BIND_RULE_REQUIRED, {0}, NULL \
276 }
277
278#define CWIST_RULE_MIN_LEN(n) \
279 (cwist_bind_rule_t) { \
280 CWIST_BIND_RULE_MIN_LEN, {.min_len = (n)}, NULL \
281 }
282
283#define CWIST_RULE_MAX_LEN(n) \
284 (cwist_bind_rule_t) { \
285 CWIST_BIND_RULE_MAX_LEN, {.max_len = (n)}, NULL \
286 }
287
288#define CWIST_RULE_MIN_VAL(v) \
289 (cwist_bind_rule_t) { \
290 CWIST_BIND_RULE_MIN_VAL, {.min_val = (v)}, NULL \
291 }
292
293#define CWIST_RULE_MAX_VAL(v) \
294 (cwist_bind_rule_t) { \
295 CWIST_BIND_RULE_MAX_VAL, {.max_val = (v)}, NULL \
296 }
297
298#define CWIST_RULE_REGEX(pat) \
299 (cwist_bind_rule_t) { \
300 CWIST_BIND_RULE_REGEX, {.pattern = (pat)}, NULL \
301 }
302
303#define CWIST_RULE_EMAIL() \
304 (cwist_bind_rule_t) { \
305 CWIST_BIND_RULE_EMAIL, {0}, NULL \
306 }
307
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 \
311 }
312
313#ifdef __cplusplus
314}
315#endif
316
317#endif /* __CWIST_VALIDATION_BIND_H__ */
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.
Definition bind.c:502
#define CWIST_BIND_MAX_ERRORS
Definition bind.h:94
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.
Definition bind.c:446
#define CWIST_BIND_MSG_MAX
Definition bind.h:95
#define CWIST_BIND_KEY_MAX
Definition bind.h:96
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.
Definition bind.h:62
@ CWIST_BIND_DOUBLE
Definition bind.h:67
@ CWIST_BIND_JSON_OBJECT
cJSON * (ownership transferred to caller).
Definition bind.h:70
@ CWIST_BIND_INT
Definition bind.h:64
@ CWIST_BIND_UINT
Definition bind.h:65
@ CWIST_BIND_FLOAT
Definition bind.h:66
@ CWIST_BIND_STRING
Null-terminated C string (copied).
Definition bind.h:68
@ CWIST_BIND_BOOL
Definition bind.h:63
@ CWIST_BIND_SSTRING
cwist_sstring target.
Definition bind.h:69
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.
Definition bind.c:426
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.
Definition bind.c:463
cwist_bind_rule_type
Supported validation constraint types.
Definition bind.h:33
@ CWIST_BIND_RULE_CUSTOM
User-supplied predicate.
Definition bind.h:41
@ CWIST_BIND_RULE_MAX_LEN
Maximum string length.
Definition bind.h:36
@ CWIST_BIND_RULE_MAX_VAL
Maximum numeric value.
Definition bind.h:38
@ CWIST_BIND_RULE_EMAIL
Must conform to RFC 5322 simplified email shape.
Definition bind.h:40
@ CWIST_BIND_RULE_REQUIRED
Field must be present and non-empty.
Definition bind.h:34
@ CWIST_BIND_RULE_REGEX
Must match POSIX extended regular expression.
Definition bind.h:39
@ CWIST_BIND_RULE_MIN_VAL
Minimum numeric value.
Definition bind.h:37
@ CWIST_BIND_RULE_MIN_LEN
Minimum string length.
Definition bind.h:35
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.
Definition bind.h:99
char key[CWIST_BIND_KEY_MAX]
Definition bind.h:100
char message[CWIST_BIND_MSG_MAX]
Definition bind.h:101
Per-field binding descriptor.
Definition bind.h:74
cwist_bind_field_type_t target_type
Destination C type.
Definition bind.h:76
size_t target_size
sizeof(destination) for bounds checking.
Definition bind.h:78
const cwist_bind_rule_t * rules
Array of rules (NULL-terminated by type == -1).
Definition bind.h:79
size_t rule_count
Number of rules (optional, for static arrays).
Definition bind.h:80
const char * json_key
Source key in JSON/Form payload.
Definition bind.h:75
size_t target_offset
Byte offset inside the user struct.
Definition bind.h:77
Result of a bind operation.
Definition bind.h:105
cwist_bind_error_t errors[CWIST_BIND_MAX_ERRORS]
Definition bind.h:107
size_t error_count
Definition bind.h:108
Single validation rule attached to a field.
Definition bind.h:45
long double min_val
For MIN_VAL.
Definition bind.h:50
struct cwist_bind_rule::@0::@1 custom
For CUSTOM.
union cwist_bind_rule::@0 u
long double max_val
For MAX_VAL.
Definition bind.h:51
const char * pattern
For REGEX (static string, compiled once).
Definition bind.h:52
cwist_bind_rule_type_t type
Definition bind.h:46
const char * error_message
Optional override for the default error text.
Definition bind.h:58
size_t max_len
For MAX_LEN.
Definition bind.h:49
bool(* fn)(const char *value, size_t len, void *ctx)
Definition bind.h:54
size_t min_len
For MIN_LEN.
Definition bind.h:48
void * ctx
Definition bind.h:55
Complete schema descriptor for a struct.
Definition bind.h:84
const cwist_bind_field_t * fields
Definition bind.h:85
size_t field_count
Definition bind.h:86
size_t struct_size
sizeof(user_struct) for bounds checking.
Definition bind.h:87
HTTP Response Object. Supports standard string body or Zero-Copy pointer body.
Definition http.h:82