Created
September 22, 2013 10:01
-
-
Save arturaz/6658547 to your computer and use it in GitHub Desktop.
Simple ADT matcher in C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace Utils.Match { | |
public interface IMatcher<in Base, Return> where Base : class { | |
IMatcher<Base, Return> when<T>(Func<T, Return> onMatch) | |
where T : class, Base; | |
Return get(); | |
Return getOrElse(Func<Return> elseFunc); | |
} | |
public class MatchError : Exception { | |
public MatchError(string message) : base(message) {} | |
} | |
public class Matcher<Base, Return> : IMatcher<Base, Return> | |
where Base : class { | |
private readonly Base subject; | |
public Matcher(Base subject) { | |
this.subject = subject; | |
} | |
public IMatcher<Base, Return> when<T>(Func<T, Return> onMatch) | |
where T : class, Base { | |
var casted = subject as T; | |
if (casted != null) | |
return new SuccessfulMatcher<Base, Return>(onMatch.Invoke(casted)); | |
return this; | |
} | |
public Return get() { | |
throw new MatchError(string.Format( | |
"Subject {0} of type {1} couldn't be matched!", subject, typeof(Base) | |
)); | |
} | |
public Return getOrElse(Func<Return> elseFunc) { return elseFunc.Invoke(); } | |
} | |
public class SuccessfulMatcher<Base, Return> : IMatcher<Base, Return> | |
where Base : class { | |
private readonly Return result; | |
public SuccessfulMatcher(Return result) { | |
this.result = result; | |
} | |
public IMatcher<Base, Return> when<T>(Func<T, Return> onMatch) | |
where T : class, Base { return this; } | |
public Return get() { return result; } | |
public Return getOrElse(Func<Return> elseFunc) { return get(); } | |
} | |
public class MatcherBuilder<T> where T : class { | |
private readonly T subject; | |
public MatcherBuilder(T subject) { | |
this.subject = subject; | |
} | |
public IMatcher<T, Return> returning<Return>() { | |
return new Matcher<T, Return>(subject); | |
} | |
} | |
public static class Match { | |
public static MatcherBuilder<T> match<T>(this T subject) | |
where T : class { return new MatcherBuilder<T>(subject); } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment