File: Class.rakumod

package info (click to toggle)
raku-json-class 0.0.21-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 128 kB
  • sloc: makefile: 4
file content (137 lines) | stat: -rw-r--r-- 4,072 bytes parent folder | download
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
127
128
129
130
131
132
133
134
135
136
137
use v6;

=begin pod

=head1 NAME

JSON::Class - Role to allow a class to unmarshall/marshall itself from JSON

=head1 SYNOPSIS

=begin code

    use JSON::Class;

    class Something does JSON::Class {

        has Str $.foo;

    }

    my Something $something = Something.from-json('{ "foo" : "stuff" }');

    ...

    my Str $json = $something.to-json(); # -> '{ "foo" : "stuff" }'


=end code

Or with C<:opt-in> marshalling:

=begin code


    use JSON::Class;
    use JSON::OptIn;

    class Something does JSON::Class[:opt-in] {

        has Str $.foo is json;
        has Str $.secret = 'secret';

    }

    my Something $something = Something.from-json('{ "foo" : "stuff" }');

    ...

    my Str $json = $something.to-json(); # -> '{ "foo" : "stuff" }'

=end code

=head1 DESCRIPTION

This is a simple role that provides methods to instantiate a class from a
JSON string that (hopefully,) represents it, and to serialise an object of
the class to a JSON string.  The JSON created from an instance should
round trip to a new instance with the same values for the "public attributes".
"Private" attributes (that is ones without accessors,) will be ignored for
both serialisation and de-serialisation.  The exact behaviour depends on that
of L<JSON::Marshal|https://github.com/jonathanstowe/JSON-Marshal> and
L<JSON::Unmarshal|https://github.com/tadzik/JSON-Unmarshal> respectively.

The  L<JSON::Marshal|https://github.com/jonathanstowe/JSON-Marshal> and
L<JSON::Unmarshal|https://github.com/tadzik/JSON-Unmarshal> provide traits
for controlling the unmarshalling/marshalling of specific attributes which
are re-exported by this module.

If your application exposes the marshalled data via, for example, an API, then
you may choose to use the C<:opt-in> parameter to the role, which will cause only
those attributes that are explicitly marked to be marshalled, avoiding the risk
of inadvertently exposing sensitive data.  This is described in more detail in
L<JSON::Marshal|https://github.com/jonathanstowe/JSON-Marshal>.


=head1 METHODS

=head2 method from-json

    method from-json(Str $json) returns JSON::Class

Deserialises the provided JSON string, returning a new object, with the
public attributes initialised with the corresponding values in the JSON
structure.

If the JSON is not valid or the data cannot be coerced into the correct
type for the target class then an exception may be thrown.

=head2 method to-json

    method to-json(Bool :$skip-null, Bool :$sorted-keys, Bool :$pretty = True ) returns Str

Serialises the public attributes of the object to a JSON string that
represents the object, this JSON can be fed to the L<from-json> of the
class to create a new object with matching (public) attributes.

If the C<:skip-null> adverb is provided all attributes without a
defined value will be ignored in serialisation. If you need finer
grained control then you should apply the C<json-skip-null> attribute
trait (defined by L<JSON::Marshal> ) to the traits you want to skip
if they aren't defined (C<:json-skip> will still have the same effect
though.)

If the C<sorted-keys> adverb is provided this will eventually be passed
to the JSON generation and will cause the keys in the JSON object to be
sorted in the output.

The adverb C<pretty> is true by default, if you want to suppress I<pretty>
formatting of the output (that is no un-necessary white space,) then
you can supply C<:!pretty>.

=end pod

use JSON::Unmarshal:ver<0.14+>;
use JSON::Marshal:ver<0.0.25+>;

my package EXPORT::DEFAULT {
    OUR::{'&trait_mod:<is>'} := &trait_mod:<is>;
}

role JSON::Class:ver<0.0.21>:auth<zef:jonathanstowe>[Bool :$opt-in = False] {


    method from-json(Str $json --> JSON::Class ) {
        my $ret = unmarshal($json, self);
        if $ret !~~ JSON::Class {
            $ret does JSON::Class;
        }
        $ret;
    }

    method to-json(Bool :$skip-null, Bool :$sorted-keys = False, Bool :$pretty = True --> Str ) {
        marshal(self, :$skip-null, :$sorted-keys, :$pretty, :$opt-in);
    }
}

# vim: expandtab shiftwidth=4 ft=raku