Commit | Line | Data |
9eedd677 |
1 | package DX::ShellFrontend; |
2 | |
80d78e1b |
3 | use Types::Standard qw(Enum); |
9eedd677 |
4 | use IO::Handle; |
5 | use Caroline; |
6 | use DX::Class; |
7 | |
8 | has session => ( |
80d78e1b |
9 | is => 'ro', isa => ShellSession, required => 1, |
9eedd677 |
10 | handles => [ qw(is_complete_command_string eval_command_string) ] |
11 | ); |
12 | |
80d78e1b |
13 | has session_mode => (is => 'rwp', isa => Enum['shell','query'], required => 1); |
9eedd677 |
14 | |
15 | has readline => (is => 'lazy', builder => sub { Caroline->new }); |
16 | |
17 | sub BUILD { STDOUT->autoflush(1) } |
18 | |
19 | sub repl { |
20 | my ($self) = @_; |
21 | while (1) { |
22 | last unless $self->rep |
23 | } |
24 | } |
25 | |
26 | sub rep { |
27 | my ($self) = @_; |
28 | return unless defined(my $command = $self->read_command); |
29 | my @result = $self->eval_command_string($command); |
30 | $self->process_result(@result); |
31 | return 1; |
32 | } |
33 | |
34 | sub read_command { |
35 | my ($self) = @_; |
36 | my $base_prompt = $self->session_mode eq 'shell' ? '$ ' : '? '; |
37 | my $rl = $self->readline; |
38 | return unless defined(my $command = $rl->readline($base_prompt)); |
39 | while (not $self->is_complete_command_string($command)) { |
40 | $command .= $rl->readline('> '); |
41 | } |
42 | $rl->history_add($command); |
43 | return $command; |
44 | } |
45 | |
46 | sub process_result { |
47 | my ($self, @result) = @_; |
48 | foreach my $res (@result) { |
49 | my ($type, $payload) = @$res; |
50 | $self->${\($self->can("process_${type}_result")||die)}($payload); |
51 | } |
52 | } |
53 | |
54 | sub process_mode_result { |
55 | my ($self, $mode) = @_; |
56 | $self->_set_session_mode($mode); |
57 | } |
58 | |
59 | sub process_output_result { |
60 | my ($self, $output) = @_; |
fa8f5696 |
61 | $output .= "\n" unless $output =~ /\n$/; |
9eedd677 |
62 | print $output; |
63 | } |
64 | |
65 | 1; |