/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="count"></param> /// <returns></returns> public static Observe <T> Take <T>(this Observe <T> source, int count) { return(o => { bool completed = false; int counter = 0; source(x => { if (completed) { return; } if (!x.HasValue) { completed = true; o(x); return; } if (counter < count) { o(x); } else { completed = true; o(new None <T>()); return; } counter++; }); }); }
/// <summary> /// /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TResult"></typeparam> /// <param name="source"></param> /// <param name="selector"></param> /// <returns></returns> public static Observe <TResult> TrySelect <TSource, TResult>(this Observe <TSource> source, Func <TSource, TResult> selector) { return(o => source(x => { if (!x.HasValue) { o(x.TransposeEmpty <TResult>()); } else { TResult result; try { result = selector(x.Value); } catch (Exception ex) { o(new Error <TResult>(ex)); return; } o(new Some <TResult>(result)); } })); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TException"></typeparam> /// <param name="source"></param> /// <param name="handler"></param> /// <returns></returns> public static Observe <T> Catch <T, TException>(this Observe <T> source, Func <TException, Observe <T> > handler) where TException : Exception { return(o => { bool completed = false; source( v => { if (completed) { return; } if (v is Error <T> ) { var error = (Error <T>)v; if (error.Exception is TException) { completed = true; handler((TException)error.Exception)(o); return; } } else if (!v.HasValue) { completed = true; } o(v); }); }); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="secondSources"></param> /// <returns></returns> public static Observe <T> Merge <T>(this Observe <T> source, params Observe <T>[] secondSources) { return(o => { source(o); foreach (var secondSource in secondSources) { secondSource(o); } }); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="secondSource"></param> /// <returns></returns> public static Observe <T> Concat <T>(this Observe <T> source, Observe <T> secondSource) { return(o => source(x => { if (x is None <T> ) { secondSource(o); } else { o(x); } })); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="onNext"></param> /// <param name="onError"></param> public static void Subscribe <T>(this Observe <T> source, Action <T> onNext, Action <Exception> onError) { source( result => { if (result is Error <T> ) { onError(((Error <T>)result).Exception); } else if (result is Some <T> ) { onNext(result.Value); } }); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="scheduler"></param> /// <returns></returns> public static Observe <T> SubscribeOn <T>(this Observe <T> source, ScheduleAction scheduler) { return(o => { IDisposable disposable = null; disposable = scheduler(() => source.Finally(() => { if (disposable != null) { disposable.Dispose(); } })(o)); }); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="scheduler"></param> /// <returns></returns> public static Observe <T> ObserveOn <T>(this Observe <T> source, ScheduleAction scheduler) { // TODO: Verify this as I don't think it's correct. return(o => source(value => { IDisposable disposable = null; disposable = scheduler(() => { o(value); if (disposable != null) { disposable.Dispose(); } }); })); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static Observe <T> DefaultIfEmpty <T>(this Observe <T> source, T defaultValue) { bool isEmpty = true; return(o => source(t => { if (!isEmpty) { o(t); } if (!(t is None <T>)) { isEmpty = false; } o(isEmpty ? new Some <T>(defaultValue) : t); })); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <returns></returns> public static Observe <List <T> > ToList <T>(this Observe <T> source) { var result = new List <T>(); return(o => source( v => { if (v is Error <T> ) { o(v.TransposeEmpty <List <T> >()); } else if (v is None <T> ) { o(new Some <List <T> >(result)); } else { result.Add(v.Value); } })); }
/// <summary> /// /// </summary> /// <typeparam name="TOuter"></typeparam> /// <typeparam name="TInner"></typeparam> /// <param name="source"></param> /// <param name="innerSource"></param> /// <returns></returns> public static Observe <TInner> SelectMany <TOuter, TInner>(this Observe <TOuter> source, Func <TOuter, Observe <TInner> > innerSource) { return(o => source(x => { if (!x.HasValue) { o(x.TransposeEmpty <TInner>()); } else { innerSource(x.Value)( y => { if (y is Some <TInner> ) { o(y); } }); } })); }
/// <summary> /// /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TResult"></typeparam> /// <param name="source"></param> /// <param name="selector"></param> /// <returns></returns> public static Observe <TResult> Select <TSource, TResult>(this Observe <TSource> source, Func <TSource, int, TResult> selector) { return(o => { bool completed = false; int counter = 0; source( x => { if (completed) { return; } if (!x.HasValue) { completed = true; o(x.TransposeEmpty <TResult>()); } else { TResult result; try { result = selector(x.Value, counter); } catch (Exception ex) { completed = true; o(new Error <TResult>(ex)); return; } o(new Some <TResult>(result)); counter++; } }); }); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="completionOrError"></param> /// <returns></returns> public static Observe <T> Finally <T>(this Observe <T> source, Action completionOrError) { return(o => { bool completed = false; source( result => { if (completed) { return; } o(result); if (!result.HasValue) { completed = true; completionOrError(); } }); }); }
/// <summary> /// Takes an Enumerable{T} and a Function that takes each T and converts to an Enumerable{C} then /// combines the results and returns an enumerable of TResult /// </summary> /// <typeparam name="TOuter"></typeparam> /// <typeparam name="TInner"></typeparam> /// <typeparam name="TResult"></typeparam> /// <param name="source"></param> /// <param name="innerSource"></param> /// <param name="selector"></param> /// <returns></returns> public static Observe <TResult> SelectMany <TOuter, TInner, TResult>(this Observe <TOuter> source, Func <TOuter, Observe <TInner> > innerSource, Func <TOuter, TInner, TResult> selector) { return(o => source( outerSet => { if (!outerSet.HasValue) { o(outerSet.TransposeEmpty <TResult>()); } else { var innerSet = innerSource(outerSet.Value); innerSet( innerValue => { if (innerValue is Some <TInner> ) { o(new Some <TResult>(selector(outerSet.Value, innerValue.Value))); } }); } })); }
/// <summary> /// /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="source"></param> /// <returns></returns> public static Observe <TSource> Do <TSource>(this Observe <TSource> source, Action <TSource> onNext) { return(o => { bool completed = false; source( x => { if (completed) { return; } if (!x.HasValue) { completed = true; o(x); } else { try { onNext(x.Value); } catch (Exception ex) { completed = true; o(new Error <TSource>(ex)); return; } o(x); } }); }); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TFinal"></typeparam> /// <param name="source"></param> /// <param name="other"></param> /// <returns></returns> public static Observe <T> TakeUntil <T, TFinal>(this Observe <T> source, Observe <TFinal> other) { return(o => { bool completed = false; other(v => { if (completed) { return; } if (v.HasValue) { completed = true; o(new None <T>()); } }); source(x => { if (completed) { return; } if (!x.HasValue) { completed = true; o(x); return; } o(x); }); }); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="filter"></param> /// <returns></returns> public static Observe <T> Where <T>(this Observe <T> source, Func <T, bool> filter) { return(source.SelectMany(t => filter(t) ? Return(t) : Empty <T>())); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <returns></returns> public static Observe <T> DefaultIfEmpty <T>(this Observe <T> source) { return(source.DefaultIfEmpty(default(T))); }