InfluxOW/php-project-lvl2

View on GitHub
src/Ast.php

Summary

Maintainability
A
1 hr
Test Coverage
<?php

namespace Differ;

use Differ\Enums\AstKey;
use Differ\Enums\AstNodeType;

class Ast
{
    public static function genDiff(array $beforeData, array $afterData): array
    {
        $keys = array_unique(array_merge(array_keys($beforeData), array_keys($afterData)));

        return array_reduce($keys, static function ($acc, $key) use ($beforeData, $afterData): array {
            $valueBefore = $beforeData[$key] ?? null;
            $valueAfter = $afterData[$key] ?? null;

            if (!array_key_exists($key, $afterData)) {
                $acc[] = [AstKey::TYPE => AstNodeType::REMOVED, AstKey::KEY => $key, AstKey::VALUE_BEFORE => $valueBefore];
                return $acc;
            }

            if (!array_key_exists($key, $beforeData)) {
                $acc[] = [AstKey::TYPE => AstNodeType::ADDED, AstKey::KEY => $key, AstKey::VALUE_AFTER => $valueAfter];
                return $acc;
            }

            if (is_array($valueBefore) && is_array($valueAfter)) {
                $children = self::genDiff($valueBefore, $valueAfter);
                $acc[] = [
                    AstKey::TYPE => AstNodeType::NESTED,
                    AstKey::KEY => $key,
                    AstKey::VALUE_BEFORE => $valueBefore,
                    AstKey::VALUE_AFTER => $valueAfter,
                    AstKey::CHILDREN => $children
                ];
                return $acc;
            }

            if ($valueBefore === $valueAfter) {
                $acc[] = [AstKey::TYPE => AstNodeType::UNCHANGED, AstKey::KEY => $key, AstKey::VALUE_BEFORE => $valueBefore, AstKey::VALUE_AFTER => $valueAfter];
                return $acc;
            }

            $acc[] = [AstKey::TYPE => AstNodeType::CHANGED, AstKey::KEY => $key, AstKey::VALUE_BEFORE => $valueBefore, AstKey::VALUE_AFTER => $valueAfter];
            return $acc;
        }, []);
    }
}