aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/event/lib/coroutine.php
diff options
context:
space:
mode:
authorredmatrix <git@macgirvin.com>2016-05-10 17:26:44 -0700
committerredmatrix <git@macgirvin.com>2016-05-10 17:26:44 -0700
commit0b02a6d123b2014705998c94ddf3d460948d3eac (patch)
tree78ff2cab9944a4f5ab3f80ec93cbe1120de90bb2 /vendor/sabre/event/lib/coroutine.php
parent40b5b6e9d2da7ab65c8b4d38cdceac83a4d78deb (diff)
downloadvolse-hubzilla-0b02a6d123b2014705998c94ddf3d460948d3eac.tar.gz
volse-hubzilla-0b02a6d123b2014705998c94ddf3d460948d3eac.tar.bz2
volse-hubzilla-0b02a6d123b2014705998c94ddf3d460948d3eac.zip
initial sabre upgrade (needs lots of work - to wit: authentication, redo the browser interface, and rework event export/import)
Diffstat (limited to 'vendor/sabre/event/lib/coroutine.php')
-rw-r--r--vendor/sabre/event/lib/coroutine.php120
1 files changed, 120 insertions, 0 deletions
diff --git a/vendor/sabre/event/lib/coroutine.php b/vendor/sabre/event/lib/coroutine.php
new file mode 100644
index 000000000..19c0ba8a7
--- /dev/null
+++ b/vendor/sabre/event/lib/coroutine.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Sabre\Event;
+
+use Generator;
+use Exception;
+
+/**
+ * Turn asynchronous promise-based code into something that looks synchronous
+ * again, through the use of generators.
+ *
+ * Example without coroutines:
+ *
+ * $promise = $httpClient->request('GET', '/foo');
+ * $promise->then(function($value) {
+ *
+ * return $httpClient->request('DELETE','/foo');
+ *
+ * })->then(function($value) {
+ *
+ * return $httpClient->request('PUT', '/foo');
+ *
+ * })->error(function($reason) {
+ *
+ * echo "Failed because: $reason\n";
+ *
+ * });
+ *
+ * Example with coroutines:
+ *
+ * coroutine(function() {
+ *
+ * try {
+ * yield $httpClient->request('GET', '/foo');
+ * yield $httpClient->request('DELETE', /foo');
+ * yield $httpClient->request('PUT', '/foo');
+ * } catch(\Exception $reason) {
+ * echo "Failed because: $reason\n";
+ * }
+ *
+ * });
+ *
+ * @copyright Copyright (C) 2013-2015 fruux GmbH. All rights reserved.
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+function coroutine(callable $gen) {
+
+ $generator = $gen();
+ if (!$generator instanceof Generator) {
+ throw new \InvalidArgumentException('You must pass a generator function');
+ }
+
+ // This is the value we're returning.
+ $promise = new Promise();
+
+ $lastYieldResult = null;
+
+ /**
+ * So tempted to use the mythical y-combinator here, but it's not needed in
+ * PHP.
+ */
+ $advanceGenerator = function() use (&$advanceGenerator, $generator, $promise, &$lastYieldResult) {
+
+ while ($generator->valid()) {
+
+ $yieldedValue = $generator->current();
+ if ($yieldedValue instanceof Promise) {
+ $yieldedValue->then(
+ function($value) use ($generator, &$advanceGenerator, &$lastYieldResult) {
+ $lastYieldResult = $value;
+ $generator->send($value);
+ $advanceGenerator();
+ },
+ function($reason) use ($generator, $advanceGenerator) {
+ if ($reason instanceof Exception) {
+ $generator->throw($reason);
+ } elseif (is_scalar($reason)) {
+ $generator->throw(new Exception($reason));
+ } else {
+ $type = is_object($reason) ? get_class($reason) : gettype($reason);
+ $generator->throw(new Exception('Promise was rejected with reason of type: ' . $type));
+ }
+ $advanceGenerator();
+ }
+ )->error(function($reason) use ($promise) {
+ // This error handler would be called, if something in the
+ // generator throws an exception, and it's not caught
+ // locally.
+ $promise->reject($reason);
+ });
+ // We need to break out of the loop, because $advanceGenerator
+ // will be called asynchronously when the promise has a result.
+ break;
+ } else {
+ // If the value was not a promise, we'll just let it pass through.
+ $lastYieldResult = $yieldedValue;
+ $generator->send($yieldedValue);
+ }
+
+ }
+
+ // If the generator is at the end, and we didn't run into an exception,
+ // we can fullfill the promise with the last thing that was yielded to
+ // us.
+ if (!$generator->valid() && $promise->state === Promise::PENDING) {
+ $promise->fulfill($lastYieldResult);
+ }
+
+ };
+
+ try {
+ $advanceGenerator();
+ } catch (Exception $e) {
+ $promise->reject($e);
+ }
+
+ return $promise;
+
+}