-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Parser.php
76 lines (64 loc) · 1.94 KB
/
Parser.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?php declare(strict_types=1);
/*
* This file is part of sebastian/csv-parser.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\CsvParser;
use function is_array;
use Generator;
use RuntimeException;
use SplFileObject;
/**
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for this library
*/
final class Parser
{
private string $separator = ',';
private bool $ignoreFirstLine = false;
/**
* @psalm-return Generator<int, array<string, bool|int|float|object|string>>
*
* @throws CannotReadCsvFileException
* @throws OutOfBoundsException
*/
public function parse(string $filename, Schema $schema): Generator
{
try {
$file = new SplFileObject($filename);
} catch (RuntimeException $e) {
throw new CannotReadCsvFileException($e->getMessage());
}
$file->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE);
$file->setCsvControl($this->separator);
return $this->generator($file, $schema);
}
public function setSeparator(string $separator): void
{
$this->separator = $separator;
}
public function ignoreFirstLine(): void
{
$this->ignoreFirstLine = true;
}
/**
* @psalm-return Generator<int, array<string, bool|int|float|object|string>>
*/
private function generator(SplFileObject $file, Schema $schema): Generator
{
$firstLine = true;
foreach ($file as $line) {
if ($this->ignoreFirstLine && $firstLine) {
$firstLine = false;
continue;
}
if (!is_array($line)) {
continue;
}
yield $schema->apply($line);
}
}
}