// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
#pragma warning disable 1591
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive.Concurrency;
using System.Reflection;
namespace System.Reactive.Linq
{
///
/// Provides a set of static methods for writing queries over observable sequences, allowing translation to a target query language.
///
public static partial class Qbservable
{
///
/// Returns the input typed as an .
/// This operator is used to separate the part of the query that's captured as an expression tree from the part that's executed locally.
///
/// The type of the elements in the source sequence.
/// An sequence to convert to an sequence.
/// The original source object, but typed as an .
/// is null.
public static IObservable AsObservable(this IQbservable source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
return source;
}
///
/// Converts an enumerable sequence to an observable sequence.
///
/// The type of the elements in the source sequence.
/// Enumerable sequence to convert to an observable sequence.
/// The observable sequence whose elements are pulled from the given enumerable sequence.
/// is null.
/// This operator requires the source's object (see ) to implement .
public static IQbservable ToQbservable(this IQueryable source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
return ((IQbservableProvider)source.Provider).CreateQuery(
Expression.Call(
null,
#if CRIPPLED_REFLECTION
InfoOf(() => ToQbservable(default)),
#else
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
#endif
source.Expression
)
);
}
///
/// Converts an enumerable sequence to an observable sequence, using the specified scheduler to run the enumeration loop.
///
/// The type of the elements in the source sequence.
/// Enumerable sequence to convert to an observable sequence.
/// Scheduler to run the enumeration of the input sequence on.
/// The observable sequence whose elements are pulled from the given enumerable sequence.
/// or is null.
/// This operator requires the source's object (see ) to implement .
public static IQbservable ToQbservable(this IQueryable source, IScheduler scheduler)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (scheduler == null)
{
throw new ArgumentNullException(nameof(scheduler));
}
return ((IQbservableProvider)source.Provider).CreateQuery(
Expression.Call(
null,
#if CRIPPLED_REFLECTION
InfoOf(() => ToQbservable(default)),
#else
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
#endif
source.Expression,
Expression.Constant(scheduler)
)
);
}
internal static Expression GetSourceExpression(IObservable source)
{
if (source is IQbservable q)
{
return q.Expression;
}
return Expression.Constant(source, typeof(IObservable));
}
internal static Expression GetSourceExpression(IEnumerable source)
{
if (source is IQueryable q)
{
return q.Expression;
}
return Expression.Constant(source, typeof(IEnumerable));
}
internal static Expression GetSourceExpression(IObservable[] sources)
{
return Expression.NewArrayInit(
typeof(IObservable),
sources.Select(source => GetSourceExpression(source))
);
}
internal static Expression GetSourceExpression(IEnumerable[] sources)
{
return Expression.NewArrayInit(
typeof(IEnumerable),
sources.Select(source => GetSourceExpression(source))
);
}
internal static MethodInfo InfoOf(Expression> f)
{
return ((MethodCallExpression)f.Body).Method;
}
}
}
#pragma warning restore 1591