Bug 1396821 - [geckodriver] Apply rustfmt other geckodriver modules. r=ato draft
authorHenrik Skupin <mail@hskupin.info>
Wed, 22 Aug 2018 10:28:07 +0200
changeset 830714 0e8d053262855b3b7f897f998ef069f57f3568d2
parent 830713 9f6a18d1f3be15237133ce7e9b0bd7f0d8126429
child 830715 ca3b49695926adb5ec2ae0eb4cdfd4335a740467
push id118848
push userbmo:hskupin@gmail.com
push dateWed, 22 Aug 2018 10:11:40 +0000
reviewersato
bugs1396821
milestone63.0a1
Bug 1396821 - [geckodriver] Apply rustfmt other geckodriver modules. r=ato MozReview-Commit-ID: IW15TkjVeLT
testing/geckodriver/src/capabilities.rs
testing/geckodriver/src/logging.rs
testing/geckodriver/src/main.rs
--- a/testing/geckodriver/src/capabilities.rs
+++ b/testing/geckodriver/src/capabilities.rs
@@ -6,19 +6,19 @@ use mozprofile::profile::Profile;
 use mozrunner::runner::platform::firefox_default_path;
 use mozversion::{self, firefox_version, Version};
 use regex::bytes::Regex;
 use serde_json::{Map, Value};
 use std::collections::BTreeMap;
 use std::default::Default;
 use std::error::Error;
 use std::fs;
+use std::io;
 use std::io::BufWriter;
 use std::io::Cursor;
-use std::io;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::str::{self, FromStr};
 use webdriver::capabilities::{BrowserCapabilities, Capabilities};
 use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult};
 use zip;
 
 /// Provides matching of `moz:firefoxOptions` and resolution of which Firefox
@@ -29,17 +29,16 @@ use zip;
 /// system Firefox installation or an override, for example given to the
 /// `--binary` flag of geckodriver.
 pub struct FirefoxCapabilities<'a> {
     pub chosen_binary: Option<PathBuf>,
     fallback_binary: Option<&'a PathBuf>,
     version_cache: BTreeMap<PathBuf, String>,
 }
 
