pervasive type constraints
[scpubgit/DX.git] / lib / DX / ShellFrontend.pm
CommitLineData
9eedd677 1package DX::ShellFrontend;
2
3use IO::Handle;
2548ce61 4use Types::Standard qw(InstanceOf);
9eedd677 5use Caroline;
6use DX::Class;
7
8has session => (
80d78e1b 9 is => 'ro', isa => ShellSession, required => 1,
9eedd677 10 handles => [ qw(is_complete_command_string eval_command_string) ]
11);
12
80d78e1b 13has session_mode => (is => 'rwp', isa => Enum['shell','query'], required => 1);
9eedd677 14
2548ce61 15has readline => (
16 is => 'lazy', isa => InstanceOf['Caroline'],
17 builder => sub { Caroline->new }
18);
9eedd677 19
20sub BUILD { STDOUT->autoflush(1) }
21
22sub repl {
23 my ($self) = @_;
24 while (1) {
25 last unless $self->rep
26 }
27}
28
29sub 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
37sub 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
49sub 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
57sub process_mode_result {
58 my ($self, $mode) = @_;
59 $self->_set_session_mode($mode);
60}
61
62sub process_output_result {
63 my ($self, $output) = @_;
fa8f5696 64 $output .= "\n" unless $output =~ /\n$/;
9eedd677 65 print $output;
66}
67
681;