2020-03-10 21:55:34 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Capnp.Rpc
|
2019-06-12 21:56:55 +02:00
|
|
|
|
{
|
|
|
|
|
static class ResolvingCapabilityExtensions
|
|
|
|
|
{
|
2020-03-31 22:01:43 +02:00
|
|
|
|
public static async Task<ConsumedCapability?> Unwrap(this ConsumedCapability? cap)
|
2020-03-29 00:07:16 +01:00
|
|
|
|
{
|
|
|
|
|
while (cap is IResolvingCapability resolving)
|
|
|
|
|
{
|
2020-03-31 22:01:43 +02:00
|
|
|
|
cap = await resolving.WhenResolved;
|
2020-03-29 00:07:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cap;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 13:27:46 +01:00
|
|
|
|
public static Action? ExportAsSenderPromise<T>(this T cap, IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
|
2019-06-12 21:56:55 +02:00
|
|
|
|
where T: ConsumedCapability, IResolvingCapability
|
|
|
|
|
{
|
|
|
|
|
var vine = Vine.Create(cap);
|
|
|
|
|
uint preliminaryId = endpoint.AllocateExport(vine, out bool first);
|
|
|
|
|
|
|
|
|
|
writer.which = CapDescriptor.WHICH.SenderPromise;
|
|
|
|
|
writer.SenderPromise = preliminaryId;
|
|
|
|
|
|
|
|
|
|
if (first)
|
|
|
|
|
{
|
2020-03-21 13:27:46 +01:00
|
|
|
|
return async () => {
|
2019-06-12 21:56:55 +02:00
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2020-03-29 00:07:16 +01:00
|
|
|
|
var resolvedCap = await Unwrap(await cap.WhenResolved);
|
2020-03-10 21:55:34 +01:00
|
|
|
|
endpoint.Resolve(preliminaryId, vine, () => resolvedCap!);
|
2019-06-12 21:56:55 +02:00
|
|
|
|
}
|
|
|
|
|
catch (System.Exception exception)
|
|
|
|
|
{
|
|
|
|
|
endpoint.Resolve(preliminaryId, vine, () => throw exception);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 13:27:46 +01:00
|
|
|
|
};
|
2019-06-12 21:56:55 +02:00
|
|
|
|
}
|
2020-03-21 13:27:46 +01:00
|
|
|
|
|
|
|
|
|
return null;
|
2019-06-12 21:56:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-22 00:12:50 +01:00
|
|
|
|
public static async Task<Proxy> AsProxyTask<T>(this Task<T> task)
|
|
|
|
|
where T: IDisposable?
|
2019-06-12 21:56:55 +02:00
|
|
|
|
{
|
2020-03-22 00:12:50 +01:00
|
|
|
|
IDisposable? obj;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
obj = await task;
|
|
|
|
|
}
|
|
|
|
|
catch (TaskCanceledException exception)
|
|
|
|
|
{
|
|
|
|
|
return new Proxy(LazyCapability.CreateCanceledCap(exception.CancellationToken));
|
|
|
|
|
}
|
|
|
|
|
catch (System.Exception exception)
|
|
|
|
|
{
|
|
|
|
|
return new Proxy(LazyCapability.CreateBrokenCap(exception.Message));
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 13:27:46 +01:00
|
|
|
|
switch (obj)
|
|
|
|
|
{
|
|
|
|
|
case Proxy proxy: return proxy;
|
2020-03-31 22:01:43 +02:00
|
|
|
|
case null: return new Proxy(null);
|
2020-03-21 13:27:46 +01:00
|
|
|
|
default: return BareProxy.FromImpl(obj);
|
|
|
|
|
}
|
2019-06-12 21:56:55 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-01-11 17:56:12 +01:00
|
|
|
|
}
|