tokio_wifiscanner/
lib.rs

1// Copyright 2016 Mark Sta Ana.
2// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
3// http://www.apache.org/licenses/LICENSE-2.0>, at your option.
4// This file may not be copied, modified, or distributed except
5// according to those terms.
6
7// Inspired by Maurice Svay's node-wifiscanner (https://github.com/mauricesvay/node-wifiscanner)
8
9//! A crate to list WiFi hotspots in your area.
10//!
11//! As of v0.5.x now supports macOS, Linux and Windows. :tada:
12//!
13//! # Usage
14//!
15//! This crate is on [crates.io](https://crates.io/crates/tokio-wifiscanner) and can be
16//! used by adding `tokio-wifiscanner` to the dependencies in your project's `Cargo.toml`.
17//!
18//! ```toml
19//! [dependencies]
20//! tokio-wifiscanner = "0.2.*"
21//! ```
22//!
23//! and this to your crate root:
24//!
25//! ```rust
26//! extern crate tokio_wifiscanner;
27//! ```
28//!
29//! # Example
30//!
31//! ```
32//!#[tokio::main(flavor = "current_thread")]
33//!async fn main() {
34//!    let networks = tokio_wifiscanner::scan().await.expect("Cannot scan network");
35//!    for network in networks {
36//!        println!(
37//!            "{} {:15} {:10} {:4} {}",
38//!            network.mac, network.ssid, network.channel, network.signal_level, network.security
39//!        );
40//!    }
41//!}
42//! ```
43//!
44//! Alternatively if you've cloned the the Git repo, you can run the above examples
45//! using: `cargo run --example scan`.
46
47//TODO need to find a way to move these out of lib and into sys or better still windows module
48#[cfg(target_os = "windows")]
49#[macro_use]
50extern crate itertools;
51#[cfg(target_os = "windows")]
52extern crate regex;
53
54mod sys;
55
56use std::fmt;
57use std::process::ExitStatus;
58
59type Result<T> = std::result::Result<T, Error>;
60
61#[allow(missing_docs)]
62#[derive(Debug, PartialEq, Eq)]
63pub enum Error {
64    SyntaxRegexError,
65    CommandNotFound,
66    CommandFailed(ExitStatus, String),
67    NoMatch,
68    FailedToParse,
69    NoValue,
70    HeaderNotFound(&'static str),
71}
72
73/// Wifi struct used to return information about wifi hotspots
74#[derive(Debug, PartialEq, Eq, Default, Clone)]
75pub struct Wifi {
76    /// mac address
77    pub mac: String,
78    /// hotspot name
79    pub ssid: String,
80    pub channel: String,
81    /// wifi signal strength in dBm
82    pub signal_level: String,
83    /// this field is currently empty in the Linux version of the lib
84    pub security: String,
85}
86
87impl fmt::Display for Error {
88    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89        match self {
90            Error::SyntaxRegexError => write!(f, "An error occured during syntax check"),
91            Error::CommandNotFound => write!(f, "Couldn't find command"),
92            Error::CommandFailed(status, reason) => {
93                write!(f, "Command failed with exit status {}: {}", status, reason)
94            }
95            Error::NoMatch => write!(f, "Couldn't match"),
96            Error::FailedToParse => write!(f, "Failed to parse command"),
97            Error::NoValue => write!(f, "Value expected but is not present"),
98            Error::HeaderNotFound(header) => {
99                write!(f, "Did not find header {} but expected it", header)
100            }
101        }
102    }
103}
104
105impl std::error::Error for Error {}
106
107/// Returns a list of WiFi hotspots in your area.
108/// Uses `airport` on macOS and `iw` on Linux.
109pub async fn scan() -> Result<Vec<Wifi>> {
110    crate::sys::scan().await
111}