use srf parsing/conversion in porfolio
This commit is contained in:
parent
44dfafd574
commit
189d09720b
1 changed files with 13 additions and 126 deletions
137
src/cache/store.zig
vendored
137
src/cache/store.zig
vendored
|
|
@ -693,7 +693,6 @@ pub fn serializePortfolio(allocator: std.mem.Allocator, lots: []const Lot) ![]co
|
||||||
|
|
||||||
/// Deserialize a portfolio from SRF data. Caller owns the returned Portfolio.
|
/// Deserialize a portfolio from SRF data. Caller owns the returned Portfolio.
|
||||||
pub fn deserializePortfolio(allocator: std.mem.Allocator, data: []const u8) !Portfolio {
|
pub fn deserializePortfolio(allocator: std.mem.Allocator, data: []const u8) !Portfolio {
|
||||||
const LotType = @import("../models/portfolio.zig").LotType;
|
|
||||||
var lots: std.ArrayList(Lot) = .empty;
|
var lots: std.ArrayList(Lot) = .empty;
|
||||||
errdefer {
|
errdefer {
|
||||||
for (lots.items) |lot| {
|
for (lots.items) |lot| {
|
||||||
|
|
@ -706,134 +705,22 @@ pub fn deserializePortfolio(allocator: std.mem.Allocator, data: []const u8) !Por
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
var it = srf.iterator(&reader, allocator, .{ .alloc_strings = false }) catch return error.InvalidData;
|
||||||
defer parsed.deinit();
|
defer it.deinit();
|
||||||
|
|
||||||
for (parsed.records) |record| {
|
while (try it.next()) |fields| {
|
||||||
var lot = Lot{
|
var lot = fields.to(Lot) catch continue;
|
||||||
.symbol = "",
|
|
||||||
.shares = 0,
|
|
||||||
.open_date = Date.epoch,
|
|
||||||
.open_price = 0,
|
|
||||||
};
|
|
||||||
var sym_raw: ?[]const u8 = null;
|
|
||||||
var note_raw: ?[]const u8 = null;
|
|
||||||
var account_raw: ?[]const u8 = null;
|
|
||||||
var sec_type_raw: ?[]const u8 = null;
|
|
||||||
var ticker_raw: ?[]const u8 = null;
|
|
||||||
|
|
||||||
for (record.fields) |field| {
|
// Dupe owned strings before iterator.deinit() frees the backing buffer
|
||||||
if (std.mem.eql(u8, field.key, "symbol")) {
|
lot.symbol = try allocator.dupe(u8, lot.symbol);
|
||||||
if (field.value) |v| sym_raw = switch (v) {
|
if (lot.note) |n| lot.note = try allocator.dupe(u8, n);
|
||||||
.string => |s| s,
|
if (lot.account) |a| lot.account = try allocator.dupe(u8, a);
|
||||||
else => null,
|
if (lot.ticker) |t| lot.ticker = try allocator.dupe(u8, t);
|
||||||
};
|
|
||||||
} else if (std.mem.eql(u8, field.key, "shares")) {
|
|
||||||
if (field.value) |v| lot.shares = Store.numVal(v);
|
|
||||||
} else if (std.mem.eql(u8, field.key, "open_date")) {
|
|
||||||
if (field.value) |v| {
|
|
||||||
const str = switch (v) {
|
|
||||||
.string => |s| s,
|
|
||||||
else => continue,
|
|
||||||
};
|
|
||||||
lot.open_date = Date.parse(str) catch continue;
|
|
||||||
}
|
|
||||||
} else if (std.mem.eql(u8, field.key, "open_price")) {
|
|
||||||
if (field.value) |v| lot.open_price = Store.numVal(v);
|
|
||||||
} else if (std.mem.eql(u8, field.key, "close_date")) {
|
|
||||||
if (field.value) |v| {
|
|
||||||
const str = switch (v) {
|
|
||||||
.string => |s| s,
|
|
||||||
else => continue,
|
|
||||||
};
|
|
||||||
lot.close_date = Date.parse(str) catch null;
|
|
||||||
}
|
|
||||||
} else if (std.mem.eql(u8, field.key, "close_price")) {
|
|
||||||
if (field.value) |v| lot.close_price = Store.numVal(v);
|
|
||||||
} else if (std.mem.eql(u8, field.key, "note")) {
|
|
||||||
if (field.value) |v| note_raw = switch (v) {
|
|
||||||
.string => |s| s,
|
|
||||||
else => null,
|
|
||||||
};
|
|
||||||
} else if (std.mem.eql(u8, field.key, "account")) {
|
|
||||||
if (field.value) |v| account_raw = switch (v) {
|
|
||||||
.string => |s| s,
|
|
||||||
else => null,
|
|
||||||
};
|
|
||||||
} else if (std.mem.eql(u8, field.key, "security_type")) {
|
|
||||||
if (field.value) |v| sec_type_raw = switch (v) {
|
|
||||||
.string => |s| s,
|
|
||||||
else => null,
|
|
||||||
};
|
|
||||||
} else if (std.mem.eql(u8, field.key, "maturity_date")) {
|
|
||||||
if (field.value) |v| {
|
|
||||||
const str = switch (v) {
|
|
||||||
.string => |s| s,
|
|
||||||
else => continue,
|
|
||||||
};
|
|
||||||
lot.maturity_date = Date.parse(str) catch null;
|
|
||||||
}
|
|
||||||
} else if (std.mem.eql(u8, field.key, "rate")) {
|
|
||||||
if (field.value) |v| {
|
|
||||||
const r = Store.numVal(v);
|
|
||||||
if (r > 0) lot.rate = r;
|
|
||||||
}
|
|
||||||
} else if (std.mem.eql(u8, field.key, "drip")) {
|
|
||||||
if (field.value) |v| {
|
|
||||||
switch (v) {
|
|
||||||
.string => |s| lot.drip = std.mem.eql(u8, s, "true") or std.mem.eql(u8, s, "1"),
|
|
||||||
.number => |n| lot.drip = n > 0,
|
|
||||||
.boolean => |b| lot.drip = b,
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (std.mem.eql(u8, field.key, "ticker")) {
|
|
||||||
if (field.value) |v| ticker_raw = switch (v) {
|
|
||||||
.string => |s| s,
|
|
||||||
else => null,
|
|
||||||
};
|
|
||||||
} else if (std.mem.eql(u8, field.key, "price")) {
|
|
||||||
if (field.value) |v| {
|
|
||||||
const p = Store.numVal(v);
|
|
||||||
if (p > 0) lot.price = p;
|
|
||||||
}
|
|
||||||
} else if (std.mem.eql(u8, field.key, "price_date")) {
|
|
||||||
if (field.value) |v| {
|
|
||||||
const str = switch (v) {
|
|
||||||
.string => |s| s,
|
|
||||||
else => continue,
|
|
||||||
};
|
|
||||||
lot.price_date = Date.parse(str) catch null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine lot type
|
// Cash lots without a symbol get a placeholder
|
||||||
if (sec_type_raw) |st| {
|
if (lot.security_type == .cash and lot.symbol.len == 0) {
|
||||||
lot.security_type = LotType.fromString(st);
|
allocator.free(lot.symbol);
|
||||||
}
|
|
||||||
|
|
||||||
// Cash lots don't require a symbol -- generate a placeholder
|
|
||||||
if (lot.security_type == .cash) {
|
|
||||||
if (sym_raw == null) {
|
|
||||||
lot.symbol = try allocator.dupe(u8, "CASH");
|
lot.symbol = try allocator.dupe(u8, "CASH");
|
||||||
} else {
|
|
||||||
lot.symbol = try allocator.dupe(u8, sym_raw.?);
|
|
||||||
}
|
|
||||||
} else if (sym_raw) |s| {
|
|
||||||
lot.symbol = try allocator.dupe(u8, s);
|
|
||||||
} else continue;
|
|
||||||
|
|
||||||
if (note_raw) |n| {
|
|
||||||
lot.note = try allocator.dupe(u8, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (account_raw) |a| {
|
|
||||||
lot.account = try allocator.dupe(u8, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ticker_raw) |t| {
|
|
||||||
lot.ticker = try allocator.dupe(u8, t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try lots.append(allocator, lot);
|
try lots.append(allocator, lot);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue