Completed
Pull Request — master (#42)
by Frederik
01:59
created

AggregateResponse::withLine()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 32
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 32
ccs 20
cts 20
cp 1
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 22
nc 4
nop 1
crap 4
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Protocol\Imap\Response;
5
6
use Genkgo\Mail\Exception\AssertionFailedException;
7
use Genkgo\Mail\Protocol\Imap\ResponseInterface;
8
use Genkgo\Mail\Protocol\Imap\Tag;
9
10
/**
11
 * Class Response
12
 * @package Genkgo\Mail\Protocol\Smtp
13
 */
14
final class AggregateResponse implements \IteratorAggregate
15
{
16
    /**
17
     * @var array|ResponseInterface[]
18
     */
19
    private $lines = [];
20
21
    /**
22
     * @var Tag
23
     */
24
    private $tag;
25
26
    /**
27
     * Reply constructor.
28
     * @param Tag $tag
29
     */
30 20
    public function __construct(Tag $tag)
31
    {
32 20
        $this->tag = $tag;
33 20
    }
34
35
    /**
36
     * @return \Iterator|ResponseInterface[]
37
     */
38 1
    public function getIterator(): \Iterator
39
    {
40 1
        return new \ArrayIterator($this->lines);
41
    }
42
43
    /**
44
     * @return ResponseInterface
45
     */
46 12
    public function first(): ResponseInterface
47
    {
48 12
        if (empty($this->lines)) {
49 1
            throw new \OutOfBoundsException('Cannot return item of empty response');
50
        }
51
52 11
        return reset($this->lines);
53
    }
54
55
    /**
56
     * @return ResponseInterface
57
     */
58 9
    public function last(): ResponseInterface
59
    {
60 9
        if (empty($this->lines)) {
61 1
            throw new \OutOfBoundsException('Cannot return item of empty response');
62
        }
63
64 8
        return end($this->lines);
65
    }
66
67
    /**
68
     * @param int $index
69
     * @return ResponseInterface
70
     */
71 2
    public function at(int $index): ResponseInterface
72
    {
73 2
        if (!isset($this->lines[$index])) {
74 1
            throw new \OutOfBoundsException('GenericItem not in response');
75
        }
76
77 1
        return $this->lines[$index];
78
    }
79
80
    /**
81
     * @return bool
82
     */
83 6
    public function hasCompleted(): bool
84
    {
85 6
        if (empty($this->lines)) {
86 6
            return false;
87
        }
88
89 6
        $lastCommand = end($this->lines);
90
        try {
91 6
            $lastCommand->assertTagged();
92 6
            return true;
93 6
        } catch (AssertionFailedException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
94
        }
95
96
        try {
97 6
            $lastCommand->assertContinuation();
98 3
            return true;
99 5
        } catch (AssertionFailedException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
100
        }
101
102 5
        return false;
103
    }
104
105
    /**
106
     * @param string $line
107
     * @return AggregateResponse
108
     */
109 16
    public function withLine(string $line): AggregateResponse
110
    {
111 16
        $clone = clone $this;
112
113 16
        switch (substr($line, 0, 2)) {
114 16
            case '+ ':
115 4
                $clone->lines[] = new CommandContinuationRequestResponse(
116 4
                    substr($line, 2)
117
                );
118 4
                break;
119 15
            case '* ':
120 13
                $clone->lines[] = new UntaggedResponse(
121 13
                    substr($line, 2)
122
                );
123 13
                break;
124
            default:
125
                try {
126 11
                    $clone->lines[] = new TaggedResponse(
127 11
                        $this->tag,
128 11
                        $this->tag->extractBodyFromLine($line)
129
                    );
130 1
                } catch (\InvalidArgumentException $e) {
131 1
                    $keys = array_keys($clone->lines);
132 1
                    $lastKey = end($keys);
133 1
                    $clone->lines[$lastKey] = $clone->lines[$lastKey]->withBody($line);
134
                }
135 11
                break;
136
137
        }
138
139 16
        return $clone;
140
    }
141
}
142