Skip to content

Commit

Permalink
Wrap error handling around other iterable types
Browse files Browse the repository at this point in the history
  • Loading branch information
veewee committed Mar 29, 2024
1 parent 2c5fcd7 commit b624e57
Show file tree
Hide file tree
Showing 18 changed files with 1,054 additions and 181 deletions.
66 changes: 48 additions & 18 deletions src/Psl/Type/Internal/IterableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Psl\Type;
use Psl\Type\Exception\AssertException;
use Psl\Type\Exception\CoercionException;
use Psl\Type\Exception\PathExpression;
use Throwable;

use function is_iterable;

Expand Down Expand Up @@ -48,15 +50,31 @@ public function coerce(mixed $value): iterable
/** @var list<array{Tk, Tv}> $entries */
$entries = [];

/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$entries[] = [
$key_type->coerce($k),
$value_type->coerce($v),
];
$k = $v = null;
$trying_key = true;
$iterating = true;

try {
/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$iterating = false;
$trying_key = true;
$k_result = $key_type->coerce($k);
$trying_key = false;
$v_result = $value_type->coerce($v);

$entries[] = [$k_result, $v_result];
$iterating = true;
}
} catch (Throwable $e) {
throw match (true) {
$iterating => CoercionException::withValue(null, $this->toString(), PathExpression::iteratorError($k), $e),
$trying_key => CoercionException::withValue($k, $this->toString(), PathExpression::iteratorKey($k), $e),
!$trying_key => CoercionException::withValue($v, $this->toString(), PathExpression::path($k), $e)
};
}

/** @var iterable<Tk, Tv> */
Expand Down Expand Up @@ -88,15 +106,27 @@ public function assert(mixed $value): iterable
/** @var list<array{Tk, Tv}> $entries */
$entries = [];

/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$entries[] = [
$key_type->assert($k),
$value_type->assert($v),
];
$k = $v = null;
$trying_key = true;

try {
/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$trying_key = true;
$k_result = $key_type->assert($k);
$trying_key = false;
$v_result = $value_type->assert($v);

$entries[] = [$k_result, $v_result];
}
} catch (AssertException $e) {
throw match ($trying_key) {
true => AssertException::withValue($k, $this->toString(), PathExpression::iteratorKey($k), $e),
false => AssertException::withValue($v, $this->toString(), PathExpression::path($k), $e)
};
}

/** @var iterable<Tk, Tv> */
Expand Down
68 changes: 50 additions & 18 deletions src/Psl/Type/Internal/MapType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
use Psl\Type;
use Psl\Type\Exception\AssertException;
use Psl\Type\Exception\CoercionException;
use Psl\Type\Exception\PathExpression;
use Throwable;

use function is_iterable;
use function is_object;
Expand Down Expand Up @@ -49,15 +51,33 @@ public function coerce(mixed $value): Collection\MapInterface

/** @var list<array{Tk, Tv}> $entries */
$entries = [];
/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$entries[] = [
$key_type->coerce($k),
$value_type->coerce($v),
];


$k = $v = null;
$trying_key = true;
$iterating = true;

try {
/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$iterating = false;
$trying_key = true;
$k_result = $key_type->coerce($k);
$trying_key = false;
$v_result = $value_type->coerce($v);

$entries[] = [$k_result, $v_result];
$iterating = true;
}
} catch (Throwable $e) {
throw match (true) {
$iterating => CoercionException::withValue(null, $this->toString(), PathExpression::iteratorError($k), $e),
$trying_key => CoercionException::withValue($k, $this->toString(), PathExpression::iteratorKey($k), $e),
!$trying_key => CoercionException::withValue($v, $this->toString(), PathExpression::path($k), $e)
};
}

/** @var Collection\Map<Tk, Tv> */
Expand Down Expand Up @@ -85,15 +105,27 @@ public function assert(mixed $value): Collection\MapInterface
/** @var list<array{Tk, Tv}> $entries */
$entries = [];

/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$entries[] = [
$key_type->assert($k),
$value_type->assert($v),
];
$k = $v = null;
$trying_key = true;

try {
/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$trying_key = true;
$k_result = $key_type->assert($k);
$trying_key = false;
$v_result = $value_type->assert($v);

$entries[] = [$k_result, $v_result];
}
} catch (AssertException $e) {
throw match ($trying_key) {
true => AssertException::withValue($k, $this->toString(), PathExpression::iteratorKey($k), $e),
false => AssertException::withValue($v, $this->toString(), PathExpression::path($k), $e)
};
}

/** @var Collection\Map<Tk, Tv> */
Expand Down
30 changes: 22 additions & 8 deletions src/Psl/Type/Internal/MixedDictType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Psl\Type;
use Psl\Type\Exception\AssertException;
use Psl\Type\Exception\CoercionException;
use Psl\Type\Exception\PathExpression;
use Throwable;

