Skip to content

Commit df5dae1

Browse files
committed
config: cleanup decoding logic significantly
Previously, we were jumping through a lot of hoops to make things work with the automatically derived RustcDecodable logic. Biting the bullet and implementing the Decodable trait for PinConfig directly removes a bunch of code and increases cohesion quite a bit. Signed-off-by: Paul Osborne <[email protected]>
1 parent c61efad commit df5dae1

File tree

1 file changed

+22
-52
lines changed

1 file changed

+22
-52
lines changed

src/config.rs

Lines changed: 22 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use glob::glob;
44
use rustc_serialize::{Decodable, Decoder};
5-
use std::collections::{BTreeSet, HashMap};
5+
use std::collections::BTreeSet;
66
use std::fs::{self, File};
77
use std::io;
88
use std::io::prelude::*;
@@ -19,15 +19,6 @@ impl From<sysfs_gpio::Direction> for Direction {
1919
}
2020
}
2121

22-
#[derive(RustcDecodable, Clone, Debug, PartialEq)]
23-
struct RawPinConfig {
24-
pub num: u64,
25-
pub direction: Option<Direction>,
26-
pub names: BTreeSet<String>,
27-
pub export: Option<bool>,
28-
pub active_low: Option<bool>,
29-
}
30-
3122
#[derive(Debug, Clone, PartialEq)]
3223
pub struct PinConfig {
3324
pub num: u64,
@@ -37,37 +28,7 @@ pub struct PinConfig {
3728
pub active_low: bool,
3829
}
3930

40-
impl Into<PinConfig> for RawPinConfig {
41-
fn into(self) -> PinConfig {
42-
let default_direction = Direction(sysfs_gpio::Direction::In);
43-
PinConfig {
44-
num: self.num,
45-
direction: self.direction.unwrap_or(default_direction).0,
46-
names: self.names,
47-
export: self.export.unwrap_or(true),
48-
active_low: self.active_low.unwrap_or(false),
49-
}
50-
}
51-
}
52-
53-
impl Decodable for Direction {
54-
fn decode<D: Decoder>(d: &mut D) -> Result<Direction, D::Error> {
55-
match &try!(d.read_str())[..] {
56-
"in" => Ok(Direction(sysfs_gpio::Direction::In)),
57-
"out" => Ok(Direction(sysfs_gpio::Direction::Out)),
58-
"high" => Ok(Direction(sysfs_gpio::Direction::High)),
59-
"low" => Ok(Direction(sysfs_gpio::Direction::Low)),
60-
_ => Err(d.error("Expected one of: {in, out, high, low}")),
61-
}
62-
}
63-
}
64-
6531
#[derive(RustcDecodable, Clone, Debug)]
66-
struct RawGpioConfig {
67-
pub pins: Vec<RawPinConfig>,
68-
}
69-
70-
#[derive(Clone, Debug)]
7132
pub struct GpioConfig {
7233
pub pins: Vec<PinConfig>,
7334
}
@@ -98,11 +59,23 @@ impl From<toml::DecodeError> for Error {
9859
}
9960
}
10061

101-
impl Into<GpioConfig> for RawGpioConfig {
102-
fn into(self) -> GpioConfig {
103-
GpioConfig {
104-
pins: self.pins.into_iter().map(|p| p.into()).collect(),
105-
}
62+
impl Decodable for PinConfig {
63+
fn decode<D: Decoder>(d: &mut D) -> Result<PinConfig, D::Error> {
64+
Ok(PinConfig {
65+
num: try!(d.read_struct_field("num", 0, Decodable::decode)),
66+
direction: d.read_struct_field("direction", 0, |dir_d| {
67+
match &try!(dir_d.read_str())[..] {
68+
"in" => Ok(sysfs_gpio::Direction::In),
69+
"out" => Ok(sysfs_gpio::Direction::Out),
70+
"high" => Ok(sysfs_gpio::Direction::High),
71+
"low" => Ok(sysfs_gpio::Direction::Low),
72+
_ => Err(dir_d.error("Expected one of: {in, out, high, low}")),
73+
}
74+
}).unwrap_or(sysfs_gpio::Direction::In), // default: In
75+
names: d.read_struct_field("names", 0, Decodable::decode).unwrap_or(BTreeSet::new()),
76+
export: d.read_struct_field("export", 0, Decodable::decode).unwrap_or(true),
77+
active_low: d.read_struct_field("active_low", 0, Decodable::decode).unwrap_or(false),
78+
})
10679
}
10780
}
10881

@@ -158,13 +131,10 @@ impl GpioConfig {
158131
pub fn from_str(config: &str) -> Result<GpioConfig, Error> {
159132
let mut parser = toml::Parser::new(config);
160133
let root = try!(parser.parse().ok_or(parser.errors));
161-
let mut d = toml::Decoder::new(toml::Value::Table(root));
162-
let rawcfg: RawGpioConfig = try!(match Decodable::decode(&mut d) {
163-
Ok(rawcfg) => Ok(rawcfg),
134+
match Decodable::decode(&mut toml::Decoder::new(toml::Value::Table(root))) {
135+
Ok(cfg) => Ok(cfg),
164136
Err(e) => Err(Error::from(e)),
165-
});
166-
167-
Ok(rawcfg.into())
137+
}
168138
}
169139

170140
/// Load a GPIO config from the specified path
@@ -311,7 +281,7 @@ names = ["wildcard"]
311281
// basically, just garbage data
312282
let configstr = r"[] -*-..asdf=-=-@#$%^&*()";
313283
match GpioConfig::from_str(configstr) {
314-
Err(Error::ParserErrors(e)) => {},
284+
Err(Error::ParserErrors(_)) => {},
315285
_ => panic!("Did not receive parse error when expected"),
316286
}
317287
}

0 commit comments

Comments
 (0)