public function testNested()
 {
     $keyMatcher = key_matcher(['article' => ['id' => ':number', 'title' => ':string']]);
     $this->assertFalse($keyMatcher());
     $this->assertFalse($keyMatcher('article', 1));
     $this->assertFalse($keyMatcher('article', []));
     $this->assertFalse($keyMatcher('article', ['id' => 1, 'title' => 1]));
     $this->assertTrue($keyMatcher('article', ['id' => 1, 'title' => 'some title']));
     $this->assertTrue($keyMatcher());
 }
/**
 * Returns true if $value matches $pattern
 *
 * @param $value
 * @param $pattern
 *
 * @return bool
 *
 * @see https://github.com/ptrofimov/matchmaker - ultra-fresh PHP matching functions
 * @author Petr Trofimov <*****@*****.**>
 */
function matches($value, $pattern)
{
    require_once 'key_matcher.php';
    if (is_array($pattern)) {
        if (!is_array($value) && !$value instanceof \Traversable) {
            return false;
        }
        $keyMatcher = key_matcher($pattern);
        foreach ($value as $key => $item) {
            if (!$keyMatcher($key, $item)) {
                return false;
            }
        }
        if (!$keyMatcher()) {
            return false;
        }
    } elseif (!matcher($value, $pattern)) {
        return false;
    }
    return true;
}