1#define NONSTD_IMPLEMENTATION
  2#include "../nonstd.h"
  3
  4#include <stdio.h>
  5
  6// Helper function to print string builder content
  7void print_sb(const char *label, const stringb *sb) {
  8	printf("%s (len=%zu, cap=%zu): \"%s\"\n", label, sb->length, sb->capacity, sb->data);
  9}
 10
 11int main(void) {
 12	// Example 1: Basic string building
 13	stringb sb1;
 14	sb_init(&sb1, 0); // 0 means use default capacity (16)
 15
 16	sb_append_cstr(&sb1, "Hello");
 17	sb_append_cstr(&sb1, ", ");
 18	sb_append_cstr(&sb1, "World");
 19	sb_append_char(&sb1, '!');
 20
 21	print_sb("  sb1", &sb1);
 22	sb_free(&sb1);
 23	printf("\n");
 24
 25	// Example 2: Building with initial capacity
 26	stringb sb2;
 27	sb_init(&sb2, 100); // Start with larger capacity to avoid reallocations
 28
 29	print_sb("  Initial", &sb2);
 30
 31	sb_append_cstr(&sb2, "This is a longer string that benefits from pre-allocation");
 32	print_sb("  After append", &sb2);
 33
 34	sb_free(&sb2);
 35	printf("\n");
 36
 37	// Example 3: Appending string views
 38	stringb sb3;
 39	sb_init(&sb3, 0);
 40
 41	const char *text = "The quick brown fox";
 42	stringv word = sv_from_parts(text + 4, 5); // "quick"
 43
 44	sb_append_cstr(&sb3, "Extracted: ");
 45	sb_append_sv(&sb3, word);
 46	sb_append_cstr(&sb3, " (from a view)");
 47
 48	print_sb("  sb3", &sb3);
 49	sb_free(&sb3);
 50	printf("\n");
 51
 52	// Example 4: Converting builder to view for reading
 53	stringb sb4;
 54	sb_init(&sb4, 0);
 55
 56	sb_append_cstr(&sb4, "Builder content");
 57
 58	// Get a read-only view of the builder
 59	stringv view = sb_as_sv(&sb4);
 60	printf("  Builder as view (len=%zu): \"", view.length);
 61	fwrite(view.data, 1, view.length, stdout);
 62	printf("\"\n");
 63
 64	// You can use all string view operations on it
 65	stringv prefix = sv_from_cstr("Builder");
 66	printf("  Starts with 'Builder': %s\n", sv_starts_with(view, prefix) ? "yes" : "no");
 67
 68	sb_free(&sb4);
 69	printf("\n");
 70
 71	// Example 5: Building a formatted message
 72	stringb sb5;
 73	sb_init(&sb5, 0);
 74
 75	const char *names[] = {"Alice", "Bob", "Charlie"};
 76	int ages[] = {25, 30, 35};
 77
 78	sb_append_cstr(&sb5, "People:\n");
 79	for (size_t i = 0; i < countof(names); i++) {
 80		sb_append_cstr(&sb5, "  - ");
 81		sb_append_cstr(&sb5, names[i]);
 82		sb_append_cstr(&sb5, " (age ");
 83
 84		// Note: For numbers, you'd typically use sprintf with a temp buffer
 85		char age_buf[32];
 86		snprintf(age_buf, sizeof(age_buf), "%d", ages[i]);
 87		sb_append_cstr(&sb5, age_buf);
 88
 89		sb_append_cstr(&sb5, ")\n");
 90	}
 91
 92	printf("%s", sb5.data);
 93	sb_free(&sb5);
 94	printf("\n");
 95
 96	// Example 6: Building CSV data
 97	stringb csv;
 98	sb_init(&csv, 64);
 99
100	sb_append_cstr(&csv, "Name,Age,City\n");
101	sb_append_cstr(&csv, "Alice,25,NYC\n");
102	sb_append_cstr(&csv, "Bob,30,LA\n");
103	sb_append_cstr(&csv, "Charlie,35,Chicago\n");
104
105	printf("  CSV output:\n%s", csv.data);
106	sb_free(&csv);
107	printf("\n");
108
109	// Example 7: Practical use case - building a SQL query
110	stringb query;
111	sb_init(&query, 128);
112
113	sb_append_cstr(&query, "SELECT * FROM users WHERE ");
114
115	const char *conditions[] = {"age > 18", "active = 1", "country = 'US'"};
116	for (size_t i = 0; i < countof(conditions); i++) {
117		if (i > 0) {
118			sb_append_cstr(&query, " AND ");
119		}
120		sb_append_cstr(&query, conditions[i]);
121	}
122
123	sb_append_char(&query, ';');
124
125	print_sb("  Query", &query);
126	sb_free(&query);
127	printf("\n");
128
129	return 0;
130}