123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- namespace Invercargill {
-
- // TODO: Reform Datum to have a type, and add specific to_x functions, with perhaps a to<T> convenience function.
- // all of these can return errors
- // int as_int() for type NUMBER
- // int64 as_int64() for type NUMBER
- // uint64 as_uint64() for type NUMBER
- // ...
- // string as_string() for type STRING or NUMBER
- // Enumerable<Datum> as_enumerable() for type ENUMERABLE
- // KeyValues<Datum, Datum> as_keyvalues() for type KEY_VALUES or PROPERTIES
- // Properties as_properties() for type PROPERTIES
- // Add mappable interface with
- // protected PropertyMapper
- // public Properties to_properties()
- // public void populate(Properties props)
- public interface Elements : Enumerable<Element> {
- public virtual Enumerable<T> elements_as<T>() {
- return try_select<T>((e, ref r) => e.try_get_as<T>(out r));
- }
- public virtual Enumerable<T> assert_elements_as<T>() {
- return select<T>(e => e.assert_as<T>());
- }
- }
-
- private class ElementSeries : Series<Element>, Elements {}
- public interface Element : Object {
- public abstract bool assignable_to_type(Type type);
- public abstract Type? type();
- public abstract bool is_null();
- public abstract bool try_get_as<T>(out T result);
- public virtual bool is_type(Type type) {
- return this.type().is_a(type);
- }
- public virtual bool assignable_to<T>() {
- return assignable_to_type(typeof(T));
- }
- public virtual bool @is<T>() {
- return is_type(typeof(T));
- }
- public virtual string type_name() {
- return type().name();
- }
- public virtual T? @as<T>() throws ElementError {
- T result;
- if(try_get_as<T>(out result)) {
- return result;
- }
- throw new ElementError.INVALID_CONVERSION(@"Could not convert from $(type_name()) to $(typeof(T).name()).");
- }
- public virtual T? as_or_default<T>() {
- T result;
- if(try_get_as<T>(out result)) {
- return result;
- }
- return null;
- }
- public virtual T assert_as<T>() {
- T result;
- if(try_get_as<T>(out result)) {
- return result;
- }
- critical(@"Element.assert_as<$(typeof(T).name())> failed: Could not get $(this.get_type().name()) as type $(typeof(T).name()).");
- assert_not_reached();
- }
- public virtual string to_string() {
- return @"Element[$(type_name())]";
- }
- }
- public class NativeElement<T> : Object, Element {
- private T object;
- public NativeElement(T obj) {
- object = obj;
- }
- public bool assignable_to_type(GLib.Type type) {
- if(is_type(type)) {
- return true;
- }
- if(typeof(T).is_a(typeof(Enumerable)) && type == typeof(Elements)) {
- return true;
- }
- return false;
- }
- public GLib.Type? type() {
- return typeof(T);
- }
- public bool is_null() {
- return object == null;
- }
- public bool try_get_as<TOut>(out TOut result) {
- if(typeof(T).is_a(typeof(Enumerable)) && typeof(TOut) == typeof(Elements)) {
- result = (TOut)((Enumerable)object).to_elements();
- return true;
- }
- if(assignable_to<TOut>()) {
- result = (TOut)object;
- return true;
- }
- result = null;
- return false;
- }
- }
- public class NullElement : Object, Element {
- public bool assignable_to_type(GLib.Type type) {
- return true;
- }
- public GLib.Type? type() {
- return null;
- }
- public bool is_null() {
- return true;
- }
- public bool try_get_as<T>(out T result) {
- result = null;
- return true;
- }
- public string to_string() {
- return "Element[null]";
- }
- }
- }
|