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