1<?php
2
3declare(strict_types=1);
4
5/*
6 * This file is a part of dflydev/dot-access-data.
7 *
8 * (c) Dragonfly Development Inc.
9 *
10 * For the full copyright and license information, please view the LICENSE
11 * file that was distributed with this source code.
12 */
13
14namespace Dflydev\DotAccessData;
15
16class Util
17{
18    /**
19     * Test if array is an associative array
20     *
21     * Note that this function will return true if an array is empty. Meaning
22     * empty arrays will be treated as if they are associative arrays.
23     *
24     * @param array<mixed> $arr
25     *
26     * @return bool
27     *
28     * @psalm-pure
29     */
30    public static function isAssoc(array $arr): bool
31    {
32        return !count($arr) || count(array_filter(array_keys($arr), 'is_string')) == count($arr);
33    }
34
35    /**
36     * Merge contents from one associtative array to another
37     *
38     * @param mixed $to
39     * @param mixed $from
40     * @param DataInterface::PRESERVE|DataInterface::REPLACE|DataInterface::MERGE $mode
41     *
42     * @return mixed
43     *
44     * @psalm-pure
45     */
46    public static function mergeAssocArray($to, $from, int $mode = DataInterface::REPLACE)
47    {
48        if ($mode === DataInterface::MERGE && self::isList($to) && self::isList($from)) {
49            return array_merge($to, $from);
50        }
51
52        if (is_array($from) && is_array($to)) {
53            foreach ($from as $k => $v) {
54                if (!isset($to[$k])) {
55                    $to[$k] = $v;
56                } else {
57                    $to[$k] = self::mergeAssocArray($to[$k], $v, $mode);
58                }
59            }
60
61            return $to;
62        }
63
64        return $mode === DataInterface::PRESERVE ? $to : $from;
65    }
66
67    /**
68     * @param mixed $value
69     *
70     * @return bool
71     *
72     * @psalm-pure
73     */
74    private static function isList($value): bool
75    {
76        return is_array($value) && array_values($value) === $value;
77    }
78}
79