Skip to content

Commit

Permalink
simple tree builder
Browse files Browse the repository at this point in the history
  • Loading branch information
dakujem committed Jan 14, 2024
1 parent 953632d commit 42dac2a
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions src/Simple/TreeBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace Dakujem\Oliva\Simple;

use Dakujem\Oliva\MovableNodeContract;
use Dakujem\Oliva\TreeNodeContract;
use LogicException;

/**
* Simple tree builder.
* Wraps data that is already structured into tree node classes.
*
* @author Andrej Rypak <[email protected]>
*/
class TreeBuilder
{
public function build(
mixed $data,
callable $node,
callable $children,
): TreeNodeContract {
return $this->buildNode(
data: $data,
nodeFactory: $node,
childrenExtractor: $children,
);
}

public function buildNode(
mixed $data,
callable $nodeFactory,
callable $childrenExtractor,
): MovableNodeContract {
// Create a node using the provided factory.
$node = $nodeFactory($data);

// Check for consistency.
if (!$node instanceof MovableNodeContract) {
// TODO improve exceptions
throw new LogicException('The node factory must return a movable node instance.');
}

$childrenData = $childrenExtractor($data, $node);
if (null !== $childrenData && !is_iterable($childrenData)) {
// TODO improve exceptions
throw new LogicException('Children data extractor must return an iterable collection containing children data.');
}
foreach ($childrenData ?? [] as $key => $childData) {
$child = $this->buildNode(
data: $childData,
nodeFactory: $nodeFactory,
childrenExtractor: $childrenExtractor,
);
$child->setParent($node);
$node->addChild($child, $key);
}
return $node;
}
}

0 comments on commit 42dac2a

Please sign in to comment.