trackler 2.2.1.179 → 2.2.1.180

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/yacht/description.md +14 -13
  4. data/tracks/ballerina/config.json +1 -0
  5. data/tracks/coffeescript/config.json +138 -41
  6. data/tracks/coffeescript/docs/ABOUT.md +3 -7
  7. data/tracks/coq/config.json +1 -0
  8. data/tracks/d/config.json +1 -0
  9. data/tracks/dart/config.json +1 -0
  10. data/tracks/elixir/config.json +17 -16
  11. data/tracks/elixir/docs/ABOUT.md +10 -2
  12. data/tracks/fortran/config.json +1 -0
  13. data/tracks/gnu-apl/config.json +1 -0
  14. data/tracks/go/config.json +13 -0
  15. data/tracks/go/exercises/list-ops/README.md +27 -0
  16. data/tracks/go/exercises/list-ops/example.go +99 -0
  17. data/tracks/go/exercises/list-ops/listops_test.go +291 -0
  18. data/tracks/groovy/config.json +1 -0
  19. data/tracks/haxe/config.json +1 -0
  20. data/tracks/perl5/exercises/leap/.meta/exercise-data.yaml +3 -5
  21. data/tracks/perl5/exercises/leap/.meta/solutions/Leap.pm +2 -4
  22. data/tracks/perl5/exercises/leap/Leap.pm +1 -1
  23. data/tracks/perl5/exercises/leap/leap.t +2 -2
  24. data/tracks/php/config.json +1 -0
  25. data/tracks/plsql/config.json +1 -0
  26. data/tracks/pony/config.json +1 -0
  27. data/tracks/purescript/config.json +1 -0
  28. data/tracks/reasonml/config/exercise_readme.go.tmpl +18 -2
  29. data/tracks/reasonml/exercises/anagram/README.md +15 -4
  30. data/tracks/reasonml/exercises/armstrong-numbers/README.md +3 -4
  31. data/tracks/reasonml/exercises/binary-search/README.md +14 -7
  32. data/tracks/reasonml/exercises/bob/README.md +14 -6
  33. data/tracks/reasonml/exercises/change/README.md +2 -4
  34. data/tracks/reasonml/exercises/hello-world/README.md +2 -3
  35. data/tracks/reasonml/exercises/isogram/README.md +4 -6
  36. data/tracks/reasonml/exercises/leap/README.md +14 -4
  37. data/tracks/reasonml/exercises/pangram/README.md +13 -3
  38. data/tracks/reasonml/exercises/phone-number/README.md +15 -7
  39. data/tracks/reasonml/exercises/raindrops/README.md +14 -7
  40. data/tracks/reasonml/exercises/rna-transcription/README.md +13 -3
  41. data/tracks/reasonml/exercises/roman-numerals/README.md +4 -8
  42. data/tracks/reasonml/exercises/run-length-encoding/README.md +14 -7
  43. data/tracks/reasonml/exercises/space-age/README.md +13 -3
  44. data/tracks/reasonml/exercises/word-count/README.md +18 -8
  45. data/tracks/rust/.travis.yml +1 -0
  46. data/tracks/rust/_test/check-exercises-for-authors.sh +10 -0
  47. data/tracks/rust/bin/format_exercises +2 -0
  48. data/tracks/rust/exercises/accumulate/Cargo.toml +0 -1
  49. data/tracks/rust/exercises/accumulate/example.rs +4 -1
  50. data/tracks/rust/exercises/acronym/example.rs +6 -5
  51. data/tracks/rust/exercises/acronym/tests/acronym.rs +1 -1
  52. data/tracks/rust/exercises/all-your-base/example.rs +8 -2
  53. data/tracks/rust/exercises/allergies/example.rs +28 -6
  54. data/tracks/rust/exercises/alphametics/example.rs +18 -10
  55. data/tracks/rust/exercises/anagram/example.rs +8 -4
  56. data/tracks/rust/exercises/atbash-cipher/example.rs +15 -15
  57. data/tracks/rust/exercises/beer-song/example.rs +18 -12
  58. data/tracks/rust/exercises/binary-search/Cargo.toml +0 -1
  59. data/tracks/rust/exercises/binary-search/example.rs +3 -4
  60. data/tracks/rust/exercises/bob/example.rs +11 -5
  61. data/tracks/rust/exercises/book-store/Cargo-example.toml +0 -1
  62. data/tracks/rust/exercises/book-store/Cargo.toml +0 -1
  63. data/tracks/rust/exercises/book-store/example.rs +15 -19
  64. data/tracks/rust/exercises/bowling/example.rs +3 -1
  65. data/tracks/rust/exercises/bracket-push/example.rs +7 -2
  66. data/tracks/rust/exercises/circular-buffer/example.rs +1 -1
  67. data/tracks/rust/exercises/clock/.meta/ALLOWED_TO_NOT_COMPILE +3 -0
  68. data/tracks/rust/exercises/clock/Cargo.toml +0 -1
  69. data/tracks/rust/exercises/clock/example.rs +5 -3
  70. data/tracks/rust/exercises/clock/src/lib.rs +14 -0
  71. data/tracks/rust/exercises/collatz-conjecture/example.rs +2 -2
  72. data/tracks/rust/exercises/crypto-square/Cargo-example.toml +0 -1
  73. data/tracks/rust/exercises/crypto-square/Cargo.toml +0 -1
  74. data/tracks/rust/exercises/custom-set/example.rs +17 -15
  75. data/tracks/rust/exercises/decimal/Cargo-example.toml +0 -1
  76. data/tracks/rust/exercises/decimal/Cargo.toml +0 -1
  77. data/tracks/rust/exercises/decimal/example.rs +5 -5
  78. data/tracks/rust/exercises/diamond/Cargo.toml +0 -1
  79. data/tracks/rust/exercises/difference-of-squares/example.rs +1 -1
  80. data/tracks/rust/exercises/dominoes/example.rs +20 -19
  81. data/tracks/rust/exercises/etl/example.rs +4 -3
  82. data/tracks/rust/exercises/forth/example.rs +29 -45
  83. data/tracks/rust/exercises/grade-school/example.rs +4 -2
  84. data/tracks/rust/exercises/hexadecimal/example.rs +2 -4
  85. data/tracks/rust/exercises/isbn-verifier/example.rs +5 -6
  86. data/tracks/rust/exercises/isbn-verifier/tests/isbn-verifier.rs +12 -0
  87. data/tracks/rust/exercises/isogram/example.rs +9 -3
  88. data/tracks/rust/exercises/largest-series-product/example.rs +2 -1
  89. data/tracks/rust/exercises/luhn-from/example.rs +3 -1
  90. data/tracks/rust/exercises/luhn/example.rs +5 -3
  91. data/tracks/rust/exercises/macros/Cargo.toml +0 -1
  92. data/tracks/rust/exercises/nth-prime/Cargo.toml +0 -1
  93. data/tracks/rust/exercises/nth-prime/example.rs +6 -6
  94. data/tracks/rust/exercises/nucleotide-codons/Cargo.toml +0 -1
  95. data/tracks/rust/exercises/nucleotide-codons/example.rs +23 -17
  96. data/tracks/rust/exercises/nucleotide-count/example.rs +15 -5
  97. data/tracks/rust/exercises/nucleotide-count/src/lib.rs +15 -0
  98. data/tracks/rust/exercises/nucleotide-count/tests/nucleotide-count.rs +3 -3
  99. data/tracks/rust/exercises/palindrome-products/Cargo.toml +0 -1
  100. data/tracks/rust/exercises/pangram/example.rs +6 -6
  101. data/tracks/rust/exercises/parallel-letter-frequency/example.rs +7 -4
  102. data/tracks/rust/exercises/pascals-triangle/example.rs +6 -2
  103. data/tracks/rust/exercises/perfect-numbers/example.rs +2 -2
  104. data/tracks/rust/exercises/phone-number/example.rs +11 -15
  105. data/tracks/rust/exercises/pig-latin/Cargo-example.toml +0 -1
  106. data/tracks/rust/exercises/pig-latin/Cargo.toml +0 -1
  107. data/tracks/rust/exercises/pig-latin/example.rs +6 -2
  108. data/tracks/rust/exercises/poker/Cargo-example.toml +0 -1
  109. data/tracks/rust/exercises/poker/Cargo.toml +0 -1
  110. data/tracks/rust/exercises/poker/example.rs +9 -8
  111. data/tracks/rust/exercises/prime-factors/Cargo.toml +0 -1
  112. data/tracks/rust/exercises/prime-factors/example.rs +1 -1
  113. data/tracks/rust/exercises/protein-translation/Cargo.toml +0 -1
  114. data/tracks/rust/exercises/protein-translation/example.rs +6 -5
  115. data/tracks/rust/exercises/proverb/Cargo.toml +0 -1
  116. data/tracks/rust/exercises/proverb/example.rs +0 -1
  117. data/tracks/rust/exercises/pythagorean-triplet/Cargo.toml +0 -1
  118. data/tracks/rust/exercises/pythagorean-triplet/example.rs +3 -3
  119. data/tracks/rust/exercises/queen-attack/example.rs +3 -3
  120. data/tracks/rust/exercises/react/example.rs +61 -29
  121. data/tracks/rust/exercises/reverse-string/Cargo.toml +0 -1
  122. data/tracks/rust/exercises/rna-transcription/example.rs +17 -9
  123. data/tracks/rust/exercises/robot-name/example.rs +4 -3
  124. data/tracks/rust/exercises/robot-simulator/example.rs +5 -2
  125. data/tracks/rust/exercises/roman-numerals/example.rs +15 -14
  126. data/tracks/rust/exercises/rotational-cipher/Cargo.toml +0 -1
  127. data/tracks/rust/exercises/rotational-cipher/example.rs +10 -14
  128. data/tracks/rust/exercises/rotational-cipher/src/lib.rs +7 -1
  129. data/tracks/rust/exercises/run-length-encoding/Cargo.toml +0 -1
  130. data/tracks/rust/exercises/run-length-encoding/example.rs +34 -29
  131. data/tracks/rust/exercises/saddle-points/example.rs +0 -1
  132. data/tracks/rust/exercises/say/Cargo.toml +0 -1
  133. data/tracks/rust/exercises/say/example.rs +34 -8
  134. data/tracks/rust/exercises/series/example.rs +6 -8
  135. data/tracks/rust/exercises/simple-linked-list/example.rs +0 -2
  136. data/tracks/rust/exercises/spiral-matrix/example.rs +0 -1
  137. data/tracks/rust/exercises/tournament/example.rs +33 -20
  138. data/tracks/rust/exercises/triangle/example.rs +1 -1
  139. data/tracks/rust/exercises/two-bucket/example.rs +2 -6
  140. data/tracks/rust/exercises/two-fer/example.rs +3 -3
  141. data/tracks/rust/exercises/variable-length-quantity/example.rs +2 -3
  142. data/tracks/rust/exercises/word-count/example.rs +4 -1
  143. data/tracks/rust/exercises/wordy/example.rs +10 -4
  144. metadata +7 -2
