Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.86% covered (success)
92.86%
13 / 14
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
LineBreakIterator
92.86% covered (success)
92.86%
13 / 14
50.00% covered (danger)
50.00%
1 / 2
5.01
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIterator
92.31% covered (success)
92.31%
12 / 13
0.00% covered (danger)
0.00%
0 / 1
4.01
1<?php
2
3declare(strict_types=1);
4
5namespace Phpdftk\Text;
6
7/**
8 * Lazy iterable view over the {@see LineBreakOpportunity}s in a string.
9 * Built by {@see LineBreaker::breakOpportunities}.
10 *
11 * The iterator is single-pass — callers re-invoke `breakOpportunities` to
12 * restart. Two iterations may yield slightly different boundaries if the
13 * locale rules change in between (rare in practice).
14 *
15 * @implements \IteratorAggregate<int, LineBreakOpportunity>
16 */
17final class LineBreakIterator implements \IteratorAggregate
18{
19    public function __construct(
20        private readonly string $text,
21        private readonly string $locale,
22    ) {}
23
24    /**
25     * @return \Generator<int, LineBreakOpportunity>
26     */
27    public function getIterator(): \Generator
28    {
29        $iter = \IntlBreakIterator::createLineInstance($this->locale);
30        if ($iter === null) {
31            return;
32        }
33        $iter->setText($this->text);
34        $iter->first();
35        $offset = $iter->next();
36        while ($offset !== \IntlBreakIterator::DONE) {
37            // Status >= LINE_HARD = mandatory break point (line terminator).
38            $status = $iter->getRuleStatus();
39            $kind = $status >= \IntlBreakIterator::LINE_HARD
40                ? LineBreakKind::Mandatory
41                : LineBreakKind::Allowed;
42            yield new LineBreakOpportunity($offset, $kind);
43            $offset = $iter->next();
44        }
45    }
46}