fix(trixy-types): Rework c header files

The old implementation tried to provide rust types in c—like the
result or option types. This implementation now removes this source of
complexity by ensuring, that these types are unwrapped on the rust->c
boundary.

This first commit changes the header files to conform to the new api.
This commit is contained in:
Benedikt Peetz 2024-02-18 13:30:03 +01:00
parent a077ef1466
commit f699ca24a9
Signed by: bpeetz
GPG Key ID: A5E94010C3A642AD
9 changed files with 39 additions and 161 deletions

View File

@ -1,21 +1,24 @@
#ifndef TRIXY_ERRNO_H #ifndef TRIXY_ERRNO_H
#define TRIXY_ERRNO_H #define TRIXY_ERRNO_H
#include <stdint.h>
/// Calculate the number of bytes in the last error's error message **not** /** Calculate the number of bytes in the last error's error message **not**
/// including any trailing `null` characters. * including any trailing `null` characters.
*/
extern int last_error_length(); extern int last_error_length();
/// Write the most recent error message into a caller-provided buffer as a UTF-8 /** Write the most recent error message into a caller-provided buffer as a UTF-8
/// string, returning the number of bytes written. * string, returning the number of bytes written.
/// *
/// # Note * # Note
/// *
/// This writes a **UTF-8** string into the buffer. Windows users may need to * This writes a **UTF-8** string into the buffer. Windows users may need to
/// convert it to a UTF-16 “Unicode” afterwards. * convert it to a UTF-16 Unicode afterwards.
/// *
/// If there are no recent errors then this returns `0` (because we wrote 0 * If there are no recent errors then this returns `0` (because we wrote 0
/// bytes). `-1` is returned if there are any errors, for example when passed a * bytes). `-1` is returned if there are any errors, for example when passed a
/// null pointer or a buffer of insufficient size. * null pointer or a buffer of insufficient size.
extern int last_error_message(char *buffer, int length); */
extern int last_error_message(char *buffer, uint64_t length);
#endif // TRIXY_ERRNO_H #endif // TRIXY_ERRNO_H

View File

@ -1,12 +0,0 @@
#ifndef TRIXY_OPTION_H
#define TRIXY_OPTION_H
#include "type_id_dec.h"
#include <stdbool.h>
typedef struct {
type_id_t type_id;
void *value;
bool some;
} option_t;
#endif // TRIXY_OPTION_H

View File

@ -1,24 +0,0 @@
#ifndef TRIXY_RESULT_H
#define TRIXY_RESULT_H
#include "result_dec.h"
#include "type_id_dec.h"
// Function to create an Ok Result variant
result_t ok_result(void *value, type_id_t type_id) {
result_t result;
result.tag = ok;
result.value = value;
result.type_id = type_id;
return result;
}
// Function to create an Err Result variant
result_t err_result(void *value, type_id_t type_id) {
result_t result;
result.tag = err;
result.value = value;
result.type_id = type_id;
return result;
}
#endif // TRIXY_RESULT_H

View File

@ -1,14 +0,0 @@
#ifndef TRIXY_RESULT_DEC_H
#define TRIXY_RESULT_DEC_H
#include "type_id_dec.h"
typedef enum { ok, err } result_tag_t;
typedef struct {
type_id_t type_id;
result_tag_t tag;
/// The type here should be remembered
void *value;
} result_t;
#endif // TRIXY_RESULT_DEC_H

View File

@ -1,12 +1,16 @@
#ifndef TRIXY_STRING_H #ifndef TRIXY_STRING_H
#define TRIXY_STRING_H #define TRIXY_STRING_H
/// This is an “owned” string, that means that you have not only a reference to the string /**
/// but are also required to free it yourself. * @brief This string type is allocated by rust, which means that you can't just
typedef char *string_t; * free it from c, but need to return it to rust to be freed.
* @see the `string_free` method
*/
typedef const char *string_t;
/// This type is, in comparison, *not* owned but still owned its source. /**
/// Thus, it would be undefined behaviour if you free this string slice or mutate it. * @brief The free function for rust stings
typedef const char *str_t; */
extern int string_free(string_t string);
#endif // TRIXY_STRING_H #endif // TRIXY_STRING_H

View File

@ -1,35 +0,0 @@
#ifndef TRIXY_TYPE_ID_H
#define TRIXY_TYPE_ID_H
#include "option.h"
#include "result_dec.h"
#include "string.h"
#include "type_id_dec.h"
#include "vec_dec.h"
#include <stdio.h>
#include <stdlib.h>
size_t type_id_size(type_id_t type_id) {
switch (type_id) {
case type_unknown:
fputs("Tried to get size of type with type_id 'unknown'!\n", stderr);
exit(1);
case type_void:
return sizeof(size_t);
case type_str_t:
return sizeof(str_t);
case type_string_t:
return sizeof(string_t);
case type_result_t:
return sizeof(result_t);
case type_vec_t:
return sizeof(vec_t);
case type_option_t:
return sizeof(option_t);
}
fputs("This is unreachable, as all variants of the type_id enum are listed "
"above",
stderr);
exit(1);
};
#endif // TRIXY_TYPE_ID_H

View File

@ -1,17 +0,0 @@
#ifndef TRIXY_TYPE_ID_DEC_H
#define TRIXY_TYPE_ID_DEC_H
/// The type of something (option, result, vec, etc.).
typedef enum {
/// We simply don't know which type this is
type_unknown,
type_void,
type_str_t,
type_string_t,
type_result_t,
type_vec_t,
type_option_t,
} type_id_t;
#endif // TRIXY_TYPE_ID_DEC_H

View File

@ -1,28 +1,19 @@
#ifndef TRIXY_VEC_H #ifndef TRIXY_VEC_H
#define TRIXY_VEC_H #define TRIXY_VEC_H
#include "type_id_dec.h"
#include "type_id.h"
#include "vec_dec.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
/// This will abort execution when called with an un-typed vector (that is one /**
/// of type_id = unknown). * @brief A read-only vector from rust.
void push_back(vec_t *vec, const void *value) { *
if (vec->size >= vec->capacity) { * @detail
// If the current size exceeds the capacity, reallocate memory * You are must not free it by calling c's `free`. Use `vec_free`
vec->capacity = * instead.
(vec->capacity == 0) ? 1 : vec->capacity * 2; // Double the capacity */
vec->data = realloc(vec->data, vec->capacity * type_id_size(vec->type_id)); struct vec {
} void *data;
void *ptr = (size_t *)vec->data + (vec->size / type_id_size(vec->type_id)); size_t length;
memcpy(ptr, value, type_id_size(vec->type_id)); };
}
void free_vector(vec_t *vec) { extern int vec_free(struct vec vector);
free(vec->data);
vec->data = NULL;
vec->size = vec->capacity = 0;
}
#endif // TRIXY_VEC_H #endif // TRIXY_VEC_H

View File

@ -1,18 +0,0 @@
#ifndef TRIXY_VEC_DEC_H
#define TRIXY_VEC_DEC_H
#include "type_id_dec.h"
#include <stdlib.h>
typedef struct vec {
type_id_t type_id;
void *data;
size_t size;
size_t capacity;
} vec_t;
void init_vector(vec_t *vec) {
vec->data = NULL;
vec->size = 0;
vec->capacity = 0;
}
#endif // TRIXY_VEC_DEC_H