Skip to content

Commit

Permalink
Introduce breaking reader/writer PHP 8.4 changes and new stream funct…
Browse files Browse the repository at this point in the history
…ions
  • Loading branch information
veewee committed Sep 18, 2024
1 parent cd83c01 commit 661653c
Show file tree
Hide file tree
Showing 17 changed files with 770 additions and 92 deletions.
23 changes: 23 additions & 0 deletions docs/reader.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,39 @@ $reader = Reader::configure($yourLoader, ...$configurators);

```php
use VeeWee\Xml\Reader\Reader;
use VeeWee\Xml\Reader\Loader\xml_file_loader;

$reader = Reader::fromXmlFile('some-file.xml', ...$configurators);

// OR

$reader = Reader::configure(xml_file_loader('some-file.xml', encoding: 'UTF-8', flags: LIBXML_NOBLANKS), ...$configurators);
```

#### xml_stream_loader

```php
use VeeWee\Xml\Reader\Reader;
use function VeeWee\Xml\Reader\Loader\xml_stream_loader;

$reader = Reader::fromXmlStream($stream, ...$configurators);

// OR

$reader = Reader::configure(xml_stream_loader($stream, encoding: 'UTF-8', flags: LIBXML_NOBLANKS), ...$configurators);
```

#### xml_string_loader

```php
use VeeWee\Xml\Reader\Reader;
use function VeeWee\Xml\Reader\Loader\xml_string_loader;

$reader = Reader::fromXmlString('<xml />', ...$configurators);

// OR

$reader = Reader::configure(xml_string_loader('<xml />', encoding: 'UTF-8', flags: LIBXML_NOBLANKS), ...$configurators);
```