@@ -1,6 +1,5 @@
1
1
  [package]
2
2
  name = "palindrome-products"
3
3
  version = "1.1.0"
4
- authors = ["Kirill Meng <kirill.meng@hotmail.de>"]
5
4
 
6
5
  [dependencies]
@@ -2,12 +2,12 @@ use std::collections::BTreeSet;
2
2
  use std::iter::FromIterator;
3
3
 
4
4
  pub fn is_pangram(sentence: &str) -> bool {
5
- sentence.to_lowercase()
6
- .chars()
7
- .filter(|c| c.is_alphabetic())
8
- .filter(|c| c.is_ascii())
9
- .collect::<BTreeSet<char>>() == english_letter_set()
10
-
5
+ sentence
6
+ .to_lowercase()
7
+ .chars()
8
+ .filter(|c| c.is_alphabetic())
9
+ .filter(|c| c.is_ascii())
10
+ .collect::<BTreeSet<char>>() == english_letter_set()
11
11
  }
12
12
 
13
13
  fn english_letter_set() -> BTreeSet<char> {
@@ -1,7 +1,6 @@
1
1
  use std::collections::HashMap;
2
- use std::thread;
3
2
  use std::sync::mpsc::channel;
4
-
3
+ use std::thread;
5
4
 
6
5
  /// Compute the frequency of each letter (technically of each unicode codepoint) using the given
7
6
  /// number of worker threads.
@@ -9,9 +8,13 @@ pub fn frequency(texts: &[&str], num_workers: usize) -> HashMap<char, usize> {
9
8
  assert!(num_workers > 0);
10
9
  let part_size_floor = texts.len() / num_workers;
11
10
  let rem = texts.len() % num_workers;
12
- let part_size = if rem > 0 { part_size_floor + 1 } else { part_size_floor };
11
+ let part_size = if rem > 0 {
12
+ part_size_floor + 1
13
+ } else {
14
+ part_size_floor
15
+ };
13
16
  let mut parts: Vec<Vec<String>> = Vec::with_capacity(part_size);
14
- for _ in 0 .. num_workers {
17
+ for _ in 0..num_workers {
15
18
  parts.push(Vec::with_capacity(part_size));
16
19
  }
17
20
  let mut i = 0;
@@ -4,11 +4,15 @@ pub struct PascalsTriangle {
4
4
 
5
5
  impl PascalsTriangle {
6
6
  pub fn new(row_count: u32) -> Self {
7
- PascalsTriangle { row_count: row_count }
7
+ PascalsTriangle {
8
+ row_count: row_count,
9
+ }
8
10
  }
9
11
 
10
12
  pub fn rows(&self) -> Vec<Vec<u32>> {
11
- (0..self.row_count).map(|row| PascalsTriangle::row(row)).collect()
13
+ (0..self.row_count)
14
+ .map(|row| PascalsTriangle::row(row))
15
+ .collect()
12
16
  }
13
17
 
14
18
  pub fn row(number: u32) -> Vec<u32> {
@@ -2,7 +2,7 @@ pub fn classify(num: u64) -> Option<Classification> {
2
2
  if num == 0 {
3
3
  return None;
4
4
  }
5
- let sum: u64 = (1..num).filter(|i| num%i == 0).sum();
5
+ let sum: u64 = (1..num).filter(|i| num % i == 0).sum();
6
6
  if sum == num {
7
7
  Some(Classification::Perfect)
8
8
  } else if sum < num {
@@ -16,5 +16,5 @@ pub fn classify(num: u64) -> Option<Classification> {
16
16
  pub enum Classification {
17
17
  Abundant,
18
18
  Perfect,
19
- Deficient
19
+ Deficient,
20
20
  }
@@ -1,21 +1,17 @@
1
1
  pub fn number(s: &str) -> Option<String> {
2
2
  let digits: String = s.chars().filter(|&c| c.is_digit(10)).collect();
3
3
  match digits.len() {
4
- 10 => {
5
- match (digits.chars().nth(0), digits.chars().nth(3)) {
6
- (Some('0'), _) => None,
7
- (Some('1'), _) => None,
8
- (_, Some('0')) => None,
9
- (_, Some('1')) => None,
10
- _ => Some(digits),
11
- }
12
- }
13
- 11 => {
14
- match digits.chars().nth(0) {
15
- Some('1') => Some(digits[1..].to_string()),
16
- _ => None,
17
- }
18
- }
4
+ 10 => match (digits.chars().nth(0), digits.chars().nth(3)) {
5
+ (Some('0'), _) => None,
6
+ (Some('1'), _) => None,
7
+ (_, Some('0')) => None,
8
+ (_, Some('1')) => None,
9
+ _ => Some(digits),
10
+ },
11
+ 11 => match digits.chars().nth(0) {
12
+ Some('1') => Some(digits[1..].to_string()),
13
+ _ => None,
14
+ },
19
15
  _ => None,
20
16
  }
21
17
  }
@@ -1,7 +1,6 @@
1
1
  [package]
2
2
  name = "pig-latin"
3
3
  version = "1.0.0"
4
- authors = ["sacherjj <sacherjj@gmail.com>"]
5
4
 
6
5
  [dependencies]
7
6
  regex = "0.2"
@@ -1,6 +1,5 @@
1
1
  [package]
2
2
  name = "pig-latin"
3
3
  version = "1.0.0"
4
- authors = ["sacherjj <sacherjj@gmail.com>"]
5
4
 
6
5
  [dependencies]
@@ -1,4 +1,5 @@
1
- #[macro_use] extern crate lazy_static;
1
+ #[macro_use]
2
+ extern crate lazy_static;
2
3
  extern crate regex;
3
4
 
4
5
  use regex::Regex;
@@ -24,5 +25,8 @@ pub fn translate_word(word: &str) -> String {
24
25
  }
25
26
 
26
27
  pub fn translate(text: &str) -> String {
27
- text.split(" ").map(|w| translate_word(w)).collect::<Vec<_>>().join(" ")
28
+ text.split(" ")
29
+ .map(|w| translate_word(w))
30
+ .collect::<Vec<_>>()
31
+ .join(" ")
28
32
  }
@@ -1,7 +1,6 @@
1
1
  [package]
2
2
  name = "poker"
3
3
  version = "1.0.0"
4
- authors = ["Peter Goodspeed-Niklaus <peter.r.goodspeedniklaus@gmail.com>"]
5
4
 
6
5
  [dependencies]
7
6
  try_opt = "0.1.1"
@@ -1,6 +1,5 @@
1
1
  [package]
2
2
  name = "poker"
3
3
  version = "1.1.0"
4
- authors = ["Peter Goodspeed-Niklaus <peter.r.goodspeedniklaus@gmail.com>"]
5
4
 
6
5
  [dependencies]
@@ -1,5 +1,5 @@
1
- use std::fmt;
2
1
  use std::cmp::Ordering;
2
+ use std::fmt;
3
3
 
4
4
  #[macro_use]
5
5
  extern crate try_opt;
@@ -181,8 +181,8 @@ impl PokerHand {
181
181
  fn is_ace_low_straight(cards: &[Card]) -> bool {
182
182
  // special case: ace-low straight
183
183
  // still depends on the sorted precondition
184
- cards[0].rank.value() == 2 && cards[4].rank == Rank::Ace &&
185
- cards
184
+ cards[0].rank.value() == 2 && cards[4].rank == Rank::Ace
185
+ && cards
186
186
  .windows(2)
187
187
  .take(3) // (0, 1), (1, 2), (2, 3) --> skips 4, ace
188
188
  .map(|pair| pair[1].rank.value() - pair[0].rank.value())
@@ -201,8 +201,8 @@ impl PokerHand {
201
201
  let is_straight = cards
202
202
  .windows(2)
203
203
  .map(|pair| pair[1].rank.value() - pair[0].rank.value())
204
- .all(|diff| diff == 1) ||
205
- PokerHand::is_ace_low_straight(cards);
204
+ .all(|diff| diff == 1)
205
+ || PokerHand::is_ace_low_straight(cards);
206
206
 
207
207
  if is_flush && is_straight {
208
208
  return Some(PokerHand::StraightFlush);
@@ -269,9 +269,10 @@ impl<'a> Hand<'a> {
269
269
  }
270
270
 
271
271
  fn cmp_high_card(&self, other: &Hand, card: usize) -> Ordering {
272
- let mut ordering = self.cards[card].rank.value().cmp(
273
- &other.cards[card].rank.value(),
274
- );
272
+ let mut ordering = self.cards[card]
273
+ .rank
274
+ .value()
275
+ .cmp(&other.cards[card].rank.value());
275
276
  if card != 0 {
276
277
  ordering = ordering.then_with(|| self.cmp_high_card(other, card - 1));
277
278
  }
@@ -1,6 +1,5 @@
1
1
  [package]
2
2
  name = "prime_factors"
3
3
  version = "1.1.0"
4
- authors = ["sacherjj <sacherjj@gmail.com>"]
5
4
 
6
5
  [dependencies]
@@ -1,7 +1,7 @@
1
1
  pub fn factors(n: u64) -> Vec<u64> {
2
2
  let mut val = n;
3
3
  let mut out: Vec<u64> = vec![];
4
- let mut possible:u64 = 2;
4
+ let mut possible: u64 = 2;
5
5
  while val > 1 {
6
6
  while val % possible == 0 {
7
7
  out.push(possible);
@@ -1,4 +1,3 @@
1
1
  [package]
2
2
  name = "protein-translation"
3
3
  version = "0.1.0"
4
- authors = ["Peter Minten <peter@pminten.nl>"]
@@ -1,12 +1,12 @@
1
1
  use std::collections::HashMap;
2
2
 
3
3
  pub struct CodonInfo<'a> {
4
- actual_codons: HashMap<&'a str, &'a str>
4
+ actual_codons: HashMap<&'a str, &'a str>,
5
5
  }
6
6
 
7
7
  pub fn parse<'a>(pairs: Vec<(&'a str, &'a str)>) -> CodonInfo<'a> {
8
- CodonInfo{
9
- actual_codons: pairs.into_iter().collect()
8
+ CodonInfo {
9
+ actual_codons: pairs.into_iter().collect(),
10
10
  }
11
11
  }
12
12
 
@@ -14,12 +14,13 @@ impl<'a> CodonInfo<'a> {
14
14
  pub fn name_for(&self, codon: &str) -> Result<&'a str, &'static str> {
15
15
  match self.actual_codons.get(&codon) {
16
16
  Some(name) => Ok(name),
17
- None => Err("Invalid")
17
+ None => Err("Invalid"),
18
18
  }
19
19
  }
20
20
 
21
21
  pub fn of_rna(&self, strand: &str) -> Result<Vec<&'a str>, &'static str> {
22
- strand.chars()
22
+ strand
23
+ .chars()
23
24
  .collect::<Vec<char>>()
24
25
  .chunks(3)
25
26
  .map(|chars| self.name_for(&chars.iter().collect::<String>()))
@@ -1,6 +1,5 @@
1
1
  [package]
2
2
  name = "proverb"
3
3
  version = "0.0.0"
4
- authors = ["sacherjj <sacherjj@gmail.com>"]
5
4
 
6
5
  [dependencies]
@@ -1,4 +1,3 @@
1
-
2
1
  pub fn build_proverb(items: Vec<&str>) -> String {
3
2
  let mut stanzas = Vec::with_capacity(items.len());
4
3
  for index in 0..items.len() {
@@ -1,6 +1,5 @@
1
1
  [package]
2
2
  name = "pythagorean_triplet"
3
3
  version = "0.0.0"
4
- authors = ["sacherjj <sacherjj@gmail.com>"]
5
4
 
6
5
  [dependencies]
@@ -1,9 +1,9 @@
1
1
  pub fn find() -> Option<u32> {
2
2
  for a in 1..1000 {
3
- for b in (a+1)..(1000-a) {
3
+ for b in (a + 1)..(1000 - a) {
4
4
  let c = 1000 - (a + b);
5
- if a*a + b*b == c*c {
6
- return Some(a*b*c);
5
+ if a * a + b * b == c * c {
6
+ return Some(a * b * c);
7
7
  }
8
8
  }
9
9
  }
@@ -12,9 +12,9 @@ impl ChessPiece for Queen {
12
12
  }
13
13
 
14
14
  fn can_attack<T: ChessPiece>(&self, piece: &T) -> bool {
15
- self.position.horizontal_from(&piece.position()) ||
16
- self.position.vertical_from(&piece.position()) ||
17
- self.position.diagonal_from(&piece.position())
15
+ self.position.horizontal_from(&piece.position())
16
+ || self.position.vertical_from(&piece.position())
17
+ || self.position.diagonal_from(&piece.position())
18
18
  }
19
19
  }
20
20
 
@@ -49,7 +49,7 @@ struct ComputeCell<'a, T: Copy> {
49
49
  callbacks: HashMap<CallbackID, Box<FnMut(T) -> () + 'a>>,
50
50
  }
51
51
 
52
- impl <T: Copy> Cell<T> {
52
+ impl<T: Copy> Cell<T> {
53
53
  fn new(initial: T) -> Self {
54
54
  Cell {
55
55
  value: initial,
@@ -59,7 +59,7 @@ impl <T: Copy> Cell<T> {
59
59
  }
60
60
  }
61
61
 
62
- impl <'a, T: Copy> ComputeCell<'a, T> {
62
+ impl<'a, T: Copy> ComputeCell<'a, T> {
63
63
  fn new<F: Fn(&[T]) -> T + 'a>(initial: T, dependencies: Vec<CellID>, f: F) -> Self {
64
64
  ComputeCell {
65
65
  cell: Cell::new(initial),
@@ -77,9 +77,9 @@ pub struct Reactor<'a, T: Copy> {
77
77
  computes: Vec<ComputeCell<'a, T>>,
78
78
  }
79
79
 
80
- impl <'a, T: Copy + PartialEq> Reactor<'a, T> {
80
+ impl<'a, T: Copy + PartialEq> Reactor<'a, T> {
81
81
  pub fn new() -> Self {
82
- Reactor{
82
+ Reactor {
83
83
  inputs: Vec::new(),
84
84
  computes: Vec::new(),
85
85
  }
@@ -90,25 +90,42 @@ impl <'a, T: Copy + PartialEq> Reactor<'a, T> {
90
90
  InputCellID(self.inputs.len() - 1)
91
91
  }
92
92
 
93
- pub fn create_compute<F: Fn(&[T]) -> T + 'a>(&mut self, dependencies: &[CellID], compute_func: F) -> Result<ComputeCellID, CellID> {
93
+ pub fn create_compute<F: Fn(&[T]) -> T + 'a>(
94
+ &mut self,
95
+ dependencies: &[CellID],
96
+ compute_func: F,
97
+ ) -> Result<ComputeCellID, CellID> {
94
98
  // Check all dependencies' validity before modifying any of them,
95
99
  // so that we don't perform an incorrect partial write.
96
100
  for &dep in dependencies {
97
101
  match dep {
98
- CellID::Input(InputCellID(id)) => if id >= self.inputs.len() { return Err(dep) },
99
- CellID::Compute(ComputeCellID(id)) => if id >= self.computes.len() { return Err(dep) },
102
+ CellID::Input(InputCellID(id)) => if id >= self.inputs.len() {
103
+ return Err(dep);
104
+ },
105
+ CellID::Compute(ComputeCellID(id)) => if id >= self.computes.len() {
106
+ return Err(dep);
107
+ },
100
108
  }
101
109
  }
102
110
  let new_id = ComputeCellID(self.computes.len());
103
111
  for &dep in dependencies {
104
112
  match dep {
105
113
  CellID::Input(InputCellID(id)) => self.inputs[id].dependents.push(new_id),
106
- CellID::Compute(ComputeCellID(id)) => self.computes[id].cell.dependents.push(new_id),
114
+ CellID::Compute(ComputeCellID(id)) => {
115
+ self.computes[id].cell.dependents.push(new_id)
116
+ }
107
117
  }
108
118
  }
109
- let inputs: Vec<_> = dependencies.iter().map(|&id| self.value(id).unwrap()).collect();
119
+ let inputs: Vec<_> = dependencies
120
+ .iter()
121
+ .map(|&id| self.value(id).unwrap())
122
+ .collect();
110
123
  let initial = compute_func(&inputs);
111
- self.computes.push(ComputeCell::new(initial, dependencies.to_vec(), compute_func));
124
+ self.computes.push(ComputeCell::new(
125
+ initial,
126
+ dependencies.to_vec(),
127
+ compute_func,
128
+ ));
112
129
  Ok(new_id)
113
130
  }
114
131
 
@@ -121,22 +138,30 @@ impl <'a, T: Copy + PartialEq> Reactor<'a, T> {
121
138
 
122
139
  pub fn set_value(&mut self, id: InputCellID, new_value: T) -> bool {
123
140
  let InputCellID(id) = id;
124
- self.inputs.get_mut(id).map(|c| {
125
- c.value = new_value;
126
- c.dependents.clone()
127
- }).map(|deps| {
128
- for &d in deps.iter() {
129
- self.update_dependent(d);
130
- }
131
- // We can only fire callbacks after all dependents have updated.
132
- // So we can't combine this for loop with the one above!
133
- for d in deps {
134
- self.fire_callbacks(d);
135
- }
136
- }).is_some()
141
+ self.inputs
142
+ .get_mut(id)
143
+ .map(|c| {
144
+ c.value = new_value;
145
+ c.dependents.clone()
146
+ })
147
+ .map(|deps| {
148
+ for &d in deps.iter() {
149
+ self.update_dependent(d);
150
+ }
151
+ // We can only fire callbacks after all dependents have updated.
152
+ // So we can't combine this for loop with the one above!
153
+ for d in deps {
154
+ self.fire_callbacks(d);
155
+ }
156
+ })
157
+ .is_some()
137
158
  }
138
159
 
139
- pub fn add_callback<F: FnMut(T) -> () + 'a>(&mut self, id: ComputeCellID, callback: F) -> Option<CallbackID> {
160
+ pub fn add_callback<F: FnMut(T) -> () + 'a>(
161
+ &mut self,
162
+ id: ComputeCellID,
163
+ callback: F,
164
+ ) -> Option<CallbackID> {
140
165
  let ComputeCellID(id) = id;
141
166
  self.computes.get_mut(id).map(|c| {
142
167
  c.callbacks_issued += 1;
@@ -146,7 +171,11 @@ impl <'a, T: Copy + PartialEq> Reactor<'a, T> {
146
171
  })
147
172
  }
148
173
 
149
- pub fn remove_callback(&mut self, cell: ComputeCellID, callback: CallbackID) -> Result<(), RemoveCallbackError> {
174
+ pub fn remove_callback(
175
+ &mut self,
176
+ cell: ComputeCellID,
177
+ callback: CallbackID,
178
+ ) -> Result<(), RemoveCallbackError> {
150
179
  let ComputeCellID(cell) = cell;
151
180
  match self.computes.get_mut(cell) {
152
181
  Some(c) => match c.callbacks.remove(&callback) {
@@ -167,7 +196,10 @@ impl <'a, T: Copy + PartialEq> Reactor<'a, T> {
167
196
  Some(c) => (&c.dependencies, &c.f, c.cell.dependents.clone()),
168
197
  None => panic!("Cell to update disappeared while querying"),
169
198
  };
170
- let inputs: Vec<_> = dependencies.iter().map(|&id| self.value(id).unwrap()).collect();
199
+ let inputs: Vec<_> = dependencies
200
+ .iter()
201
+ .map(|&id| self.value(id).unwrap())
202
+ .collect();
171
203
  (f(&inputs), dependents)
172
204
  };
173
205
 
@@ -179,7 +211,7 @@ impl <'a, T: Copy + PartialEq> Reactor<'a, T> {
179
211
  return;
180
212
  }
181
213
  c.cell.value = new_value;
182
- },
214
+ }
183
215
  None => panic!("Cell to update disappeared while updating"),
184
216
  }
185
217
 
@@ -195,14 +227,14 @@ impl <'a, T: Copy + PartialEq> Reactor<'a, T> {
195
227
  if c.cell.value == c.cell.last_value {
196
228
  // Value hasn't changed since last callback fire.
197
229
  // We thus shouldn't fire the callbacks.
198
- return
230
+ return;
199
231
  }
200
232
  for cb in c.callbacks.values_mut() {
201
233
  cb(c.cell.value);
202
234
  }
203
235
  c.cell.last_value = c.cell.value;
204
236
  c.cell.dependents.clone()
205
- },
237
+ }
206
238
  None => panic!("Callback cell disappeared"),
207
239
  };
208
240