1 /// 2 module rxd.rx.example; 3 4 import std.stdio; 5 import std.traits : Parameters, ReturnType; 6 7 enum isObserver(O, E) = is(typeof(useObserver!(O, E)())); 8 9 enum isFunctionLike(F, This) = 10 is(typeof(F(Parameters!This.init)) : ReturnType!This); 11 12 void useObserver(O, E)() 13 { 14 alias OnNext = void delegate(E); 15 alias OnComplete = void delegate(); 16 alias OnError = void delegate(Exception); 17 18 static assert( isFunctionLike!(typeof(&O.init.onNext), OnNext)); 19 static assert( isFunctionLike!(typeof(&O.init.onComplete), OnComplete)); 20 static assert( isFunctionLike!(typeof(&O.init.onError), OnError)); 21 } 22 23 unittest 24 { 25 class ObserverClass 26 { 27 void onNext(int) { } 28 void onComplete() { } 29 void onError(Exception) { } 30 } 31 32 struct ObserverStruct 33 { 34 void onNext(double) const nothrow { } 35 void onComplete() @nogc pure { } 36 void onError(Exception) @safe const { } 37 } 38 39 useObserver!(ObserverClass, int)(); 40 useObserver!(ObserverStruct, double)(); 41 } 42 43 struct Result 44 { 45 alias OnNext = void delegate(int); 46 47 void subscribe(alias onNext)() 48 { 49 onNext(42); 50 } 51 52 void subscribe(O)(O observer) 53 if (isObserver!(O, int)) 54 { 55 observer.onNext(42); 56 } 57 } 58 59 auto createDummyObservable() 60 { 61 return Result.init; 62 } 63 64 unittest 65 { 66 67 // defines, but does not invoke, the Subscriber's onNext handler 68 // (in this example, the observer is very simple and has only 69 // an onNext handler) 70 alias myOnNext = (int x) => writeln(x); 71 72 // defines, but does not invoke, the Observable 73 auto myObservable = createDummyObservable(); 74 75 // subscribes the Subscriber to the Observable, and invokes the Observable 76 myObservable.subscribe!(myOnNext)(); 77 78 // go on about my business 79 }