/
JSON.pm6
57 lines (45 loc) · 1.28 KB
/
JSON.pm6
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
# JSON::Tiny is used to render basic stuff like hashes.
use JSON::Tiny;
unit role AsIf::JSON;
# For reasons I don't quite understand, this has to be separated out into
# it's own sub right now. I'd probably really just fold it into Str.
sub handled-elsewhere ($obj) {
try {
to-json($obj);
return True;
}
CATCH {
return False;
}
}
##
# This helper sub renders class-based objects as JSON. Objects are treated
# as hashes, public properties are rendered; private properties are omitted.
# This could probably be improved to do things like let objects that inherit
# from Arrays render as JavaScript arrays (or something). But it works fine
# for my purposes for now.
sub asif-json ($obj) {
# This hash will be rendered to JSON by JSON::Tiny. It's just simple
# storage.
my %json;
# Loop through the object's attributes. If the attribute is public,
# include it in the JSON. If it's private, ignore it.
for $obj.^attributes -> $attr {
if $attr.has-accessor {
%json{$attr.name.substr(2)} = $attr.get_value($obj);
}
}
return to-json(%json);
}
# Render as string.
method Str () {
if (handled-elsewhere(self)) {
return to-json(self);
} else {
return asif-json(self);
}
}
# Outsource gist to Str.
method gist () {
return self.Str();
}