#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "text/utf8/rune.h"
#include "text/utf8/utf8.h"
static bool utf8_transform(char* s, size_t n, uint32_t (*transform)(uint32_t)) {
utf8_decode_t d = {.state = 0};
while ((n > 0) & (*s != 0)) {
size_t i = 0;
do {
utf8_decode(&d, (uint8_t)s[i++]);
} while (d.state);
uint32_t c = transform(d.codep);
int len = utf8_encode(s, c);
if (len == 0) {
return false;
}
s += len;
n -= len;
}
return true;
}
bool utf8_tolower(char* s, size_t n) {
return utf8_transform(s, n, rune_tolower);
}
bool utf8_toupper(char* s, size_t n) {
return utf8_transform(s, n, rune_toupper);
}
bool utf8_casefold(char* s, size_t n) {
return utf8_transform(s, n, rune_casefold);
}
bool utf8_totitle(char* s, size_t n) {
utf8_decode_t d = {.state = 0};
bool upper = true;
while ((n > 0) & (*s != 0)) {
size_t i = 0;
do {
utf8_decode(&d, (uint8_t)s[i++]);
} while (d.state);
uint32_t c = upper ? rune_toupper(d.codep) : rune_tolower(d.codep);
int len = utf8_encode(s, c);
if (len == 0) {
return false;
}
upper = !rune_isword(d.codep);
s += len;
n -= len;
}
return true;
}