#### Writing your own loader
Expand Down
75 changes: 58 additions & 17 deletions docs/writer.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ The Writer consists out of following composable blocks:
- [Builders](#builders): Lets you build XML by using a declarative API.
- [Configurators](#configurators): Configure how the Writer behaves.
- [Mappers](#mappers): Map the XMLWriter to something else.
- [Applicatives](#applicatives): Apply an action on the open writer.
- [Openers](#openers): Specify where you want to write to.

## Builders
Expand Down Expand Up @@ -446,20 +447,6 @@ class MyAttribute implements Builder

Specify how you want to configure the XML writer.

#### open

The opener configurator takes an [opener](#openers) to specify the target of the writer.

```php
use VeeWee\Xml\Writer\Writer;
use function VeeWee\Xml\Writer\Configurator\open;
use function VeeWee\Xml\Writer\Opener\xml_file_opener;

Writer::configure(
open(xml_file_opener('somefile.xml'))
);
```

#### indentation

By default, the writer does not indent.
Expand Down Expand Up @@ -515,6 +502,47 @@ $doc = Writer::inMemory()
->map(memory_output());
```

## Applicatives

Apply an action on the open writer.


#### flush

Flushes the writer to the output.

```php
use VeeWee\Xml\Writer\Writer;
use function VeeWee\Xml\Writer\Applicative\flush;

$doc = Writer::forStream($stream)
->write($yourXml)
->apply(flush());
```

#### Writing your own applicatives

```php
namespace VeeWee\Xml\Writer\Applicative;

interface Applicative
{
/**
* @return mixed
*/
public function __invoke(\XMLWriter $writer): mixed;
}

```

You can apply the applicative as followed:

```php
namespace VeeWee\Xml\Writer\Writer;

$writer = Writer::configure($opener)->apply($applicative);
```

## Openers

#### memory_opener
Expand All @@ -533,7 +561,7 @@ $doc = Writer::inMemory(...$configurators)

#### xml_file_opener

Loads an XML document from a file.
Writes an XML document to a file.
When the file or folder does not exists, the code will attempt to create it.
If it is not possible to create a target to write to, a `RuntimException` will be thrown.

Expand All @@ -543,6 +571,19 @@ use VeeWee\Xml\Writer\Writer;
$doc = Writer::forFile('some-xml.xml', ...$configurators);
```

#### xml_stream_opener

Loads an XML document into an open resource stream.

```php
use VeeWee\Xml\Writer\Writer;
use function VeeWee\Xml\Writer\Applicative\flush;

$doc = Writer::forStream($stream, ...$configurators)
->write($yourXml)
->apply(flush())
```

#### Writing your own opener

```php
Expand All @@ -552,7 +593,7 @@ use XMLWriter;

interface Opener
{
public function __invoke(XMLWriter $writer): bool;
public function __invoke(): XMLWriter;
}
```

Expand All @@ -561,5 +602,5 @@ You can apply the loader as followed:
```php
namespace VeeWee\Xml\Writer\Writer;

$writer = Writer::configure($loader, ...$configurators);
$writer = Writer::configure($opener, ...$configurators);
```
6 changes: 3 additions & 3 deletions src/Xml/Reader/Loader/xml_file_loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
/**
* @return Closure(): XMLReader
*/
function xml_file_loader(string $file): Closure
function xml_file_loader(string $file, ?string $encoding = null, int $flags = 0): Closure
{
return static fn (): XMLReader => disallow_issues(
static function () use ($file): XMLReader {
static function () use ($file, $encoding, $flags): XMLReader {
Assert::fileExists($file);
return disallow_libxml_false_returns(
XMLReader::open($file),
XMLReader::fromUri($file, $encoding, $flags),
'Could not open the provided XML file!'
);
}
Expand Down
27 changes: 27 additions & 0 deletions src/Xml/Reader/Loader/xml_stream_loader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace VeeWee\Xml\Reader\Loader;

use Closure;
use Webmozart\Assert\Assert;
use XMLReader;
use function VeeWee\Xml\ErrorHandling\disallow_issues;
use function VeeWee\Xml\ErrorHandling\disallow_libxml_false_returns;

/**
* @param resource $stream
* @return Closure(): XMLReader
*/
function xml_stream_loader(mixed $stream, ?string $encoding = null, int $flags = 0, ?string $documentUri = null): Closure
{
return static fn (): XMLReader => disallow_issues(
static function () use ($stream, $encoding, $flags, $documentUri): XMLReader {
return disallow_libxml_false_returns(
XMLReader::fromStream($stream, $encoding, $flags, $documentUri),
'Could not read the provided XML stream!'
);
}
);
}
6 changes: 3 additions & 3 deletions src/Xml/Reader/Loader/xml_string_loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
/**
* @return Closure(): XMLReader
*/
function xml_string_loader(string $xml): Closure
function xml_string_loader(string $xml, ?string $encoding = null, int $flags = 0): Closure
{
return static fn (): XMLReader => disallow_issues(
static function () use ($xml): XMLReader {
static function () use ($xml, $encoding, $flags): XMLReader {
Assert::notEmpty($xml, 'The provided XML can not be empty!');

return disallow_libxml_false_returns(
XMLReader::XML($xml),
XMLReader::fromString($xml, $encoding, $flags),
'Could not read the provided XML!'
);
}
Expand Down
10 changes: 10 additions & 0 deletions src/Xml/Reader/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use function VeeWee\Xml\ErrorHandling\stop_on_first_issue;
use function VeeWee\Xml\Internal\configure;
use function VeeWee\Xml\Reader\Loader\xml_file_loader;
use function VeeWee\Xml\Reader\Loader\xml_stream_loader;
use function VeeWee\Xml\Reader\Loader\xml_string_loader;

final class Reader
Expand Down Expand Up @@ -57,6 +58,15 @@ public static function fromXmlString(string $xml, callable ... $configurators):
return self::configure(xml_string_loader($xml), ...$configurators);
}

/**
* @param resource $stream
* @param list<callable(XMLReader): XMLReader> $configurators
*/
public static function fromXmlStream(mixed $stream, callable ... $configurators): self
{
return self::configure(xml_stream_loader($stream), ...$configurators);
}

/**
* @param callable(NodeSequence): bool $matcher
*
Expand Down
11 changes: 11 additions & 0 deletions src/Xml/Writer/Applicative/Applicative.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace VeeWee\Xml\Writer\Applicative;

interface Applicative
{
/**
* @return mixed
*/
public function __invoke(\XMLWriter $writer): mixed;
}
18 changes: 18 additions & 0 deletions src/Xml/Writer/Applicative/flush.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace VeeWee\Xml\Writer\Applicative;

use XMLWriter;

/**
* @param bool $empty - Whether to empty the buffer or not.
*
* @return \Closure(XMLWriter): mixed
*/
function flush(bool $empty = true): \Closure {
return function (XMLWriter $writer) use ($empty): void {
$writer->flush($empty);
};
}
28 changes: 0 additions & 28 deletions src/Xml/Writer/Configurator/open.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Xml/Writer/Opener/Opener.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@

interface Opener
{
public function __invoke(XMLWriter $writer): bool;
public function __invoke(): XMLWriter;
}
6 changes: 2 additions & 4 deletions src/Xml/Writer/Opener/memory_opener.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
use XMLWriter;

/**
* @return Closure(XMLWriter): bool XMLWriter
* @return Closure(): XMLWriter
*/
function memory_opener(): Closure
{
return static function (XMLWriter $writer): bool {
return $writer->openMemory();
};
return static fn () => XMLWriter::toMemory();
}
6 changes: 3 additions & 3 deletions src/Xml/Writer/Opener/xml_file_opener.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
/**
* @param non-empty-string $file
*
* @return Closure(XMLWriter): bool XMLWriter
* @return Closure(): XMLWriter
*/
function xml_file_opener(string $file): Closure
{
return static function (XMLWriter $writer) use ($file) : bool {
return static function () use ($file) : XMLWriter {
// Try to create the file first.
// If the file exists, it will truncated. (Default behaviour of XMLWriter as well)
// If it cannot be created, it will throw exceptions.
write($file, '', WriteMode::Truncate);

return $writer->openUri($file);
return XMLWriter::toUri($file);
};
}
22 changes: 22 additions & 0 deletions src/Xml/Writer/Opener/xml_stream_opener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace VeeWee\Xml\Writer\Opener;

use Closure;
use Psl\File\WriteMode;
use XMLWriter;
use function Psl\File\write;

/**
* @param resource $stream
*
* @return Closure(): XMLWriter
*/
function xml_stream_opener(mixed $stream): Closure
{
return static function () use ($stream) : XMLWriter {
return XMLWriter::toStream($stream);
};
}
Loading

0 comments on commit 661653c

Please sign in to comment.