-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathto_napi_value.zig
More file actions
126 lines (119 loc) · 4.41 KB
/
to_napi_value.zig
File metadata and controls
126 lines (119 loc) · 4.41 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const std = @import("std");
const ssz = @import("ssz");
const napi = @import("zapi:zapi");
const constants = @import("constants");
pub fn sszValueToNapiValue(env: napi.Env, comptime ST: type, value: *const ST.Type) !napi.Value {
switch (ST.kind) {
.uint => {
if (ST.Type == u64 and value.* == constants.FAR_FUTURE_EPOCH) {
return try (try env.getGlobal()).getNamedProperty("Infinity");
}
return try env.createInt64(@intCast(value.*));
},
.bool => {
return try env.getBoolean(value.*);
},
.vector => {
if (comptime ssz.isByteVectorType(ST)) {
var bytes: [*]u8 = undefined;
const buf = try env.createArrayBuffer(ST.length, &bytes);
@memcpy(bytes[0..ST.length], value);
return try env.createTypedarray(.uint8, ST.length, buf, 0);
} else {
const arr = try env.createArrayWithLength(ST.length);
for (value, 0..) |*v, i| {
const napi_element = try sszValueToNapiValue(env, ST.Element, v);
try arr.setElement(@intCast(i), napi_element);
}
return arr;
}
},
.list => {
if (comptime ssz.isByteListType(ST)) {
var bytes: [*]u8 = undefined;
const buf = try env.createArrayBuffer(value.items.len, &bytes);
@memcpy(bytes[0..value.items.len], value.items);
return try env.createTypedarray(.uint8, value.items.len, buf, 0);
} else {
const arr = try env.createArrayWithLength(value.items.len);
for (value.items, 0..) |*v, i| {
const napi_element = try sszValueToNapiValue(env, ST.Element, v);
try arr.setElement(@intCast(i), napi_element);
}
return arr;
}
},
.container => {
const obj = try env.createObject();
inline for (ST.fields) |field| {
const field_value = &@field(value, field.name);
const napi_field_value = try sszValueToNapiValue(env, field.type, field_value);
try obj.setNamedProperty(snakeToCamel(field.name), napi_field_value);
}
return obj;
},
}
}
const NumberSliceOpts = struct {
typed_array: ?napi.value_types.TypedarrayType = null,
};
pub fn numberSliceToNapiValue(
env: napi.Env,
comptime T: type,
numbers: []const T,
comptime opts: NumberSliceOpts,
) !napi.Value {
if (opts.typed_array) |typed_array_type| {
var bytes: [*]u8 = undefined;
const bytes_len = numbers.len * typed_array_type.elementSize();
const buf = try env.createArrayBuffer(bytes_len, &bytes);
if (T == typed_array_type.elementType()) {
@memcpy(bytes[0..bytes_len], @as([]const u8, @ptrCast(numbers)));
} else {
const ET = typed_array_type.elementType();
const bytes_numbers_ptr: [*]ET = @ptrCast(@alignCast(bytes));
const bytes_numbers = bytes_numbers_ptr[0..numbers.len];
for (numbers, 0..) |num, i| {
bytes_numbers[i] = @intCast(num);
}
}
return try env.createTypedarray(typed_array_type, numbers.len, buf, 0);
} else {
const arr = try env.createArrayWithLength(numbers.len);
for (numbers, 0..) |num, i| {
const napi_element = try env.createInt64(@intCast(num));
try arr.setElement(@intCast(i), napi_element);
}
return arr;
}
}
fn snakeToCamel(comptime str: []const u8) [:0]const u8 {
const count = comptime count: {
var n: usize = 0;
for (str) |c| {
if (c != '_') n += 1;
}
break :count n;
};
const result = comptime result: {
var buf: [count:0]u8 = undefined;
var out_idx: usize = 0;
var capitalize = false;
for (str) |c| {
if (c == '_') {
capitalize = true;
} else {
if (capitalize) {
buf[out_idx] = std.ascii.toUpper(c);
capitalize = false;
} else {
buf[out_idx] = c;
}
out_idx += 1;
}
}
buf[count] = 0;
break :result buf;
};
return &result;
}