rosavox/lib/alveolata/xml/concrete/complex/implementation.php
2025-05-23 07:33:29 +00:00

164 lines
2.8 KiB
PHP

<?php
namespace alveolata\xml;
require_once(DIR_ALVEOLATA . '/string/functions.php');
require_once(DIR_ALVEOLATA . '/list/functions.php');
require_once(DIR_ALVEOLATA . '/xml/abstract/interface.php');
require_once(DIR_ALVEOLATA . '/xml/concrete/complex/type.php');
/**
* @author Christian Fraß <frass@greenscale.de>
*/
class implementation_complex implements interface_node
{
/**
* @var \alveolata\xml\struct_complex
*/
private $subject;
/**
*/
public function __construct(
struct_complex $subject
)
{
$this->subject = $subject;
}
/**
* @implementation
*/
public function find(
\Closure $sub,
\Closure $predicate,
?int $max_depth
) : array
{
return (
((! \is_null($max_depth)) && ($max_depth <= 0))
? []
: \alveolata\list_\reduce(
(
\is_null($this->subject->children)
? []
: \alveolata\list_\map(
$this->subject->children,
fn($child) => ($sub)(
$child,
$predicate,
(\is_null($max_depth) ? null : ($max_depth - 1))
)
)
),
(
($predicate)($this->subject)
? [$this->subject]
: []
),
fn($x, $y) => \array_merge($x, $y)
)
);
}
/**
* @implementation
*/
public function transform(
\Closure $sub,
\Closure $function
)
{
return ($function)(
new struct_complex(
$this->subject->name,
$this->subject->attributes,
(
\is_null($this->subject->children)
? null
: \alveolata\list_\map(
$this->subject->children,
fn($child) => ($sub)($child, $function)
)
)
)
);
}
/**
* @implementation
*/
public function to_raw(
\Closure $sub
)
{
return [
'kind' => 'complex',
'data' => [
'name' => $this->subject->name,
'attributes' => $this->subject->attributes,
'children' => (
\is_null($this->subject->children)
? null
: \alveolata\list_\map(
$this->subject->children,
fn($child) => ($sub)($child)
)
),
],
];
}
/**
* @implementation
*/
public function to_string(
\Closure $sub,
int $depth
) : string
{
return \alveolata\string\coin(
(
\is_null($this->subject->children)
? '<{{name}}{{attributes}}/>'
: '<{{name}}{{attributes}}>{{children}}</{{name}}>'
),
[
'name' => $this->subject->name,
'attributes' => \implode(
'',
\alveolata\list_\map(
\alveolata\list_\filter(
\array_keys($this->subject->attributes),
fn($key) => (! \is_null($this->subject->attributes[$key]))
),
fn($key) => \alveolata\string\coin(
' {{key}}="{{value}}"',
[
'key' => $key,
'value' => $this->subject->attributes[$key],
]
)
)
),
'children' => \implode(
'',
\alveolata\list_\map(
$this->subject->children,
fn($child) => ($sub)($child, ['depth' => ($depth + 1)])
)
),
]
);
}
}
?>