diff --git a/src/SUMMARY.md b/src/SUMMARY.md index d47311f..a60aa4e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -12,6 +12,7 @@ - [RcChars](./exercises/rcchars.md) - [Async Fn](./exercises/async_fn.md) - [Get Functions](./exercises/get_functions.md) + - [Linked](./exercises/linked.md) - [Chapter 2](./chapter_2.md) - [AnyStr](./exercises/anystr.md) - [Mode](./exercises/mode.md) diff --git a/src/exercises/linked.md b/src/exercises/linked.md new file mode 100644 index 0000000..74332ba --- /dev/null +++ b/src/exercises/linked.md @@ -0,0 +1,68 @@ +# `Linked` + +Fix (many) errors to make this compile and pass tests: + +```rust +# #[derive(Clone, Copy)] +struct Node<'a> { + next: Option<&'a Self>, + value: &'a str, +} + +struct Linked<'a, F> { + node: Node<'a>, + callback: &'a mut F, +} + +impl<'a, F: FnMut(String)> Linked<'a, F> { +# /* + fn with(&mut self, value: &str) -> Linked<'_, F> { + Self { + node: Node { + next: Some(self.node), +# */ +# fn with<'b>(&'b mut self, value: &'b str) -> Linked<'b, F> { +# Linked { +# node: Node { +# next: Some(&self.node), + value, + }, + callback: self.callback, + } + } + + fn call(&mut self) { + let mut node = self.node; + let mut value = node.value.to_string(); + while let Some(next) = node.next { + value += next.value; +# /* + node = next; + } + self.callback(value); +# */ +# node = *next; } +# (self.callback)(value); + } +} + +let mut vec = vec![]; + + +let mut linked = Linked { + node: Node { next: None, value: "0" }, + callback: &mut |value| vec.push(value), +}; + +// why does removing code below cause the instantiation to fail? + +linked.call(); +{ + let mut linked = linked.with("1"); + linked.with("2").call(); + linked.with("3").call(); +} +linked.with("4").call(); + +assert_eq!(vec, ["0", "210", "310", "40"]); +```