diff --git a/.gitignore b/.gitignore index a68ba4c7f..5efb0dd0e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ Cargo.lock # Intellij IDEA .idea + +# macOS DS_Store files +.DS_Store diff --git a/examples/blinky.rs b/examples/blinky.rs index 883dbad98..156273a81 100644 --- a/examples/blinky.rs +++ b/examples/blinky.rs @@ -8,10 +8,10 @@ extern crate sysfs_gpio; -use sysfs_gpio::{Direction, Pin}; -use std::time::Duration; -use std::thread::sleep; use std::env; +use std::thread::sleep; +use std::time::Duration; +use sysfs_gpio::{Direction, Pin}; struct Arguments { pin: u64, @@ -58,20 +58,18 @@ fn get_args() -> Option { Err(_) => return None, }; Some(Arguments { - pin: pin, - duration_ms: duration_ms, - period_ms: period_ms, - }) + pin: pin, + duration_ms: duration_ms, + period_ms: period_ms, + }) } fn main() { match get_args() { None => print_usage(), - Some(args) => { - match blink_my_led(args.pin, args.duration_ms, args.period_ms) { - Ok(()) => println!("Success!"), - Err(err) => println!("We have a blinking problem: {}", err), - } - } + Some(args) => match blink_my_led(args.pin, args.duration_ms, args.period_ms) { + Ok(()) => println!("Success!"), + Err(err) => println!("We have a blinking problem: {}", err), + }, } } diff --git a/examples/interrupt.rs b/examples/interrupt.rs index 37136861e..ef0b4e5ea 100644 --- a/examples/interrupt.rs +++ b/examples/interrupt.rs @@ -8,10 +8,10 @@ extern crate sysfs_gpio; -use sysfs_gpio::{Direction, Edge, Pin}; use std::env; use std::io::prelude::*; use std::io::stdout; +use sysfs_gpio::{Direction, Edge, Pin}; fn interrupt(pin: u64) -> sysfs_gpio::Result<()> { let input = Pin::new(pin); @@ -38,12 +38,10 @@ fn main() { println!("Usage: ./interrupt "); } else { match args[1].parse::() { - Ok(pin) => { - match interrupt(pin) { - Ok(()) => println!("Interrupting Complete!"), - Err(err) => println!("Error: {}", err), - } - } + Ok(pin) => match interrupt(pin) { + Ok(()) => println!("Interrupting Complete!"), + Err(err) => println!("Error: {}", err), + }, Err(_) => println!("Usage: ./interrupt "), } } diff --git a/examples/poll.rs b/examples/poll.rs index a5cdb46b4..1482f0173 100644 --- a/examples/poll.rs +++ b/examples/poll.rs @@ -8,10 +8,10 @@ extern crate sysfs_gpio; -use sysfs_gpio::{Direction, Pin}; use std::env; use std::thread::sleep; use std::time::Duration; +use sysfs_gpio::{Direction, Pin}; fn poll(pin_num: u64) -> sysfs_gpio::Result<()> { // NOTE: this currently runs forever and as such if @@ -40,12 +40,10 @@ fn main() { println!("Usage: ./poll "); } else { match args[1].parse::() { - Ok(pin) => { - match poll(pin) { - Ok(()) => println!("Polling Complete!"), - Err(err) => println!("Error: {}", err), - } - } + Ok(pin) => match poll(pin) { + Ok(()) => println!("Polling Complete!"), + Err(err) => println!("Error: {}", err), + }, Err(_) => println!("Usage: ./poll "), } } diff --git a/examples/tokio.rs b/examples/tokio.rs index 607c6989c..9395e9c51 100644 --- a/examples/tokio.rs +++ b/examples/tokio.rs @@ -9,7 +9,7 @@ extern crate tokio; use std::env; #[cfg(feature = "use_tokio")] -use futures::{Future, lazy, Stream}; +use futures::{lazy, Future, Stream}; #[cfg(feature = "use_tokio")] use sysfs_gpio::{Direction, Edge, Pin}; @@ -27,12 +27,15 @@ fn stream(pin_nums: Vec) -> sysfs_gpio::Result<()> { pin.export().unwrap(); pin.set_direction(Direction::In).unwrap(); pin.set_edge(Edge::BothEdges).unwrap(); - tokio::spawn(pin.get_value_stream().unwrap() - .for_each(move |val| { - println!("Pin {} changed value to {}", i, val); - Ok(()) - }) - .map_err(|_| ())); + tokio::spawn( + pin.get_value_stream() + .unwrap() + .for_each(move |val| { + println!("Pin {} changed value to {}", i, val); + Ok(()) + }) + .map_err(|_| ()), + ); } Ok(()) }); diff --git a/src/error.rs b/src/error.rs index f79e7610b..48ca47cc1 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,7 +1,7 @@ +use nix; use std::convert; use std::fmt; use std::io; -use nix; #[derive(Debug)] pub enum Error { @@ -25,7 +25,7 @@ impl ::std::error::Error for Error { } } - fn cause(&self) -> Option<&::std::error::Error> { + fn cause(&self) -> Option<&dyn std::error::Error> { match *self { Error::Io(ref e) => Some(e), _ => None, @@ -44,7 +44,6 @@ impl fmt::Display for Error { } } - impl convert::From for Error { fn from(e: io::Error) -> Error { Error::Io(e) diff --git a/src/lib.rs b/src/lib.rs index b64b6e61c..24fb65de6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,17 +51,19 @@ extern crate tokio; use std::fs; use std::fs::File; -use std::io::{self, SeekFrom}; +use std::io; use std::io::prelude::*; +#[cfg(any(target_os = "linux", target_os = "android"))] +use std::io::SeekFrom; use std::os::unix::prelude::*; use std::path::Path; #[cfg(feature = "use_tokio")] use futures::{Async, Poll, Stream}; #[cfg(feature = "mio-evented")] -use mio::Evented; -#[cfg(feature = "mio-evented")] use mio::unix::EventedFd; +#[cfg(feature = "mio-evented")] +use mio::Evented; #[cfg(any(target_os = "linux", target_os = "android"))] use nix::sys::epoll::*; use nix::unistd::close; @@ -95,10 +97,15 @@ pub enum Edge { #[macro_export] macro_rules! try_unexport { - ($gpio:ident, $e:expr) => (match $e { - Ok(res) => res, - Err(e) => { try!($gpio.unexport()); return Err(e) }, - }); + ($gpio:ident, $e:expr) => { + match $e { + Ok(res) => res, + Err(e) => { + try!($gpio.unexport()); + return Err(e); + } + } + }; } pub type Result = ::std::result::Result; @@ -108,19 +115,24 @@ pub type Result = ::std::result::Result; /// Typically, one would just use seek() for this sort of thing, /// but for certain files (e.g. in sysfs), you need to actually /// read it. +#[cfg(any(target_os = "linux", target_os = "android"))] fn flush_input_from_file(dev_file: &mut File, max: usize) -> io::Result { let mut s = String::with_capacity(max); dev_file.read_to_string(&mut s) } /// Get the pin value from the provided file +#[cfg(any(target_os = "linux", target_os = "android"))] fn get_value_from_file(dev_file: &mut File) -> Result { let mut s = String::with_capacity(10); dev_file.seek(SeekFrom::Start(0))?; dev_file.read_to_string(&mut s)?; match s[..1].parse::() { Ok(n) => Ok(n), - Err(_) => Err(Error::Unexpected(format!("Unexpected value file contents: {:?}", s))), + Err(_) => Err(Error::Unexpected(format!( + "Unexpected value file contents: {:?}", + s + ))), } } @@ -166,9 +178,11 @@ impl Pin { // determine if this is valid and figure out the pin_num if !fs::metadata(&pb)?.is_dir() { - return Err(Error::Unexpected("Provided path not a directory or symlink to \ + return Err(Error::Unexpected( + "Provided path not a directory or symlink to \ a directory" - .to_owned())); + .to_owned(), + )); } let num = Pin::extract_pin_from_path(&pb)?; Ok(Pin::new(num)) @@ -179,7 +193,7 @@ impl Pin { path.as_ref() .file_name() .and_then(|filename| filename.to_str()) - .and_then(|filename_str| filename_str.trim_left_matches("gpio").parse::().ok()) + .and_then(|filename_str| filename_str.trim_start_matches("gpio").parse::().ok()) .ok_or(Error::InvalidPath(format!("{:?}", path.as_ref()))) } @@ -210,11 +224,10 @@ impl Pin { /// ``` #[inline] pub fn with_exported Result<()>>(&self, closure: F) -> Result<()> { - self.export()?; match closure() { Ok(()) => { - try!(self.unexport()); + self.unexport()?; Ok(()) } Err(err) => { @@ -260,8 +273,7 @@ impl Pin { pub fn export(&self) -> Result<()> { if fs::metadata(&format!("/sys/class/gpio/gpio{}", self.pin_num)).is_err() { let mut export_file = File::create("/sys/class/gpio/export")?; - export_file - .write_all(format!("{}", self.pin_num).as_bytes())?; + export_file.write_all(format!("{}", self.pin_num).as_bytes())?; } Ok(()) } @@ -275,8 +287,7 @@ impl Pin { pub fn unexport(&self) -> Result<()> { if fs::metadata(&format!("/sys/class/gpio/gpio{}", self.pin_num)).is_ok() { let mut unexport_file = File::create("/sys/class/gpio/unexport")?; - unexport_file - .write_all(format!("{}", self.pin_num).as_bytes())?; + unexport_file.write_all(format!("{}", self.pin_num).as_bytes())?; } Ok(()) } @@ -289,15 +300,16 @@ impl Pin { /// Get the direction of the Pin pub fn get_direction(&self) -> Result { match self.read_from_device_file("direction") { - Ok(s) => { - match s.trim() { - "in" => Ok(Direction::In), - "out" => Ok(Direction::Out), - "high" => Ok(Direction::High), - "low" => Ok(Direction::Low), - other => Err(Error::Unexpected(format!("direction file contents {}", other))), - } - } + Ok(s) => match s.trim() { + "in" => Ok(Direction::In), + "out" => Ok(Direction::Out), + "high" => Ok(Direction::High), + "low" => Ok(Direction::Low), + other => Err(Error::Unexpected(format!( + "direction file contents {}", + other + ))), + }, Err(e) => Err(::std::convert::From::from(e)), } } @@ -316,12 +328,15 @@ impl Pin { /// not support changing the direction of a pin in userspace. If /// this is the case, you will get an error. pub fn set_direction(&self, dir: Direction) -> Result<()> { - self.write_to_device_file("direction", match dir { + self.write_to_device_file( + "direction", + match dir { Direction::In => "in", Direction::Out => "out", Direction::High => "high", Direction::Low => "low", - })?; + }, + )?; Ok(()) } @@ -334,13 +349,11 @@ impl Pin { /// on the GPIO "active_low" entry). pub fn get_value(&self) -> Result { match self.read_from_device_file("value") { - Ok(s) => { - match s.trim() { - "1" => Ok(1), - "0" => Ok(0), - other => Err(Error::Unexpected(format!("value file contents {}", other))), - } - } + Ok(s) => match s.trim() { + "1" => Ok(1), + "0" => Ok(0), + other => Err(Error::Unexpected(format!("value file contents {}", other))), + }, Err(e) => Err(::std::convert::From::from(e)), } } @@ -351,10 +364,13 @@ impl Pin { /// A 0 value will set the pin low and any other value will /// set the pin high (1 is typical). pub fn set_value(&self, value: u8) -> Result<()> { - self.write_to_device_file("value", match value { + self.write_to_device_file( + "value", + match value { 0 => "0", _ => "1", - })?; + }, + )?; Ok(()) } @@ -365,15 +381,16 @@ impl Pin { /// for interrupts. pub fn get_edge(&self) -> Result { match self.read_from_device_file("edge") { - Ok(s) => { - match s.trim() { - "none" => Ok(Edge::NoInterrupt), - "rising" => Ok(Edge::RisingEdge), - "falling" => Ok(Edge::FallingEdge), - "both" => Ok(Edge::BothEdges), - other => Err(Error::Unexpected(format!("Unexpected file contents {}", other))), - } - } + Ok(s) => match s.trim() { + "none" => Ok(Edge::NoInterrupt), + "rising" => Ok(Edge::RisingEdge), + "falling" => Ok(Edge::FallingEdge), + "both" => Ok(Edge::BothEdges), + other => Err(Error::Unexpected(format!( + "Unexpected file contents {}", + other + ))), + }, Err(e) => Err(::std::convert::From::from(e)), } } @@ -384,12 +401,15 @@ impl Pin { /// result in `poll()` returning. This call will return an Error /// if the pin does not allow interrupts. pub fn set_edge(&self, edge: Edge) -> Result<()> { - self.write_to_device_file("edge", match edge { + self.write_to_device_file( + "edge", + match edge { Edge::NoInterrupt => "none", Edge::RisingEdge => "rising", Edge::FallingEdge => "falling", Edge::BothEdges => "both", - })?; + }, + )?; Ok(()) } @@ -397,13 +417,14 @@ impl Pin { /// Get polarity of the Pin (`true` is active low) pub fn get_active_low(&self) -> Result { match self.read_from_device_file("active_low") { - Ok(s) => { - match s.trim() { - "1" => Ok(true), - "0" => Ok(false), - other => Err(Error::Unexpected(format!("active_low file contents {}", other))), - } - } + Ok(s) => match s.trim() { + "1" => Ok(true), + "0" => Ok(false), + other => Err(Error::Unexpected(format!( + "active_low file contents {}", + other + ))), + }, Err(e) => Err(::std::convert::From::from(e)), } } @@ -413,11 +434,13 @@ impl Pin { /// This will affect "rising" and "falling" edge triggered /// configuration. pub fn set_active_low(&self, active_low: bool) -> Result<()> { - self.write_to_device_file("active_low", - match active_low { - true => "1", - false => "0", - })?; + self.write_to_device_file( + "active_low", + match active_low { + true => "1", + false => "0", + }, + )?; Ok(()) } @@ -453,7 +476,6 @@ impl Pin { PinStream::init_with_handle(self.clone(), handle) } - /// Get a Stream of pin interrupts for this pin /// /// The PinStream object can be used with the `tokio` crate. You should probably call @@ -478,7 +500,10 @@ impl Pin { /// This method is only available when the `use_tokio` crate feature is enabled. #[cfg(feature = "use_tokio")] pub fn get_value_stream_with_handle(&self, handle: &Handle) -> Result { - Ok(PinValueStream(PinStream::init_with_handle(self.clone(), handle)?)) + Ok(PinValueStream(PinStream::init_with_handle( + self.clone(), + handle, + )?)) } /// Get a Stream of pin values for this pin @@ -537,13 +562,11 @@ impl PinPoller { let mut event = EpollEvent::new(EpollFlags::EPOLLPRI | EpollFlags::EPOLLET, 0u64); match epoll_ctl(epoll_fd, EpollOp::EpollCtlAdd, devfile_fd, &mut event) { - Ok(_) => { - Ok(PinPoller { - pin_num: pin_num, - devfile: devfile, - epoll_fd: epoll_fd, - }) - } + Ok(_) => Ok(PinPoller { + pin_num: pin_num, + devfile: devfile, + epoll_fd: epoll_fd, + }), Err(err) => { let _ = close(epoll_fd); // cleanup Err(::std::convert::From::from(err)) @@ -552,7 +575,7 @@ impl PinPoller { } #[cfg(not(any(target_os = "linux", target_os = "android")))] - pub fn new(pin_num: u64) -> Result { + pub fn new(_pin_num: u64) -> Result { Err(Error::Unsupported("PinPoller".into())) } @@ -580,13 +603,13 @@ impl PinPoller { let mut events: [EpollEvent; 1] = [dummy_event]; let cnt = epoll_wait(self.epoll_fd, &mut events, timeout_ms)?; Ok(match cnt { - 0 => None, // timeout - _ => Some(get_value_from_file(&mut self.devfile)?), - }) + 0 => None, // timeout + _ => Some(get_value_from_file(&mut self.devfile)?), + }) } #[cfg(not(any(target_os = "linux", target_os = "android")))] - pub fn poll(&mut self, timeout_ms: isize) -> Result> { + pub fn poll(&mut self, _timeout_ms: isize) -> Result> { Err(Error::Unsupported("PinPoller".into())) } } @@ -616,21 +639,23 @@ impl AsyncPinPoller { #[cfg(feature = "mio-evented")] impl Evented for AsyncPinPoller { - fn register(&self, - poll: &mio::Poll, - token: mio::Token, - interest: mio::Ready, - opts: mio::PollOpt) - -> io::Result<()> { + fn register( + &self, + poll: &mio::Poll, + token: mio::Token, + interest: mio::Ready, + opts: mio::PollOpt, + ) -> io::Result<()> { EventedFd(&self.devfile.as_raw_fd()).register(poll, token, interest, opts) } - fn reregister(&self, - poll: &mio::Poll, - token: mio::Token, - interest: mio::Ready, - opts: mio::PollOpt) - -> io::Result<()> { + fn reregister( + &self, + poll: &mio::Poll, + token: mio::Token, + interest: mio::Ready, + opts: mio::PollOpt, + ) -> io::Result<()> { EventedFd(&self.devfile.as_raw_fd()).reregister(poll, token, interest, opts) } @@ -649,9 +674,9 @@ pub struct PinStream { impl PinStream { pub fn init_with_handle(pin: Pin, handle: &Handle) -> Result { Ok(PinStream { - evented: PollEvented::new(pin.get_async_poller()?, &handle)?, - skipped_first_event: false, - }) + evented: PollEvented::new(pin.get_async_poller()?, &handle)?, + skipped_first_event: false, + }) } } @@ -659,9 +684,9 @@ impl PinStream { impl PinStream { pub fn init(pin: Pin) -> Result { Ok(PinStream { - evented: PollEvented::new(pin.get_async_poller()?, &Handle::default())?, - skipped_first_event: false, - }) + evented: PollEvented::new(pin.get_async_poller()?, &Handle::default())?, + skipped_first_event: false, + }) } } @@ -672,7 +697,7 @@ impl Stream for PinStream { fn poll(&mut self) -> Poll, Self::Error> { Ok(match self.evented.poll_read() { - Async::Ready(()) => { + Async::Ready(()) => { self.evented.need_read(); if self.skipped_first_event { Async::Ready(Some(())) @@ -681,8 +706,8 @@ impl Stream for PinStream { Async::NotReady } } - Async::NotReady => Async::NotReady, - }) + Async::NotReady => Async::NotReady, + }) } }