-
 impl<'a> FirefoxCapabilities<'a> {
     pub fn new(fallback_binary: Option<&'a PathBuf>) -> FirefoxCapabilities<'a> {
         FirefoxCapabilities {
             chosen_binary: None,
             fallback_binary: fallback_binary,
             version_cache: BTreeMap::new(),
         }
     }
@@ -64,52 +63,54 @@ impl<'a> FirefoxCapabilities<'a> {
                 .ok()
                 .and_then(|x| x.version_string)
                 .or_else(|| {
                     debug!("Trying to read firefox version from binary");
                     self.version_from_binary(binary)
                 });
             if let Some(ref version) = rv {
                 debug!("Found version {}", version);
-                self.version_cache
-                    .insert(binary.clone(), version.clone());
+                self.version_cache.insert(binary.clone(), version.clone());
             } else {
                 debug!("Failed to get binary version");
             }
             rv
         } else {
             None
         }
     }
 
     fn version_from_binary(&self, binary: &PathBuf) -> Option<String> {
-        let version_regexp = Regex::new(r#"\d+\.\d+(?:[a-z]\d+)?"#).expect("Error parsing version regexp");
+        let version_regexp =
+            Regex::new(r#"\d+\.\d+(?:[a-z]\d+)?"#).expect("Error parsing version regexp");
         let output = Command::new(binary)
             .args(&["-version"])
             .stdout(Stdio::piped())
             .spawn()
             .and_then(|child| child.wait_with_output())
             .ok();
 
         if let Some(x) = output {
-            version_regexp.captures(&*x.stdout)
+            version_regexp
+                .captures(&*x.stdout)
                 .and_then(|captures| captures.get(0))
                 .and_then(|m| str::from_utf8(m.as_bytes()).ok())
                 .map(|x| x.into())
         } else {
             None
         }
     }
 }
 
 // TODO: put this in webdriver-rust
 fn convert_version_error(err: mozversion::Error) -> WebDriverError {
     WebDriverError::new(
         ErrorStatus::SessionNotCreated,
-        err.description().to_string())
+        err.description().to_string(),
+    )
 }
 
 impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> {
     fn init(&mut self, capabilities: &Capabilities) {
         self.set_binary(capabilities);
     }
 
     fn browser_name(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> {
@@ -117,18 +118,18 @@ impl<'a> BrowserCapabilities for Firefox
     }
 
     fn browser_version(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> {
         Ok(self.version())
     }
 
     fn platform_name(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> {
         Ok(if cfg!(target_os = "windows") {
-               Some("windows".into())
-           } else if cfg!(target_os = "macos") {
+            Some("windows".into())
+        } else if cfg!(target_os = "macos") {
             Some("mac".into())
         } else if cfg!(target_os = "linux") {
             Some("linux".into())
         } else {
             None
         })
     }
 
@@ -140,120 +141,149 @@ impl<'a> BrowserCapabilities for Firefox
             Ok(false)
         }
     }
 
     fn set_window_rect(&mut self, _: &Capabilities) -> WebDriverResult<bool> {
         Ok(true)
     }
 
-    fn compare_browser_version(&mut self,
-                               version: &str,
-                               comparison: &str)
-                               -> WebDriverResult<bool> {
+    fn compare_browser_version(
+        &mut self,
+        version: &str,
+        comparison: &str,
+    ) -> WebDriverResult<bool> {
         try!(Version::from_str(version).or_else(|x| Err(convert_version_error(x))))
             .matches(comparison)
             .or_else(|x| Err(convert_version_error(x)))
     }
 
     fn accept_proxy(&mut self, _: &Capabilities, _: &Capabilities) -> WebDriverResult<bool> {
         Ok(true)
     }
 
-    fn validate_custom(&self, name: &str,  value: &Value) -> WebDriverResult<()> {
+    fn validate_custom(&self, name: &str, value: &Value) -> WebDriverResult<()> {
         if !name.starts_with("moz:") {
-            return Ok(())
+            return Ok(());
         }
         match name {
             "moz:firefoxOptions" => {
-                let data = try_opt!(value.as_object(),
-                                    ErrorStatus::InvalidArgument,
-                                    "moz:firefoxOptions is not an object");
+                let data = try_opt!(
+                    value.as_object(),
+                    ErrorStatus::InvalidArgument,
+                    "moz:firefoxOptions is not an object"
+                );
                 for (key, value) in data.iter() {
                     match &**key {
                         "binary" => {
                             if !value.is_string() {
                                 return Err(WebDriverError::new(
                                     ErrorStatus::InvalidArgument,
-                                         "binary path is not a string"));
+                                    "binary path is not a string",
+                                ));
                             }
-                        },
+                        }
                         "args" => {
-                            if !try_opt!(value.as_array(),
-                                         ErrorStatus::InvalidArgument,
-                                         "args is not an array")
-                                .iter()
-                                .all(|value| value.is_string()) {
+                            if !try_opt!(
+                                value.as_array(),
+                                ErrorStatus::InvalidArgument,
+                                "args is not an array"
+                            ).iter()
+                                .all(|value| value.is_string())
+                            {
                                 return Err(WebDriverError::new(
                                     ErrorStatus::InvalidArgument,
-                                         "args entry is not a string"));
-                                }
-                        },
+                                    "args entry is not a string",
+                                ));
+                            }
+                        }
                         "profile" => {
                             if !value.is_string() {
                                 return Err(WebDriverError::new(
                                     ErrorStatus::InvalidArgument,
-                                         "profile is not a string"));
+                                    "profile is not a string",
+                                ));
                             }
-                        },
+                        }
                         "log" => {
-                            let log_data = try_opt!(value.as_object(),
-                                                    ErrorStatus::InvalidArgument,
-                                                    "log value is not an object");
+                            let log_data = try_opt!(
+                                value.as_object(),
+                                ErrorStatus::InvalidArgument,
+                                "log value is not an object"
+                            );
                             for (log_key, log_value) in log_data.iter() {
                                 match &**log_key {
                                     "level" => {
-                                        let level = try_opt!(log_value.as_str(),
-                                                             ErrorStatus::InvalidArgument,
-                                                             "log level is not a string");
+                                        let level = try_opt!(
+                                            log_value.as_str(),
+                                            ErrorStatus::InvalidArgument,
+                                            "log level is not a string"
+                                        );
                                         if Level::from_str(level).is_err() {
                                             return Err(WebDriverError::new(
                                                 ErrorStatus::InvalidArgument,
-                                                format!("Not a valid log level: {}", level)))
+                                                format!("Not a valid log level: {}", level),
+                                            ));
                                         }
                                     }
-                                    x => return Err(WebDriverError::new(
-                                        ErrorStatus::InvalidArgument,
-                                        format!("Invalid log field {}", x)))
+                                    x => {
+                                        return Err(WebDriverError::new(
+                                            ErrorStatus::InvalidArgument,
+                                            format!("Invalid log field {}", x),
+                                        ))
+                                    }
                                 }
                             }
-                        },
+                        }
                         "prefs" => {
-                            let prefs_data = try_opt!(value.as_object(),
-                                                    ErrorStatus::InvalidArgument,
-                                                    "prefs value is not an object");
-                            if !prefs_data.values()
-                                .all(|x| x.is_string() || x.is_i64() || x.is_u64() || x.is_boolean()) {
-                                    return Err(WebDriverError::new(
-                                        ErrorStatus::InvalidArgument,
-                                        "Preference values not all string or integer or boolean"));
-                                }
+                            let prefs_data = try_opt!(
+                                value.as_object(),
+                                ErrorStatus::InvalidArgument,
+                                "prefs value is not an object"
+                            );
+                            if !prefs_data.values().all(|x| {
+                                x.is_string() || x.is_i64() || x.is_u64() || x.is_boolean()
+                            }) {
+                                return Err(WebDriverError::new(
+                                    ErrorStatus::InvalidArgument,
+                                    "Preference values not all string or integer or boolean",
+                                ));
+                            }
                         }
-                        x => return Err(WebDriverError::new(
-                            ErrorStatus::InvalidArgument,
-                            format!("Invalid moz:firefoxOptions field {}", x)))
+                        x => {
+                            return Err(WebDriverError::new(
+                                ErrorStatus::InvalidArgument,
+                                format!("Invalid moz:firefoxOptions field {}", x),
+                            ))
+                        }
                     }
                 }
             }
             "moz:useNonSpecCompliantPointerOrigin" => {
                 if !value.is_boolean() {
                     return Err(WebDriverError::new(
                         ErrorStatus::InvalidArgument,
-                        "moz:useNonSpecCompliantPointerOrigin is not a boolean"));
+                        "moz:useNonSpecCompliantPointerOrigin is not a boolean",
+                    ));
                 }
             }
             "moz:webdriverClick" => {
                 if !value.is_boolean() {
                     return Err(WebDriverError::new(
                         ErrorStatus::InvalidArgument,
-                        "moz:webdriverClick is not a boolean"));
+                        "moz:webdriverClick is not a boolean",
+                    ));
                 }
             }
-            _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
-                                                format!("Unrecognised option {}", name)))
+            _ => {
+                return Err(WebDriverError::new(
+                    ErrorStatus::InvalidArgument,
+                    format!("Unrecognised option {}", name),
+                ))
+            }
         }
         Ok(())
     }
 
     fn accept_custom(&mut self, _: &str, _: &Value, _: &Capabilities) -> WebDriverResult<bool> {
         Ok(true)
     }
 }
@@ -273,75 +303,82 @@ pub struct FirefoxOptions {
     pub prefs: Vec<(String, Pref)>,
 }
 
 impl FirefoxOptions {
     pub fn new() -> FirefoxOptions {
         Default::default()
     }
 
-    pub fn from_capabilities(binary_path: Option<PathBuf>,
-                             matched: &mut Capabilities)
-                             -> WebDriverResult<FirefoxOptions> {
+    pub fn from_capabilities(
+        binary_path: Option<PathBuf>,
+        matched: &mut Capabilities,
+    ) -> WebDriverResult<FirefoxOptions> {
         let mut rv = FirefoxOptions::new();
         rv.binary = binary_path;
 
         if let Some(json) = matched.remove("moz:firefoxOptions") {
-            let options = try!(json.as_object()
-                                   .ok_or(WebDriverError::new(ErrorStatus::InvalidArgument,
-                                                              "'moz:firefoxOptions' \
-                                                               capability is not an object")));
+            let options = try!(json.as_object().ok_or(WebDriverError::new(
+                ErrorStatus::InvalidArgument,
+                "'moz:firefoxOptions' \
+                 capability is not an object"
+            )));
 
             rv.profile = try!(FirefoxOptions::load_profile(&options));
             rv.args = try!(FirefoxOptions::load_args(&options));
             rv.log = try!(FirefoxOptions::load_log(&options));
             rv.prefs = try!(FirefoxOptions::load_prefs(&options));
         }
 
         Ok(rv)
     }
 
     fn load_profile(options: &Capabilities) -> WebDriverResult<Option<Profile>> {
         if let Some(profile_json) = options.get("profile") {
-            let profile_base64 =
-                try!(profile_json
-                         .as_str()
-                         .ok_or(WebDriverError::new(ErrorStatus::UnknownError,
-                                                    "Profile is not a string")));
+            let profile_base64 = try!(profile_json.as_str().ok_or(WebDriverError::new(
+                ErrorStatus::UnknownError,
+                "Profile is not a string"
+            )));
             let profile_zip = &*try!(base64::decode(profile_base64));
 
             // Create an emtpy profile directory
             let profile = try!(Profile::new(None));
-            try!(unzip_buffer(profile_zip,
-                              profile
-                                  .temp_dir
-                                  .as_ref()
-                                  .expect("Profile doesn't have a path")
-                                  .path()));
+            try!(unzip_buffer(
+                profile_zip,
+                profile
+                    .temp_dir
+                    .as_ref()
+                    .expect("Profile doesn't have a path")
+                    .path()
+            ));
 
             Ok(Some(profile))
         } else {
             Ok(None)
         }
     }
 
     fn load_args(options: &Capabilities) -> WebDriverResult<Option<Vec<String>>> {
         if let Some(args_json) = options.get("args") {
-            let args_array = try!(args_json
-                                      .as_array()
-                                      .ok_or(WebDriverError::new(ErrorStatus::UnknownError,
-                                                                 "Arguments were not an \
-                                                                  array")));
-            let args = try!(args_array
-                                .iter()
-                                .map(|x| x.as_str().map(|x| x.to_owned()))
-                                .collect::<Option<Vec<String>>>()
-                                .ok_or(WebDriverError::new(ErrorStatus::UnknownError,
-                                                           "Arguments entries were not all \
-                                                            strings")));
+            let args_array = try!(args_json.as_array().ok_or(WebDriverError::new(
+                ErrorStatus::UnknownError,
+                "Arguments were not an \
+                 array"
+            )));
+            let args = try!(
+                args_array
+                    .iter()
+                    .map(|x| x.as_str().map(|x| x.to_owned()))
+                    .collect::<Option<Vec<String>>>()
+                    .ok_or(WebDriverError::new(
+                        ErrorStatus::UnknownError,
+                        "Arguments entries were not all \
+                         strings"
+                    ))
+            );
             Ok(Some(args))
         } else {
             Ok(None)
         }
     }
 
     fn load_log(options: &Capabilities) -> WebDriverResult<LogOptions> {
         if let Some(json) = options.get("log") {
@@ -367,51 +404,55 @@ impl FirefoxOptions {
             Ok(LogOptions { level })
         } else {
             Ok(Default::default())
         }
     }
 
     pub fn load_prefs(options: &Capabilities) -> WebDriverResult<Vec<(String, Pref)>> {
         if let Some(prefs_data) = options.get("prefs") {
-            let prefs = try!(prefs_data
-                                 .as_object()
-                                 .ok_or(WebDriverError::new(ErrorStatus::UnknownError,
-                                                            "Prefs were not an object")));
+            let prefs = try!(prefs_data.as_object().ok_or(WebDriverError::new(
+                ErrorStatus::UnknownError,
+                "Prefs were not an object"
+            )));
             let mut rv = Vec::with_capacity(prefs.len());
             for (key, value) in prefs.iter() {
                 rv.push((key.clone(), try!(pref_from_json(value))));
             }
             Ok(rv)
         } else {
             Ok(vec![])
         }
     }
 }
 
 fn pref_from_json(value: &Value) -> WebDriverResult<Pref> {
     match value {
         &Value::String(ref x) => Ok(Pref::new(x.clone())),
         &Value::Number(ref x) => Ok(Pref::new(x.as_i64().unwrap())),
         &Value::Bool(x) => Ok(Pref::new(x)),
-        _ => Err(WebDriverError::new(ErrorStatus::UnknownError,
-                                     "Could not convert pref value to string, boolean, or integer"))
+        _ => Err(WebDriverError::new(
+            ErrorStatus::UnknownError,
+            "Could not convert pref value to string, boolean, or integer",
+        )),
     }
 }
 
 fn unzip_buffer(buf: &[u8], dest_dir: &Path) -> WebDriverResult<()> {
     let reader = Cursor::new(buf);
-    let mut zip = try!(zip::ZipArchive::new(reader).map_err(|_| {
-        WebDriverError::new(ErrorStatus::UnknownError, "Failed to unzip profile")
-    }));
+    let mut zip = try!(
+        zip::ZipArchive::new(reader)
+            .map_err(|_| WebDriverError::new(ErrorStatus::UnknownError, "Failed to unzip profile"))
+    );
 
     for i in 0..zip.len() {
-        let mut file = try!(zip.by_index(i).map_err(|_| {
-            WebDriverError::new(ErrorStatus::UnknownError, "Processing profile zip file failed")
-        }));
+        let mut file = try!(zip.by_index(i).map_err(|_| WebDriverError::new(
+            ErrorStatus::UnknownError,
+            "Processing profile zip file failed"
+        )));
         let unzip_path = {
             let name = file.name();
             let is_dir = name.ends_with("/");
             let rel_path = Path::new(name);
             let dest_path = dest_dir.join(rel_path);
 
             {
                 let create_dir = if is_dir {
@@ -481,18 +522,20 @@ mod tests {
         firefox_opts.insert("profile".into(), encoded_profile);
 
         let opts = make_options(firefox_opts);
         let mut profile = opts.profile.unwrap();
         let prefs = profile.user_prefs().unwrap();
 
         println!("{:#?}", prefs.prefs);
 
-        assert_eq!(prefs.get("startup.homepage_welcome_url"),
-                   Some(&Pref::new("data:text/html,PASS")));
+        assert_eq!(
+            prefs.get("startup.homepage_welcome_url"),
+            Some(&Pref::new("data:text/html,PASS"))
+        );
     }
 
     #[test]
     fn test_prefs() {
         let encoded_profile = example_profile();
         let mut prefs: Map<String, Value> = Map::new();
         prefs.insert(
             "browser.display.background_color".into(),
--- a/testing/geckodriver/src/logging.rs
+++ b/testing/geckodriver/src/logging.rs
@@ -274,17 +274,20 @@ mod tests {
             (Level::Warn, "Warn"),
             (Level::Info, "Info"),
             (Level::Config, "Config"),
             (Level::Debug, "Debug"),
             (Level::Trace, "Trace"),
         ];
 
         for &(lvl, s) in tests.iter() {
-            let expected = Pref { value: PrefValue::String(s.to_string()), sticky: false };
+            let expected = Pref {
+                value: PrefValue::String(s.to_string()),
+                sticky: false,
+            };
             assert_eq!(Into::<Pref>::into(lvl), expected);
         }
     }
 
     #[test]
     fn test_level_from_str() {
         assert_eq!(Level::from_str("fatal"), Ok(Level::Fatal));
         assert_eq!(Level::from_str("error"), Ok(Level::Error));
--- a/testing/geckodriver/src/main.rs
+++ b/testing/geckodriver/src/main.rs
@@ -9,49 +9,49 @@ extern crate mozprofile;
 extern crate mozrunner;
 extern crate mozversion;
 extern crate regex;
 extern crate serde;
 #[macro_use]
 extern crate serde_derive;
 extern crate serde_json;
 extern crate uuid;
+extern crate webdriver;
 extern crate zip;
-extern crate webdriver;
 
 #[macro_use]
 extern crate log;
 
 use std::io::Write;
 use std::net::{IpAddr, SocketAddr};
 use std::path::PathBuf;
 use std::str::FromStr;
 
 use clap::{App, Arg};
 
 macro_rules! try_opt {
-    ($expr:expr, $err_type:expr, $err_msg:expr) => ({
+    ($expr:expr, $err_type:expr, $err_msg:expr) => {{
         match $expr {
             Some(x) => x,
-            None => return Err(WebDriverError::new($err_type, $err_msg))
+            None => return Err(WebDriverError::new($err_type, $err_msg)),
         }
-    })
+    }};
 }
 
 mod build;
+mod capabilities;
 mod logging;
+mod marionette;
 mod prefs;
-mod marionette;
-mod capabilities;
 
 #[cfg(test)]
 pub mod test;
 
 use build::BuildInfo;
-use marionette::{MarionetteHandler, MarionetteSettings, extension_routes};
+use marionette::{extension_routes, MarionetteHandler, MarionetteSettings};
 
 type ProgramResult = std::result::Result<(), (ExitCode, String)>;
 
 enum ExitCode {
     Ok = 0,
     Usage = 64,
     Unavailable = 69,
 }
@@ -64,62 +64,80 @@ fn print_version() {
     println!("");
     println!("This program is subject to the terms of the Mozilla Public License 2.0.");
     println!("You can obtain a copy of the license at https://mozilla.org/MPL/2.0/.");
 }
 
 fn app<'a, 'b>() -> App<'a, 'b> {
     App::new(format!("geckodriver {}", crate_version!()))
         .about("WebDriver implementation for Firefox.")
-        .arg(Arg::with_name("webdriver_host")
-            .long("host")
-            .value_name("HOST")
-            .help("Host ip to use for WebDriver server (default: 127.0.0.1)")
-            .takes_value(true))
-        .arg(Arg::with_name("webdriver_port")
-            .short("p")
-            .long("port")
-            .value_name("PORT")
-            .help("Port to use for WebDriver server (default: 4444)")
-            .takes_value(true)
-            .alias("webdriver-port"))
-        .arg(Arg::with_name("binary")
-            .short("b")
-            .long("binary")
-            .value_name("BINARY")
-            .help("Path to the Firefox binary")
-            .takes_value(true))
-        .arg(Arg::with_name("marionette_port")
-            .long("marionette-port")
-            .value_name("PORT")
-            .help("Port to use to connect to Gecko (default: random free port)")
-            .takes_value(true))
-        .arg(Arg::with_name("connect_existing")
-            .long("connect-existing")
-            .requires("marionette_port")
-            .help("Connect to an existing Firefox instance"))
-        .arg(Arg::with_name("jsdebugger")
-            .long("jsdebugger")
-            .takes_value(false)
-            .help("Attach browser toolbox debugger for Firefox"))
-        .arg(Arg::with_name("verbosity")
-            .short("v")
-            .multiple(true)
-            .conflicts_with("log_level")
-            .help("Log level verbosity (-v for debug and -vv for trace level)"))
-        .arg(Arg::with_name("log_level")
-            .long("log")
-            .takes_value(true)
-            .value_name("LEVEL")
-            .possible_values(&["fatal", "error", "warn", "info", "config", "debug", "trace"])
-            .help("Set Gecko log level"))
-        .arg(Arg::with_name("version")
-            .short("V")
-            .long("version")
-            .help("Prints version and copying information"))
+        .arg(
+            Arg::with_name("webdriver_host")
+                .long("host")
+                .value_name("HOST")
+                .help("Host ip to use for WebDriver server (default: 127.0.0.1)")
+                .takes_value(true),
+        )
+        .arg(
+            Arg::with_name("webdriver_port")
+                .short("p")
+                .long("port")
+                .value_name("PORT")
+                .help("Port to use for WebDriver server (default: 4444)")
+                .takes_value(true)
+                .alias("webdriver-port"),
+        )
+        .arg(
+            Arg::with_name("binary")
+                .short("b")
+                .long("binary")
+                .value_name("BINARY")
+                .help("Path to the Firefox binary")
+                .takes_value(true),
+        )
+        .arg(
+            Arg::with_name("marionette_port")
+                .long("marionette-port")
+                .value_name("PORT")
+                .help("Port to use to connect to Gecko (default: random free port)")
+                .takes_value(true),
+        )
+        .arg(
+            Arg::with_name("connect_existing")
+                .long("connect-existing")
+                .requires("marionette_port")
+                .help("Connect to an existing Firefox instance"),
+        )
+        .arg(
+            Arg::with_name("jsdebugger")
+                .long("jsdebugger")
+                .takes_value(false)
+                .help("Attach browser toolbox debugger for Firefox"),
+        )
+        .arg(
+            Arg::with_name("verbosity")
+                .short("v")
+                .multiple(true)
+                .conflicts_with("log_level")
+                .help("Log level verbosity (-v for debug and -vv for trace level)"),
+        )
+        .arg(
+            Arg::with_name("log_level")
+                .long("log")
+                .takes_value(true)
+                .value_name("LEVEL")
+                .possible_values(&["fatal", "error", "warn", "info", "config", "debug", "trace"])
+                .help("Set Gecko log level"),
+        )
+        .arg(
+            Arg::with_name("version")
+                .short("V")
+                .long("version")
+                .help("Prints version and copying information"),
+        )
 }
 
 fn run() -> ProgramResult {
     let matches = app().get_matches();
 
     if matches.is_present("version") {
         print_version();
         return Ok(());
@@ -138,22 +156,20 @@ fn run() -> ProgramResult {
     let addr = match IpAddr::from_str(host) {
         Ok(addr) => SocketAddr::new(addr, port),
         Err(_) => return Err((ExitCode::Usage, "invalid host address".into())),
     };
 
     let binary = matches.value_of("binary").map(|x| PathBuf::from(x));
 
     let marionette_port = match matches.value_of("marionette_port") {
-        Some(x) => {
-            match u16::from_str(x) {
-                Ok(x) => Some(x),
-                Err(_) => return Err((ExitCode::Usage, "invalid Marionette port".into())),
-            }
-        }
+        Some(x) => match u16::from_str(x) {
+            Ok(x) => Some(x),
+            Err(_) => return Err((ExitCode::Usage, "invalid Marionette port".into())),
+        },
         None => None,
     };
 
     let log_level = if matches.is_present("log_level") {
         logging::Level::from_str(matches.value_of("log_level").unwrap()).ok()
     } else {
         match matches.occurrences_of("verbosity") {
             0 => Some(logging::Level::Info),