1package Net::CLI::Interact::Action;
2{ $Net::CLI::Interact::Action::VERSION = '2.300003' }
3
4use Moo;
5use Sub::Quote;
6use MooX::Types::MooseLike::Base qw(Any Bool Str ArrayRef InstanceOf RegexpRef);
7use Net::CLI::Interact::ActionSet;
8
9has 'type' => (
10    is => 'ro',
11    isa => quote_sub(
12        q{ die "$_[0] not send/match" unless $_[0] =~ m/^(?:send|match)$/ }),
13    required => 1,
14);
15
16has 'value' => (
17    is => 'ro',
18    isa => Any, # FIXME 'Str|ArrayRef[RegexpRef]',
19    required => 1,
20);
21
22has 'no_ors' => (
23    is => 'ro',
24    isa => Bool,
25    default => quote_sub('0'),
26);
27
28has 'continuation' => (
29    is => 'rw',
30    isa => InstanceOf['Net::CLI::Interact::ActionSet'],
31);
32
33has 'params' => (
34    is => 'rw',
35    isa => ArrayRef,
36    default => sub { [] },
37);
38
39has 'response' => (
40    is => 'rw',
41    isa => Str,
42    default => quote_sub(q{''}),
43);
44
45has 'response_stash' => (
46    is => 'rw',
47    isa => Str,
48    default => quote_sub(q{''}),
49);
50
51has 'prompt_hit' => (
52    is => 'rw',
53    isa => RegexpRef,
54);
55
56sub BUILDARGS {
57    my ($class, @rest) = @_;
58
59    # accept single hash ref or naked hash
60    my $params = (ref {} eq ref $rest[0] ? $rest[0] : {@rest});
61
62    if (exists $params->{continuation} and ref [] eq ref $params->{continuation}) {
63        $params->{continuation} = Net::CLI::Interact::ActionSet->new({
64            actions => $params->{continuation},
65        });
66    }
67
68    return $params;
69}
70
71# Only a shallow copy so all the reference based slots still
72# share data with the original Action's slots.
73#
74# I asked in #web-simple and was told that if the object is more magical than
75# a simple hashref, then someone is trying to be far too clever. agreed!
76sub clone {
77    my $self = shift;
78    bless({ %{$self}, %{(shift) || {}} }, ref $self)
79}
80
81# count the number of sprintf parameters used in the value
82sub num_params {
83    my $self = shift;
84    return 0 if ref $self->value;
85    # this tricksy little number comes from the Perl FAQ
86    my $count = () = $self->value =~ m/(?<!%)%/g;
87    return $count;
88}
89
901;
91
92=pod
93
94=head1 NAME
95
96Net::CLI::Interact::Action - Sent data or matched response from connected device
97
98=head1 DESCRIPTION
99
100This class is used internally by L<Net::CLI::Interact> and it's unlikely that
101an end-user will need to make use of Action objects directly. The interface is
102documented here as a matter of record.
103
104An Action object represents I<either> some kind of text or command to send to
105a connected device, I<or> a regular expression matching the response from a
106connected device. Such Actions are built up into ActionSets which describe a
107conversation with the connected device.
108
109If the Action is a C<send> type, then after execution it can be cloned and
110augmented with the response text of the command. If the response is likely to
111be paged, then the Action may also store instruction in how to trigger and
112consume the pages.
113
114=head1 INTERFACE
115
116=head2 type
117
118Denotes the kind of Action, which may be C<send> or C<match>.
119
120=head2 value
121
122In the case of C<send>, a String command to send to the device. In the case of
123C<match>, a regular expression reference to match response from the device. In
124special circumstances an array reference of regular expression references is
125also valid, and each will be checked for a match against the device response.
126
127=head2 no_ors
128
129Only applies to the C<send> kind. Whether to skip appending the I<output
130record separator> (newline) to the C<send> command when sent to the connected
131device.
132
133=head2 continuation
134
135Only applies to the C<send> kind. When response output is likely to be paged,
136this stores an L<ActionSet|Net::CLI::Interact::ActionSet> that contains two
137Actions: one for the C<match> which indicates output has paused at the end of
138a page, and one for the C<send> command which triggers printing of the next
139page.
140
141=head2 params
142
143Only applies to the C<send> kind, and contains a list of parameters which are
144substituted into the C<value> using Perl's C<sprintf> function. Insufficient
145parameters causes C<sprintf> to die.
146
147=head2 num_params
148
149Only applies to the C<send> kind, and returns the number of parameters which
150are required for the current C<value>. Used for error checking when setting
151C<params>.
152
153=head2 response
154
155A stash for the returned prompt which matched and triggered the end of this
156action.
157
158=head2 response_stash
159
160A stash for the returned output following a C<send> command, but not including
161the matched prompt which ended the action. This slot is used by the C<match>
162action as it slurps output, but the content is then transferred over to the
163partner C<send> in the ActionSet.
164
165=head2 prompt_hit
166
167When a command is successfully issued, the response is terminated by a prompt.
168However that prompt can be one of a list, defined in the Action. This slot
169records the regular expression from that list which was actually matched.
170
171=head2 clone
172
173Returns a new Action, which is a shallow clone of the existing one. All the
174reference based slots will share data, but you can add (for example) a
175C<response> without affecting the original Action. Used when preparing to
176execute an Action which has been retrieved from the
177L<Phrasebook|Net::CLI::Interact::Phrasebook>.
178
179=cut
180