Attempts.vala 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. using Invercargill.DataStructures;
  2. using Invercargill.Mapping;
  3. namespace Invercargill {
  4. public class Attempts<T> : Proxy<Attempt<T>>, Promotion<Attempt<T>> {
  5. public Enumerable<Attempt<T>> wrap (Enumerable<Attempt<T>> enumerable) {
  6. inner = enumerable;
  7. results = inner.where(a => a.success).select<T>(a => a.result);
  8. errors = inner.where(a => !a.success).select<Error>(a => a.error);
  9. return this;
  10. }
  11. public bool can_wrap (GLib.Type element_type) {
  12. return element_type.is_a (typeof(Attempt));
  13. }
  14. public Enumerable<T> results { get; private set; }
  15. public Enumerable<Error> errors { get; private set; }
  16. public bool fully_successful() {
  17. return inner.all(a => a.success);
  18. }
  19. public new bool iterate_if(PredicateDelegate<T> handler) throws Error {
  20. var tracker = get_tracker();
  21. while(tracker.has_next()) {
  22. var item = tracker.get_next();
  23. if(item.success) {
  24. if(!handler(item.result)) {
  25. return false;
  26. }
  27. }
  28. else {
  29. throw item.error;
  30. }
  31. }
  32. return true;
  33. }
  34. public new void iterate(ItemDelegate<T> handler) throws Error {
  35. iterate_if(i => {
  36. handler(i);
  37. return true;
  38. });
  39. }
  40. public new Series<T> to_series() throws Error {
  41. var series = new Series<T>();
  42. iterate(i => series.add(i));
  43. return series;
  44. }
  45. public new T[] to_array() throws Error {
  46. var array = new T[1024];
  47. var index = 0;
  48. foreach (var item in this) {
  49. if(!item.success) {
  50. throw item.error;
  51. }
  52. if(index >= array.length) {
  53. array.resize(array.length*2);
  54. }
  55. safely_assign_to_array<T>(array, index, item.result);
  56. index++;
  57. }
  58. array.resize(index);
  59. return array;
  60. }
  61. public new Vector<T> to_vector() throws Error {
  62. var vector = new Vector<T>();
  63. iterate(i => vector.add(i));
  64. return vector;
  65. }
  66. public new Dictionary<TKey, T> to_dictionary<TKey>(TransformDelegate<T, TKey> key_selecter, HashDelegate<TKey>? key_hash_func = null, EqualityDelegate<TKey>? key_equal_func = null) throws Error {
  67. var dict = new Dictionary<TKey, T>(key_hash_func, key_equal_func);
  68. iterate(i => dict.set(key_selecter(i), i));
  69. return dict;
  70. }
  71. public new Dictionary<TKey, TValue> select_to_dictionary<TKey, TValue>(TransformDelegate<T, TKey> key_selecter, TransformDelegate<T, TValue> value_selecter, HashDelegate<TKey>? key_hash_func = null, EqualityDelegate<TKey>? key_equal_func = null) throws Error {
  72. var dict = new Dictionary<TKey, T>(key_hash_func, key_equal_func);
  73. iterate(i => dict.set(key_selecter(i), value_selecter(i)));
  74. return dict;
  75. }
  76. public new Set<T> to_set(HashDelegate<T>? hash_func = null, EqualityDelegate<T>? equal_func = null) throws Error {
  77. var @set = new HashSet<T>(hash_func, equal_func);
  78. iterate(i => @set.add(i));
  79. return @set;
  80. }
  81. public new Elements to_elements() throws Error {
  82. var series = new ElementSeries();
  83. if(typeof(T).is_a(typeof(Element))) {
  84. iterate(i => series.add((Element)i));
  85. }
  86. else {
  87. iterate(i => series.add(new NativeElement<T>(i)));
  88. }
  89. return series;
  90. }
  91. public new Object[] to_object_array() throws Error {
  92. return to_vector().to_object_array();
  93. }
  94. // New Functions
  95. public new bool any(PredicateDelegate<T> predicate = (i) => true) throws Error {
  96. var result = false;
  97. var p = resolve_nullable_predicate(predicate);
  98. iterate_if(i => {
  99. if(p(i)) {
  100. result = true;
  101. return false;
  102. }
  103. return true;
  104. });
  105. return result;
  106. }
  107. public new bool all(PredicateDelegate<T> predicate) throws Error {
  108. return !any(i => !predicate(i));
  109. }
  110. public new bool no(PredicateDelegate<T>? predicate = null) throws Error {
  111. var p = resolve_nullable_predicate(predicate);
  112. return all(i => !p(i));
  113. }
  114. public new Attempts<T> where(owned PredicateDelegate<T> predicate) {
  115. return inner.where(i => !i.success || predicate(i)).assert_promotion<Attempts<T>>();
  116. }
  117. public new Attempts<TOut> select<TOut>(owned TransformDelegate<T, TOut> transform) {
  118. return inner.select<Attempt<TOut>>(a => a.success ? new Attempt<TOut>.successful(transform(a.result)) : new Attempt<TOut>.unsuccessful(a.error)).assert_promotion<Attempts<T>>();
  119. }
  120. public new Attempts<TOut> select_many<TOut>(owned TransformDelegate<T, Enumerable<TOut>> transform) {
  121. return inner.select_many<Attempt<TOut>>(a => a.success ? transform(a.result).select<Attempt<TOut>>(i => new Attempt<TOut>.successful(i)) : Iterate.single<Attempt<TOut>>(new Attempt<TOut>.unsuccessful(a.error))).assert_promotion<Attempts<T>>();
  122. }
  123. public new Attempts<T> concat(Enumerable<Attempt<T>> other) {
  124. return inner.concat(other).assert_promotion<Attempts>();
  125. }
  126. public new Attempts<TOut> cast<TOut>() {
  127. return select<TOut>(i => (TOut)i);
  128. }
  129. public new Attempts<SelectionContext<T, TOut>> contextualised_select<TOut>(owned TransformDelegate<T, TOut> transform) {
  130. return select<SelectionContext<T, TOut>>((i) => new SelectionContext<T, TOut>(i, transform(i)));
  131. }
  132. public new TOut aggregate<TOut>(TOut initial, AggregateDelegate<TOut, T> aggregate_func) throws Error {
  133. var aggregate = initial;
  134. iterate(i => {
  135. aggregate = aggregate_func(aggregate, i);
  136. });
  137. return aggregate;
  138. }
  139. public new T max(TransformDelegate<T, int> int_delegate) throws Error{
  140. T item = null;
  141. var first = true;
  142. var value = 0;
  143. foreach (var a in this) {
  144. var i = a.unwrap();
  145. if(first) {
  146. first = false;
  147. item = i;
  148. value = int_delegate(i);
  149. continue;
  150. }
  151. var item_value = int_delegate(i);
  152. if(item_value > value) {
  153. value = item_value;
  154. item = i;
  155. }
  156. }
  157. return item;
  158. }
  159. public new T min(TransformDelegate<T, int> int_delegate) throws Error {
  160. T item = null;
  161. var first = true;
  162. var value = 0;
  163. foreach (var a in this) {
  164. var i = a.unwrap();
  165. if(first) {
  166. first = false;
  167. item = i;
  168. value = int_delegate(i);
  169. continue;
  170. }
  171. var item_value = int_delegate(i);
  172. if(item_value < value) {
  173. value = item_value;
  174. item = i;
  175. }
  176. }
  177. return item;
  178. }
  179. public new bool contains(T item) throws Error {
  180. return any(i => i == item);
  181. }
  182. public Type attempt_element_type {
  183. get {
  184. return typeof(T);
  185. }
  186. }
  187. public new Attempts<TOut> select_where<TOut>(owned FilterTransformDelegate<T, TOut> transform) {
  188. return inner.select_where<TOut>((a, out o) => !a.success || transform(a.result, out o)).assert_promotion<Attempts<TOut>>();
  189. }
  190. public new Attempts<TOut> attempt_select<TOut>(owned AttemptTransformDelegate<T, TOut> transform) {
  191. return inner.attempt_select<TOut>(a => a.success ? new Attempt<TOut>(() => transform(a.result)) : new Attempt<TOut>.unsuccessful(a.error));
  192. }
  193. public new Attempts<TOut> attempt_select_nested<TOut>(owned AttemptTransformDelegate<T, Enumerable<Attempt<TOut>>> transform) {
  194. return attempt_select<Enumerable<Attempt<TOut>>>((owned)transform)
  195. .as_enumerable()
  196. .select_many<Attempt<TOut>>(a => a.success ? a.result : Iterate.single<Attempt<TOut>>(new Attempt<TOut>.unsuccessful(a.error)))
  197. .assert_promotion<Attempts<TOut>>();
  198. }
  199. public new Attempts<TOut> attempt_map_with<TOut>(Mapper<TOut, T> mapper) {
  200. return attempt_select<TOut>(o => mapper.materialise(o));
  201. }
  202. private PredicateDelegate<T> resolve_nullable_predicate(PredicateDelegate<T>? predicate) {
  203. if(predicate == null) {
  204. return (p) => true;
  205. }
  206. return predicate;
  207. }
  208. }
  209. }