Element.vala 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. namespace Invercargill {
  2. // TODO: Reform Datum to have a type, and add specific to_x functions, with perhaps a to<T> convenience function.
  3. // all of these can return errors
  4. // int as_int() for type NUMBER
  5. // int64 as_int64() for type NUMBER
  6. // uint64 as_uint64() for type NUMBER
  7. // ...
  8. // string as_string() for type STRING or NUMBER
  9. // Enumerable<Datum> as_enumerable() for type ENUMERABLE
  10. // KeyValues<Datum, Datum> as_keyvalues() for type KEY_VALUES or PROPERTIES
  11. // Properties as_properties() for type PROPERTIES
  12. // Add mappable interface with
  13. // protected PropertyMapper
  14. // public Properties to_properties()
  15. // public void populate(Properties props)
  16. public interface Elements : Enumerable<Element> {
  17. public virtual Enumerable<T> elements_as<T>() {
  18. return try_select<T>((e, ref r) => e.try_get_as<T>(out r));
  19. }
  20. public virtual Enumerable<T> assert_elements_as<T>() {
  21. return select<T>(e => e.assert_as<T>());
  22. }
  23. }
  24. private class ElementSeries : Series<Element>, Elements {}
  25. public interface Element : Object {
  26. public abstract bool assignable_to_type(Type type);
  27. public abstract Type? type();
  28. public abstract bool is_null();
  29. public abstract bool try_get_as<T>(out T result);
  30. public virtual bool is_type(Type type) {
  31. return this.type().is_a(type);
  32. }
  33. public virtual bool assignable_to<T>() {
  34. return assignable_to_type(typeof(T));
  35. }
  36. public virtual bool @is<T>() {
  37. return is_type(typeof(T));
  38. }
  39. public virtual string type_name() {
  40. return type().name();
  41. }
  42. public virtual T? @as<T>() throws ElementError {
  43. T result;
  44. if(try_get_as<T>(out result)) {
  45. return result;
  46. }
  47. throw new ElementError.INVALID_CONVERSION(@"Could not convert from $(type_name()) to $(typeof(T).name()).");
  48. }
  49. public virtual T? as_or_default<T>() {
  50. T result;
  51. if(try_get_as<T>(out result)) {
  52. return result;
  53. }
  54. return null;
  55. }
  56. public virtual T assert_as<T>() {
  57. T result;
  58. if(try_get_as<T>(out result)) {
  59. return result;
  60. }
  61. critical(@"Element.assert_as<$(typeof(T).name())> failed: Could not get $(this.get_type().name()) as type $(typeof(T).name()).");
  62. assert_not_reached();
  63. }
  64. public virtual string to_string() {
  65. return @"Element[$(type_name())]";
  66. }
  67. }
  68. public class NativeElement<T> : Object, Element {
  69. private T object;
  70. public NativeElement(T obj) {
  71. object = obj;
  72. }
  73. public bool assignable_to_type(GLib.Type type) {
  74. if(is_type(type)) {
  75. return true;
  76. }
  77. if(typeof(T).is_a(typeof(Enumerable)) && type == typeof(Elements)) {
  78. return true;
  79. }
  80. return false;
  81. }
  82. public GLib.Type? type() {
  83. return typeof(T);
  84. }
  85. public bool is_null() {
  86. return object == null;
  87. }
  88. public bool try_get_as<TOut>(out TOut result) {
  89. if(typeof(T).is_a(typeof(Enumerable)) && typeof(TOut) == typeof(Elements)) {
  90. result = (TOut)((Enumerable)object).to_elements();
  91. return true;
  92. }
  93. if(assignable_to<TOut>()) {
  94. result = (TOut)object;
  95. return true;
  96. }
  97. result = null;
  98. return false;
  99. }
  100. }
  101. public class NullElement : Object, Element {
  102. public bool assignable_to_type(GLib.Type type) {
  103. return true;
  104. }
  105. public GLib.Type? type() {
  106. return null;
  107. }
  108. public bool is_null() {
  109. return true;
  110. }
  111. public bool try_get_as<T>(out T result) {
  112. result = null;
  113. return true;
  114. }
  115. public string to_string() {
  116. return "Element[null]";
  117. }
  118. }
  119. }