diff --git a/include/mastodont_relationship.h b/include/mastodont_relationship.h index 09a91c0..a8936c7 100644 --- a/include/mastodont_relationship.h +++ b/include/mastodont_relationship.h @@ -15,29 +15,37 @@ #ifndef MASTODONT_RELATIONSHIP_H #define MASTODONT_RELATIONSHIP_H +#include #include #include +typedef uint16_t mstdnt_relationship_flag_t; + +#define MSTDNT_RELATIONSHIP_NOOP 0 +#define MSTDNT_RELATIONSHIP_FOLLOWING (1<<0) +#define MSTDNT_RELATIONSHIP_REQUESTED (1<<1) +#define MSTDNT_RELATIONSHIP_ENDORSED (1<<2) +#define MSTDNT_RELATIONSHIP_FOLLOWED_BY (1<<3) +#define MSTDNT_RELATIONSHIP_MUTING (1<<4) +#define MSTDNT_RELATIONSHIP_MUTING_NOTIFS (1<<5) +#define MSTDNT_RELATIONSHIP_SHOWING_REBLOGS (1<<6) +#define MSTDNT_RELATIONSHIP_NOTIFYING (1<<7) +#define MSTDNT_RELATIONSHIP_BLOCKING (1<<8) +#define MSTDNT_RELATIONSHIP_DOMAIN_BLOCKING (1<<9) +#define MSTDNT_RELATIONSHIP_BLOCKED_BY (1<<10) + struct mstdnt_relationship { char* id; - mstdnt_bool following; - mstdnt_bool requested; - mstdnt_bool endorsed; - mstdnt_bool followed_by; - mstdnt_bool muting; - mstdnt_bool muting_notifications; - mstdnt_bool showing_reblogs; - mstdnt_bool notifying; - mstdnt_bool blocking; - mstdnt_bool domain_blocking; - mstdnt_bool blocked_by; + mstdnt_relationship_flag_t flags; char* note; }; +int mstdnt_relationship_json(struct mstdnt_relationship* relationship, cJSON* js); + int mstdnt_relationships_result(struct mstdnt_fetch_results* results, struct mstdnt_storage* storage, - struct mstdnt_relationship* relationships, + struct mstdnt_relationship* relationships[], size_t* size); int _mstdnt_relationships_result_callback(struct mstdnt_fetch_results* results, diff --git a/src/relationship.c b/src/relationship.c index ab64230..7c23191 100644 --- a/src/relationship.c +++ b/src/relationship.c @@ -13,7 +13,11 @@ * along with this program. If not, see . */ +#include #include +#include + +#define FLAG_ARG(flag) { &(relationship->flags), flag } struct _mstdnt_relationships_cb_args { @@ -21,11 +25,82 @@ struct _mstdnt_relationships_cb_args size_t* size; }; +struct _mstdnt_relationship_flags_args +{ + mstdnt_relationship_flag_t* flags; + mstdnt_relationship_flag_t flag; +}; + +static void _mstdnt_val_relationship_flag_call(cJSON* v, void* _type) +{ + struct _mstdnt_relationship_flags_args* arg = _type; + *(arg->flags) |= arg->flag; +} + +int mstdnt_relationship_json(struct mstdnt_relationship* relationship, cJSON* js) +{ + cJSON* v; + + /* Store values as flags instead of booleans, this saves us + * a little bit of space but does involve a bit more typing */ + struct _mstdnt_relationship_flags_args args[11] = { + FLAG_ARG(MSTDNT_RELATIONSHIP_FOLLOWING), + FLAG_ARG(MSTDNT_RELATIONSHIP_REQUESTED), + FLAG_ARG(MSTDNT_RELATIONSHIP_ENDORSED), + FLAG_ARG(MSTDNT_RELATIONSHIP_FOLLOWED_BY), + FLAG_ARG(MSTDNT_RELATIONSHIP_MUTING), + FLAG_ARG(MSTDNT_RELATIONSHIP_MUTING_NOTIFS), + FLAG_ARG(MSTDNT_RELATIONSHIP_SHOWING_REBLOGS), + FLAG_ARG(MSTDNT_RELATIONSHIP_NOTIFYING), + FLAG_ARG(MSTDNT_RELATIONSHIP_BLOCKING), + FLAG_ARG(MSTDNT_RELATIONSHIP_DOMAIN_BLOCKING), + FLAG_ARG(MSTDNT_RELATIONSHIP_BLOCKED_BY) + }; + + struct _mstdnt_val_ref vals[] = { + { "id", &(relationship->id), _mstdnt_val_string_call }, + { "following", args, _mstdnt_val_relationship_flag_call }, + { "requested", args + 1, _mstdnt_val_relationship_flag_call }, + { "endorsed", args + 2, _mstdnt_val_relationship_flag_call }, + { "followed_by", args + 3, _mstdnt_val_relationship_flag_call }, + { "muting", args + 4, _mstdnt_val_relationship_flag_call }, + { "muting_notifications", args + 5, _mstdnt_val_relationship_flag_call }, + { "showing_reblogs", args + 6, _mstdnt_val_relationship_flag_call }, + { "notifying", args + 7, _mstdnt_val_relationship_flag_call }, + { "blocking", args + 8, _mstdnt_val_relationship_flag_call }, + { "domain_blocking", args + 9, _mstdnt_val_relationship_flag_call }, + { "blocked_by", args + 10, _mstdnt_val_relationship_flag_call }, + { "note", &(relationship->note), _mstdnt_val_string_call }, + }; + + for (v = js; v; v = v->next) + _mstdnt_key_val_ref(v, vals, _mstdnt_arr_len(vals)); + + return 0; +} + int mstdnt_relationships_result(struct mstdnt_fetch_results* results, struct mstdnt_storage* storage, - struct mstdnt_relationship* relationships, + struct mstdnt_relationship* relationships[], size_t* size) { + size_t i = 0; + cJSON* root, *rel_j_list; + if (_mstdnt_json_init(&root, results, storage) && + !cJSON_IsArray(root)) + return 1; + + if (size) *size = cJSON_GetArraySize(root); + + *relationships = calloc(1, (size ? *size : cJSON_GetArraySize(root)) + * sizeof(struct mstdnt_relationship)); + if (*relationships == NULL) + return 1; + + cJSON_ArrayForEach(rel_j_list, root) + { + mstdnt_relationship_json((*relationships) + i++, rel_j_list->child); + } } int _mstdnt_relationships_result_callback(struct mstdnt_fetch_results* results, @@ -54,8 +129,7 @@ int mastodont_get_relationships(mastodont_t* data, /* params, _mstdnt_arr_len(params), */ CURLOPT_HTTPGET, &cb_args, - _mstdnt_relationships_result_callback, /* TODO populate the status back? - * (not sure if the api returns it or not) */ + _mstdnt_relationships_result_callback }; return mastodont_request(data, &req_args);