Attempts.vala 9.7 KB

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