introduce deinit on Dividend
This commit is contained in:
parent
bbdf340de4
commit
3d679f9d75
6 changed files with 42 additions and 12 deletions
9
src/cache/store.zig
vendored
9
src/cache/store.zig
vendored
|
|
@ -268,10 +268,13 @@ pub const Store = struct {
|
||||||
/// Deserialize dividends from SRF data.
|
/// Deserialize dividends from SRF data.
|
||||||
pub fn deserializeDividends(allocator: std.mem.Allocator, data: []const u8) ![]Dividend {
|
pub fn deserializeDividends(allocator: std.mem.Allocator, data: []const u8) ![]Dividend {
|
||||||
var dividends: std.ArrayList(Dividend) = .empty;
|
var dividends: std.ArrayList(Dividend) = .empty;
|
||||||
errdefer dividends.deinit(allocator);
|
errdefer {
|
||||||
|
for (dividends.items) |d| d.deinit(allocator);
|
||||||
|
dividends.deinit(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
var reader = std.Io.Reader.fixed(data);
|
var reader = std.Io.Reader.fixed(data);
|
||||||
const parsed = srf.parse(&reader, allocator, .{ .alloc_strings = false }) catch return error.InvalidData;
|
const parsed = srf.parse(&reader, allocator, .{ .alloc_strings = true }) catch return error.InvalidData;
|
||||||
defer parsed.deinit();
|
defer parsed.deinit();
|
||||||
|
|
||||||
for (parsed.records.items) |record| {
|
for (parsed.records.items) |record| {
|
||||||
|
|
@ -794,7 +797,7 @@ test "dividend serialize/deserialize round-trip" {
|
||||||
defer allocator.free(data);
|
defer allocator.free(data);
|
||||||
|
|
||||||
const parsed = try Store.deserializeDividends(allocator, data);
|
const parsed = try Store.deserializeDividends(allocator, data);
|
||||||
defer allocator.free(parsed);
|
defer Dividend.freeSlice(allocator, parsed);
|
||||||
|
|
||||||
try std.testing.expectEqual(@as(usize, 2), parsed.len);
|
try std.testing.expectEqual(@as(usize, 2), parsed.len);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ pub fn run(allocator: std.mem.Allocator, svc: *zfin.DataService, symbol: []const
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
defer allocator.free(result.data);
|
defer zfin.Dividend.freeSlice(allocator, result.data);
|
||||||
|
|
||||||
if (result.source == .cached) try cli.stderrPrint("(using cached dividend data)\n");
|
if (result.source == .cached) try cli.stderrPrint("(using cached dividend data)\n");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ pub fn run(allocator: std.mem.Allocator, svc: *zfin.DataService, symbol: []const
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
defer allocator.free(result.candles);
|
defer allocator.free(result.candles);
|
||||||
defer if (result.dividends) |d| allocator.free(d);
|
defer if (result.dividends) |d| zfin.Dividend.freeSlice(allocator, d);
|
||||||
|
|
||||||
if (result.source == .cached) try cli.stderrPrint("(using cached data)\n");
|
if (result.source == .cached) try cli.stderrPrint("(using cached data)\n");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
const std = @import("std");
|
||||||
const Date = @import("date.zig").Date;
|
const Date = @import("date.zig").Date;
|
||||||
|
|
||||||
pub const DividendType = enum {
|
pub const DividendType = enum {
|
||||||
|
|
@ -22,6 +23,17 @@ pub const Dividend = struct {
|
||||||
frequency: ?u8 = null,
|
frequency: ?u8 = null,
|
||||||
/// Classification of the dividend
|
/// Classification of the dividend
|
||||||
type: DividendType = .unknown,
|
type: DividendType = .unknown,
|
||||||
/// Currency code (e.g., "USD")
|
/// Currency code (e.g., "USD"). Heap-allocated; freed by deinit().
|
||||||
currency: ?[]const u8 = null,
|
currency: ?[]const u8 = null,
|
||||||
|
|
||||||
|
/// Free any owned string fields.
|
||||||
|
pub fn deinit(self: Dividend, allocator: std.mem.Allocator) void {
|
||||||
|
if (self.currency) |c| allocator.free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Free a slice of dividends, calling deinit on each element first.
|
||||||
|
pub fn freeSlice(allocator: std.mem.Allocator, divs: []const Dividend) void {
|
||||||
|
for (divs) |d| d.deinit(allocator);
|
||||||
|
allocator.free(divs);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,10 @@ pub const Polygon = struct {
|
||||||
to: ?Date,
|
to: ?Date,
|
||||||
) provider.ProviderError![]Dividend {
|
) provider.ProviderError![]Dividend {
|
||||||
var all_dividends: std.ArrayList(Dividend) = .empty;
|
var all_dividends: std.ArrayList(Dividend) = .empty;
|
||||||
errdefer all_dividends.deinit(allocator);
|
errdefer {
|
||||||
|
for (all_dividends.items) |d| d.deinit(allocator);
|
||||||
|
all_dividends.deinit(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
var next_url: ?[]const u8 = null;
|
var next_url: ?[]const u8 = null;
|
||||||
defer if (next_url) |u| allocator.free(u);
|
defer if (next_url) |u| allocator.free(u);
|
||||||
|
|
@ -248,7 +251,10 @@ fn parseDividendsPage(
|
||||||
.record_date = parseDateField(obj, "record_date"),
|
.record_date = parseDateField(obj, "record_date"),
|
||||||
.frequency = parseFrequency(obj),
|
.frequency = parseFrequency(obj),
|
||||||
.type = parseDividendType(obj),
|
.type = parseDividendType(obj),
|
||||||
.currency = jsonStr(obj.get("currency")),
|
.currency = if (jsonStr(obj.get("currency"))) |s|
|
||||||
|
(allocator.dupe(u8, s) catch null)
|
||||||
|
else
|
||||||
|
null,
|
||||||
}) catch return provider.ProviderError.OutOfMemory;
|
}) catch return provider.ProviderError.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -442,7 +448,10 @@ test "parseDividendsPage basic" {
|
||||||
|
|
||||||
const allocator = std.testing.allocator;
|
const allocator = std.testing.allocator;
|
||||||
var out = std.ArrayList(Dividend).empty;
|
var out = std.ArrayList(Dividend).empty;
|
||||||
defer out.deinit(allocator);
|
defer {
|
||||||
|
for (out.items) |d| d.deinit(allocator);
|
||||||
|
out.deinit(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
const next_url = try parseDividendsPage(allocator, body, &out);
|
const next_url = try parseDividendsPage(allocator, body, &out);
|
||||||
try std.testing.expect(next_url == null);
|
try std.testing.expect(next_url == null);
|
||||||
|
|
@ -471,7 +480,10 @@ test "parseDividendsPage with pagination" {
|
||||||
|
|
||||||
const allocator = std.testing.allocator;
|
const allocator = std.testing.allocator;
|
||||||
var out = std.ArrayList(Dividend).empty;
|
var out = std.ArrayList(Dividend).empty;
|
||||||
defer out.deinit(allocator);
|
defer {
|
||||||
|
for (out.items) |d| d.deinit(allocator);
|
||||||
|
out.deinit(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
const next_url = try parseDividendsPage(allocator, body, &out);
|
const next_url = try parseDividendsPage(allocator, body, &out);
|
||||||
try std.testing.expect(next_url != null);
|
try std.testing.expect(next_url != null);
|
||||||
|
|
@ -488,7 +500,10 @@ test "parseDividendsPage error status" {
|
||||||
|
|
||||||
const allocator = std.testing.allocator;
|
const allocator = std.testing.allocator;
|
||||||
var out = std.ArrayList(Dividend).empty;
|
var out = std.ArrayList(Dividend).empty;
|
||||||
defer out.deinit(allocator);
|
defer {
|
||||||
|
for (out.items) |d| d.deinit(allocator);
|
||||||
|
out.deinit(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
const result = parseDividendsPage(allocator, body, &out);
|
const result = parseDividendsPage(allocator, body, &out);
|
||||||
try std.testing.expectError(provider.ProviderError.RequestFailed, result);
|
try std.testing.expectError(provider.ProviderError.RequestFailed, result);
|
||||||
|
|
|
||||||
|
|
@ -1606,7 +1606,7 @@ const App = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn freeDividends(self: *App) void {
|
fn freeDividends(self: *App) void {
|
||||||
if (self.dividends) |d| self.allocator.free(d);
|
if (self.dividends) |d| zfin.Dividend.freeSlice(self.allocator, d);
|
||||||
self.dividends = null;
|
self.dividends = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue