199 lines
5.9 KiB
C
199 lines
5.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define YAML_IMPLEMENTATION
|
|
#include "../include/cyaml.h"
|
|
|
|
// Define a simple User struct.
|
|
typedef struct {
|
|
int id;
|
|
char name[100];
|
|
char email[100];
|
|
} User;
|
|
|
|
#define MAX_USERS 100
|
|
|
|
User users[MAX_USERS];
|
|
size_t user_count = 0;
|
|
|
|
// Display the list of users.
|
|
void list_users(void) {
|
|
printf("\n-- User Database --\n");
|
|
if (user_count == 0) {
|
|
printf("No users found.\n");
|
|
return;
|
|
}
|
|
for (size_t i = 0; i < user_count; i++) {
|
|
printf("ID %d: %s, %s\n", users[i].id, users[i].name, users[i].email);
|
|
}
|
|
}
|
|
|
|
// Save the in-memory user database to a YAML file.
|
|
// The output YAML file will have a mapping with the key "users"
|
|
// which contains a sequence of mappings (each representing a user).
|
|
int save_to_file(const char *filename) {
|
|
// Create a new document with a mapping as root.
|
|
YAMLDoc *doc = (YAMLDoc*)malloc(sizeof(YAMLDoc));
|
|
if (!doc) return -1;
|
|
doc->root = yaml_new_map();
|
|
if (!doc->root) {
|
|
free(doc);
|
|
return -1;
|
|
}
|
|
|
|
// Create a sequence to hold all user mappings.
|
|
YAMLNode *userSeq = yaml_new_seq();
|
|
if (!userSeq) {
|
|
yaml_doc_destroy(doc);
|
|
return -1;
|
|
}
|
|
|
|
// For each user, create a mapping and add it to the sequence.
|
|
for (size_t i = 0; i < user_count; i++) {
|
|
YAMLNode *userMap = yaml_new_map();
|
|
char idStr[20];
|
|
snprintf(idStr, sizeof(idStr), "%d", users[i].id);
|
|
yaml_map_set(userMap, "id", yaml_new_str(idStr));
|
|
yaml_map_set(userMap, "name", yaml_new_str(users[i].name));
|
|
yaml_map_set(userMap, "email", yaml_new_str(users[i].email));
|
|
yaml_seq_append(userSeq, userMap);
|
|
}
|
|
yaml_map_set(doc->root, "users", userSeq);
|
|
|
|
// Create an emitter and write the document to the file.
|
|
YAMLEmitter *emitter = yaml_emitter_create();
|
|
if (!emitter) {
|
|
yaml_doc_destroy(doc);
|
|
return -1;
|
|
}
|
|
if (yaml_emit(emitter, doc) != 0) {
|
|
yaml_emitter_destroy(emitter);
|
|
yaml_doc_destroy(doc);
|
|
return -1;
|
|
}
|
|
int ret = yaml_emit_to_file(emitter, filename);
|
|
|
|
// Clean up.
|
|
yaml_emitter_destroy(emitter);
|
|
yaml_doc_destroy(doc);
|
|
return ret;
|
|
}
|
|
|
|
// Add a new user via CLI.
|
|
void add_user(void) {
|
|
if (user_count >= MAX_USERS) {
|
|
printf("User database is full.\n");
|
|
return;
|
|
}
|
|
User newUser;
|
|
newUser.id = user_count + 1; // Simple sequential id assignment.
|
|
|
|
printf("Enter user name: ");
|
|
if (!fgets(newUser.name, sizeof(newUser.name), stdin)) {
|
|
printf("Error reading name.\n");
|
|
return;
|
|
}
|
|
newUser.name[strcspn(newUser.name, "\n")] = '\0'; // Remove newline.
|
|
|
|
printf("Enter user email: ");
|
|
if (!fgets(newUser.email, sizeof(newUser.email), stdin)) {
|
|
printf("Error reading email.\n");
|
|
return;
|
|
}
|
|
newUser.email[strcspn(newUser.email, "\n")] = '\0';
|
|
|
|
users[user_count++] = newUser;
|
|
printf("User added successfully.\n");
|
|
}
|
|
|
|
// Edit an existing user via CLI.
|
|
void edit_user(void) {
|
|
list_users();
|
|
printf("Enter the user ID to edit: ");
|
|
int id;
|
|
if (scanf("%d", &id) != 1) {
|
|
printf("Invalid input.\n");
|
|
while(getchar() != '\n'); // Flush input buffer.
|
|
return;
|
|
}
|
|
while(getchar() != '\n'); // Consume newline.
|
|
|
|
int found = 0;
|
|
for (size_t i = 0; i < user_count; i++) {
|
|
if (users[i].id == id) {
|
|
found = 1;
|
|
printf("Editing user (ID %d): %s, %s\n", users[i].id, users[i].name, users[i].email);
|
|
printf("Enter new name (leave empty to keep unchanged): ");
|
|
char newName[100];
|
|
if (fgets(newName, sizeof(newName), stdin)) {
|
|
newName[strcspn(newName, "\n")] = '\0';
|
|
if (strlen(newName) > 0)
|
|
strncpy(users[i].name, newName, sizeof(users[i].name));
|
|
}
|
|
printf("Enter new email (leave empty to keep unchanged): ");
|
|
char newEmail[100];
|
|
if (fgets(newEmail, sizeof(newEmail), stdin)) {
|
|
newEmail[strcspn(newEmail, "\n")] = '\0';
|
|
if (strlen(newEmail) > 0)
|
|
strncpy(users[i].email, newEmail, sizeof(users[i].email));
|
|
}
|
|
printf("User updated successfully.\n");
|
|
break;
|
|
}
|
|
}
|
|
if (!found)
|
|
printf("User with ID %d not found.\n", id);
|
|
}
|
|
|
|
int main(void) {
|
|
int running = 1;
|
|
while (running) {
|
|
printf("\n--- User Database CLI ---\n");
|
|
printf("1. List users\n");
|
|
printf("2. Add user\n");
|
|
printf("3. Edit user\n");
|
|
printf("4. Save database to file\n");
|
|
printf("5. Exit\n");
|
|
printf("Enter choice: ");
|
|
|
|
int choice;
|
|
if (scanf("%d", &choice) != 1) {
|
|
printf("Invalid input. Please enter a number.\n");
|
|
while(getchar() != '\n'); // Clear the invalid input.
|
|
continue;
|
|
}
|
|
while(getchar() != '\n'); // Consume newline.
|
|
|
|
switch (choice) {
|
|
case 1:
|
|
list_users();
|
|
break;
|
|
case 2:
|
|
add_user();
|
|
break;
|
|
case 3:
|
|
edit_user();
|
|
break;
|
|
case 4: {
|
|
char filename[256];
|
|
printf("Enter filename to save the database: ");
|
|
if (fgets(filename, sizeof(filename), stdin)) {
|
|
filename[strcspn(filename, "\n")] = '\0';
|
|
if (save_to_file(filename) == 0)
|
|
printf("Database saved successfully to '%s'.\n", filename);
|
|
else
|
|
printf("Error saving database to '%s'.\n", filename);
|
|
}
|
|
break;
|
|
}
|
|
case 5:
|
|
running = 0;
|
|
break;
|
|
default:
|
|
printf("Invalid choice. Please try again.\n");
|
|
}
|
|
}
|
|
return 0;
|
|
}
|