Completed
Pull Request — master (#42)
by Frederik
02:26
created

AggregateResponse::getIterator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
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 24
    public function __construct(Tag $tag)
31
    {
32 24
        $this->tag = $tag;
33 24
    }
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 10
    public function last(): ResponseInterface
59
    {
60 10
        if (empty($this->lines)) {
61 1
            throw new \OutOfBoundsException('Cannot return item of empty response');
62
        }
63
64 9
        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 9
    public function hasCompleted(): bool
84
    {
85 9
        if (empty($this->lines)) {
86 9
            return false;
87
        }
88
89 9
        $lastCommand = end($this->lines);
90
        try {
91 9
            $lastCommand->assertTagged();
92 9
            return true;
93 7
        } 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 7
            $lastCommand->assertContinuation();
98 4
            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 20
    public function withLine(string $line): AggregateResponse
110
    {
111 20
        $clone = clone $this;
112
113 20
        switch (substr($line, 0, 2)) {
114 20
            case '+ ':
115 5
                $clone->lines[] = new CommandContinuationRequestResponse(
116 5
                    substr($line, 2)
117
                );
118 5
                break;
119 19
            case '* ':
120 13
                $clone->lines[] = new UntaggedResponse(
121 13
                    substr($line, 2)
122
                );
123 13
                break;
124
            default:
125
                try {
126 15
                    $clone->lines[] = new TaggedResponse(
127 15
                        $this->tag,
128 15
                        $this->tag->extractBodyFromLine($line)
129
                    );
130 2
                } catch (\InvalidArgumentException $e) {
131 2
                    if (empty($clone->lines)) {
132 1
                        throw new \UnexpectedValueException(
133 1
                            'Expected line to begin with +, * or tag. Got: ' . $line
134
                        );
135
                    }
136
137 1
                    $keys = array_keys($clone->lines);
138 1
                    $lastKey = end($keys);
139 1
                    $clone->lines[$lastKey] = $clone->lines[$lastKey]->withAddedBody($line);
140
                }
141 14
                break;
142
143
        }
144
145 19
        return $clone;
146
    }
147
}
148