-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathenvironmentmap.zig
80 lines (67 loc) · 2.78 KB
/
environmentmap.zig
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
const std = @import("std");
const lola = @import("../main.zig");
/// This map is required by the VM serialization to identify environment pointers
/// and allow serialization/deserialization of the correct references.
pub const EnvironmentMap = struct {
const Self = @This();
const Entry = struct {
env: *lola.runtime.Environment,
id: u32,
};
items: std.ArrayList(Entry),
pub fn init(allocator: std.mem.Allocator) Self {
return Self{
.items = std.ArrayList(Entry).init(allocator),
};
}
pub fn deinit(self: *Self) void {
self.items.deinit();
self.* = undefined;
}
/// Adds a new environment-id-pair to the map.
/// Will return `error.IdAlreadyMapped` if a environment with this ID already exists,
/// will return `error.EnvironmentAlreadyMapped` if the given environment is already in the map.
/// Will return `error.OutOfMemory` when the internal storage cannot be resized.
pub fn add(self: *Self, id: u32, env: *lola.runtime.Environment) !void {
for (self.items.items) |item| {
if (item.id == id)
return error.IdAlreadyMapped;
if (item.env == env)
return error.EnvironmentAlreadyMapped;
}
try self.items.append(Entry{
.id = id,
.env = env,
});
}
/// Returns the ID for the given environment or `null` if the environment was not registered.
pub fn queryByPtr(self: Self, env: *lola.runtime.Environment) ?u32 {
return for (self.items.items) |item| {
if (item.env == env)
break item.id;
} else null;
}
/// Returns the Environment for the given id or `null` if the environment was not registered.
pub fn queryById(self: Self, id: u32) ?*lola.runtime.Environment {
return for (self.items.items) |item| {
if (item.id == id)
break item.env;
} else null;
}
};
test "EnvironmentMap" {
// three storage locations
var env_1: lola.runtime.Environment = undefined;
var env_2: lola.runtime.Environment = undefined;
var env_3: lola.runtime.Environment = undefined;
var map = EnvironmentMap.init(std.testing.allocator);
defer map.deinit();
try map.add(1, &env_1);
try map.add(2, &env_2);
try std.testing.expectEqual(@as(?*lola.runtime.Environment, &env_1), map.queryById(1));
try std.testing.expectEqual(@as(?*lola.runtime.Environment, &env_2), map.queryById(2));
try std.testing.expectEqual(@as(?*lola.runtime.Environment, null), map.queryById(3));
try std.testing.expectEqual(@as(?u32, 1), map.queryByPtr(&env_1));
try std.testing.expectEqual(@as(?u32, 2), map.queryByPtr(&env_2));
try std.testing.expectEqual(@as(?u32, null), map.queryByPtr(&env_3));
}