title case sector in enrich command

This commit is contained in:
Emil Lerch 2026-03-03 12:27:23 -08:00
parent 9f4adc1ee0
commit 52337ab5a9
Signed by: lobo
GPG key ID: A7B62D657EF764F8
2 changed files with 34 additions and 2 deletions

View file

@ -55,7 +55,9 @@ fn enrichSymbol(allocator: std.mem.Allocator, av_key: []const u8, sym: []const u
if (overview.asset_type) |at| allocator.free(at);
}
const sector_str = overview.sector orelse "Unknown";
const sector_raw = overview.sector orelse "Unknown";
var sector_buf: [64]u8 = undefined;
const sector_str = cli.fmt.toTitleCase(&sector_buf, sector_raw);
const country_str = overview.country orelse "US";
const geo_str = if (std.mem.eql(u8, country_str, "USA")) "US" else country_str;
@ -166,7 +168,9 @@ fn enrichPortfolio(allocator: std.mem.Allocator, av_key: []const u8, file_path:
if (overview.asset_type) |at| allocator.free(at);
}
const sector_str = overview.sector orelse "Unknown";
const sector_raw = overview.sector orelse "Unknown";
var sector_buf: [64]u8 = undefined;
const sector_str = cli.fmt.toTitleCase(&sector_buf, sector_raw);
const country_str = overview.country orelse "US";
const geo_str = if (std.mem.eql(u8, country_str, "USA")) "US" else country_str;

View file

@ -350,6 +350,25 @@ pub fn isCusipLike(s: []const u8) bool {
return has_digit;
}
/// Convert a string to title case ("TECHNOLOGY" -> "Technology", "CONSUMER CYCLICAL" -> "Consumer Cyclical").
/// Writes into a caller-provided buffer and returns the slice.
pub fn toTitleCase(buf: []u8, s: []const u8) []const u8 {
const len = @min(s.len, buf.len);
var capitalize_next = true;
for (s[0..len], 0..) |c, i| {
if (c == ' ') {
buf[i] = ' ';
capitalize_next = true;
} else if (capitalize_next) {
buf[i] = std.ascii.toUpper(c);
capitalize_next = false;
} else {
buf[i] = std.ascii.toLower(c);
}
}
return buf[0..len];
}
/// Format an options contract line: strike + last + bid + ask + volume + OI + IV.
pub fn fmtContractLine(alloc: std.mem.Allocator, prefix: []const u8, c: OptionContract) ![]const u8 {
var last_buf: [12]u8 = undefined;
@ -1070,6 +1089,15 @@ test "isCusipLike" {
try std.testing.expect(!isCusipLike("12345")); // Too short
}
test "toTitleCase" {
var buf: [64]u8 = undefined;
try std.testing.expectEqualStrings("Technology", toTitleCase(&buf, "TECHNOLOGY"));
try std.testing.expectEqualStrings("Consumer Cyclical", toTitleCase(&buf, "CONSUMER CYCLICAL"));
try std.testing.expectEqualStrings("Healthcare", toTitleCase(&buf, "HEALTHCARE"));
try std.testing.expectEqualStrings("Technology", toTitleCase(&buf, "Technology"));
try std.testing.expectEqualStrings("Unknown", toTitleCase(&buf, "Unknown"));
}
test "lotSortFn" {
const open_new = Lot{
.symbol = "A",