-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.zig
More file actions
106 lines (100 loc) · 3.61 KB
/
Copy pathutil.zig
File metadata and controls
106 lines (100 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
const std = @import("std");
pub fn calculateEncodedSize(value: anytype) !usize {
const T = @TypeOf(value);
const type_info = @typeInfo(T);
// Check for custom scaleEncodedSize method first (for structs and unions)
if (type_info == .@"struct" or type_info == .@"union") {
if (@hasDecl(T, "scaleEncodedSize")) {
return value.scaleEncodedSize();
}
}
return switch (type_info) {
.bool => 1,
.int => |info| info.bits / 8,
.array => |info| {
if (info.child == u8) {
return calculateCompactSize(@intCast(info.len)) + info.len;
} else {
var size: usize = 0;
for (value) |item| {
size += try calculateEncodedSize(item);
}
return size;
}
},
.pointer => |info| {
if (info.size == .slice) {
if (info.child == u8) {
return calculateCompactSize(@intCast(value.len)) + value.len;
} else {
var size = calculateCompactSize(@intCast(value.len));
for (value) |item| {
size += try calculateEncodedSize(item);
}
return size;
}
} else if (info.size == .one and @typeInfo(info.child) == .array) {
// Handle pointers to arrays (like string literals)
const array_info = @typeInfo(info.child).array;
if (array_info.child == u8) {
return calculateCompactSize(@intCast(array_info.len)) + array_info.len;
} else {
var size = calculateCompactSize(@intCast(array_info.len));
for (value) |item| {
size += try calculateEncodedSize(item);
}
return size;
}
}
@compileError("Unsupported pointer type for SCALE size calculation: " ++ @typeName(T));
},
.optional => {
const base_size = 1;
return base_size + if (value) |v| try calculateEncodedSize(v) else 0;
},
.@"struct" => {
var size: usize = 0;
const fields = std.meta.fields(T);
inline for (fields) |field| {
const field_value = @field(value, field.name);
size += try calculateEncodedSize(field_value);
}
return size;
},
.@"union" => |info| {
// 1 byte for variant index + payload size
var size: usize = 1;
const tag = std.meta.activeTag(value);
const tag_int = @intFromEnum(tag);
inline for (info.fields) |field| {
if (@intFromEnum(@field(info.tag_type.?, field.name)) == tag_int) {
if (field.type != void) {
const field_value = @field(value, field.name);
size += try calculateEncodedSize(field_value);
}
break;
}
}
return size;
},
else => {
@compileError("Unsupported type for SCALE size calculation: " ++ @typeName(T));
},
};
}
pub fn calculateCompactSize(value: u128) usize {
if (value < 64) {
return 1;
} else if (value < 16384) {
return 2;
} else if (value < 1073741824) {
return 4;
} else {
var bytes: usize = 0;
var v = value;
while (v > 0) : (v /= 256) {
bytes += 1;
}
return bytes + 1;
}
}