mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-28 00:34:06 +02:00
460 lines
11 KiB
C
460 lines
11 KiB
C
#include "models.h"
|
|
#include "../json/json.h"
|
|
#include "../util/panic.h"
|
|
#include "../util/str.h"
|
|
#include "models_json.h"
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
void user_destroy(User* m)
|
|
{
|
|
static_assert(sizeof(User) == 40, "model has changed");
|
|
|
|
free(m->name);
|
|
free(m->email);
|
|
free(m->password_hash);
|
|
}
|
|
|
|
void coord_destroy(Coord* m)
|
|
{
|
|
static_assert(sizeof(Coord) == 24, "model has changed");
|
|
|
|
(void)m;
|
|
}
|
|
|
|
void product_destroy(Product* m)
|
|
{
|
|
static_assert(sizeof(Product) == 48, "model has changed");
|
|
|
|
free(m->name);
|
|
free(m->description);
|
|
free(m->barcode);
|
|
}
|
|
|
|
void product_price_destroy(ProductPrice* m)
|
|
{
|
|
static_assert(sizeof(ProductPrice) == 24, "model has changed");
|
|
|
|
(void)m;
|
|
}
|
|
|
|
void receipt_product_destroy(ReceiptProduct* m)
|
|
{
|
|
static_assert(sizeof(ReceiptProduct) == 32, "model has changed");
|
|
|
|
(void)m;
|
|
}
|
|
|
|
void receipt_destroy(Receipt* m)
|
|
{
|
|
static_assert(sizeof(Receipt) == 48, "model has changed");
|
|
|
|
(void)m;
|
|
}
|
|
|
|
void users_register_req_destroy(UsersRegisterReq* model)
|
|
{
|
|
static_assert(sizeof(UsersRegisterReq) == 24, "model has changed");
|
|
|
|
free(model->name);
|
|
free(model->email);
|
|
free(model->password);
|
|
}
|
|
|
|
void sessions_login_req_destroy(SessionsLoginReq* model)
|
|
{
|
|
static_assert(sizeof(SessionsLoginReq) == 16, "model has changed");
|
|
|
|
free(model->email);
|
|
free(model->password);
|
|
}
|
|
|
|
void carts_purchase_req_destroy(CartsPurchaseReq* model)
|
|
{
|
|
static_assert(sizeof(CartsPurchaseReq) == 24, "model has changed");
|
|
|
|
carts_item_vec_destroy(&model->items);
|
|
}
|
|
|
|
char* user_to_json_string(const User* m)
|
|
{
|
|
static_assert(sizeof(User) == 40, "model has changed");
|
|
|
|
String string;
|
|
string_construct(&string);
|
|
string_pushf(&string,
|
|
"{"
|
|
"\"id\":%ld,"
|
|
"\"name\":\"%s\","
|
|
"\"email\":\"%s\","
|
|
"\"password_hash\":\"%s\","
|
|
"\"balance_dkk_cent\":%ld"
|
|
"}",
|
|
m->id,
|
|
m->name,
|
|
m->email,
|
|
m->password_hash,
|
|
m->balance_dkk_cent);
|
|
|
|
char* result = string_copy(&string);
|
|
string_destroy(&string);
|
|
return result;
|
|
}
|
|
|
|
char* coord_to_json_string(const Coord* m)
|
|
{
|
|
static_assert(sizeof(Coord) == 24, "model has changed");
|
|
|
|
String string;
|
|
string_construct(&string);
|
|
string_pushf(&string,
|
|
"{"
|
|
"\"id\":%ld,"
|
|
"\"x\":%ld,"
|
|
"\"y\":%ld"
|
|
"}",
|
|
m->id,
|
|
m->x,
|
|
m->y);
|
|
|
|
char* result = string_copy(&string);
|
|
string_destroy(&string);
|
|
return result;
|
|
}
|
|
|
|
char* product_to_json_string(const Product* m)
|
|
{
|
|
static_assert(sizeof(Product) == 48, "model has changed");
|
|
|
|
String string;
|
|
string_construct(&string);
|
|
string_pushf(&string,
|
|
"{"
|
|
"\"id\":%ld,"
|
|
"\"name\":\"%s\","
|
|
"\"description\":\"%s\","
|
|
"\"price_dkk_cent\":%ld,"
|
|
"\"coord_id\":%ld,"
|
|
"\"barcode\":\"%s\""
|
|
"}",
|
|
m->id,
|
|
m->name,
|
|
m->description,
|
|
m->price_dkk_cent,
|
|
m->coord_id,
|
|
m->barcode);
|
|
|
|
char* result = string_copy(&string);
|
|
string_destroy(&string);
|
|
return result;
|
|
}
|
|
|
|
char* product_price_to_json_string(const ProductPrice* m)
|
|
{
|
|
static_assert(sizeof(ProductPrice) == 24, "model has changed");
|
|
|
|
String string;
|
|
string_construct(&string);
|
|
string_pushf(&string,
|
|
"{"
|
|
"\"id\":%ld,"
|
|
"\"product_id\":%ld,"
|
|
"\"price_dkk_cent\":%ld"
|
|
"}",
|
|
m->id,
|
|
m->product_id,
|
|
m->price_dkk_cent);
|
|
|
|
char* result = string_copy(&string);
|
|
string_destroy(&string);
|
|
return result;
|
|
}
|
|
char* receipt_to_json_string(const Receipt* m)
|
|
{
|
|
static_assert(sizeof(Receipt) == 48, "model has changed");
|
|
|
|
String string;
|
|
string_construct(&string);
|
|
string_pushf(&string,
|
|
"{"
|
|
"\"id\":%ld,"
|
|
"\"user_id\":%ld,"
|
|
"\"timestamp\":\"%s\","
|
|
"\"products\":[",
|
|
m->id,
|
|
m->user_id,
|
|
m->timestamp);
|
|
|
|
for (size_t i = 0; i < m->products.size; ++i) {
|
|
if (i != 0) {
|
|
string_pushf(&string, ",");
|
|
}
|
|
string_pushf(&string,
|
|
"{"
|
|
"\"id\":%ld,"
|
|
"\"receipt_id\":%ld,"
|
|
"\"product_price_id\":%ld,"
|
|
"\"amount\":%ld"
|
|
"}",
|
|
m->products.data[i].id,
|
|
m->products.data[i].receipt_id,
|
|
m->products.data[i].product_price_id,
|
|
m->products.data[i].amount);
|
|
}
|
|
string_pushf(&string, "]}");
|
|
char* result = string_copy(&string);
|
|
string_destroy(&string);
|
|
return result;
|
|
}
|
|
|
|
char* users_register_req_to_json(const UsersRegisterReq* m)
|
|
{
|
|
static_assert(sizeof(UsersRegisterReq) == 24, "model has changed");
|
|
|
|
String string;
|
|
string_construct(&string);
|
|
string_pushf(&string,
|
|
"{"
|
|
"\"name\":\"%s\","
|
|
"\"email\":\"%s\","
|
|
"\"password\":\"%s\""
|
|
"}",
|
|
m->name,
|
|
m->email,
|
|
m->password);
|
|
|
|
char* result = string_copy(&string);
|
|
string_destroy(&string);
|
|
return result;
|
|
}
|
|
|
|
char* sessions_login_req_to_json(const SessionsLoginReq* m)
|
|
{
|
|
static_assert(sizeof(SessionsLoginReq) == 16, "model has changed");
|
|
|
|
String string;
|
|
string_construct(&string);
|
|
string_pushf(&string,
|
|
"{"
|
|
"\"email\":\"%s\","
|
|
"\"password\":\"%s\""
|
|
"}",
|
|
m->email,
|
|
m->password);
|
|
|
|
char* result = string_copy(&string);
|
|
string_destroy(&string);
|
|
return result;
|
|
}
|
|
|
|
char* carts_purchase_req_to_json(const CartsPurchaseReq* m)
|
|
{
|
|
static_assert(sizeof(CartsPurchaseReq) == 24, "model has changed");
|
|
|
|
PANIC("not implemented");
|
|
}
|
|
|
|
typedef struct {
|
|
const char* key;
|
|
JsonType type;
|
|
} ObjField;
|
|
|
|
static inline bool obj_conforms(
|
|
const JsonValue* val, const ObjField* fields, size_t fields_size)
|
|
{
|
|
if (!json_is(val, JsonType_Object)) {
|
|
return false;
|
|
}
|
|
for (size_t i = 0; i < fields_size; ++i) {
|
|
if (!json_object_has(val, fields[i].key)) {
|
|
return false;
|
|
}
|
|
if (!json_is(json_object_get(val, fields[i].key), fields[i].type)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#define OBJ_GET_INT(JSON, K) json_int(json_object_get(JSON, K))
|
|
#define OBJ_GET_STR(JSON, K) str_dup(json_string(json_object_get(JSON, K)))
|
|
|
|
#define OBJ_CONFORMS(JSON, FIELDS) \
|
|
obj_conforms(JSON, FIELDS, sizeof(FIELDS) / sizeof(FIELDS[0]))
|
|
|
|
#define GET_INT(K) OBJ_GET_INT(json, K)
|
|
#define GET_STR(K) OBJ_GET_STR(json, K)
|
|
|
|
int user_from_json(User* m, const JsonValue* json)
|
|
{
|
|
static_assert(sizeof(User) == 40, "model has changed");
|
|
|
|
ObjField fields[] = {
|
|
{ "id", JsonType_Number },
|
|
{ "name", JsonType_String },
|
|
{ "email", JsonType_String },
|
|
{ "password_hash", JsonType_String },
|
|
{ "balance_dkk_cent", JsonType_Number },
|
|
};
|
|
if (!OBJ_CONFORMS(json, fields))
|
|
return -1;
|
|
*m = (User) {
|
|
.id = GET_INT("id"),
|
|
.name = GET_STR("name"),
|
|
.email = GET_STR("email"),
|
|
.password_hash = GET_STR("password_hash"),
|
|
.balance_dkk_cent = GET_INT("balance_dkk_cent"),
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
int coord_from_json(Coord* m, const JsonValue* json)
|
|
{
|
|
static_assert(sizeof(Coord) == 24, "model has changed");
|
|
|
|
ObjField fields[] = {
|
|
{ "id", JsonType_Number },
|
|
{ "x", JsonType_Number },
|
|
{ "y", JsonType_Number },
|
|
};
|
|
if (!OBJ_CONFORMS(json, fields))
|
|
return -1;
|
|
*m = (Coord) {
|
|
.id = GET_INT("id"),
|
|
.x = GET_INT("x"),
|
|
.y = GET_INT("y"),
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
int product_from_json(Product* m, const JsonValue* json)
|
|
{
|
|
static_assert(sizeof(Product) == 48, "model has changed");
|
|
|
|
ObjField fields[] = {
|
|
{ "id", JsonType_Number },
|
|
{ "name", JsonType_String },
|
|
{ "description", JsonType_String },
|
|
{ "price_dkk_cent", JsonType_Number },
|
|
{ "coord_id", JsonType_Number },
|
|
{ "barcode", JsonType_String },
|
|
};
|
|
if (!OBJ_CONFORMS(json, fields))
|
|
return -1;
|
|
*m = (Product) {
|
|
.id = GET_INT("id"),
|
|
.name = GET_STR("name"),
|
|
.description = GET_STR("description"),
|
|
.price_dkk_cent = GET_INT("price_dkk_cent"),
|
|
.coord_id = GET_INT("coord_id"),
|
|
.barcode = GET_STR("y"),
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
int product_price_from_json(ProductPrice* m, const JsonValue* json)
|
|
{
|
|
static_assert(sizeof(ProductPrice) == 24, "model has changed");
|
|
|
|
ObjField fields[] = {
|
|
{ "id", JsonType_Number },
|
|
{ "product_id", JsonType_Number },
|
|
{ "price_dkk_cent", JsonType_Number },
|
|
};
|
|
if (!OBJ_CONFORMS(json, fields))
|
|
return -1;
|
|
*m = (ProductPrice) {
|
|
.id = GET_INT("id"),
|
|
.product_id = GET_INT("product_id"),
|
|
.price_dkk_cent = GET_INT("price_dkk_cent"),
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
int receipt_from_json(Receipt* m, const JsonValue* json)
|
|
{
|
|
static_assert(sizeof(Receipt) == 48, "model has changed");
|
|
|
|
PANIC("not implemented");
|
|
}
|
|
|
|
int users_register_req_from_json(UsersRegisterReq* m, const JsonValue* json)
|
|
{
|
|
static_assert(sizeof(UsersRegisterReq) == 24, "model has changed");
|
|
|
|
ObjField fields[] = {
|
|
{ "name", JsonType_String },
|
|
{ "email", JsonType_String },
|
|
{ "password", JsonType_String },
|
|
};
|
|
if (!OBJ_CONFORMS(json, fields))
|
|
return -1;
|
|
*m = (UsersRegisterReq) {
|
|
.name = GET_STR("name"),
|
|
.email = GET_STR("email"),
|
|
.password = GET_STR("password"),
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
int sessions_login_req_from_json(SessionsLoginReq* m, const JsonValue* json)
|
|
{
|
|
static_assert(sizeof(SessionsLoginReq) == 16, "model has changed");
|
|
|
|
ObjField fields[] = {
|
|
{ "email", JsonType_String },
|
|
{ "password", JsonType_String },
|
|
};
|
|
if (!OBJ_CONFORMS(json, fields))
|
|
return -1;
|
|
*m = (SessionsLoginReq) {
|
|
.email = GET_STR("email"),
|
|
.password = GET_STR("password"),
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
int carts_purchase_req_from_json(CartsPurchaseReq* m, const JsonValue* json)
|
|
{
|
|
static_assert(sizeof(CartsPurchaseReq) == 24, "model has changed");
|
|
|
|
ObjField fields[] = {
|
|
{ "items", JsonType_Array },
|
|
};
|
|
if (!OBJ_CONFORMS(json, fields))
|
|
return -1;
|
|
*m = (CartsPurchaseReq) {
|
|
.items = (CartsItemVec) { 0 },
|
|
};
|
|
carts_item_vec_construct(&m->items);
|
|
|
|
const JsonValue* items = json_object_get(json, "items");
|
|
size_t items_size = json_array_size(items);
|
|
|
|
for (size_t i = 0; i < items_size; ++i) {
|
|
const JsonValue* item = json_array_get(items, i);
|
|
|
|
ObjField item_fields[] = {
|
|
{ "product_id", JsonType_Number },
|
|
{ "amount", JsonType_Number },
|
|
};
|
|
if (!OBJ_CONFORMS(item, item_fields)) {
|
|
carts_item_vec_destroy(&m->items);
|
|
return -1;
|
|
}
|
|
|
|
carts_item_vec_push(&m->items,
|
|
(CartsItem) {
|
|
.product_id = OBJ_GET_INT(item, "product_id"),
|
|
.amount = OBJ_GET_INT(item, "amount"),
|
|
});
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
DEFINE_VEC_IMPL(ProductPrice, ProductPriceVec, product_price_vec, )
|
|
DEFINE_VEC_IMPL(ReceiptProduct, ReceiptProductVec, receipt_product_vec, )
|
|
DEFINE_VEC_IMPL(CartsItem, CartsItemVec, carts_item_vec, )
|