Commit | Line | Data |
cd780129 |
1 | package App::Clifton::ConsoleService::Session; |
2 | |
3 | use Eval::WithLexicals; |
4 | use Data::Dumper::Concise; |
5 | use Moo; |
6 | |
7 | extends 'IO::Async::Protocol::LineStream'; |
8 | |
9 | has lex_env => (is => 'lazy'); |
10 | |
11 | sub _build_lex_env { Eval::WithLexicals->new } |
12 | |
13 | sub on_read_line { |
14 | my ($self, $line) = @_; |
15 | my ($cmd, $body) = split(/ /, $line, 2); |
16 | if ($cmd !~ /^([A-Z]+)$/) { |
17 | $self->_send_response(ERROR => "Invalid command ${cmd}"); |
18 | } elsif (my $call = $self->can(lc "handle_${cmd}")) { |
19 | $self->$call($body ? eval $body : ()); |
20 | } else { |
21 | $self->_send_response(ERROR => "Unknown command ${cmd}"); |
22 | } |
23 | } |
24 | |
25 | sub _send_response { |
26 | my ($self, $code, $body) = @_; |
27 | |
28 | if (my $ref = ref($body)) { |
29 | ($code, $body) = (ERROR => "Command returned body of reftype ${ref}"); |
30 | } |
31 | if ($code !~ /^([A-Z]+)$/) { |
32 | ($code, $body) = (ERROR => "Command returned malformed code ${code}"); |
33 | } |
34 | |
35 | chomp(my $enc_body = Dumper $body); |
36 | |
37 | $self->write_line(join ' ', $code, $enc_body); |
38 | } |
39 | |
40 | sub handle_echo { |
41 | my ($self, $body) = @_; |
42 | $self->_send_response(ECHO => $body); |
43 | } |
44 | |
45 | sub handle_eval { |
46 | my ($self, $body) = @_; |
47 | return $self->_send_response(ERROR => 'You asked me to eval undef!') |
48 | unless defined $body; |
49 | if (my $ref = ref $body) { |
50 | return $self->_send_response( |
51 | ERROR => "You asked me to eval a ${ref} ref" |
52 | ); |
53 | } |
54 | my $eval = $self->lex_env; |
55 | my $code = 'RESULT'; |
56 | my @ret; local $@; eval { |
57 | @ret = $eval->eval($body); 1; |
58 | } or ($code, @ret) = (ERROR => $@); |
59 | $self->_send_response( |
60 | $code => do { local $Data::Dumper::Maxdepth = 1; Dumper @ret } |
61 | ); |
62 | } |
63 | |
64 | sub on_closed { |
65 | my ($self) = @_; |
66 | $self->parent->remove_child($self); |
67 | } |
68 | |
69 | 1; |