Commit | Line | Data |
e653a487 |
1 | package Reaction::InterfaceModel::Search::Spec; |
2 | |
065f3d3d |
3 | use Reaction::Role; |
e653a487 |
4 | use Method::Signatures::Simple; |
e7b0b9e2 |
5 | use JSON::Any; |
e653a487 |
6 | use Scalar::Util qw(weaken); |
7 | use namespace::clean -except => [ qw(meta) ]; |
8 | |
9 | has '_search_spec' => ( |
10 | is => 'ro', lazy_build => 1, clearer => '_clear_search_spec', |
11 | ); |
12 | |
13 | has '_dependent_clients' => ( |
14 | is => 'ro', default => sub { {} }, |
15 | ); |
16 | |
17 | method register_dependent ($dep, $callback) { |
18 | weaken($self->_dependent_clients->{$dep} = $callback); |
19 | } |
20 | |
21 | method unregister_dependent ($dep) { |
22 | delete $self->_dependent_clients->{$dep}; |
23 | } |
24 | |
25 | after '_clear_search_spec' => method () { |
26 | $_->($self) for grep defined, values %{$self->_dependent_clients}; |
27 | }; |
28 | |
29 | requires '_build__search_spec'; |
30 | |
31 | method filter_collection ($coll) { |
32 | return $coll->where(@{$self->_search_spec}); |
33 | } |
34 | |
35 | method _to_string_fetch ($attr) { |
36 | return () unless $self->${\($attr->get_predicate_method||sub{ 1 })}; |
37 | my $value = $self->${\$attr->get_read_method}; |
38 | return ($attr->name => $self->_to_string_pack_value($attr->name, $value)); |
39 | } |
40 | |
41 | requires '_to_string_pack_value'; |
42 | |
43 | method to_string () { |
44 | my %val = map { $self->_to_string_fetch($_) } |
45 | grep { $_->name !~ /^_/ } $self->meta->get_all_attributes; |
46 | return to_json(\%val, { canonical => 1 }); |
47 | } |
48 | |
49 | requires '_from_string_unpack_value'; |
50 | |
51 | method from_string ($class: $string, $other) { |
52 | my %raw = %{from_json($string)}; |
53 | my %val; |
54 | @val{keys %raw} = map { |
55 | $class->_from_string_unpack_value($_, $raw{$_}) |
56 | } keys %raw; |
57 | return $class->new({ %val, %{$other||{}} }); |
58 | } |
59 | |
60 | 1; |
61 | |