Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/macros/output/Hyperf/Collection/Arr.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@

class Arr
{
/**
* Determine whether the given value is arrayable.
*
* @param mixed $value
* @return bool
*/
public static function arrayable($value)
{
}

/**
* Get an array item from an array using "dot" notation.
* @return array
Expand Down Expand Up @@ -43,6 +53,21 @@ public static function float(ArrayAccess|array $array, string|int|null $key, ?fl
{
}

/**
* Get the underlying array of items from the given argument.
*
* @template TKey of array-key = array-key
* @template TValue = mixed
*
* @param array<TKey, TValue>|Enumerable<TKey, TValue>|Arrayable<TKey, TValue>|WeakMap<object, TValue>|Traversable<TKey, TValue>|Jsonable|JsonSerializable|object $items
* @return ($items is WeakMap ? list<TValue> : array<TKey, TValue>)
*
* @throws InvalidArgumentException
*/
public static function from($items)
{
}

/**
* Get an integer item from an array using "dot" notation.
* @return int
Expand Down
40 changes: 35 additions & 5 deletions src/macros/src/ArrMixin.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,29 @@

use ArrayAccess;
use Hyperf\Collection\Arr;
use Hyperf\Collection\Enumerable;
use Hyperf\Contract\Arrayable;
use Hyperf\Contract\Jsonable;
use InvalidArgumentException;
use JsonSerializable;
use Traversable;
use WeakMap;

/**
* @mixin Arr
*/
class ArrMixin
{
public static function array()
public function arrayable()
{
return fn ($value) => is_array($value)
|| $value instanceof Arrayable
|| $value instanceof Traversable
|| $value instanceof Jsonable
|| $value instanceof JsonSerializable;
}

public function array()
{
return function (ArrayAccess|array $array, string|int|null $key, ?array $default = null) {
$value = Arr::get($array, $key, $default);
Expand All @@ -38,7 +53,7 @@ public static function array()
/**
* Get a boolean item from an array using "dot" notation.
*/
public static function boolean()
public function boolean()
{
return function (ArrayAccess|array $array, string|int|null $key, ?bool $default = null) {
$value = Arr::get($array, $key, $default);
Expand All @@ -56,7 +71,7 @@ public static function boolean()
/**
* Get a float item from an array using "dot" notation.
*/
public static function float()
public function float()
{
return function (ArrayAccess|array $array, string|int|null $key, ?float $default = null) {
$value = Arr::get($array, $key, $default);
Expand All @@ -71,10 +86,25 @@ public static function float()
};
}

public function from()
{
return fn ($items) => match (true) {
is_array($items) => $items,
$items instanceof Enumerable => $items->all(),
$items instanceof Arrayable => $items->toArray(),
$items instanceof WeakMap => iterator_to_array($items, false),
$items instanceof Traversable => iterator_to_array($items),
$items instanceof Jsonable => json_decode($items->__toString(), true),
$items instanceof JsonSerializable => (array) $items->jsonSerialize(),
is_object($items) => (array) $items,
default => throw new InvalidArgumentException('Items cannot be represented by a scalar value.'),
};
}

/**
* Get an integer item from an array using "dot" notation.
*/
public static function integer()
public function integer()
{
return function (ArrayAccess|array $array, string|int|null $key, ?int $default = null) {
$value = Arr::get($array, $key, $default);
Expand All @@ -92,7 +122,7 @@ public static function integer()
/**
* Get a string item from an array using "dot" notation.
*/
public static function string()
public function string()
{
return function (ArrayAccess|array $array, string|int|null $key, ?string $default = null) {
$value = Arr::get($array, $key, $default);
Expand Down
45 changes: 45 additions & 0 deletions tests/Macros/ArrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@
*/
use Hyperf\Collection\Arr;

require_once __DIR__ . '/Stubs/Common.php';

test('test arrayable', function () {
$this->assertTrue(Arr::arrayable([]));
$this->assertTrue(Arr::arrayable(new FriendsOfHyperf\Tests\Macros\Stubs\TestArrayableObject()));
$this->assertTrue(Arr::arrayable(new FriendsOfHyperf\Tests\Macros\Stubs\TestJsonableObject()));
$this->assertTrue(Arr::arrayable(new FriendsOfHyperf\Tests\Macros\Stubs\TestJsonSerializeObject()));
$this->assertTrue(Arr::arrayable(new FriendsOfHyperf\Tests\Macros\Stubs\TestTraversableAndJsonSerializableObject()));

$this->assertFalse(Arr::arrayable(null));
$this->assertFalse(Arr::arrayable('abc'));
$this->assertFalse(Arr::arrayable(new stdClass()));
$this->assertFalse(Arr::arrayable((object) ['a' => 1, 'b' => 2]));
$this->assertFalse(Arr::arrayable(123));
$this->assertFalse(Arr::arrayable(12.34));
$this->assertFalse(Arr::arrayable(true));
$this->assertFalse(Arr::arrayable(new DateTime()));
$this->assertFalse(Arr::arrayable(static fn () => null));
});

test('test getsAString', function () {
$test_array = ['string' => 'foo bar', 'integer' => 1234];

Expand Down Expand Up @@ -73,6 +93,31 @@
Arr::float($test_array, 'string');
});

test('test from', function () {
$this->assertSame(['foo' => 'bar'], Arr::from(['foo' => 'bar']));
$this->assertSame(['foo' => 'bar'], Arr::from((object) ['foo' => 'bar']));
$this->assertSame(['foo' => 'bar'], Arr::from(new FriendsOfHyperf\Tests\Macros\Stubs\TestArrayableObject()));
$this->assertSame(['foo' => 'bar'], Arr::from(new FriendsOfHyperf\Tests\Macros\Stubs\TestJsonableObject()));
$this->assertSame(['foo' => 'bar'], Arr::from(new FriendsOfHyperf\Tests\Macros\Stubs\TestJsonSerializeObject()));
$this->assertSame(['foo'], Arr::from(new FriendsOfHyperf\Tests\Macros\Stubs\TestJsonSerializeWithScalarValueObject()));

$this->assertSame(['name' => 'A'], Arr::from(TestEnum::A));
$this->assertSame(['name' => 'A', 'value' => 1], Arr::from(TestBackedEnum::A));
$this->assertSame(['name' => 'A', 'value' => 'A'], Arr::from(TestStringBackedEnum::A));

$subject = [new stdClass(), new stdClass()];
$items = new FriendsOfHyperf\Tests\Macros\Stubs\TestTraversableAndJsonSerializableObject($subject);
$this->assertSame($subject, Arr::from($items));

$items = new WeakMap();
$items[$temp = new class {}] = 'bar';
$this->assertSame(['bar'], Arr::from($items));

$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Items cannot be represented by a scalar value.');
Arr::from(123);
});

test('test getsABoolean', function () {
$test_array = ['string' => 'foo bar', 'boolean' => true];

Expand Down
76 changes: 76 additions & 0 deletions tests/Macros/Stubs/Common.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);
/**
* This file is part of friendsofhyperf/components.
*
* @link https://github.com/friendsofhyperf/components
* @document https://github.com/friendsofhyperf/components/blob/main/README.md
* @contact huangdijia@gmail.com
*/

namespace FriendsOfHyperf\Tests\Macros\Stubs;

use ArrayIterator;
use Hyperf\Contract\Arrayable;
use Hyperf\Contract\Jsonable;
use IteratorAggregate;
use JsonSerializable;
use Traversable;

class TestArrayableObject implements Arrayable
{
public function toArray(): array
{
return ['foo' => 'bar'];
}
}

class TestJsonableObject implements Jsonable
{
public function __toString(): string
{
return '{"foo":"bar"}';
}

public function toJson($options = 0): string
{
return '{"foo":"bar"}';
}
}

class TestJsonSerializeObject implements JsonSerializable
{
public function jsonSerialize(): array
{
return ['foo' => 'bar'];
}
}

class TestJsonSerializeWithScalarValueObject implements JsonSerializable
{
public function jsonSerialize(): string
{
return 'foo';
}
}

class TestTraversableAndJsonSerializableObject implements IteratorAggregate, JsonSerializable
{
public $items;

public function __construct($items = [])
{
$this->items = $items;
}

public function getIterator(): Traversable
{
return new ArrayIterator($this->items);
}

public function jsonSerialize(): array
{
return json_decode(json_encode($this->items), true);
}
}