Result Library 0.1
Elegant error handling in C
Loading...
Searching...
No Matches
Examples

To help you become familiar with this library, you can explore a demo project that showcases how to handle Result objects within a C application. This example is a very limited implementation of a Pet Store.

Header File

pet-store.h

#ifndef PET_STORE_H
#define PET_STORE_H
#include <result.h>
// Pet status in the store
typedef enum pet_status { AVAILABLE, PENDING, SOLD } pet_status;
// Represents a pet
typedef struct pet { int id; const char * name; pet_status status; } * Pet;
// Convenience macros
#define PET_ID(pet) (pet)->id
#define PET_NAME(pet) (pet)->name
#define PET_STATUS(pet) (pet)->status
// Pet error codes
typedef enum pet_error { OK, PET_NOT_FOUND, PET_NOT_AVAILABLE, PET_ALREADY_SOLD } pet_error;
// Result type used by the pet store
RESULT_STRUCT(Pet, pet_error);
// Pet store API
const char * pet_error_message(pet_error code);
const char * pet_status_name(pet_status status);
RESULT(Pet, pet_error) find_pet(int pet_id);
RESULT(Pet, pet_error) buy_pet(Pet pet);
#endif

Source Files

pet-store.c

#include <stddef.h>
#include "pet-store.h"
// Available pets in the store
static struct pet pets[] = {
{ .id = 0, .name = "Rocky", .status = AVAILABLE },
{ .id = 1, .name = "Garfield", .status = PENDING },
{ .id = 2, .name = "Rantanplan", .status = SOLD }
};
// Returns a textual description of the supplied error code
const char * pet_error_message(pet_error code) {
switch (code) {
case OK: return "OK";
case PET_NOT_FOUND: return "Pet not found";
case PET_NOT_AVAILABLE: return "Pet not available";
case PET_ALREADY_SOLD: return "Pet already sold";
default: return "Unknown error";
}
}
// Returns a textual representation of the supplied status
const char * pet_status_name(pet_status status) {
switch (status) {
case AVAILABLE: return "Available";
case PENDING: return "Pending";
case SOLD: return "Sold";
default: return "Unknown pet status";
}
}
// Returns a pet by id
RESULT(Pet, pet_error) find_pet(int pet_id) {
for (int index = 0; index < sizeof(pets) / sizeof(pets[0]); index++) {
Pet pet = &pets[index];
if (PET_ID(pet) == pet_id) {
return (RESULT(Pet, pet_error)) RESULT_SUCCESS(pet);
}
}
return (RESULT(Pet, pet_error)) RESULT_FAILURE(PET_NOT_FOUND);
}
// Sets the status of the supplied pet to SOLD (if available)
RESULT(Pet, pet_error) buy_pet(Pet pet) {
if (PET_STATUS(pet) != AVAILABLE) {
return (RESULT(Pet, pet_error)) RESULT_FAILURE(PET_NOT_AVAILABLE);
}
PET_STATUS(pet) = SOLD;
return (RESULT(Pet, pet_error)) RESULT_SUCCESS(pet);
}

application.c

#include <stdlib.h>
#include <stdio.h>
#include "pet-store.h"
// Prints pet details
static void print_pet(const Pet pet) {
printf(">>> Pet(id: %d, name: %s, status: %s)\n",
PET_ID(pet),
PET_NAME(pet),
pet_status_name(PET_STATUS(pet)));
}
// Prints pet error
static void print_error(const pet_error error) {
printf(">>> Error: %s\n", pet_error_message(error));
}
// Pet store application
int main(int argc, char * argv[]) {
int pet_id;
RESULT(Pet, pet_error) result;
if (argc != 1) {
printf("Error: Please provide one argument (pet ID)\n");
return EXIT_FAILURE;
}
if (sscanf(argv[0], "%d", &pet_id) != 1) {
printf("Error: Illegal pet ID provided: %s\n", argv[0]);
return EXIT_FAILURE;
}
printf("Finding pet %d...\n", pet_id);
result = find_pet(pet_id);
RESULT_IF_SUCCESS_OR_ELSE(result, print_pet, print_error);
printf("Buying pet...\n");
result = RESULT_FLAT_MAP_SUCCESS(result, buy_pet);
RESULT_IF_SUCCESS_OR_ELSE(result, print_pet, print_error);
if (RESULT_HAS_FAILURE(result)) {
printf("Sorry!\n");
return EXIT_FAILURE;
}
printf("Thank you!\n");
return EXIT_SUCCESS;
}