// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive.Joins;
using System.Reflection;
namespace System.Reactive.Linq
{
public static partial class Qbservable
{
/* NOTE: Keep XML docs consistent with the corresponding Observable methods (modulo the IQbservableProvider parameters of course). */
///
/// Creates a pattern that matches when both observable sequences have an available element.
///
/// The type of the elements in the left sequence.
/// The type of the elements in the right sequence.
/// Observable sequence to match with the right sequence.
/// Observable sequence to match with the left sequence.
/// Pattern object that matches when both observable sequences have an available element.
/// or is null.
public static QueryablePattern And(this IQbservable left, IObservable right)
{
if (left == null)
{
throw new ArgumentNullException(nameof(left));
}
if (right == null)
{
throw new ArgumentNullException(nameof(right));
}
return new QueryablePattern(
Expression.Call(
null,
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TLeft), typeof(TRight)),
#pragma warning restore IL2060
left.Expression,
GetSourceExpression(right)
)
);
}
///
/// Matches when the observable sequence has an available element and projects the element by invoking the selector function.
///
/// The type of the elements in the source sequence.
/// The type of the elements in the result sequence, returned by the selector function.
/// Observable sequence to apply the selector on.
/// Selector that will be invoked for elements in the source sequence.
/// Plan that produces the projected results, to be fed (with other plans) to the When operator.
/// or is null.
public static QueryablePlan Then(this IQbservable source, Expression> selector)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (selector == null)
{
throw new ArgumentNullException(nameof(selector));
}
return new QueryablePlan(
Expression.Call(
null,
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TSource), typeof(TResult)),
#pragma warning restore IL2060
source.Expression,
selector
)
);
}
///
/// Joins together the results from several patterns.
///
/// The type of the elements in the result sequence, obtained from the specified patterns.
/// Query provider used to construct the data source.
/// A series of plans created by use of the Then operator on patterns.
/// An observable sequence with the results from matching several patterns.
/// or is null.
public static IQbservable When(this IQbservableProvider provider, params QueryablePlan[] plans)
{
if (provider == null)
{
throw new ArgumentNullException(nameof(provider));
}
if (plans == null)
{
throw new ArgumentNullException(nameof(plans));
}
return provider.CreateQuery(
Expression.Call(
null,
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TResult)),
#pragma warning restore IL2060
Expression.Constant(provider, typeof(IQbservableProvider)),
Expression.NewArrayInit(
typeof(QueryablePlan),
plans.Select(p => p.Expression)
)
)
);
}
///
/// Joins together the results from several patterns.
///
/// The type of the elements in the result sequence, obtained from the specified patterns.
/// Query provider used to construct the data source.
/// A series of plans created by use of the Then operator on patterns.
/// An observable sequence with the results form matching several patterns.
/// or is null.
public static IQbservable When(this IQbservableProvider provider, IEnumerable> plans)
{
if (provider == null)
{
throw new ArgumentNullException(nameof(provider));
}
if (plans == null)
{
throw new ArgumentNullException(nameof(plans));
}
return provider.CreateQuery(
Expression.Call(
null,
#pragma warning disable IL2060 // ('System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed.) This gets the MethodInfo for the method running right now, so it can't have been trimmed
((MethodInfo)MethodBase.GetCurrentMethod()!).MakeGenericMethod(typeof(TResult)),
#pragma warning restore IL2060
Expression.Constant(provider, typeof(IQbservableProvider)),
Expression.Constant(plans, typeof(IEnumerable>))
)
);
}
}
}