Passed
Push — master ( 956163...dedbc7 )
by Christian
03:02
created

InteractionOperator::interact()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 2
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Cocotte\Console;
4
5
use Symfony\Component\Console\Input\InputInterface;
6
7
class InteractionOperator
8
{
9
    /**
10
     * @var Style
11
     */
12
    private $style;
13
14
    public function __construct(Style $style)
15
    {
16
        $this->style = $style;
17
    }
18
19
    public function interact(InputInterface $input, OptionProvider $optionProvider)
20
    {
21
        $name = $optionProvider->optionName();
22
23
        if (!$input->hasOption($name)) {
24
            throw new \Exception("input does not have option '$name'");
25
        }
26
27
        try {
28
            $optionProvider->validate($input->getOption($name) ?? "");
29
        } catch (\Throwable $e) {
30
            $this->style->error($e->getMessage());
31
            $input->setOption($name, $this->ask($optionProvider));
32
        }
33
    }
34
35
    public function ask(OptionProvider $optionProvider): string
36
    {
37
        $this->style->help($optionProvider->helpMessage());
38
39
        return $this->style->askQuestion(
40
            $optionProvider
41
                ->question()
42
                ->setNormalizer($this->normalizer())
43
                ->setValidator($this->validator($optionProvider))
44
        );
45
    }
46
47
    private function normalizer(): \Closure
48
    {
49
        return function ($answer): string {
50
            return trim((string)$answer);
51
        };
52
    }
53
54
    private function validator(OptionProvider $optionProvider): \Closure
55
    {
56
        return function (string $answer) use ($optionProvider): string {
57
            if (!$answer) {
58
                throw new \Exception('No answer was given. Try again.');
59
            }
60
61
            $optionProvider->validate($answer);
62
            $optionProvider->onCorrectAnswer($answer);
63
64
            return $answer;
65
        };
66
    }
67
68
}