2 use std::io::prelude::*;
3 use std::collections::HashMap;
5 pub fn read_file(path: &str) -> Result<String, std::io::Error> {
6 let mut s = String::new();
8 .read_to_string(&mut s)?;
12 // needs Copy trait, good for simple types
13 pub fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
14 let mut result = list[0];
23 // expensive for large strings, don't use that
24 pub fn largest_clone<T: PartialOrd + Clone>(list: &[T]) -> T {
25 let mut result = list[0].clone();
34 // good for everything, but more expensive for simple types
35 pub fn largest_ref<T: PartialOrd>(list: &[T]) -> &T {
36 let mut result = &list[0];
45 pub fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
46 if x.len() > y.len() {
53 /// Wrap and cache an expensive calculation
55 /// This calls a closure just once for every distinct argument. Any subsequent
56 /// call to `.value()` with the same argument uses the cached value.
57 pub struct Cacher<T, A, V>
60 A: Eq + Copy + std::hash::Hash,
64 values: HashMap<A, V>,
67 impl<T, A, V> Cacher<T, A, V>
70 A: Eq + Copy + std::hash::Hash,
73 pub fn new(calc: T) -> Cacher<T, A, V> {
74 Cacher { calc, values: HashMap::new() }
77 pub fn value(&mut self, arg: A) -> V {
78 match self.values.get(&arg) {
81 let v = (self.calc)(arg);
82 self.values.insert(arg, v);
94 pub fn new() -> Counter5 {
99 impl Iterator for Counter5 {
102 fn next(&mut self) -> Option<Self::Item> {
113 state: Box<dyn State>,
118 pub fn new() -> Post {
120 state: Box::new(Draft {}),
121 content: String::new(),
125 pub fn add_text(&mut self, text: &str) {
126 self.content.push_str(text);
129 pub fn content(&self) -> &str {
130 self.state.content(self)
133 pub fn request_review(&mut self) {
134 self.state = self.state.request_review();
137 pub fn approve(&mut self) {
138 self.state = self.state.approve();
141 pub fn reject(&mut self) {
142 self.state = self.state.reject();
147 fn request_review(&self) -> Box<dyn State>;
148 fn approve(&mut self) -> Box<dyn State>;
149 fn reject(&self) -> Box<dyn State>;
151 #[allow(unused_variables)]
152 fn content<'a>(&self, post: &'a Post) -> &'a str {
158 impl State for Draft {
159 fn request_review(&self) -> Box<dyn State> {
160 Box::new(PendingReview {acks: 0})
163 fn approve(&mut self) -> Box<dyn State> {
164 // don't change state
168 fn reject(&self) -> Box<dyn State> {
173 struct PendingReview {
177 impl State for PendingReview {
178 fn request_review(&self) -> Box<dyn State> {
179 Box::new(Self {acks: self.acks})
182 fn approve(&mut self) -> Box<dyn State> {
184 Box::new(Published {})
186 Box::new(Self {acks: self.acks + 1})
190 fn reject(&self) -> Box<dyn State> {
196 impl State for Published {
197 fn request_review(&self) -> Box<dyn State> {
201 fn approve(&mut self) -> Box<dyn State> {
202 Box::new(Published {})
205 fn reject(&self) -> Box<dyn State> {
209 fn content<'a>(&self, post: &'a Post) -> &'a str {
214 // state encoded as types; this is the "approved" state
220 pub fn new() -> TPostDraft {
221 TPostDraft {content: String::new()}
224 pub fn content(&self) -> &str {
229 pub struct TPostDraft {
234 pub fn add_text(&mut self, text: &str) {
235 self.content.push_str(text);
238 pub fn request_review(self) -> TPostReview {
239 TPostReview {content: self.content}
243 pub struct TPostReview {
248 pub fn approve(self) -> TPost {
249 TPost {content: self.content}
252 pub fn reject(self) -> TPostDraft {
253 TPostDraft {content: self.content}