Completed
Push — master ( 6ae8fd...612217 )
by Ryosuke
03:27
created

Utils::isArrayLike()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 9.4285
cc 3
eloc 5
nc 3
nop 1
crap 3
1
<?php
2
3
namespace mpyw\Co\Internal;
4
5
use mpyw\Co\CoInterface;
6
use mpyw\Co\Internal\GeneratorContainer;
7
8
class Utils {
9
10
    /**
11
     * Recursively normalize value.
12
     *   Closure     -> Returned value
13
     *   Generator   -> GeneratorContainer
14
     *   Array       -> Array (children's are normalized)
15
     *   Traversable -> Array (children's are normalized)
16
     *   Others      -> Others
17
     * @param  mixed    $value
18
     * @param  CoOption $options
19
     * @param  mixed    $yield_key
20
     * @return mixed
21
     */
22 11
    public static function normalize($value, CoOption $options, $yield_key = null)
23 11
    {
24 11
        while ($value instanceof \Closure) {
25
            try {
26 11
                $value = $value();
27 4
            } catch (\RuntimeException $value) {
28 3
                if ($yield_key === CoInterface::UNSAFE ||
29 3
                    $yield_key !== CoInterface::SAFE && $options['throw']) {
30 2
                    throw $value;
31
                }
32
            }
33
        }
34 11
        if ($value instanceof \Generator) {
35 11
            return new GeneratorContainer($value, $options, $yield_key);
36
        }
37 9
        if (self::isArrayLike($value)) {
38 6
            $tmp = [];
39 6
            foreach ($value as $k => $v) {
40 6
                $tmp[$k] = self::normalize($v, $options, $yield_key);
41
            }
42 6
            return $tmp;
43
        }
44 9
        return $value;
45
    }
46
47
    /**
48
     * Recursively search yieldable values.
49
     * Each entries are assoc those contain keys 'value' and 'keylist'.
50
     *   value   -> the value itself.
51
     *   keylist -> position of the value. nests are represented as array values.
52
     * @param  mixed $value   Must be already normalized.
53
     * @param  array $keylist Internally used.
54
     * @return array
55
     */
56 9
    public static function getYieldables($value, array $keylist = [])
57 9
    {
58 9
        $r = [];
59 9
        if (!is_array($value)) {
60 9
            if (self::isCurl($value) || self::isGeneratorContainer($value)) {
61 8
                $r[(string)$value] = [
62 8
                    'value' => $value,
63 8
                    'keylist' => $keylist,
64
                ];
65
            }
66 9
            return $r;
67
        }
68 6
        foreach ($value as $k => $v) {
69 6
            $newlist = array_merge($keylist, [$k]);
70 6
            $r = array_merge($r, self::getYieldables($v, $newlist));
71
        }
72 6
        return $r;
73
    }
74
75
    /**
76
     * Check if value is a valid cURL handle.
77
     * @param  mixed $value
78
     * @return bool
79
     */
80 10
    public static function isCurl($value)
81 10
    {
82 2
        return is_resource($value) && get_resource_type($value) === 'curl';
83
    }
84
85
    /**
86
     * Check if value is a valid Generator.
87
     * @param  mixed $value
88
     * @return bool
89
     */
90 10
    public static function isGeneratorContainer($value)
91 10
    {
92 10
        return $value instanceof GeneratorContainer;
93
    }
94
95
    /**
96
     * Check if value is a valid array or Traversable, not a Generator.
97
     * @param  mixed $value
98
     * @return bool
99
     */
100 10
    public static function isArrayLike($value)
101 10
    {
102
        return
103 10
            $value instanceof \Traversable
104 2
            && !$value instanceof \Generator
105 10
            || is_array($value);
106
    }
107
108
}
109