|
| 1 | +module re.util.jar; |
| 2 | + |
| 3 | +import std.array; |
| 4 | +import std.typecons; |
| 5 | + |
| 6 | +/// a container for registered types |
| 7 | +class Jar { |
| 8 | + private Object[][TypeInfo] _instance_registry; |
| 9 | + |
| 10 | + /// register a type instance |
| 11 | + public T register(T)(T instance) { |
| 12 | + auto type = typeid(instance); |
| 13 | + if (type !in _instance_registry) { |
| 14 | + _instance_registry[type] = new Object[0]; |
| 15 | + } |
| 16 | + _instance_registry[type] ~= instance; |
| 17 | + return instance; |
| 18 | + } |
| 19 | + |
| 20 | + /// resolve all matching type instances |
| 21 | + public T[] resolve_all(T)() { |
| 22 | + auto type = typeid(T); |
| 23 | + if (type in _instance_registry) { |
| 24 | + Appender!(T[]) resolved; |
| 25 | + foreach (item; _instance_registry[type]) { |
| 26 | + resolved ~= cast(T) item; |
| 27 | + } |
| 28 | + return resolved.data; |
| 29 | + } |
| 30 | + return new T[0]; |
| 31 | + } |
| 32 | + |
| 33 | + /// resolve first matching type instance |
| 34 | + public Nullable!T resolve(T)() { |
| 35 | + auto items = resolve_all!T(); |
| 36 | + if (items.length > 0) { |
| 37 | + return Nullable!T(items[0]); |
| 38 | + } |
| 39 | + return Nullable!T.init; |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +unittest { |
| 44 | + class Cookie { |
| 45 | + bool delicious = true; |
| 46 | + } |
| 47 | + |
| 48 | + auto jar = new Jar(); |
| 49 | + |
| 50 | + auto c1 = new Cookie(); |
| 51 | + jar.register(c1); |
| 52 | + auto r1 = jar.resolve!Cookie(); |
| 53 | + assert(!r1.isNull, "resolved item was null"); |
| 54 | + assert(r1.get() == c1, "resolved item did not match"); |
| 55 | + |
| 56 | + auto c2 = new Cookie(); |
| 57 | + jar.register(c2); |
| 58 | + |
| 59 | + const auto cookies = jar.resolve_all!Cookie(); |
| 60 | + assert(cookies.length == 2, "mismatch in number of registered items"); |
| 61 | +} |
0 commit comments