App-vaporcalc
view release on metacpan or search on metacpan
bin/vaporcalc view on Meta::CPAN
my $recipe = $rset->recipe;
my $result = $rset->result;
my $flav_recipe_str = flavor_strings($rset)->recipe_flavor_string;
my $flav_result_str = flavor_strings($rset)->result_flavor_string;
format_str( $tmpl =>
notes => sub {
$recipe->notes->has_any ?
"\n" . $recipe->notes
->map(sub { colorify('bold yellow', ' - '.$_) })
->join("\n")
: 'none'
},
flavor_recipe => $flav_recipe_str,
flavor_result => $flav_result_str,
(map {; $_ => colorify('bold red', $recipe->$_) } qw/
target_quantity target_nic_per_ml
base_nic_per_ml base_nic_type
target_pg target_vg
/),
(map {; $_ => colorify('bold yellow', $result->$_) } qw/
vg pg nic total
/),
max_vg_total => sub {
colorify('bold yellow', $result->pg + $result->vg)
},
)
}
use Term::UI;
use Term::ReadLine;
my $termpkg =
$ENV{PERL_RL}
|| try { use_module('Term::ReadLine::Perl5') }
|| try { use_module('Term::ReadLine::Perl') }
|| 'Term::ReadLine';
my $term = $termpkg->new('vcalc');
my $outfh = $term->OUT || \*STDOUT;
$outfh->autoflush(1);
$outfh->say('Welcome to App::vaporcalc!');
$outfh->say("Try '@{[ colorify yellow => 'help' ]}' for usage details.");
my $cmdeng = App::vaporcalc::CmdEngine->new;
my $recipe = App::vaporcalc::Recipe->new(
target_quantity => 10,
base_nic_per_ml => 100,
target_nic_per_ml => 12,
target_pg => 45,
target_vg => 55,
flavor_percentage => 10,
);
my $initial_input = getopts->recipe ? 'recipe load '.getopts->recipe : undef;
my $orig_prompt = colorify green => 'vcalc> ';
my $prompt;
PROMPT: while (1) {
$prompt //= $orig_prompt;
my $input = $initial_input // $term->get_reply(
prompt => $prompt,
default => 'calc'
);
undef $initial_input;
next PROMPT unless $input;
$term->addhistory($input);
$input = 'show recipe' if $input eq 'calc';
last PROMPT if $input =~ /^(?:exit|quit)/i;
my $parsed = try {
$cmdeng->parse_cmd($input)
} catch {
$outfh->say( format_error(">> Parser err: $_") );
undef
} or next PROMPT;
my $cmd_result = try {
$cmdeng->prepare_cmd(
subject => $parsed->subject,
verb => $parsed->verb,
params => $parsed->params,
recipe => $recipe,
)->execute
} catch {
$outfh->say( format_error(">> Cmd err: $_") );
# FIXME if this is a RoundedResult err,
# the recipe is busted;
# use separate recipe/result templates so we can
# display the broken recipe
undef
} or next PROMPT;
sswitch ($cmd_result->action) {
case 'display': {
$outfh->print( format_resultset( $cmd_result->resultset ) );
}
case 'print': {
$outfh->say( colorify yellow => $cmd_result->string );
}
case 'prompt': {
my $reply = $term->get_reply(prompt => $cmd_result->prompt);
$cmd_result->run_prompt_callback($reply)
}
case 'recipe': {
$recipe = $cmd_result->recipe;
$outfh->say( colorify yellow => $cmd_result->string )
if $cmd_result->string;
}
case 'next': { next PROMPT }
case 'last': { last PROMPT }
default: {
$outfh->say(
format_error(">> Unknown Cmd::Result action: ".$cmd_result->action)
);
}
}
} # PROMPT
say "Bye!"; exit 0
__END__
=pod
=head1 NAME
vaporcalc - Terminal-based e-liquid recipe calculator
=head1 SYNOPSIS
vaporcalc [OPTIONS]...
=head1 OPTIONS
--nocolor Disable ANSI colors
--version
--help
=head1 DESCRIPTION
A terminal-based calculator for manging DIY e-liquid recipes.
See L<App::vaporcalc>, and especially L<App::vaporcalc/"WARNING">.
=head1 COMMANDS
Commands can be issued in a reasonably natural manner; a command has a
subject, possibly a verb (action the subject should perform), and possibly
some parameters. For example, these are equally valid commands:
vcalc> show nic base
vcalc> nic base show
vcalc> set nic base 36
vcalc> nic base set 36
The complete list of available subjects and their usage is available via the
command C<help>.
( run in 2.375 seconds using v1.01-cache-2.11-cpan-800906f7e73 )