comparison rust/src/types.rs @ 611:f3e39e2107fd rust

still doesn't compile, improvements to TemplogError and tokio curl though
author Matt Johnston <matt@ucc.asn.au>
date Tue, 28 Feb 2017 22:58:47 +0800
parents af0dac00d40b
children 5fc41e0833b4
comparison
equal deleted inserted replaced
610:af0dac00d40b 611:f3e39e2107fd
1 use std::collections::HashMap; 1 use std::collections::HashMap;
2 use std::time::{Duration,Instant}; 2 use std::time::{Duration,Instant};
3 use std::error::Error; 3 use std::error::Error;
4 use std::fmt; 4 use std::fmt;
5 use std::io;
5 use std::cmp; 6 use std::cmp;
6 use std::cell::Cell; 7 use std::cell::Cell;
7 use std::iter::FromIterator; 8 use std::iter::FromIterator;
8 9 use std;
10
11 use futures::{Stream,IntoFuture};
9 use serde::{Deserialize,Serialize}; 12 use serde::{Deserialize,Serialize};
13 use toml;
14 use curl;
15 use serde_json;
10 16
11 #[derive(Deserialize, Serialize, Debug)] 17 #[derive(Deserialize, Serialize, Debug)]
12 pub struct Params { 18 pub struct Params {
13 pub fridge_setpoint: f32, 19 pub fridge_setpoint: f32,
14 pub fridge_difference: f32, 20 pub fridge_difference: f32,
75 self.temps.get(name).map(|f| *f) 81 self.temps.get(name).map(|f| *f)
76 } 82 }
77 } 83 }
78 84
79 #[derive(Debug)] 85 #[derive(Debug)]
86 pub enum TemplogErrorKind {
87 None,
88 Io(io::Error),
89 ParseFloat(std::num::ParseFloatError),
90 TomlDe(toml::de::Error),
91 SerdeJson(serde_json::Error),
92 Curl(curl::Error),
93 }
94
95 #[derive(Debug)]
80 pub struct TemplogError { 96 pub struct TemplogError {
81 desc: String, 97 desc: String,
98 kind: TemplogErrorKind,
82 } 99 }
83 100
84 impl Error for TemplogError { 101 impl Error for TemplogError {
85 fn description(&self) -> &str { &self.desc } 102 fn description(&self) -> &str {
86 fn cause(&self) -> Option<&Error> { None } 103 &format!("{}", self)
104 }
105
106 fn cause(&self) -> Option<&Error> {
107 match self.kind {
108 TemplogErrorKind::None => None,
109 TemplogErrorKind::Io(e) => Some(&e),
110 TemplogErrorKind::ParseFloat(e) => Some(&e),
111 TemplogErrorKind::TomlDe(e) => Some(&e),
112 TemplogErrorKind::SerdeJson(e) => Some(&e),
113 TemplogErrorKind::Curl(e) => Some(&e),
114 }
115 }
87 } 116 }
88 117
89 impl fmt::Display for TemplogError { 118 impl fmt::Display for TemplogError {
90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 119 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91 write!(f, "TemplogError: {}", self.desc); 120 match self.kind {
121 TemplogErrorKind::None => write!(f, "Templog Error: {}", self.desc),
122 TemplogErrorKind::Io(e) => write!(f, "Templog IO error {}: {}", self.desc, e),
123 TemplogErrorKind::TomlDe(e) => write!(f, "Templog toml error {}: {}", self.desc, e),
124 TemplogErrorKind::SerdeJson(e) => write!(f, "Json decode error {}: {}", self.desc, e),
125 TemplogErrorKind::ParseFloat(e) => write!(f, "Templog parse error {}: {}", self.desc, e),
126 TemplogErrorKind::Curl(e) => write!(f, "Templog curl http error {}: {}", self.desc, e),
127 };
92 Ok(()) 128 Ok(())
93 } 129 }
94
95
96 } 130 }
97 131
98 impl TemplogError { 132 impl TemplogError {
99 pub fn new(desc: &str) -> Self { 133 pub fn new(desc: &str) -> Self {
100 TemplogError { 134 TemplogError {
101 desc: desc.to_string(), 135 desc: desc.to_string(),
102 } 136 kind: TemplogErrorKind::None,
103 } 137 }
104 } 138 }
105 139
140 pub fn new_io(desc: &str, e: io::Error) -> Self {
141 TemplogError {
142 desc: desc.to_string(),
143 kind: TemplogErrorKind::Io(e),
144 }
145 }
146
147 pub fn new_toml_de(desc: &str, e: toml::de::Error) -> Self {
148 TemplogError {
149 desc: desc.to_string(),
150 kind: TemplogErrorKind::TomlDe(e),
151 }
152 }
153
154 pub fn new_parse_float(desc: &str, e: std::num::ParseFloatError) -> Self {
155 TemplogError {
156 desc: desc.to_string(),
157 kind: TemplogErrorKind::ParseFloat(e),
158 }
159 }
160
161 pub fn new_curl(desc: &str, e: curl::Error) -> Self {
162 TemplogError {
163 desc: desc.to_string(),
164 kind: TemplogErrorKind::Curl(e),
165 }
166 }
167
168 pub fn new_serde_json(desc: &str, e: serde_json::Error) -> Self {
169 TemplogError {
170 desc: desc.to_string(),
171 kind: TemplogErrorKind::SerdeJson(e),
172 }
173 }
174 }
175
176 impl From<io::Error> for TemplogError {
177 fn from(e: io::Error) -> Self {
178 TemplogError::new_io("", e)
179 }
180 }
181
182 impl From<toml::de::Error> for TemplogError {
183 fn from(e: toml::de::Error) -> Self {
184 TemplogError::new_toml_de("", e)
185 }
186 }
187
188 impl From<std::num::ParseFloatError> for TemplogError {
189 fn from(e: std::num::ParseFloatError) -> Self {
190 TemplogError::new_parse_float("", e)
191 }
192 }
193
194 impl From<curl::Error> for TemplogError {
195 fn from(e: curl::Error) -> Self {
196 TemplogError::new_curl("", e)
197 }
198 }
199
200 impl From<serde_json::Error> for TemplogError {
201 fn from(e: serde_json::Error) -> Self {
202 TemplogError::new_serde_json("", e)
203 }
204 }
106 205
107 /// Call closures with a rate limit. Useful for log message ratelimiting 206 /// Call closures with a rate limit. Useful for log message ratelimiting
207 #[derive(Clone)]
108 pub struct NotTooOften { 208 pub struct NotTooOften {
109 last: Cell<Instant>, 209 last: Cell<Instant>,
110 limit: Duration, 210 limit: Duration,
111 } 211 }
112 212
198 p.start = cmp::max(p.start, begin); 298 p.start = cmp::max(p.start, begin);
199 } 299 }
200 } 300 }
201 } 301 }
202 302
303 /// Takes a stream and returns a stream without errors.
304 pub fn consume_errors<S>(s: S) -> Box<Stream<Item=S::Item, Error=S::Error>>
305 // XXX not sure why 'static is really necessary here?
306 where
307 S: Stream+Send+'static,
308 <S as Stream>::Error: std::fmt::Display+Send+'static,
309 <S as Stream>::Item: Send+'static,
310 {
311 s.then(|r| {
312 match r {
313 Ok(v) => Ok(Some(v)),
314 Err(e) => {
315 debug!("Stream error: {}", e);
316 Ok(None)
317 }
318 }
319 })
320 .filter_map(|p| p).boxed()
321 }