hallernsk/php-project-lvl2

View on GitHub
src/Formatters/Stylish.php

Summary

Maintainability
A
2 hrs
Test Coverage
A
98%
<?php

namespace Differ\Formatters\Stylish;

const BASE_INDENT = '    ';

function format(array $data): string
{
    $lines = formatToStylish($data);
    return '{' . PHP_EOL . implode(PHP_EOL, $lines) . PHP_EOL . '}';
}

function formatToStylish(array $diffTree, int $depth = 0): array
{
    $indent = getIndent($depth);
    $nextDepth = $depth + 1;
    $result = array_map(function ($node) use ($indent, $nextDepth): string {
        switch ($node['type']) {
            case 'deleted':
                $value = $node['value'];
                $formattedValue = toString($value, $nextDepth);
                return "{$indent}  - {$node['key']}: {$formattedValue}";

            case 'added':
                $value = $node['value'];
                $formattedValue = toString($value, $nextDepth);
                return "{$indent}  + {$node['key']}: {$formattedValue}";

            case 'unchanged':
                $value = $node['value'];
                $formattedValue = toString($value, $nextDepth);
                return "{$indent}    {$node['key']}: {$formattedValue}";

            case 'changed':
                $valueOld = $node['valueOld'];
                $formattedValueOld = toString($valueOld, $nextDepth);
                $valueNew = $node['valueNew'];
                $formattedValueNew = toString($valueNew, $nextDepth);
                return "{$indent}  - {$node['key']}: {$formattedValueOld}" . PHP_EOL .
                       "{$indent}  + {$node['key']}: {$formattedValueNew}";

            case 'nested':
                $stringNested = implode(PHP_EOL, formatToStylish($node['children'], $nextDepth));
                return "{$indent}    {$node['key']}: {" . PHP_EOL .
                     "{$stringNested}" . PHP_EOL . "{$indent}    }";

            default:
                throw new \Exception("Incorrect node type: {$node['type']}");
        }
    }, $diffTree);
    return $result;
}

function toString($value, int $depth): string
{
    if (is_bool($value)) {
        return $value ? 'true' : 'false';
    }

    if (is_null($value)) {
        return 'null';
    }

    if (is_array($value)) {
        $result = arrayToString($value, $depth);
        $indent = getIndent($depth);
        $bracketsResult = "{{$result}" . PHP_EOL . "{$indent}}";
        return $bracketsResult;
    }

    return "{$value}";
}

function arrayToString(array $arrayValue, int $depth): string
{
    $keys = array_keys($arrayValue);
    $inDepth = $depth + 1;
    $result = array_map(function ($key) use ($arrayValue, $inDepth): string {
        $val = toString($arrayValue[$key], $inDepth);
        $indent = getIndent($inDepth);
        $result = PHP_EOL . "{$indent}{$key}: {$val}";
        return $result;
    }, $keys);
    return implode('', $result);
}

function getIndent(int $multiplier): string
{
    return str_repeat(BASE_INDENT, $multiplier);
}