consolidate watchlist loading/use srf

This commit is contained in:
Emil Lerch 2026-03-19 13:00:57 -07:00
parent 46bf34fd1c
commit e29fb5b743
Signed by: lobo
GPG key ID: A7B62D657EF764F8
3 changed files with 46 additions and 54 deletions

View file

@ -123,6 +123,41 @@ pub const LoadProgress = struct {
}
};
// Watchlist loading
/// Load a watchlist file using the library's SRF deserializer.
/// Returns owned symbol strings. Returns null if file missing or empty.
pub fn loadWatchlist(allocator: std.mem.Allocator, path: []const u8) ?[][]const u8 {
const file_data = std.fs.cwd().readFileAlloc(allocator, path, 1024 * 1024) catch return null;
defer allocator.free(file_data);
var portfolio = zfin.cache.deserializePortfolio(allocator, file_data) catch return null;
defer portfolio.deinit();
if (portfolio.lots.len == 0) return null;
var syms: std.ArrayList([]const u8) = .empty;
for (portfolio.lots) |lot| {
const duped = allocator.dupe(u8, lot.symbol) catch continue;
syms.append(allocator, duped) catch {
allocator.free(duped);
continue;
};
}
if (syms.items.len == 0) {
syms.deinit(allocator);
return null;
}
return syms.toOwnedSlice(allocator) catch null;
}
pub fn freeWatchlist(allocator: std.mem.Allocator, watchlist: ?[][]const u8) void {
if (watchlist) |wl| {
for (wl) |sym| allocator.free(sym);
allocator.free(wl);
}
}
// Tests
test "setFg emits ANSI when color enabled" {

View file

@ -161,18 +161,10 @@ pub fn run(allocator: std.mem.Allocator, config: zfin.Config, svc: *zfin.DataSer
// Separate watchlist file (backward compat)
if (watchlist_path) |wl_path| {
const wl_data = std.fs.cwd().readFileAlloc(allocator, wl_path, 1024 * 1024) catch null;
if (wl_data) |wd| {
defer allocator.free(wd);
var wl_lines = std.mem.splitScalar(u8, wd, '\n');
while (wl_lines.next()) |line| {
const trimmed = std.mem.trim(u8, line, &std.ascii.whitespace);
if (trimmed.len == 0 or trimmed[0] == '#') continue;
if (std.mem.indexOf(u8, trimmed, "symbol::")) |idx| {
const rest = trimmed[idx + "symbol::".len ..];
const end = std.mem.indexOfScalar(u8, rest, ',') orelse rest.len;
const sym = std.mem.trim(u8, rest[0..end], &std.ascii.whitespace);
if (sym.len > 0 and sym.len <= 10) {
const wl_syms = cli.loadWatchlist(allocator, wl_path);
defer cli.freeWatchlist(allocator, wl_syms);
if (wl_syms) |syms_list| {
for (syms_list) |sym| {
if (watch_seen.contains(sym)) continue;
try watch_seen.put(sym, {});
try watch_list.append(allocator, sym);
@ -183,8 +175,6 @@ pub fn run(allocator: std.mem.Allocator, config: zfin.Config, svc: *zfin.DataSer
}
}
}
}
}
try display(
allocator,

View file

@ -1670,41 +1670,8 @@ pub fn renderBrailleToStyledLines(arena: std.mem.Allocator, lines: *std.ArrayLis
}
}
pub fn loadWatchlist(allocator: std.mem.Allocator, path: []const u8) ?[][]const u8 {
const file_data = std.fs.cwd().readFileAlloc(allocator, path, 1024 * 1024) catch return null;
defer allocator.free(file_data);
var syms: std.ArrayList([]const u8) = .empty;
var file_lines = std.mem.splitScalar(u8, file_data, '\n');
while (file_lines.next()) |line| {
const trimmed = std.mem.trim(u8, line, &std.ascii.whitespace);
if (trimmed.len == 0 or trimmed[0] == '#') continue;
if (std.mem.indexOf(u8, trimmed, "symbol::")) |idx| {
const rest = trimmed[idx + "symbol::".len ..];
const end = std.mem.indexOfScalar(u8, rest, ',') orelse rest.len;
const sym = std.mem.trim(u8, rest[0..end], &std.ascii.whitespace);
if (sym.len > 0 and sym.len <= 10) {
const duped = allocator.dupe(u8, sym) catch continue;
syms.append(allocator, duped) catch {
allocator.free(duped);
continue;
};
}
}
}
if (syms.items.len == 0) {
syms.deinit(allocator);
return null;
}
return syms.toOwnedSlice(allocator) catch null;
}
pub fn freeWatchlist(allocator: std.mem.Allocator, watchlist: ?[][]const u8) void {
if (watchlist) |wl| {
for (wl) |sym| allocator.free(sym);
allocator.free(wl);
}
}
pub const loadWatchlist = cli.loadWatchlist;
pub const freeWatchlist = cli.freeWatchlist;
// Force test discovery for imported TUI sub-modules
comptime {