Created
April 5, 2018 07:37
-
-
Save run-dlang/f4883adea0012830de0a7671501a8053 to your computer and use it in GitHub Desktop.
Code shared from run.dlang.io.
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
| import std.stdio; | |
| mixin template Enforcement(T) { | |
| private bool _ensured; | |
| private Throwable _throwable; | |
| ~this() { | |
| if (this.hasThrowable) { | |
| throw _throwable; | |
| } | |
| } | |
| auto enforce(bool ensured) { | |
| _ensured = ensured; | |
| return this; | |
| } | |
| auto releaseThrowable() { | |
| scope(exit) _throwable = null; | |
| return _throwable; | |
| } | |
| bool hasThrowable() const { | |
| return _throwable !is null; | |
| } | |
| bool isEnsured() const { | |
| return !_ensured; | |
| } | |
| auto orThrow(string message) { | |
| if (!this.isEnsured) { | |
| this.orThrow(new Exception(message)); | |
| } | |
| return this; | |
| } | |
| auto orThrow(lazy Throwable throwable) { | |
| if (!this.isEnsured) { | |
| if (this.hasThrowable) { | |
| throwable.next(_throwable); | |
| } | |
| _throwable = throwable; | |
| } | |
| return this; | |
| } | |
| } | |
| mixin template EnsuranceImpl(T) | |
| { | |
| private T _value; | |
| this()(Ensurance!T ensurance) { | |
| _value = ensurance.get; | |
| _ensured = ensurance.isEnsured; | |
| _throwable = ensurance.releaseThrowable; | |
| } | |
| mixin Enforcement!T; | |
| } | |
| struct StringEnsurance { | |
| mixin EnsuranceImpl!string; | |
| auto hasLength(size_t length) { | |
| return this.enforce(_value.length == length); | |
| } | |
| } | |
| struct BooleanEnsurance { | |
| mixin EnsuranceImpl!bool; | |
| } | |
| struct Ensurance(T) { | |
| import std.traits: isSomeString, isArray, isScalarType, isNumeric, isBoolean; | |
| private T _value; | |
| mixin Enforcement!T; | |
| this(T value) { | |
| _value = value; | |
| } | |
| auto get() { | |
| return _value; | |
| } | |
| auto isString() { | |
| return StringEnsurance(this.enforce(isSomeString!T)); | |
| } | |
| auto isArray() const { | |
| return isArray!T; | |
| } | |
| auto isScalar() { | |
| return isScalarType!T; | |
| } | |
| auto isNumeric() { | |
| return isNumeric!T; | |
| } | |
| auto isBool() { | |
| return isBoolean!T; | |
| } | |
| } | |
| auto ensure(T)(T value) { | |
| return Ensurance!T(value); | |
| } | |
| void main() { | |
| writeln(ensure("Hello D").isString.hasLength(42)); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment