move tax type to enum
This commit is contained in:
parent
57b0811ecd
commit
f1e9321bdc
1 changed files with 25 additions and 21 deletions
|
|
@ -17,10 +17,27 @@ pub const BreakdownItem = struct {
|
|||
weight: f64, // fraction of total (0.0 - 1.0)
|
||||
};
|
||||
|
||||
/// Tax type classification for accounts.
|
||||
pub const TaxType = enum {
|
||||
taxable,
|
||||
roth,
|
||||
traditional,
|
||||
hsa,
|
||||
|
||||
pub fn label(self: TaxType) []const u8 {
|
||||
return switch (self) {
|
||||
.taxable => "Taxable",
|
||||
.roth => "Roth (Post-Tax)",
|
||||
.traditional => "Traditional (Pre-Tax)",
|
||||
.hsa => "HSA (Triple Tax-Free)",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// Account tax type classification entry, parsed from accounts.srf.
|
||||
pub const AccountTaxEntry = struct {
|
||||
account: []const u8,
|
||||
tax_type: []const u8,
|
||||
tax_type: TaxType,
|
||||
};
|
||||
|
||||
/// Parsed account metadata.
|
||||
|
|
@ -31,7 +48,6 @@ pub const AccountMap = struct {
|
|||
pub fn deinit(self: *AccountMap) void {
|
||||
for (self.entries) |e| {
|
||||
self.allocator.free(e.account);
|
||||
self.allocator.free(e.tax_type);
|
||||
}
|
||||
self.allocator.free(self.entries);
|
||||
}
|
||||
|
|
@ -40,22 +56,13 @@ pub const AccountMap = struct {
|
|||
pub fn taxTypeFor(self: AccountMap, account: []const u8) []const u8 {
|
||||
for (self.entries) |e| {
|
||||
if (std.mem.eql(u8, e.account, account)) {
|
||||
return taxTypeLabel(e.tax_type);
|
||||
return e.tax_type.label();
|
||||
}
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
};
|
||||
|
||||
/// Map raw tax_type strings to display labels.
|
||||
fn taxTypeLabel(raw: []const u8) []const u8 {
|
||||
if (std.mem.eql(u8, raw, "taxable")) return "Taxable";
|
||||
if (std.mem.eql(u8, raw, "roth")) return "Roth (Post-Tax)";
|
||||
if (std.mem.eql(u8, raw, "traditional")) return "Traditional (Pre-Tax)";
|
||||
if (std.mem.eql(u8, raw, "hsa")) return "HSA (Triple Tax-Free)";
|
||||
return raw;
|
||||
}
|
||||
|
||||
/// Parse an accounts.srf file into an AccountMap.
|
||||
/// Each record has: account::<NAME>,tax_type::<TYPE>
|
||||
pub fn parseAccountsFile(allocator: std.mem.Allocator, data: []const u8) !AccountMap {
|
||||
|
|
@ -63,7 +70,6 @@ pub fn parseAccountsFile(allocator: std.mem.Allocator, data: []const u8) !Accoun
|
|||
errdefer {
|
||||
for (entries.items) |e| {
|
||||
allocator.free(e.account);
|
||||
allocator.free(e.tax_type);
|
||||
}
|
||||
entries.deinit(allocator);
|
||||
}
|
||||
|
|
@ -76,7 +82,7 @@ pub fn parseAccountsFile(allocator: std.mem.Allocator, data: []const u8) !Accoun
|
|||
const entry = record.to(AccountTaxEntry) catch continue;
|
||||
try entries.append(allocator, .{
|
||||
.account = try allocator.dupe(u8, entry.account),
|
||||
.tax_type = try allocator.dupe(u8, entry.tax_type),
|
||||
.tax_type = entry.tax_type,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -287,13 +293,11 @@ test "parseAccountsFile" {
|
|||
try std.testing.expectEqualStrings("Unknown", am.taxTypeFor("Nonexistent"));
|
||||
}
|
||||
|
||||
test "taxTypeLabel" {
|
||||
try std.testing.expectEqualStrings("Taxable", taxTypeLabel("taxable"));
|
||||
try std.testing.expectEqualStrings("Roth (Post-Tax)", taxTypeLabel("roth"));
|
||||
try std.testing.expectEqualStrings("Traditional (Pre-Tax)", taxTypeLabel("traditional"));
|
||||
try std.testing.expectEqualStrings("HSA (Triple Tax-Free)", taxTypeLabel("hsa"));
|
||||
// Unknown type returns raw string
|
||||
try std.testing.expectEqualStrings("custom_type", taxTypeLabel("custom_type"));
|
||||
test "TaxType.label" {
|
||||
try std.testing.expectEqualStrings("Taxable", TaxType.taxable.label());
|
||||
try std.testing.expectEqualStrings("Roth (Post-Tax)", TaxType.roth.label());
|
||||
try std.testing.expectEqualStrings("Traditional (Pre-Tax)", TaxType.traditional.label());
|
||||
try std.testing.expectEqualStrings("HSA (Triple Tax-Free)", TaxType.hsa.label());
|
||||
}
|
||||
|
||||
test "mapToSortedBreakdown" {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue