basic console service
[scpubgit/Clifton.git] / lib / App / Clifton / ConsoleService / Session.pm
CommitLineData
cd780129 1package App::Clifton::ConsoleService::Session;
2
3use Eval::WithLexicals;
4use Data::Dumper::Concise;
5use Moo;
6
7extends 'IO::Async::Protocol::LineStream';
8
9has lex_env => (is => 'lazy');
10
11sub _build_lex_env { Eval::WithLexicals->new }
12
13sub 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
25sub _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
40sub handle_echo {
41 my ($self, $body) = @_;
42 $self->_send_response(ECHO => $body);
43}
44
45sub 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
64sub on_closed {
65 my ($self) = @_;
66 $self->parent->remove_child($self);
67}
68
691;