1181 lines
44 KiB
C

#ifndef NIM_FFI_LIB_MY_TIMER_H_INCLUDED
#define NIM_FFI_LIB_MY_TIMER_H_INCLUDED
#include "nim_ffi_cbor.h"
/* ============================================================ */
/* Generated types (user-declared + per-proc request envelopes) */
/* ============================================================ */
typedef struct {
NimFfiStr name;
} TimerConfig;
typedef struct {
NimFfiStr message;
int64_t delayMs;
} EchoRequest;
typedef struct {
NimFfiStr echoed;
NimFfiStr timerName;
} EchoResponse;
typedef struct {
EchoRequest* data;
size_t len;
} MyTimerSeq_EchoRequest;
typedef struct {
NimFfiStr* data;
size_t len;
} MyTimerSeq_Str;
typedef struct {
bool has_value;
NimFfiStr value;
} MyTimerOpt_Str;
typedef struct {
bool has_value;
int64_t value;
} MyTimerOpt_I64;
typedef struct {
MyTimerSeq_EchoRequest messages;
MyTimerSeq_Str tags;
MyTimerOpt_Str note;
MyTimerOpt_I64 retries;
} ComplexRequest;
typedef struct {
NimFfiStr summary;
int64_t itemCount;
bool hasNote;
} ComplexResponse;
typedef struct {
NimFfiStr message;
int64_t echoCount;
} EchoEvent;
typedef struct {
NimFfiStr name;
MyTimerSeq_Str payload;
int64_t priority;
} JobSpec;
typedef struct {
int64_t maxAttempts;
int64_t backoffMs;
MyTimerSeq_Str retryOn;
} RetryPolicy;
typedef struct {
int64_t startAtMs;
int64_t intervalMs;
MyTimerOpt_I64 jitter;
} ScheduleConfig;
typedef struct {
NimFfiStr jobId;
int64_t willRunCount;
int64_t firstRunAtMs;
int64_t effectiveBackoffMs;
} ScheduleResult;
typedef struct {
TimerConfig config;
} MyTimerCreateCtorReq;
typedef struct {
EchoRequest req;
} MyTimerEchoReq;
typedef struct {
char _nimffi_empty; /* C forbids empty structs */
} MyTimerVersionReq;
typedef struct {
ComplexRequest req;
} MyTimerComplexReq;
typedef struct {
JobSpec job;
RetryPolicy retry;
ScheduleConfig schedule;
} MyTimerScheduleReq;
static inline CborError my_timer_enc_TimerConfig(
CborEncoder* e, const TimerConfig* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 1);
if (err) return err;
err = cbor_encode_text_stringz(&m, "name");
if (err) return err;
err = nimffi_enc_str(&m, &v->name);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_TimerConfig(
CborValue* it, TimerConfig* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "name", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_str(&field, &out->name);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_TimerConfig(TimerConfig* v) {
if (!v) return;
nimffi_free_str(&v->name);
}
static inline CborError my_timer_enc_EchoRequest(
CborEncoder* e, const EchoRequest* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 2);
if (err) return err;
err = cbor_encode_text_stringz(&m, "message");
if (err) return err;
err = nimffi_enc_str(&m, &v->message);
if (err) return err;
err = cbor_encode_text_stringz(&m, "delayMs");
if (err) return err;
err = nimffi_enc_i64(&m, &v->delayMs);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_EchoRequest(
CborValue* it, EchoRequest* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "message", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_str(&field, &out->message);
if (err) return err;
err = cbor_value_map_find_value(it, "delayMs", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->delayMs);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_EchoRequest(EchoRequest* v) {
if (!v) return;
nimffi_free_str(&v->message);
}
static inline CborError my_timer_enc_EchoResponse(
CborEncoder* e, const EchoResponse* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 2);
if (err) return err;
err = cbor_encode_text_stringz(&m, "echoed");
if (err) return err;
err = nimffi_enc_str(&m, &v->echoed);
if (err) return err;
err = cbor_encode_text_stringz(&m, "timerName");
if (err) return err;
err = nimffi_enc_str(&m, &v->timerName);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_EchoResponse(
CborValue* it, EchoResponse* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "echoed", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_str(&field, &out->echoed);
if (err) return err;
err = cbor_value_map_find_value(it, "timerName", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_str(&field, &out->timerName);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_EchoResponse(EchoResponse* v) {
if (!v) return;
nimffi_free_str(&v->echoed);
nimffi_free_str(&v->timerName);
}
static inline CborError my_timer_enc_MyTimerSeq_EchoRequest(
CborEncoder* e, const MyTimerSeq_EchoRequest* v) {
CborEncoder arr;
CborError err = cbor_encoder_create_array(e, &arr, v->len);
if (err) return err;
for (size_t i = 0; i < v->len; i++) {
err = my_timer_enc_EchoRequest(&arr, &v->data[i]);
if (err) return err;
}
return cbor_encoder_close_container(e, &arr);
}
static inline CborError my_timer_dec_MyTimerSeq_EchoRequest(
CborValue* it, MyTimerSeq_EchoRequest* out) {
if (!cbor_value_is_array(it)) return CborErrorImproperValue;
size_t len = 0;
CborError err = cbor_value_get_array_length(it, &len);
if (err) return err;
out->data = (EchoRequest*)calloc(len ? len : 1, sizeof(EchoRequest));
if (!out->data) return CborErrorOutOfMemory;
out->len = len;
CborValue inner;
err = cbor_value_enter_container(it, &inner);
if (err) return err;
for (size_t i = 0; i < len; i++) {
err = my_timer_dec_EchoRequest(&inner, &out->data[i]);
if (err) return err;
}
return cbor_value_leave_container(it, &inner);
}
static inline void my_timer_free_MyTimerSeq_EchoRequest(MyTimerSeq_EchoRequest* v) {
if (!v || !v->data) return;
for (size_t i = 0; i < v->len; i++) my_timer_free_EchoRequest(&v->data[i]);
free(v->data);
v->data = NULL;
v->len = 0;
}
static inline CborError my_timer_enc_MyTimerSeq_Str(
CborEncoder* e, const MyTimerSeq_Str* v) {
CborEncoder arr;
CborError err = cbor_encoder_create_array(e, &arr, v->len);
if (err) return err;
for (size_t i = 0; i < v->len; i++) {
err = nimffi_enc_str(&arr, &v->data[i]);
if (err) return err;
}
return cbor_encoder_close_container(e, &arr);
}
static inline CborError my_timer_dec_MyTimerSeq_Str(
CborValue* it, MyTimerSeq_Str* out) {
if (!cbor_value_is_array(it)) return CborErrorImproperValue;
size_t len = 0;
CborError err = cbor_value_get_array_length(it, &len);
if (err) return err;
out->data = (NimFfiStr*)calloc(len ? len : 1, sizeof(NimFfiStr));
if (!out->data) return CborErrorOutOfMemory;
out->len = len;
CborValue inner;
err = cbor_value_enter_container(it, &inner);
if (err) return err;
for (size_t i = 0; i < len; i++) {
err = nimffi_dec_str(&inner, &out->data[i]);
if (err) return err;
}
return cbor_value_leave_container(it, &inner);
}
static inline void my_timer_free_MyTimerSeq_Str(MyTimerSeq_Str* v) {
if (!v || !v->data) return;
for (size_t i = 0; i < v->len; i++) nimffi_free_str(&v->data[i]);
free(v->data);
v->data = NULL;
v->len = 0;
}
static inline CborError my_timer_enc_MyTimerOpt_Str(
CborEncoder* e, const MyTimerOpt_Str* v) {
if (!v->has_value) return cbor_encode_null(e);
return nimffi_enc_str(e, &v->value);
}
static inline CborError my_timer_dec_MyTimerOpt_Str(
CborValue* it, MyTimerOpt_Str* out) {
if (cbor_value_is_null(it)) {
out->has_value = false;
memset(&out->value, 0, sizeof(out->value));
return cbor_value_advance(it);
}
out->has_value = true;
return nimffi_dec_str(it, &out->value);
}
static inline void my_timer_free_MyTimerOpt_Str(MyTimerOpt_Str* v) {
if (!v || !v->has_value) return;
nimffi_free_str(&v->value);
v->has_value = false;
}
static inline CborError my_timer_enc_MyTimerOpt_I64(
CborEncoder* e, const MyTimerOpt_I64* v) {
if (!v->has_value) return cbor_encode_null(e);
return nimffi_enc_i64(e, &v->value);
}
static inline CborError my_timer_dec_MyTimerOpt_I64(
CborValue* it, MyTimerOpt_I64* out) {
if (cbor_value_is_null(it)) {
out->has_value = false;
memset(&out->value, 0, sizeof(out->value));
return cbor_value_advance(it);
}
out->has_value = true;
return nimffi_dec_i64(it, &out->value);
}
static inline CborError my_timer_enc_ComplexRequest(
CborEncoder* e, const ComplexRequest* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 4);
if (err) return err;
err = cbor_encode_text_stringz(&m, "messages");
if (err) return err;
err = my_timer_enc_MyTimerSeq_EchoRequest(&m, &v->messages);
if (err) return err;
err = cbor_encode_text_stringz(&m, "tags");
if (err) return err;
err = my_timer_enc_MyTimerSeq_Str(&m, &v->tags);
if (err) return err;
err = cbor_encode_text_stringz(&m, "note");
if (err) return err;
err = my_timer_enc_MyTimerOpt_Str(&m, &v->note);
if (err) return err;
err = cbor_encode_text_stringz(&m, "retries");
if (err) return err;
err = my_timer_enc_MyTimerOpt_I64(&m, &v->retries);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_ComplexRequest(
CborValue* it, ComplexRequest* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "messages", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_MyTimerSeq_EchoRequest(&field, &out->messages);
if (err) return err;
err = cbor_value_map_find_value(it, "tags", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_MyTimerSeq_Str(&field, &out->tags);
if (err) return err;
err = cbor_value_map_find_value(it, "note", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_MyTimerOpt_Str(&field, &out->note);
if (err) return err;
err = cbor_value_map_find_value(it, "retries", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_MyTimerOpt_I64(&field, &out->retries);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_ComplexRequest(ComplexRequest* v) {
if (!v) return;
my_timer_free_MyTimerSeq_EchoRequest(&v->messages);
my_timer_free_MyTimerSeq_Str(&v->tags);
my_timer_free_MyTimerOpt_Str(&v->note);
}
static inline CborError my_timer_enc_ComplexResponse(
CborEncoder* e, const ComplexResponse* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 3);
if (err) return err;
err = cbor_encode_text_stringz(&m, "summary");
if (err) return err;
err = nimffi_enc_str(&m, &v->summary);
if (err) return err;
err = cbor_encode_text_stringz(&m, "itemCount");
if (err) return err;
err = nimffi_enc_i64(&m, &v->itemCount);
if (err) return err;
err = cbor_encode_text_stringz(&m, "hasNote");
if (err) return err;
err = nimffi_enc_bool(&m, &v->hasNote);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_ComplexResponse(
CborValue* it, ComplexResponse* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "summary", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_str(&field, &out->summary);
if (err) return err;
err = cbor_value_map_find_value(it, "itemCount", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->itemCount);
if (err) return err;
err = cbor_value_map_find_value(it, "hasNote", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_bool(&field, &out->hasNote);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_ComplexResponse(ComplexResponse* v) {
if (!v) return;
nimffi_free_str(&v->summary);
}
static inline CborError my_timer_enc_EchoEvent(
CborEncoder* e, const EchoEvent* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 2);
if (err) return err;
err = cbor_encode_text_stringz(&m, "message");
if (err) return err;
err = nimffi_enc_str(&m, &v->message);
if (err) return err;
err = cbor_encode_text_stringz(&m, "echoCount");
if (err) return err;
err = nimffi_enc_i64(&m, &v->echoCount);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_EchoEvent(
CborValue* it, EchoEvent* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "message", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_str(&field, &out->message);
if (err) return err;
err = cbor_value_map_find_value(it, "echoCount", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->echoCount);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_EchoEvent(EchoEvent* v) {
if (!v) return;
nimffi_free_str(&v->message);
}
static inline CborError my_timer_enc_JobSpec(
CborEncoder* e, const JobSpec* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 3);
if (err) return err;
err = cbor_encode_text_stringz(&m, "name");
if (err) return err;
err = nimffi_enc_str(&m, &v->name);
if (err) return err;
err = cbor_encode_text_stringz(&m, "payload");
if (err) return err;
err = my_timer_enc_MyTimerSeq_Str(&m, &v->payload);
if (err) return err;
err = cbor_encode_text_stringz(&m, "priority");
if (err) return err;
err = nimffi_enc_i64(&m, &v->priority);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_JobSpec(
CborValue* it, JobSpec* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "name", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_str(&field, &out->name);
if (err) return err;
err = cbor_value_map_find_value(it, "payload", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_MyTimerSeq_Str(&field, &out->payload);
if (err) return err;
err = cbor_value_map_find_value(it, "priority", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->priority);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_JobSpec(JobSpec* v) {
if (!v) return;
nimffi_free_str(&v->name);
my_timer_free_MyTimerSeq_Str(&v->payload);
}
static inline CborError my_timer_enc_RetryPolicy(
CborEncoder* e, const RetryPolicy* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 3);
if (err) return err;
err = cbor_encode_text_stringz(&m, "maxAttempts");
if (err) return err;
err = nimffi_enc_i64(&m, &v->maxAttempts);
if (err) return err;
err = cbor_encode_text_stringz(&m, "backoffMs");
if (err) return err;
err = nimffi_enc_i64(&m, &v->backoffMs);
if (err) return err;
err = cbor_encode_text_stringz(&m, "retryOn");
if (err) return err;
err = my_timer_enc_MyTimerSeq_Str(&m, &v->retryOn);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_RetryPolicy(
CborValue* it, RetryPolicy* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "maxAttempts", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->maxAttempts);
if (err) return err;
err = cbor_value_map_find_value(it, "backoffMs", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->backoffMs);
if (err) return err;
err = cbor_value_map_find_value(it, "retryOn", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_MyTimerSeq_Str(&field, &out->retryOn);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_RetryPolicy(RetryPolicy* v) {
if (!v) return;
my_timer_free_MyTimerSeq_Str(&v->retryOn);
}
static inline CborError my_timer_enc_ScheduleConfig(
CborEncoder* e, const ScheduleConfig* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 3);
if (err) return err;
err = cbor_encode_text_stringz(&m, "startAtMs");
if (err) return err;
err = nimffi_enc_i64(&m, &v->startAtMs);
if (err) return err;
err = cbor_encode_text_stringz(&m, "intervalMs");
if (err) return err;
err = nimffi_enc_i64(&m, &v->intervalMs);
if (err) return err;
err = cbor_encode_text_stringz(&m, "jitter");
if (err) return err;
err = my_timer_enc_MyTimerOpt_I64(&m, &v->jitter);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_ScheduleConfig(
CborValue* it, ScheduleConfig* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "startAtMs", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->startAtMs);
if (err) return err;
err = cbor_value_map_find_value(it, "intervalMs", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->intervalMs);
if (err) return err;
err = cbor_value_map_find_value(it, "jitter", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_MyTimerOpt_I64(&field, &out->jitter);
if (err) return err;
return cbor_value_advance(it);
}
static inline CborError my_timer_enc_ScheduleResult(
CborEncoder* e, const ScheduleResult* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 4);
if (err) return err;
err = cbor_encode_text_stringz(&m, "jobId");
if (err) return err;
err = nimffi_enc_str(&m, &v->jobId);
if (err) return err;
err = cbor_encode_text_stringz(&m, "willRunCount");
if (err) return err;
err = nimffi_enc_i64(&m, &v->willRunCount);
if (err) return err;
err = cbor_encode_text_stringz(&m, "firstRunAtMs");
if (err) return err;
err = nimffi_enc_i64(&m, &v->firstRunAtMs);
if (err) return err;
err = cbor_encode_text_stringz(&m, "effectiveBackoffMs");
if (err) return err;
err = nimffi_enc_i64(&m, &v->effectiveBackoffMs);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_ScheduleResult(
CborValue* it, ScheduleResult* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "jobId", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_str(&field, &out->jobId);
if (err) return err;
err = cbor_value_map_find_value(it, "willRunCount", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->willRunCount);
if (err) return err;
err = cbor_value_map_find_value(it, "firstRunAtMs", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->firstRunAtMs);
if (err) return err;
err = cbor_value_map_find_value(it, "effectiveBackoffMs", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = nimffi_dec_i64(&field, &out->effectiveBackoffMs);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_ScheduleResult(ScheduleResult* v) {
if (!v) return;
nimffi_free_str(&v->jobId);
}
static inline CborError my_timer_enc_MyTimerCreateCtorReq(
CborEncoder* e, const MyTimerCreateCtorReq* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 1);
if (err) return err;
err = cbor_encode_text_stringz(&m, "config");
if (err) return err;
err = my_timer_enc_TimerConfig(&m, &v->config);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_MyTimerCreateCtorReq(
CborValue* it, MyTimerCreateCtorReq* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "config", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_TimerConfig(&field, &out->config);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_MyTimerCreateCtorReq(MyTimerCreateCtorReq* v) {
if (!v) return;
my_timer_free_TimerConfig(&v->config);
}
static inline CborError my_timer_enc_MyTimerEchoReq(
CborEncoder* e, const MyTimerEchoReq* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 1);
if (err) return err;
err = cbor_encode_text_stringz(&m, "req");
if (err) return err;
err = my_timer_enc_EchoRequest(&m, &v->req);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_MyTimerEchoReq(
CborValue* it, MyTimerEchoReq* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "req", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_EchoRequest(&field, &out->req);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_MyTimerEchoReq(MyTimerEchoReq* v) {
if (!v) return;
my_timer_free_EchoRequest(&v->req);
}
static inline CborError my_timer_enc_MyTimerVersionReq(
CborEncoder* e, const MyTimerVersionReq* v) {
(void)v;
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 0);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_MyTimerVersionReq(
CborValue* it, MyTimerVersionReq* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
(void)out;
return cbor_value_advance(it);
}
static inline CborError my_timer_enc_MyTimerComplexReq(
CborEncoder* e, const MyTimerComplexReq* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 1);
if (err) return err;
err = cbor_encode_text_stringz(&m, "req");
if (err) return err;
err = my_timer_enc_ComplexRequest(&m, &v->req);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_MyTimerComplexReq(
CborValue* it, MyTimerComplexReq* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "req", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_ComplexRequest(&field, &out->req);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_MyTimerComplexReq(MyTimerComplexReq* v) {
if (!v) return;
my_timer_free_ComplexRequest(&v->req);
}
static inline CborError my_timer_enc_MyTimerScheduleReq(
CborEncoder* e, const MyTimerScheduleReq* v) {
CborEncoder m;
CborError err = cbor_encoder_create_map(e, &m, 3);
if (err) return err;
err = cbor_encode_text_stringz(&m, "job");
if (err) return err;
err = my_timer_enc_JobSpec(&m, &v->job);
if (err) return err;
err = cbor_encode_text_stringz(&m, "retry");
if (err) return err;
err = my_timer_enc_RetryPolicy(&m, &v->retry);
if (err) return err;
err = cbor_encode_text_stringz(&m, "schedule");
if (err) return err;
err = my_timer_enc_ScheduleConfig(&m, &v->schedule);
if (err) return err;
return cbor_encoder_close_container(e, &m);
}
static inline CborError my_timer_dec_MyTimerScheduleReq(
CborValue* it, MyTimerScheduleReq* out) {
if (!cbor_value_is_map(it)) return CborErrorImproperValue;
CborValue field;
CborError err;
err = cbor_value_map_find_value(it, "job", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_JobSpec(&field, &out->job);
if (err) return err;
err = cbor_value_map_find_value(it, "retry", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_RetryPolicy(&field, &out->retry);
if (err) return err;
err = cbor_value_map_find_value(it, "schedule", &field);
if (err) return err;
if (!cbor_value_is_valid(&field)) return CborErrorImproperValue;
err = my_timer_dec_ScheduleConfig(&field, &out->schedule);
if (err) return err;
return cbor_value_advance(it);
}
static inline void my_timer_free_MyTimerScheduleReq(MyTimerScheduleReq* v) {
if (!v) return;
my_timer_free_JobSpec(&v->job);
my_timer_free_RetryPolicy(&v->retry);
}
/* ============================================================ */
/* C ABI declarations (symbols exported by the Nim dylib) */
/* ============================================================ */
#ifdef __cplusplus
extern "C" {
#endif
void* my_timer_create(const uint8_t* req_cbor, size_t req_cbor_len, FFICallback callback, void* user_data);
int my_timer_echo(void* ctx, FFICallback callback, void* user_data, const uint8_t* req_cbor, size_t req_cbor_len);
int my_timer_version(void* ctx, FFICallback callback, void* user_data, const uint8_t* req_cbor, size_t req_cbor_len);
int my_timer_complex(void* ctx, FFICallback callback, void* user_data, const uint8_t* req_cbor, size_t req_cbor_len);
int my_timer_schedule(void* ctx, FFICallback callback, void* user_data, const uint8_t* req_cbor, size_t req_cbor_len);
int my_timer_destroy(void* ctx);
uint64_t my_timer_add_event_listener(void* ctx, const char* event_name, FFICallback callback, void* user_data);
int my_timer_remove_event_listener(void* ctx, uint64_t listener_id);
#ifdef __cplusplus
} /* extern "C" */
#endif
/* CBOR buffer adapters (typed codec → void* driver signature) */
static inline CborError my_timer_encv_MyTimerCreateCtorReq(CborEncoder* e, const void* v) { return my_timer_enc_MyTimerCreateCtorReq(e, (const MyTimerCreateCtorReq*)v); }
static inline CborError my_timer_encv_MyTimerEchoReq(CborEncoder* e, const void* v) { return my_timer_enc_MyTimerEchoReq(e, (const MyTimerEchoReq*)v); }
static inline CborError my_timer_encv_MyTimerVersionReq(CborEncoder* e, const void* v) { return my_timer_enc_MyTimerVersionReq(e, (const MyTimerVersionReq*)v); }
static inline CborError my_timer_encv_MyTimerComplexReq(CborEncoder* e, const void* v) { return my_timer_enc_MyTimerComplexReq(e, (const MyTimerComplexReq*)v); }
static inline CborError my_timer_encv_MyTimerScheduleReq(CborEncoder* e, const void* v) { return my_timer_enc_MyTimerScheduleReq(e, (const MyTimerScheduleReq*)v); }
static inline CborError my_timer_decv_EchoResponse(CborValue* it, void* v) { return my_timer_dec_EchoResponse(it, (EchoResponse*)v); }
static inline CborError my_timer_decv_Str(CborValue* it, void* v) { return nimffi_dec_str(it, (NimFfiStr*)v); }
static inline CborError my_timer_decv_ComplexResponse(CborValue* it, void* v) { return my_timer_dec_ComplexResponse(it, (ComplexResponse*)v); }
static inline CborError my_timer_decv_ScheduleResult(CborValue* it, void* v) { return my_timer_dec_ScheduleResult(it, (ScheduleResult*)v); }
/* Event listener machinery */
typedef void (*MyTimerOnEchoFiredFn)(const EchoEvent* evt, void* user_data);
typedef struct { MyTimerOnEchoFiredFn fn; void* user_data; } MyTimerOnEchoFiredBox;
static void my_timer_on_echo_fired_trampoline(int ret, const char* msg, size_t len, void* ud) {
if (!ud || ret != 0 || !msg || len == 0) return;
MyTimerOnEchoFiredBox* box = (MyTimerOnEchoFiredBox*)ud;
if (!box->fn) return;
CborParser parser;
CborValue it;
if (cbor_parser_init((const uint8_t*)msg, len, 0, &parser, &it) != CborNoError) return;
if (!cbor_value_is_map(&it)) return;
CborValue payloadField;
if (cbor_value_map_find_value(&it, "payload", &payloadField) != CborNoError) return;
EchoEvent payload;
memset(&payload, 0, sizeof(payload));
if (my_timer_dec_EchoEvent(&payloadField, &payload) != CborNoError) return;
box->fn(&payload, box->user_data);
my_timer_free_EchoEvent(&payload);
}
/* ============================================================ */
/* High-level context wrapper */
/* ============================================================ */
typedef struct {
uint64_t id;
void* box;
} MyTimerCtxListener;
typedef struct {
void* ptr;
MyTimerCtxListener* listeners;
size_t listeners_len;
size_t listeners_cap;
} MyTimerCtx;
typedef void (*MyTimerCreateFn)(int err_code, MyTimerCtx* ctx, const char* err_msg, void* user_data);
typedef struct { MyTimerCreateFn fn; void* user_data; } MyTimerCreateBox;
static void my_timer_create_trampoline(int ret, const char* msg, size_t len, void* ud) {
MyTimerCreateBox* box = (MyTimerCreateBox*)ud;
if (!box->fn) {
free(box);
return;
}
if (ret != 0) {
char* em = nimffi_dup_cstr_n(msg ? msg : "", msg ? len : 0);
box->fn(ret, NULL, em ? em : "FFI create failed", box->user_data);
free(em);
free(box);
return;
}
char* err = NULL;
NimFfiStr addr;
memset(&addr, 0, sizeof(addr));
if (nimffi_decode_from_buf(my_timer_decv_Str, (const uint8_t*)msg, len, &addr, &err) != 0) {
box->fn(-1, NULL, err ? err : "decode failed", box->user_data);
free(err);
free(box);
return;
}
char* endp = NULL;
unsigned long long a = addr.data ? strtoull(addr.data, &endp, 10) : 0;
bool ok = addr.data && addr.len > 0 && endp && *endp == '\0';
nimffi_free_str(&addr);
if (!ok) {
box->fn(-1, NULL, "FFI create returned non-numeric address", box->user_data);
free(box);
return;
}
MyTimerCtx* ctx = (MyTimerCtx*)calloc(1, sizeof(MyTimerCtx));
if (!ctx) {
box->fn(-1, NULL, "out of memory", box->user_data);
free(box);
return;
}
ctx->ptr = (void*)(uintptr_t)a;
box->fn(NIMFFI_RET_OK, ctx, NULL, box->user_data);
free(box);
}
static inline int my_timer_ctx_create(const TimerConfig* config, MyTimerCreateFn on_created, void* user_data) {
MyTimerCreateCtorReq ffi_req;
memset(&ffi_req, 0, sizeof(ffi_req));
ffi_req.config = *config;
uint8_t* req_buf = NULL;
size_t req_len = 0;
char* err = NULL;
if (nimffi_encode_to_buf(my_timer_encv_MyTimerCreateCtorReq, &ffi_req, &req_buf, &req_len, &err) != 0) {
if (on_created) on_created(-1, NULL, err ? err : "encode failed", user_data);
free(err);
return -1;
}
MyTimerCreateBox* box = (MyTimerCreateBox*)malloc(sizeof(MyTimerCreateBox));
if (!box) {
free(req_buf);
if (on_created) on_created(-1, NULL, "out of memory", user_data);
return -1;
}
box->fn = on_created;
box->user_data = user_data;
(void)my_timer_create(req_buf, req_len, my_timer_create_trampoline, box);
free(req_buf);
return 0;
}
static inline void my_timer_ctx_destroy(MyTimerCtx* ctx) {
if (!ctx) return;
if (ctx->ptr) { my_timer_destroy(ctx->ptr); ctx->ptr = NULL; }
for (size_t i = 0; i < ctx->listeners_len; i++) free(ctx->listeners[i].box);
free(ctx->listeners);
free(ctx);
}
static inline uint64_t my_timer_ctx_add_on_echo_fired_listener(MyTimerCtx* ctx, MyTimerOnEchoFiredFn fn, void* user_data) {
MyTimerOnEchoFiredBox* box = (MyTimerOnEchoFiredBox*)malloc(sizeof(MyTimerOnEchoFiredBox));
if (!box) return 0;
box->fn = fn;
box->user_data = user_data;
uint64_t id = my_timer_add_event_listener(ctx->ptr, "on_echo_fired", my_timer_on_echo_fired_trampoline, box);
if (id == 0) { free(box); return 0; }
if (ctx->listeners_len == ctx->listeners_cap) {
size_t ncap = ctx->listeners_cap ? ctx->listeners_cap * 2 : 4;
MyTimerCtxListener* grown = (MyTimerCtxListener*)realloc(ctx->listeners, ncap * sizeof(MyTimerCtxListener));
if (!grown) { my_timer_remove_event_listener(ctx->ptr, id); free(box); return 0; }
ctx->listeners = grown;
ctx->listeners_cap = ncap;
}
ctx->listeners[ctx->listeners_len].id = id;
ctx->listeners[ctx->listeners_len].box = box;
ctx->listeners_len++;
return id;
}
static inline bool my_timer_ctx_remove_event_listener(MyTimerCtx* ctx, uint64_t id) {
if (id == 0) return false;
int rc = my_timer_remove_event_listener(ctx->ptr, id);
for (size_t i = 0; i < ctx->listeners_len; i++) {
if (ctx->listeners[i].id == id) {
free(ctx->listeners[i].box);
ctx->listeners[i] = ctx->listeners[ctx->listeners_len - 1];
ctx->listeners_len--;
break;
}
}
return rc == 0;
}
typedef void (*MyTimerEchoReplyFn)(int err_code, const EchoResponse* reply, const char* err_msg, void* user_data);
typedef struct { MyTimerEchoReplyFn fn; void* user_data; } MyTimerEchoCallBox;
static void my_timer_echo_reply_trampoline(int ret, const char* msg, size_t len, void* ud) {
MyTimerEchoCallBox* box = (MyTimerEchoCallBox*)ud;
if (!box->fn) {
free(box);
return;
}
if (ret != 0) {
char* em = nimffi_dup_cstr_n(msg ? msg : "", msg ? len : 0);
box->fn(ret, NULL, em ? em : "FFI call failed", box->user_data);
free(em);
free(box);
return;
}
char* err = NULL;
EchoResponse out;
memset(&out, 0, sizeof(out));
int dec = nimffi_decode_from_buf(my_timer_decv_EchoResponse, (const uint8_t*)msg, len, &out, &err);
if (dec != 0) {
box->fn(-1, NULL, err ? err : "decode failed", box->user_data);
free(err);
my_timer_free_EchoResponse(&out);
free(box);
return;
}
box->fn(NIMFFI_RET_OK, &out, NULL, box->user_data);
my_timer_free_EchoResponse(&out);
free(box);
}
static inline int my_timer_ctx_echo(const MyTimerCtx* ctx, const EchoRequest* req, MyTimerEchoReplyFn on_reply, void* user_data) {
MyTimerEchoReq ffi_req;
memset(&ffi_req, 0, sizeof(ffi_req));
ffi_req.req = *req;
uint8_t* req_buf = NULL;
size_t req_len = 0;
char* err = NULL;
if (nimffi_encode_to_buf(my_timer_encv_MyTimerEchoReq, &ffi_req, &req_buf, &req_len, &err) != 0) {
if (on_reply) on_reply(-1, NULL, err ? err : "encode failed", user_data);
free(err);
return -1;
}
MyTimerEchoCallBox* box = (MyTimerEchoCallBox*)malloc(sizeof(MyTimerEchoCallBox));
if (!box) {
free(req_buf);
if (on_reply) on_reply(-1, NULL, "out of memory", user_data);
return -1;
}
box->fn = on_reply;
box->user_data = user_data;
int ret = my_timer_echo(ctx->ptr, my_timer_echo_reply_trampoline, box, req_buf, req_len);
free(req_buf);
if (ret == NIMFFI_RET_MISSING_CALLBACK) {
if (on_reply) on_reply(-1, NULL, "RET_MISSING_CALLBACK (internal error)", user_data);
free(box);
return -1;
}
return 0;
}
typedef void (*MyTimerVersionReplyFn)(int err_code, const NimFfiStr* reply, const char* err_msg, void* user_data);
typedef struct { MyTimerVersionReplyFn fn; void* user_data; } MyTimerVersionCallBox;
static void my_timer_version_reply_trampoline(int ret, const char* msg, size_t len, void* ud) {
MyTimerVersionCallBox* box = (MyTimerVersionCallBox*)ud;
if (!box->fn) {
free(box);
return;
}
if (ret != 0) {
char* em = nimffi_dup_cstr_n(msg ? msg : "", msg ? len : 0);
box->fn(ret, NULL, em ? em : "FFI call failed", box->user_data);
free(em);
free(box);
return;
}
char* err = NULL;
NimFfiStr out;
memset(&out, 0, sizeof(out));
int dec = nimffi_decode_from_buf(my_timer_decv_Str, (const uint8_t*)msg, len, &out, &err);
if (dec != 0) {
box->fn(-1, NULL, err ? err : "decode failed", box->user_data);
free(err);
nimffi_free_str(&out);
free(box);
return;
}
box->fn(NIMFFI_RET_OK, &out, NULL, box->user_data);
nimffi_free_str(&out);
free(box);
}
static inline int my_timer_ctx_version(const MyTimerCtx* ctx, MyTimerVersionReplyFn on_reply, void* user_data) {
MyTimerVersionReq ffi_req;
memset(&ffi_req, 0, sizeof(ffi_req));
uint8_t* req_buf = NULL;
size_t req_len = 0;
char* err = NULL;
if (nimffi_encode_to_buf(my_timer_encv_MyTimerVersionReq, &ffi_req, &req_buf, &req_len, &err) != 0) {
if (on_reply) on_reply(-1, NULL, err ? err : "encode failed", user_data);
free(err);
return -1;
}
MyTimerVersionCallBox* box = (MyTimerVersionCallBox*)malloc(sizeof(MyTimerVersionCallBox));
if (!box) {
free(req_buf);
if (on_reply) on_reply(-1, NULL, "out of memory", user_data);
return -1;
}
box->fn = on_reply;
box->user_data = user_data;
int ret = my_timer_version(ctx->ptr, my_timer_version_reply_trampoline, box, req_buf, req_len);
free(req_buf);
if (ret == NIMFFI_RET_MISSING_CALLBACK) {
if (on_reply) on_reply(-1, NULL, "RET_MISSING_CALLBACK (internal error)", user_data);
free(box);
return -1;
}
return 0;
}
typedef void (*MyTimerComplexReplyFn)(int err_code, const ComplexResponse* reply, const char* err_msg, void* user_data);
typedef struct { MyTimerComplexReplyFn fn; void* user_data; } MyTimerComplexCallBox;
static void my_timer_complex_reply_trampoline(int ret, const char* msg, size_t len, void* ud) {
MyTimerComplexCallBox* box = (MyTimerComplexCallBox*)ud;
if (!box->fn) {
free(box);
return;
}
if (ret != 0) {
char* em = nimffi_dup_cstr_n(msg ? msg : "", msg ? len : 0);
box->fn(ret, NULL, em ? em : "FFI call failed", box->user_data);
free(em);
free(box);
return;
}
char* err = NULL;
ComplexResponse out;
memset(&out, 0, sizeof(out));
int dec = nimffi_decode_from_buf(my_timer_decv_ComplexResponse, (const uint8_t*)msg, len, &out, &err);
if (dec != 0) {
box->fn(-1, NULL, err ? err : "decode failed", box->user_data);
free(err);
my_timer_free_ComplexResponse(&out);
free(box);
return;
}
box->fn(NIMFFI_RET_OK, &out, NULL, box->user_data);
my_timer_free_ComplexResponse(&out);
free(box);
}
static inline int my_timer_ctx_complex(const MyTimerCtx* ctx, const ComplexRequest* req, MyTimerComplexReplyFn on_reply, void* user_data) {
MyTimerComplexReq ffi_req;
memset(&ffi_req, 0, sizeof(ffi_req));
ffi_req.req = *req;
uint8_t* req_buf = NULL;
size_t req_len = 0;
char* err = NULL;
if (nimffi_encode_to_buf(my_timer_encv_MyTimerComplexReq, &ffi_req, &req_buf, &req_len, &err) != 0) {
if (on_reply) on_reply(-1, NULL, err ? err : "encode failed", user_data);
free(err);
return -1;
}
MyTimerComplexCallBox* box = (MyTimerComplexCallBox*)malloc(sizeof(MyTimerComplexCallBox));
if (!box) {
free(req_buf);
if (on_reply) on_reply(-1, NULL, "out of memory", user_data);
return -1;
}
box->fn = on_reply;
box->user_data = user_data;
int ret = my_timer_complex(ctx->ptr, my_timer_complex_reply_trampoline, box, req_buf, req_len);
free(req_buf);
if (ret == NIMFFI_RET_MISSING_CALLBACK) {
if (on_reply) on_reply(-1, NULL, "RET_MISSING_CALLBACK (internal error)", user_data);
free(box);
return -1;
}
return 0;
}
typedef void (*MyTimerScheduleReplyFn)(int err_code, const ScheduleResult* reply, const char* err_msg, void* user_data);
typedef struct { MyTimerScheduleReplyFn fn; void* user_data; } MyTimerScheduleCallBox;
static void my_timer_schedule_reply_trampoline(int ret, const char* msg, size_t len, void* ud) {
MyTimerScheduleCallBox* box = (MyTimerScheduleCallBox*)ud;
if (!box->fn) {
free(box);
return;
}
if (ret != 0) {
char* em = nimffi_dup_cstr_n(msg ? msg : "", msg ? len : 0);
box->fn(ret, NULL, em ? em : "FFI call failed", box->user_data);
free(em);
free(box);
return;
}
char* err = NULL;
ScheduleResult out;
memset(&out, 0, sizeof(out));
int dec = nimffi_decode_from_buf(my_timer_decv_ScheduleResult, (const uint8_t*)msg, len, &out, &err);
if (dec != 0) {
box->fn(-1, NULL, err ? err : "decode failed", box->user_data);
free(err);
my_timer_free_ScheduleResult(&out);
free(box);
return;
}
box->fn(NIMFFI_RET_OK, &out, NULL, box->user_data);
my_timer_free_ScheduleResult(&out);
free(box);
}
static inline int my_timer_ctx_schedule(const MyTimerCtx* ctx, const JobSpec* job, const RetryPolicy* retry, const ScheduleConfig* schedule, MyTimerScheduleReplyFn on_reply, void* user_data) {
MyTimerScheduleReq ffi_req;
memset(&ffi_req, 0, sizeof(ffi_req));
ffi_req.job = *job;
ffi_req.retry = *retry;
ffi_req.schedule = *schedule;
uint8_t* req_buf = NULL;
size_t req_len = 0;
char* err = NULL;
if (nimffi_encode_to_buf(my_timer_encv_MyTimerScheduleReq, &ffi_req, &req_buf, &req_len, &err) != 0) {
if (on_reply) on_reply(-1, NULL, err ? err : "encode failed", user_data);
free(err);
return -1;
}
MyTimerScheduleCallBox* box = (MyTimerScheduleCallBox*)malloc(sizeof(MyTimerScheduleCallBox));
if (!box) {
free(req_buf);
if (on_reply) on_reply(-1, NULL, "out of memory", user_data);
return -1;
}
box->fn = on_reply;
box->user_data = user_data;
int ret = my_timer_schedule(ctx->ptr, my_timer_schedule_reply_trampoline, box, req_buf, req_len);
free(req_buf);
if (ret == NIMFFI_RET_MISSING_CALLBACK) {
if (on_reply) on_reply(-1, NULL, "RET_MISSING_CALLBACK (internal error)", user_data);
free(box);
return -1;
}
return 0;
}
#endif /* NIM_FFI_LIB_MY_TIMER_H_INCLUDED */