/**
* @extends Type\Type<array<array-key, mixed>>
Expand All @@ -33,17 +35,29 @@ public function coerce(mixed $value): array
$result = [];

$key_type = Type\array_key();
$k = null;
$iterating = true;

/**
* @var array-key $k
* @var mixed $v
*
* @psalm-suppress MixedAssignment
*/
foreach ($value as $k => $v) {
$result[$key_type->coerce($k)] = $v;
try {
/**
* @var array-key $k
* @var mixed $v
*
* @psalm-suppress MixedAssignment
*/
foreach ($value as $k => $v) {
$iterating = false;
$result[$key_type->coerce($k)] = $v;
$iterating = true;
}
} catch (Throwable $e) {
throw match (true) {
$iterating => CoercionException::withValue(null, $this->toString(), PathExpression::iteratorError($k), $e),
default => CoercionException::withValue($k, $this->toString(), PathExpression::iteratorKey($k), $e),
};
}


return $result;
}

Expand Down
67 changes: 48 additions & 19 deletions src/Psl/Type/Internal/MutableMapType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
use Psl\Type;
use Psl\Type\Exception\AssertException;
use Psl\Type\Exception\CoercionException;
use Psl\Type\Exception\PathExpression;
use Throwable;

use function is_iterable;
use function is_object;
Expand Down Expand Up @@ -50,17 +52,32 @@ public function coerce(mixed $value): Collection\MutableMapInterface
/** @var list<array{Tk, Tv}> $entries */
$entries = [];

/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$entries[] = [
$key_type->coerce($k),
$value_type->coerce($v),
];
$k = $v = null;
$trying_key = true;
$iterating = true;

try {
/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$iterating = false;
$trying_key = true;
$k_result = $key_type->coerce($k);
$trying_key = false;
$v_result = $value_type->coerce($v);

$entries[] = [$k_result, $v_result];
$iterating = true;
}
} catch (Throwable $e) {
throw match (true) {
$iterating => CoercionException::withValue(null, $this->toString(), PathExpression::iteratorError($k), $e),
$trying_key => CoercionException::withValue($k, $this->toString(), PathExpression::iteratorKey($k), $e),
!$trying_key => CoercionException::withValue($v, $this->toString(), PathExpression::path($k), $e)
};
}

$dict = Dict\from_entries($entries);

/** @var Collection\MutableMap<Tk, Tv> */
Expand Down Expand Up @@ -88,15 +105,27 @@ public function assert(mixed $value): Collection\MutableMapInterface
/** @var list<array{Tk, Tv}> $entries */
$entries = [];

/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$entries[] = [
$key_type->assert($k),
$value_type->assert($v),
];
$k = $v = null;
$trying_key = true;

try {
/**
* @var Tk $k
* @var Tv $v
*/
foreach ($value as $k => $v) {
$trying_key = true;
$k_result = $key_type->assert($k);
$trying_key = false;
$v_result = $value_type->assert($v);

$entries[] = [$k_result, $v_result];
}
} catch (AssertException $e) {
throw match ($trying_key) {
true => AssertException::withValue($k, $this->toString(), PathExpression::iteratorKey($k), $e),
false => AssertException::withValue($v, $this->toString(), PathExpression::path($k), $e)
};
}

$dict = Dict\from_entries($entries);
Expand Down
44 changes: 32 additions & 12 deletions src/Psl/Type/Internal/MutableVectorType.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Psl\Type;
use Psl\Type\Exception\AssertException;
use Psl\Type\Exception\CoercionException;
use Psl\Type\Exception\PathExpression;
use Throwable;

use function is_iterable;
use function is_object;
Expand Down Expand Up @@ -45,12 +47,24 @@ public function coerce(mixed $value): Collection\MutableVectorInterface
* @var list<T> $values
*/
$values = [];

/**
* @var T $v
*/
foreach ($value as $v) {
$values[] = $value_type->coerce($v);
$i = $v = null;
$iterating = true;

try {
/**
* @var T $v
* @var array-key $i
*/
foreach ($value as $i => $v) {
$iterating = false;
$values[] = $value_type->coerce($v);
$iterating = true;
}
} catch (Throwable $e) {
throw match (true) {
$iterating => CoercionException::withValue(null, $this->toString(), PathExpression::iteratorError($i), $e),
default => CoercionException::withValue($v, $this->toString(), PathExpression::path($i), $e)
};
}

/** @var Collection\MutableVector<T> */
Expand All @@ -77,12 +91,18 @@ public function assert(mixed $value): Collection\MutableVectorInterface
* @var list<T> $values
*/
$values = [];

/**
* @var T $v
*/
foreach ($value as $v) {
$values[] = $value_type->coerce($v);
$i = $v = null;

try {
/**
* @var T $v
* @var array-key $i
*/
foreach ($value as $i => $v) {
$values[] = $value_type->assert($v);
}
} catch (AssertException $e) {
throw AssertException::withValue($v, $this->toString(), PathExpression::path($i), $e);
}

/** @var Collection\MutableVector<T> */
Expand Down
Loading

0 comments on commit b624e57

Please sign in to comment.