<commit_before>use crate::spec::{LinkerFlavor, Target, TargetResult};

pub fn target() -> TargetResult {
    let mut base = super::illumos_base::opts();
    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string(), "-std=c99".to_string()]);
    base.cpu = "x86-64".to_string();
    base.max_atomic_width = Some(64);

    Ok(Target {
        // LLVM does not currently have a separate illumos target,
        // so we still pass Solaris to it
        llvm_target: "x86_64-pc-solaris".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "64".to_string(),
        target_c_int_width: "32".to_string(),
        data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
        arch: "x86_64".to_string(),
        target_os: "illumos".to_string(),
        target_env: String::new(),
        target_vendor: "unknown".to_string(),
        linker_flavor: LinkerFlavor::Gcc,
        options: base,
    })
}
<commit_msg>Rollup merge of #72695 - jclulow:illumos-llvm-catchup, r=nikic<commit_after>use crate::spec::{LinkerFlavor, Target, TargetResult};

pub fn target() -> TargetResult {
    let mut base = super::illumos_base::opts();
    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string(), "-std=c99".to_string()]);
    base.cpu = "x86-64".to_string();
    base.max_atomic_width = Some(64);

    Ok(Target {
        // LLVM does not currently have a separate illumos target,
        // so we still pass Solaris to it
        llvm_target: "x86_64-pc-solaris".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "64".to_string(),
        target_c_int_width: "32".to_string(),
        data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
            .to_string(),
        arch: "x86_64".to_string(),
        target_os: "illumos".to_string(),
        target_env: String::new(),
        target_vendor: "unknown".to_string(),
        linker_flavor: LinkerFlavor::Gcc,
        options: base,
    })
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::rc::Rc;

use super::row::{PrivateSqliteRow, SqliteRow};
use super::stmt::StatementUse;
use crate::result::QueryResult;

#[allow(missing_debug_implementations)]
pub struct StatementIterator<'stmt, 'query> {
    inner: PrivateStatementIterator<'stmt, 'query>,
    column_names: Option<Rc<[Option<String>]>>,
    field_count: usize,
}

enum PrivateStatementIterator<'stmt, 'query> {
    NotStarted(StatementUse<'stmt, 'query>),
    Started(Rc<RefCell<PrivateSqliteRow<'stmt, 'query>>>),
    TemporaryEmpty,
}

impl<'stmt, 'query> StatementIterator<'stmt, 'query> {
    pub fn new(stmt: StatementUse<'stmt, 'query>) -> StatementUse<'stmt, 'query> {
        Self {
            inner: PrivateStatementIterator::NotStarted(stmt),
            column_names: None,
            field_count: 0,
        }
    }
}

impl<'stmt, 'query> Iterator for StatementIterator<'stmt, 'query> {
    type Item = QueryResult<SqliteRow<'stmt, 'query>>;

    fn next(&mut self) -> Option<Self::Item> {
        use PrivateStatementIterator::{NotStarted, Started, TemporaryEmpty};

        match std::mem::replace(&mut self.inner, TemporaryEmpty) {
            NotStarted(stmt) => match stmt.step() {
                Err(e) => Some(Err(e)),
                Ok(None) => None,
                Ok(Some(stmt)) => {
                    let field_count = stmt.column_count() as usize;
                    self.field_count = field_count;
                    let inner = Rc::new(RefCell::new(PrivateSqliteRow::Direct(stmt)));
                    self.inner = Started(inner.clone());
                    Some(Ok(SqliteRow { inner, field_count }))
                }
            },
            Started(mut last_row) => {
                // There was already at least one iteration step
                // We check here if the caller already released the row value or not
                // by checking if our Rc owns the data or not
                if let Some(last_row_ref) = Rc::get_mut(&mut last_row) {
                    // We own the statement, there is no other reference here.
                    // This means we don't need to copy out values from the sqlite provided
                    // datastructures for now
                    // We don't need to use the runtime borrowing system of the RefCell here
                    // as we have a mutable reference, so all of this below is checked at compile time
                    if let PrivateSqliteRow::Direct(stmt) =
                        std::mem::replace(last_row_ref.get_mut(), PrivateSqliteRow::TemporaryEmpty)
                    {
                        match stmt.step() {
                            Err(e) => Some(Err(e)),
                            Ok(None) => None,
                            Ok(Some(stmt)) => {
                                let field_count = self.field_count;
                                (*last_row_ref.get_mut()) = PrivateSqliteRow::Direct(stmt);
                                self.inner = Started(last_row.clone());
                                Some(Ok(SqliteRow {
                                    inner: last_row,
                                    field_count,
                                }))
                            }
                        }
                    } else {
                        // any other state than `PrivateSqliteRow::Direct` is invalid here
                        // and should not happen. If this ever happens this is a logic error
                        // in the code above
                        unreachable!(
                            "You've reached an impossible internal state. \
                             If you ever see this error message please open \
                             an issue at https://github.com/diesel-rs/diesel \
                             providing example code how to trigger this error."
                        )
                    }
                } else {
                    // We don't own the statement. There is another existing reference, likly because
                    // a user stored the row in some long time container before calling next another time
                    // In this case we copy out the current values into a temporary store and advance
                    // the statement iterator internally afterwards
                    let last_row = {
                        let mut last_row = match last_row.try_borrow_mut() {
                            Ok(o) => o,
                            Err(_e) => {
                                self.inner = Started(last_row.clone());
                                return Some(Err(crate::result::Error::DeserializationError(
                                    "Failed to reborrow row. Try to release any `SqliteField` or `SqliteValue` \
                                     that exists at this point"
                                        .into(),
                                )));
                            }
                        };
                        let last_row = &mut *last_row;
                        let duplicated = last_row.duplicate(&mut self.column_names);
                        std::mem::replace(last_row, duplicated)
                    };
                    if let PrivateSqliteRow::Direct(stmt) = last_row {
                        match stmt.step() {
                            Err(e) => Some(Err(e)),
                            Ok(None) => None,
                            Ok(Some(stmt)) => {
                                let field_count = self.field_count;
                                let last_row =
                                    Rc::new(RefCell::new(PrivateSqliteRow::Direct(stmt)));
                                self.inner = Started(last_row.clone());
                                Some(Ok(SqliteRow {
                                    inner: last_row,
                                    field_count,
                                }))
                            }
                        }
                    } else {
                        // any other state than `PrivateSqliteRow::Direct` is invalid here
                        // and should not happen. If this ever happens this is a logic error
                        // in the code above
                        unreachable!(
                            "You've reached an impossible internal state. \
                             If you ever see this error message please open \
                             an issue at https://github.com/diesel-rs/diesel \
                             providing example code how to trigger this error."
                        )
                    }
                }
            }
            TemporaryEmpty => None,
        }
    }
}
<commit_msg>Fix a typo<commit_after>use std::cell::RefCell;
use std::rc::Rc;

use super::row::{PrivateSqliteRow, SqliteRow};
use super::stmt::StatementUse;
use crate::result::QueryResult;

#[allow(missing_debug_implementations)]
pub struct StatementIterator<'stmt, 'query> {
    inner: PrivateStatementIterator<'stmt, 'query>,
    column_names: Option<Rc<[Option<String>]>>,
    field_count: usize,
}

enum PrivateStatementIterator<'stmt, 'query> {
    NotStarted(StatementUse<'stmt, 'query>),
    Started(Rc<RefCell<PrivateSqliteRow<'stmt, 'query>>>),
    TemporaryEmpty,
}

impl<'stmt, 'query> StatementIterator<'stmt, 'query> {
    pub fn new(stmt: StatementUse<'stmt, 'query>) -> StatementIterator<'stmt, 'query> {
        Self {
            inner: PrivateStatementIterator::NotStarted(stmt),
            column_names: None,
            field_count: 0,
        }
    }
}

impl<'stmt, 'query> Iterator for StatementIterator<'stmt, 'query> {
    type Item = QueryResult<SqliteRow<'stmt, 'query>>;

    fn next(&mut self) -> Option<Self::Item> {
        use PrivateStatementIterator::{NotStarted, Started, TemporaryEmpty};

        match std::mem::replace(&mut self.inner, TemporaryEmpty) {
            NotStarted(stmt) => match stmt.step() {
                Err(e) => Some(Err(e)),
                Ok(None) => None,
                Ok(Some(stmt)) => {
                    let field_count = stmt.column_count() as usize;
                    self.field_count = field_count;
                    let inner = Rc::new(RefCell::new(PrivateSqliteRow::Direct(stmt)));
                    self.inner = Started(inner.clone());
                    Some(Ok(SqliteRow { inner, field_count }))
                }
            },
            Started(mut last_row) => {
                // There was already at least one iteration step
                // We check here if the caller already released the row value or not
                // by checking if our Rc owns the data or not
                if let Some(last_row_ref) = Rc::get_mut(&mut last_row) {
                    // We own the statement, there is no other reference here.
                    // This means we don't need to copy out values from the sqlite provided
                    // datastructures for now
                    // We don't need to use the runtime borrowing system of the RefCell here
                    // as we have a mutable reference, so all of this below is checked at compile time
                    if let PrivateSqliteRow::Direct(stmt) =
                        std::mem::replace(last_row_ref.get_mut(), PrivateSqliteRow::TemporaryEmpty)
                    {
                        match stmt.step() {
                            Err(e) => Some(Err(e)),
                            Ok(None) => None,
                            Ok(Some(stmt)) => {
                                let field_count = self.field_count;
                                (*last_row_ref.get_mut()) = PrivateSqliteRow::Direct(stmt);
                                self.inner = Started(last_row.clone());
                                Some(Ok(SqliteRow {
                                    inner: last_row,
                                    field_count,
                                }))
                            }
                        }
                    } else {
                        // any other state than `PrivateSqliteRow::Direct` is invalid here
                        // and should not happen. If this ever happens this is a logic error
                        // in the code above
                        unreachable!(
                            "You've reached an impossible internal state. \
                             If you ever see this error message please open \
                             an issue at https://github.com/diesel-rs/diesel \
                             providing example code how to trigger this error."
                        )
                    }
                } else {
                    // We don't own the statement. There is another existing reference, likly because
                    // a user stored the row in some long time container before calling next another time
                    // In this case we copy out the current values into a temporary store and advance
                    // the statement iterator internally afterwards
                    let last_row = {
                        let mut last_row = match last_row.try_borrow_mut() {
                            Ok(o) => o,
                            Err(_e) => {
                                self.inner = Started(last_row.clone());
                                return Some(Err(crate::result::Error::DeserializationError(
                                    "Failed to reborrow row. Try to release any `SqliteField` or `SqliteValue` \
                                     that exists at this point"
                                        .into(),
                                )));
                            }
                        };
                        let last_row = &mut *last_row;
                        let duplicated = last_row.duplicate(&mut self.column_names);
                        std::mem::replace(last_row, duplicated)
                    };
                    if let PrivateSqliteRow::Direct(stmt) = last_row {
                        match stmt.step() {
                            Err(e) => Some(Err(e)),
                            Ok(None) => None,
                            Ok(Some(stmt)) => {
                                let field_count = self.field_count;
                                let last_row =
                                    Rc::new(RefCell::new(PrivateSqliteRow::Direct(stmt)));
                                self.inner = Started(last_row.clone());
                                Some(Ok(SqliteRow {
                                    inner: last_row,
                                    field_count,
                                }))
                            }
                        }
                    } else {
                        // any other state than `PrivateSqliteRow::Direct` is invalid here
                        // and should not happen. If this ever happens this is a logic error
                        // in the code above
                        unreachable!(
                            "You've reached an impossible internal state. \
                             If you ever see this error message please open \
                             an issue at https://github.com/diesel-rs/diesel \
                             providing example code how to trigger this error."
                        )
                    }
                }
            }
            TemporaryEmpty => None,
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use gdk_sys;
use glib::object::IsA;
use glib::translate::*;
use AxisUse;
use Device;
use TimeCoord;
use Window;

use std::mem;
use std::ptr;

impl Device {
    pub fn get_axis(&self, axes: &mut [f64], use_: AxisUse, value: &mut f64) -> bool {
        unsafe {
            from_glib(gdk_sys::gdk_device_get_axis(
                self.to_glib_none().0,
                axes.as_mut_ptr(),
                use_.to_glib(),
                value,
            ))
        }
    }

    pub fn get_history<P: IsA<Window>>(
        &self,
        window: &P,
        start: u32,
        stop: u32,
    ) -> Option<Vec<TimeCoord>> {
        unsafe {
            let mut events = ptr::null_mut();
            let mut n_events = mem::MaybeUninit::uninit();
            let ret: bool = from_glib(gdk_sys::gdk_device_get_history(
                self.to_glib_none().0,
                window.as_ref().to_glib_none().0,
                start,
                stop,
                &mut events,
                n_events.as_mut_ptr(),
            ));
            if !ret {
                return None;
            }
            let n_events = n_events.assume_init() as usize;
            let mut r_events = Vec::with_capacity(n_events);
            for i in 0..n_events {
                r_events.push((*(events.offset(i as isize) as *mut TimeCoord)).clone());
            }
            gdk_sys::gdk_device_free_history(events, n_events as _);
            Some(r_events)
        }
    }
}
<commit_msg>Improve get_device_history api<commit_after>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use gdk_sys;
use glib::object::IsA;
use glib::translate::*;
use AxisUse;
use Device;
use TimeCoord;
use Window;

use std::mem;
use std::ptr;

impl Device {
    pub fn get_axis(&self, axes: &mut [f64], use_: AxisUse, value: &mut f64) -> bool {
        unsafe {
            from_glib(gdk_sys::gdk_device_get_axis(
                self.to_glib_none().0,
                axes.as_mut_ptr(),
                use_.to_glib(),
                value,
            ))
        }
    }

    pub fn get_history<P: IsA<Window>>(&self, window: &P, start: u32, stop: u32) -> Vec<TimeCoord> {
        unsafe {
            let mut events = ptr::null_mut();
            let mut n_events = mem::MaybeUninit::uninit();
            let ret: bool = from_glib(gdk_sys::gdk_device_get_history(
                self.to_glib_none().0,
                window.as_ref().to_glib_none().0,
                start,
                stop,
                &mut events,
                n_events.as_mut_ptr(),
            ));
            if !ret {
                return Vec::new();
            }
            let n_events = n_events.assume_init() as usize;
            let mut r_events = Vec::with_capacity(n_events);
            for i in 0..n_events {
                r_events.push((*(events.offset(i as isize) as *mut TimeCoord)).clone());
            }
            gdk_sys::gdk_device_free_history(events, n_events as _);
            r_events
        }
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::io::Write;
use std::path;

use clap;
use env_logger;
use failure::ResultExt;

use crate::error::*;
use cobalt;

pub fn get_config_args() -> Vec<clap::Arg<'static, 'static>> {
    [
        clap::Arg::with_name("config")
            .short("c")
            .long("config")
            .value_name("FILE")
            .help("Config file to use [default: _cobalt.yml]")
            .takes_value(true),
        clap::Arg::with_name("destination")
            .short("d")
            .long("destination")
            .value_name("DIR")
            .help("Site destination folder [default: ./]")
            .takes_value(true),
        clap::Arg::with_name("drafts")
            .long("drafts")
            .help("Include drafts.")
            .takes_value(false),
        clap::Arg::with_name("no-drafts")
            .long("no-drafts")
            .help("Ignore drafts.")
            .conflicts_with("drafts")
            .takes_value(false),
    ]
    .to_vec()
}

pub fn get_config(matches: &clap::ArgMatches) -> Result<cobalt::ConfigBuilder> {
    let config_path = matches.value_of("config");

    // Fetch config information if available
    let mut config = if let Some(config_path) = config_path {
        cobalt::ConfigBuilder::from_file(config_path)
            .with_context(|_| failure::format_err!("Error reading config file {:?}", config_path))?
    } else {
        let cwd = env::current_dir().expect("How does this fail?");
        cobalt::ConfigBuilder::from_cwd(cwd)?
    };

    config.abs_dest = matches.value_of("destination").map(path::PathBuf::from);

    if matches.is_present("drafts") {
        config.include_drafts = true;
    }
    if matches.is_present("no-drafts") {
        config.include_drafts = false;
    }

    Ok(config)
}

pub fn get_logging_args() -> Vec<clap::Arg<'static, 'static>> {
    [
        clap::Arg::with_name("log-level")
            .short("L")
            .long("log-level")
            .possible_values(&["error", "warn", "info", "debug", "trace", "off"])
            .help("Log level [default: info]")
            .global(true)
            .takes_value(true),
        clap::Arg::with_name("trace")
            .long("trace")
            .help("Log ultra-verbose (trace level) information")
            .global(true)
            .takes_value(false),
        clap::Arg::with_name("silent")
            .long("silent")
            .help("Suppress all output")
            .global(true)
            .takes_value(false),
    ]
    .to_vec()
}

pub fn get_logging(
    global_matches: &clap::ArgMatches,
    matches: &clap::ArgMatches,
) -> Result<env_logger::Builder> {
    let mut builder = env_logger::Builder::new();

    let level = if matches.is_present("trace") {
        log::LevelFilter::Trace
    } else if matches.is_present("silent") {
        log::LevelFilter::Off
    } else {
        match matches
            .value_of("log-level")
            .or_else(|| global_matches.value_of("log-level"))
        {
            Some("error") => log::LevelFilter::Error,
            Some("warn") => log::LevelFilter::Warn,
            Some("debug") => log::LevelFilter::Debug,
            Some("trace") => log::LevelFilter::Trace,
            Some("off") => log::LevelFilter::Off,
            Some("info") | _ => log::LevelFilter::Info,
        }
    };
    builder.filter(None, level);

    if level == log::LevelFilter::Trace {
        builder.format_timestamp_secs();
    } else {
        builder.format(|f, record| {
            writeln!(
                f,
                "[{}] {}",
                record.level().to_string().to_lowercase(),
                record.args()
            )
        });
    }

    Ok(builder)
}
<commit_msg>chore: Fix a `match`-related beta clippy warning<commit_after>use std::env;
use std::io::Write;
use std::path;

use clap;
use env_logger;
use failure::ResultExt;

use crate::error::*;
use cobalt;

pub fn get_config_args() -> Vec<clap::Arg<'static, 'static>> {
    [
        clap::Arg::with_name("config")
            .short("c")
            .long("config")
            .value_name("FILE")
            .help("Config file to use [default: _cobalt.yml]")
            .takes_value(true),
        clap::Arg::with_name("destination")
            .short("d")
            .long("destination")
            .value_name("DIR")
            .help("Site destination folder [default: ./]")
            .takes_value(true),
        clap::Arg::with_name("drafts")
            .long("drafts")
            .help("Include drafts.")
            .takes_value(false),
        clap::Arg::with_name("no-drafts")
            .long("no-drafts")
            .help("Ignore drafts.")
            .conflicts_with("drafts")
            .takes_value(false),
    ]
    .to_vec()
}

pub fn get_config(matches: &clap::ArgMatches) -> Result<cobalt::ConfigBuilder> {
    let config_path = matches.value_of("config");

    // Fetch config information if available
    let mut config = if let Some(config_path) = config_path {
        cobalt::ConfigBuilder::from_file(config_path)
            .with_context(|_| failure::format_err!("Error reading config file {:?}", config_path))?
    } else {
        let cwd = env::current_dir().expect("How does this fail?");
        cobalt::ConfigBuilder::from_cwd(cwd)?
    };

    config.abs_dest = matches.value_of("destination").map(path::PathBuf::from);

    if matches.is_present("drafts") {
        config.include_drafts = true;
    }
    if matches.is_present("no-drafts") {
        config.include_drafts = false;
    }

    Ok(config)
}

pub fn get_logging_args() -> Vec<clap::Arg<'static, 'static>> {
    [
        clap::Arg::with_name("log-level")
            .short("L")
            .long("log-level")
            .possible_values(&["error", "warn", "info", "debug", "trace", "off"])
            .help("Log level [default: info]")
            .global(true)
            .takes_value(true),
        clap::Arg::with_name("trace")
            .long("trace")
            .help("Log ultra-verbose (trace level) information")
            .global(true)
            .takes_value(false),
        clap::Arg::with_name("silent")
            .long("silent")
            .help("Suppress all output")
            .global(true)
            .takes_value(false),
    ]
    .to_vec()
}

pub fn get_logging(
    global_matches: &clap::ArgMatches,
    matches: &clap::ArgMatches,
) -> Result<env_logger::Builder> {
    let mut builder = env_logger::Builder::new();

    let level = if matches.is_present("trace") {
        log::LevelFilter::Trace
    } else if matches.is_present("silent") {
        log::LevelFilter::Off
    } else {
        match matches
            .value_of("log-level")
            .or_else(|| global_matches.value_of("log-level"))
        {
            Some("error") => log::LevelFilter::Error,
            Some("warn") => log::LevelFilter::Warn,
            Some("debug") => log::LevelFilter::Debug,
            Some("trace") => log::LevelFilter::Trace,
            Some("off") => log::LevelFilter::Off,
            Some("info") => log::LevelFilter::Info,
            _ => log::LevelFilter::Info,
        }
    };
    builder.filter(None, level);

    if level == log::LevelFilter::Trace {
        builder.format_timestamp_secs();
    } else {
        builder.format(|f, record| {
            writeln!(
                f,
                "[{}] {}",
                record.level().to_string().to_lowercase(),
                record.args()
            )
        });
    }

    Ok(builder)
}
<|endoftext|>


<commit_before>//! This program demonstrates a way of ensuring that a program on Linux is
//! running at most once using abstract sockets (Unix domain sockets and the
//! abstract namespace).
//!
//! For more details, see e.g. Section 57.6 ("The Linux Abstract Socket
//! Namespace") in The Linux Programming Interface by Michael Kerrisk.

// We use the 'nix' crate as it provides Rust-friendly bindings to various *nix
// system functions.
extern crate nix;

use std::error::Error;
use std::process::exit;
use std::thread::sleep;
use std::time::Duration;

use nix::sys::socket::AddressFamily;
use nix::sys::socket::SockAddr;
use nix::sys::socket::SockFlag;
use nix::sys::socket::SockType;
use nix::sys::socket::UnixAddr;
use nix::sys::socket::bind;
use nix::sys::socket::socket;

fn do_work() {
    // We simulate the work by sleeping.
    // Use e.g. Ctrl-C or SIGTERM to kill the program.
    sleep(Duration::from_secs(3600));
}

fn run() -> Result<(), Box<Error>> {
    // Create a Unix domain socket socket.
    let s = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), 0)?;

    // Create a socket address in the abstract namespace using a unique ID.
    let addr = SockAddr::Unix(UnixAddr::new_abstract(b"some-unique-id")?);

    // Try binding the socket to the above address in the abstract namespace.
    // When bind() fails with EADDRINUSE, it means that we should quit as
    // another instance of our program is already running.
    //
    // When the process is terminated, the kernel automatically closes the
    // socket.
    if let Err(e) = bind(s, &addr) {
        match e {
            nix::Error::Sys(nix::Errno::EADDRINUSE) => {
                eprintln!("program is already running");
                return Ok(());
            },
            _ => {
                // bind() failed because of an unexpected reason.
                return Err(Box::new(e));
            }

        };
    }

    do_work();

    Ok(())
}

fn main() {
    if let Err(e) = run() {
        eprintln!("error: {}", e);
        exit(1);
    }
}
<commit_msg>en-2017-07-24: Improve the wording in a comment.<commit_after>//! This program demonstrates a way of ensuring that a program on Linux is
//! running at most once using abstract sockets (Unix domain sockets and the
//! abstract namespace).
//!
//! For more details, see e.g. Section 57.6 ("The Linux Abstract Socket
//! Namespace") in The Linux Programming Interface by Michael Kerrisk.

// We use the 'nix' crate as it provides Rust-friendly bindings to various *nix
// system functions.
extern crate nix;

use std::error::Error;
use std::process::exit;
use std::thread::sleep;
use std::time::Duration;

use nix::sys::socket::AddressFamily;
use nix::sys::socket::SockAddr;
use nix::sys::socket::SockFlag;
use nix::sys::socket::SockType;
use nix::sys::socket::UnixAddr;
use nix::sys::socket::bind;
use nix::sys::socket::socket;

fn do_work() {
    // We simulate the actual work by sleeping.
    // Use e.g. Ctrl-C or SIGTERM to kill the program.
    sleep(Duration::from_secs(3600));
}

fn run() -> Result<(), Box<Error>> {
    // Create a Unix domain socket socket.
    let s = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), 0)?;

    // Create a socket address in the abstract namespace using a unique ID.
    let addr = SockAddr::Unix(UnixAddr::new_abstract(b"some-unique-id")?);

    // Try binding the socket to the above address in the abstract namespace.
    // When bind() fails with EADDRINUSE, it means that we should quit as
    // another instance of our program is already running.
    //
    // When the process is terminated, the kernel automatically closes the
    // socket.
    if let Err(e) = bind(s, &addr) {
        match e {
            nix::Error::Sys(nix::Errno::EADDRINUSE) => {
                eprintln!("program is already running");
                return Ok(());
            },
            _ => {
                // bind() failed because of an unexpected reason.
                return Err(Box::new(e));
            }

        };
    }

    do_work();

    Ok(())
}

fn main() {
    if let Err(e) = run() {
        eprintln!("error: {}", e);
        exit(1);
    }
}
<|endoftext|>


<commit_before>use dbus::{arg::cast, arg::RefArg, arg::TypeMismatchError, arg::Variant, Message};
use std::collections::HashMap;

#[derive(Clone, Debug)]
pub enum BluetoothEvent {
    Powered {
        object_path: String,
        powered: bool,
    },
    Discovering {
        object_path: String,
        discovering: bool,
    },
    Connected {
        object_path: String,
        connected: bool,
    },
    ServicesResolved {
        object_path: String,
        services_resolved: bool,
    },
    Value {
        object_path: String,
        value: Box<[u8]>,
    },
    None,
}

impl BluetoothEvent {
    pub fn from(conn_msg: Message) -> Option<BluetoothEvent> {
        let result: Result<
            (&str, HashMap<String, Variant<Box<RefArg>>>),
            TypeMismatchError,
        > = conn_msg.read2();

        match result {
            Ok((_, properties)) => {
                let object_path = conn_msg.path().unwrap().to_string();

                if let Some(value) = properties.get("Powered") {
                    if let Some(powered) = cast::<bool>(&value.0) {
                        let event = BluetoothEvent::Powered {
                            object_path: object_path.clone(),
                            powered: *powered,
                        };

                        return Some(event);
                    }
                }

                if let Some(value) = properties.get("Discovering") {
                    if let Some(discovering) = cast::<bool>(&value.0) {
                        let event = BluetoothEvent::Discovering {
                            object_path: object_path.clone(),
                            discovering: *discovering,
                        };

                        return Some(event);
                    }
                }

                if let Some(value) = properties.get("Connected") {
                    if let Some(connected) = cast::<bool>(&value.0) {
                        let event = BluetoothEvent::Connected {
                            object_path: object_path.clone(),
                            connected: *connected,
                        };

                        return Some(event);
                    }
                }

                if let Some(value) = properties.get("ServicesResolved") {
                    if let Some(services_resolved) = cast::<bool>(&value.0) {
                        let event = BluetoothEvent::ServicesResolved {
                            object_path: object_path.clone(),
                            services_resolved: *services_resolved,
                        };

                        return Some(event);
                    }
                }

                if let Some(value) = properties.get("Value") {
                    if let Some(value) = cast::<Vec<u8>>(&value.0) {
                        let event = BluetoothEvent::Value {
                            object_path: object_path.clone(),
                            value: value.clone().into_boxed_slice(),
                        };

                        return Some(event);
                    }
                }

                Some(BluetoothEvent::None)
            }
            Err(_err) => None,
        }
    }
}
<commit_msg>added BluethootEvent::RSSI<commit_after>use dbus::{arg::cast, arg::RefArg, arg::TypeMismatchError, arg::Variant, Message};
use std::collections::HashMap;

#[derive(Clone, Debug)]
pub enum BluetoothEvent {
    Powered {
        object_path: String,
        powered: bool,
    },
    Discovering {
        object_path: String,
        discovering: bool,
    },
    Connected {
        object_path: String,
        connected: bool,
    },
    ServicesResolved {
        object_path: String,
        services_resolved: bool,
    },
    Value {
        object_path: String,
        value: Box<[u8]>,
    },
    RSSI {
        object_path: String,
        rssi: i16,
    },
    None,
}

impl BluetoothEvent {
    pub fn from(conn_msg: Message) -> Option<BluetoothEvent> {
        let result: Result<
            (&str, HashMap<String, Variant<Box<RefArg>>>),
            TypeMismatchError,
        > = conn_msg.read2();

        match result {
            Ok((_, properties)) => {
                let object_path = conn_msg.path().unwrap().to_string();

                if let Some(value) = properties.get("Powered") {
                    if let Some(powered) = cast::<bool>(&value.0) {
                        let event = BluetoothEvent::Powered {
                            object_path: object_path.clone(),
                            powered: *powered,
                        };

                        return Some(event);
                    }
                }

                if let Some(value) = properties.get("Discovering") {
                    if let Some(discovering) = cast::<bool>(&value.0) {
                        let event = BluetoothEvent::Discovering {
                            object_path: object_path.clone(),
                            discovering: *discovering,
                        };

                        return Some(event);
                    }
                }

                if let Some(value) = properties.get("Connected") {
                    if let Some(connected) = cast::<bool>(&value.0) {
                        let event = BluetoothEvent::Connected {
                            object_path: object_path.clone(),
                            connected: *connected,
                        };

                        return Some(event);
                    }
                }

                if let Some(value) = properties.get("ServicesResolved") {
                    if let Some(services_resolved) = cast::<bool>(&value.0) {
                        let event = BluetoothEvent::ServicesResolved {
                            object_path: object_path.clone(),
                            services_resolved: *services_resolved,
                        };

                        return Some(event);
                    }
                }

                if let Some(value) = properties.get("Value") {
                    if let Some(value) = cast::<Vec<u8>>(&value.0) {
                        let event = BluetoothEvent::Value {
                            object_path: object_path.clone(),
                            value: value.clone().into_boxed_slice(),
                        };

                        return Some(event);
                    }
                }

                if let Some(value) = properties.get("RSSI") {
                    if let Some(rssi) = cast::<i16>(&value.0) {
                        let event = BluetoothEvent::RSSI {
                            object_path: object_path.clone(),
                            rssi: *rssi,
                        };

                        return Some(event);
                    }
                }

                Some(BluetoothEvent::None)
            }
            Err(_err) => None,
        }
    }
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with
// this file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::borrow::Cow;
use regex::Regex;

const NB_CHAR:char = ' '; // non breaking space
const NB_CHAR_NARROW:char = '\u{202F}'; // narrow non breaking space
const NB_CHAR_EM:char = '\u{2002}'; // demi em space

/// Escape non breaking spaces for HTML, so there is no problem for displaying them if the font or browser
/// doesn't know what to do with them
pub fn escape_nb_spaces<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    let input = input.into();
    if let Some(first) = input.chars().position(|c| match c {
        NB_CHAR | NB_CHAR_NARROW | NB_CHAR_EM => true,
        _ => false
    }) {
        let mut chars = input.chars().collect::<Vec<_>>();
        let rest = chars.split_off(first);
        let mut output = chars.into_iter().collect::<String>();
        for c in rest {
            match c {
                NB_CHAR_NARROW  => output.push_str(r#" "#),
                NB_CHAR_EM => output.push_str(r#" "#),
                NB_CHAR => output.push_str(r#" "#),
                _ => output.push(c),
            }
        }
        Cow::Owned(output)
    } else {
        input.into()
    }
}

/// Escape characters `<`, `>`, and `&`
///
/// # Examples
///
/// ```
/// use crowbook_text_processing::escape::escape_html;
/// let s = escape_html("<foo> & <bar>");
/// assert_eq!(&s, "<foo> & <bar>");
/// ```
pub fn escape_html<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
        lazy_static! {
        static ref REGEX: Regex = Regex::new("[<>&]").unwrap();
    }
    let input = input.into();
    let first = REGEX.find(&input);
    if let Some((first, _)) = first {
        let len = input.len();
        let mut output = Vec::with_capacity(len + len /2);
        output.extend_from_slice(input[0..first].as_bytes());
        let rest = input[first..].bytes();
        for c in rest {
            match c {
                b'<' => output.extend_from_slice(b"<"),
                b'>' => output.extend_from_slice(b">"),
                b'&' => output.extend_from_slice(b"&"),
                _ => output.push(c),
            }
        }
        Cow::Owned(String::from_utf8(output).unwrap())
    } else {
        input
    }
}

/// Escape quotes
///
/// Replace `"` by `'`
pub fn escape_quotes<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    let input = input.into();
    if input.contains('"') {
        let mut output = String::with_capacity(input.len());
        for c in input.chars() {
            match c {
                '"' => output.push('\''),
                _ => output.push(c)
            }
        }
        Cow::Owned(output)
    } else {
        input
    }
}

/// Escape characters for LaTeX
///
/// # Examples
///
/// ```
/// use crowbook_text_processing::escape::escape_tex;
/// let s = escape_tex("command --foo # calls command with option foo");
/// assert_eq!(&s, r"command -{}-foo \# calls command with option foo");
/// ```
pub fn escape_tex<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    let input = input.into();
    const REGEX_LITERAL:&'static str = r"[&%$#_\x7E\x2D\{\}\^\\]";
    lazy_static! {
       static ref REGEX: Regex = Regex::new(REGEX_LITERAL).unwrap();

    }
    let first = REGEX.find(&input);
    if let Some((first, _)) = first {
        let len = input.len();
        let mut output = Vec::with_capacity(len + len/2);
        output.extend_from_slice(input[0..first].as_bytes());
        let mut bytes:Vec<_> = input[first..].bytes().collect();
        bytes.push(b' '); // add a dummy char for call to .windows()
        // for &[c, next] in chars.windows(2) { // still experimental, uncomment when stable
        for win in bytes.windows(2) {
            let c = win[0];
            let next = win[1];
            match c {
                b'-' => {
                    if next == b'-' {
                        output.extend_from_slice(br"-{}"); // if next char is also a -, to avoid tex ligatures
                    } else {
                        output.push(c);
                    }
                },
                b'&' => output.extend_from_slice(br"\&"),
                b'%' => output.extend_from_slice(br"\%"),
                b'$' => output.extend_from_slice(br"\$"),
                b'#' => output.extend_from_slice(br"\#"),
                b'_' => output.extend_from_slice(br"\_"),
                b'{' => output.extend_from_slice(br"\{"),
                b'}' => output.extend_from_slice(br"\}"),
                b'~' => output.extend_from_slice(br"\textasciitilde{}" ),
                b'^' => output.extend_from_slice(br"\textasciicircum{}"),
                b'\\' => output.extend_from_slice(br"\textbackslash{}"),
                _  => output.push(c)
            }
        }
        Cow::Owned(String::from_utf8(output).unwrap())
    } else {
        input
    }
}

#[test]
fn html_escape_nothing() {
    let s = "Some string without any character to escape";
    let result = escape_html(s);
    assert_eq!(s, &result);
}

#[test]
fn tex_escape_nothing() {
    let s = "Some string without any character to escape";
    let result = escape_tex(s);
    assert_eq!(s, &result);
}

#[test]
fn nb_spaces_escape_nothing() {
    let s = "Some string without any character to escape";
    let result = escape_nb_spaces(s);
    assert_eq!(s, &result);
}

#[test]
fn quotes_escape_nothing() {
    let s = "Some string without any character to escape";
    let result = escape_quotes(s);
    assert_eq!(s, &result);
}

#[test]
fn html_escape_1() {
    let s = "
Some characters need escaping & something
";
    let expected = "<p>Some characters need escaping & something</p>";
    let actual = escape_html(s);
    assert_eq!(expected, &actual);
}

#[test]
fn html_escape_2() {
    let actual = escape_html("<foo> & <bar>");
    let expected = "<foo> & <bar>";
    assert_eq!(&actual, expected);
}

#[test]
fn tex_escape_braces() {
    let actual = escape_tex(r"\foo{bar}");
    let expected = r"\textbackslash{}foo\{bar\}";
    assert_eq!(&actual, expected);
}

#[test]
fn tex_escape_dashes() {
    let actual = escape_tex("--foo, ---bar");
    let expected = r"-{}-foo, -{}-{}-bar";
    assert_eq!(&actual, expected);
}

#[test]
fn tex_escape_numbers() {
    let actual = escape_tex(r"30000$ is 10% of number #1 income");
    let expected = r"30000\$ is 10\% of number \#1 income";
    assert_eq!(&actual, expected);
}

#[test]
fn quotes_escape() {
    let actual = escape_quotes(r#"Some text with "quotes""#);
    let expected = r#"Some text with 'quotes'"#;
    assert_eq!(&actual, expected);
}

#[test]
fn nb_spaces_escape() {
    let actual = escape_nb_spaces("This contains non breaking spaces");
    let expected = r#"This contains non breaking spaces"#;
    assert_eq!(&actual, expected);
}
<commit_msg>Update docstrings<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with
// this file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::borrow::Cow;
use regex::Regex;

const NB_CHAR:char = ' '; // non breaking space
const NB_CHAR_NARROW:char = '\u{202F}'; // narrow non breaking space
const NB_CHAR_EM:char = '\u{2002}'; // demi em space

/// Escape non breaking spaces for HTML, so there is no problem for displaying them if the font or browser
/// doesn't know what to do with them (particularly the narrow non breaking space which isn't very
/// well supported.
pub fn escape_nb_spaces<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    let input = input.into();
    if let Some(first) = input.chars().position(|c| match c {
        NB_CHAR | NB_CHAR_NARROW | NB_CHAR_EM => true,
        _ => false
    }) {
        let mut chars = input.chars().collect::<Vec<_>>();
        let rest = chars.split_off(first);
        let mut output = chars.into_iter().collect::<String>();
        for c in rest {
            match c {
                NB_CHAR_NARROW  => output.push_str(r#" "#),
                NB_CHAR_EM => output.push_str(r#" "#),
                NB_CHAR => output.push_str(r#" "#),
                _ => output.push(c),
            }
        }
        Cow::Owned(output)
    } else {
        input.into()
    }
}

/// Escape characters `<`, `>`, and `&`
///
/// **Warning**: this function was written for escaping text in a markdown
/// text processor that is designed to run on a local machine, so the content
/// can actually be trusted, it should *not* be used for untrusted content.
///
/// # Example
///
/// ```
/// use crowbook_text_processing::escape::escape_html;
/// let s = escape_html("<foo> & <bar>");
/// assert_eq!(&s, "<foo> & <bar>");
/// ```
pub fn escape_html<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
        lazy_static! {
        static ref REGEX: Regex = Regex::new("[<>&]").unwrap();
    }
    let input = input.into();
    let first = REGEX.find(&input);
    if let Some((first, _)) = first {
        let len = input.len();
        let mut output = Vec::with_capacity(len + len /2);
        output.extend_from_slice(input[0..first].as_bytes());
        let rest = input[first..].bytes();
        for c in rest {
            match c {
                b'<' => output.extend_from_slice(b"<"),
                b'>' => output.extend_from_slice(b">"),
                b'&' => output.extend_from_slice(b"&"),
                _ => output.push(c),
            }
        }
        Cow::Owned(String::from_utf8(output).unwrap())
    } else {
        input
    }
}

/// Escape quotes
///
/// Simply replace `"` by `'`
pub fn escape_quotes<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    let input = input.into();
    if input.contains('"') {
        let mut output = String::with_capacity(input.len());
        for c in input.chars() {
            match c {
                '"' => output.push('\''),
                _ => output.push(c)
            }
        }
        Cow::Owned(output)
    } else {
        input
    }
}

/// Escape characters for LaTeX
///
/// # Example
///
/// ```
/// use crowbook_text_processing::escape::escape_tex;
/// let s = escape_tex("command --foo # calls command with option foo");
/// assert_eq!(&s, r"command -{}-foo \# calls command with option foo");
/// ```
pub fn escape_tex<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    let input = input.into();
    const REGEX_LITERAL:&'static str = r"[&%$#_\x7E\x2D\{\}\^\\]";
    lazy_static! {
       static ref REGEX: Regex = Regex::new(REGEX_LITERAL).unwrap();

    }
    let first = REGEX.find(&input);
    if let Some((first, _)) = first {
        let len = input.len();
        let mut output = Vec::with_capacity(len + len/2);
        output.extend_from_slice(input[0..first].as_bytes());
        let mut bytes:Vec<_> = input[first..].bytes().collect();
        bytes.push(b' '); // add a dummy char for call to .windows()
        // for &[c, next] in chars.windows(2) { // still experimental, uncomment when stable
        for win in bytes.windows(2) {
            let c = win[0];
            let next = win[1];
            match c {
                b'-' => {
                    if next == b'-' {
                        output.extend_from_slice(br"-{}"); // if next char is also a -, to avoid tex ligatures
                    } else {
                        output.push(c);
                    }
                },
                b'&' => output.extend_from_slice(br"\&"),
                b'%' => output.extend_from_slice(br"\%"),
                b'$' => output.extend_from_slice(br"\$"),
                b'#' => output.extend_from_slice(br"\#"),
                b'_' => output.extend_from_slice(br"\_"),
                b'{' => output.extend_from_slice(br"\{"),
                b'}' => output.extend_from_slice(br"\}"),
                b'~' => output.extend_from_slice(br"\textasciitilde{}" ),
                b'^' => output.extend_from_slice(br"\textasciicircum{}"),
                b'\\' => output.extend_from_slice(br"\textbackslash{}"),
                _  => output.push(c)
            }
        }
        Cow::Owned(String::from_utf8(output).unwrap())
    } else {
        input
    }
}

#[test]
fn html_escape_nothing() {
    let s = "Some string without any character to escape";
    let result = escape_html(s);
    assert_eq!(s, &result);
}

#[test]
fn tex_escape_nothing() {
    let s = "Some string without any character to escape";
    let result = escape_tex(s);
    assert_eq!(s, &result);
}

#[test]
fn nb_spaces_escape_nothing() {
    let s = "Some string without any character to escape";
    let result = escape_nb_spaces(s);
    assert_eq!(s, &result);
}

#[test]
fn quotes_escape_nothing() {
    let s = "Some string without any character to escape";
    let result = escape_quotes(s);
    assert_eq!(s, &result);
}

#[test]
fn html_escape_1() {
    let s = "
Some characters need escaping & something
";
    let expected = "<p>Some characters need escaping & something</p>";
    let actual = escape_html(s);
    assert_eq!(expected, &actual);
}

#[test]
fn html_escape_2() {
    let actual = escape_html("<foo> & <bar>");
    let expected = "<foo> & <bar>";
    assert_eq!(&actual, expected);
}

#[test]
fn tex_escape_braces() {
    let actual = escape_tex(r"\foo{bar}");
    let expected = r"\textbackslash{}foo\{bar\}";
    assert_eq!(&actual, expected);
}

#[test]
fn tex_escape_dashes() {
    let actual = escape_tex("--foo, ---bar");
    let expected = r"-{}-foo, -{}-{}-bar";
    assert_eq!(&actual, expected);
}

#[test]
fn tex_escape_numbers() {
    let actual = escape_tex(r"30000$ is 10% of number #1 income");
    let expected = r"30000\$ is 10\% of number \#1 income";
    assert_eq!(&actual, expected);
}

#[test]
fn quotes_escape() {
    let actual = escape_quotes(r#"Some text with "quotes""#);
    let expected = r#"Some text with 'quotes'"#;
    assert_eq!(&actual, expected);
}

#[test]
fn nb_spaces_escape() {
    let actual = escape_nb_spaces("This contains non breaking spaces");
    let expected = r#"This contains non breaking spaces"#;
    assert_eq!(&actual, expected);
}
<|endoftext|>


<commit_before>use std::f64::consts::PI;
use std::num::Float;
use std::num::FloatMath;

/// Cutoff: fraction of sample rate (eg. frequencies below sample_rate / cutoff are preserved)
/// Transition band: fraction of sample rate (how harsh a cutoff this is)
pub fn lowpass_filter(cutoff: f64, band: f64) -> Vec<f64> {
    let mut n = (4.0 / band).ceil() as uint;
    if n % 2 == 1 { n += 1; }

    let sinc = |x: f64| -> f64 {
        (x * PI).sin() / (x * PI)
    };

    let sinc_wave = Vec::from_fn(n, |i| {
        sinc(2.0 * cutoff * (i as f64 - (n as f64 - 1.0) / 2.0))
    });

    let blackman_window = Vec::from_fn(n, |i| {
        0.42 - 0.5 * (2.0 * PI * i as f64 / (n as f64 - 1.0)).cos()
        + 0.08 * (4.0 * PI * i as f64 / (n as f64 - 1.0)).cos()
    });

    let filter: Vec<f64> =  sinc_wave.iter().zip(blackman_window.iter()).map(|tup| {
        *tup.val0() * *tup.val1()
    }).collect();

    // Normalize
    let sum = filter.iter().fold(0.0, |acc, el| {
        acc + *el
    });

    filter.iter().map(|el| {
        *el / sum
    }).collect()
}

pub fn highpass_filter(cutoff: f64, band: f64) -> Vec<f64> {
    spectral_invert(lowpass_filter(cutoff, band))
}

pub fn bandpass_filter(low_frequency: f64, high_frequency: f64, band: f64) -> Vec<f64> {
    assert!(low_frequency <= high_frequency);
    let lowpass = lowpass_filter(high_frequency, band);
    let highpass = highpass_filter(low_frequency, band);
    convolve(highpass, lowpass)
}

pub fn bandreject_filter(low_frequency: f64, high_frequency: f64, band: f64) -> Vec<f64> {
    assert!(low_frequency <= high_frequency);
    let lowpass = lowpass_filter(low_frequency, band);
    let highpass = highpass_filter(high_frequency, band);
    add(highpass, lowpass)
}

pub fn spectral_invert(filter: Vec<f64>) -> Vec<f64> {
    assert_eq!(filter.len() % 2, 0);
    let mut count = 0;

    filter.iter().map(|el| {
        let add = if count == filter.len() / 2 { 1.0 } else { 0.0 };
        count += 1;
        -*el + add
    }).collect()
}

// Output will be longer than input as we add to border
pub fn convolve(filter: Vec<f64>, input: Vec<f64>) -> Vec<f64> {
    let mut output: Vec<f64> = Vec::new();
    let h_len = (filter.len() / 2) as int;

    for i in range(-(filter.len() as int / 2), input.len() as int - 1) {
        output.push(0.0);
        for j in range(0i, filter.len() as int) {
            let input_idx = i + j;
            let output_idx = i + h_len;
            if input_idx < 0 || input_idx >= input.len() as int { continue; }
            output[output_idx as uint] += input[input_idx as uint] * filter[j as uint]
        }
    }

    output
}

pub fn add(left: Vec<f64>, right: Vec<f64>) -> Vec<f64> {
    left.iter().zip(right.iter()).map(|tup| {
        *tup.val0() + *tup.val1()
    }).collect()
}

pub fn cutoff_from_frequency(frequency: f64, sample_rate: uint) -> f64 {
    frequency / sample_rate as f64
}

#[test]
fn it_convolves() {
    let filter = vec!(1.0, 1.0, 1.0);
    let input = vec!(0.0, 0.0, 3.0, 0.0, 3.0, 0.0, 0.0);
    let output = vec!(0.0, 3.0, 3.0, 6.0, 3.0, 3.0, 0.0);
    assert_eq!(convolve(filter, input), output);
}

#[test]
fn it_does_elementwise_addition_of_two_samples() {
    let a = vec!(1.0, -1.0, -8.0);
    let b = vec!(-1.0, 5.0, 3.0);
    let expected = vec!(0.0, 4.0, -5.0);
    assert_eq!(add(a, b), expected);
}
<commit_msg>Move Blackman window creation into function<commit_after>use std::f64::consts::PI;
use std::num::Float;
use std::num::FloatMath;

/// Cutoff: fraction of sample rate (eg. frequencies below sample_rate / cutoff are preserved)
/// Transition band: fraction of sample rate (how harsh a cutoff this is)
pub fn lowpass_filter(cutoff: f64, band: f64) -> Vec<f64> {
    let mut n = (4.0 / band).ceil() as uint;
    if n % 2 == 1 { n += 1; }

    let sinc = |x: f64| -> f64 {
        (x * PI).sin() / (x * PI)
    };

    let sinc_wave = Vec::from_fn(n, |i| {
        sinc(2.0 * cutoff * (i as f64 - (n as f64 - 1.0) / 2.0))
    });

    let blackman_window = blackman_window(n);

    let filter: Vec<f64> =  sinc_wave.iter().zip(blackman_window.iter()).map(|tup| {
        *tup.val0() * *tup.val1()
    }).collect();

    // Normalize
    let sum = filter.iter().fold(0.0, |acc, el| {
        acc + *el
    });

    filter.iter().map(|el| {
        *el / sum
    }).collect()
}

pub fn blackman_window(size: uint) -> Vec<f64> {
    Vec::from_fn(size, |i| {
        0.42 - 0.5 * (2.0 * PI * i as f64 / (size as f64 - 1.0)).cos()
        + 0.08 * (4.0 * PI * i as f64 / (size as f64 - 1.0)).cos()
    })
}

pub fn highpass_filter(cutoff: f64, band: f64) -> Vec<f64> {
    spectral_invert(lowpass_filter(cutoff, band))
}

pub fn bandpass_filter(low_frequency: f64, high_frequency: f64, band: f64) -> Vec<f64> {
    assert!(low_frequency <= high_frequency);
    let lowpass = lowpass_filter(high_frequency, band);
    let highpass = highpass_filter(low_frequency, band);
    convolve(highpass, lowpass)
}

pub fn bandreject_filter(low_frequency: f64, high_frequency: f64, band: f64) -> Vec<f64> {
    assert!(low_frequency <= high_frequency);
    let lowpass = lowpass_filter(low_frequency, band);
    let highpass = highpass_filter(high_frequency, band);
    add(highpass, lowpass)
}

pub fn spectral_invert(filter: Vec<f64>) -> Vec<f64> {
    assert_eq!(filter.len() % 2, 0);
    let mut count = 0;

    filter.iter().map(|el| {
        let add = if count == filter.len() / 2 { 1.0 } else { 0.0 };
        count += 1;
        -*el + add
    }).collect()
}

// Output will be longer than input as we add to border
pub fn convolve(filter: Vec<f64>, input: Vec<f64>) -> Vec<f64> {
    let mut output: Vec<f64> = Vec::new();
    let h_len = (filter.len() / 2) as int;

    for i in range(-(filter.len() as int / 2), input.len() as int - 1) {
        output.push(0.0);
        for j in range(0i, filter.len() as int) {
            let input_idx = i + j;
            let output_idx = i + h_len;
            if input_idx < 0 || input_idx >= input.len() as int { continue; }
            output[output_idx as uint] += input[input_idx as uint] * filter[j as uint]
        }
    }

    output
}

pub fn add(left: Vec<f64>, right: Vec<f64>) -> Vec<f64> {
    left.iter().zip(right.iter()).map(|tup| {
        *tup.val0() + *tup.val1()
    }).collect()
}

pub fn cutoff_from_frequency(frequency: f64, sample_rate: uint) -> f64 {
    frequency / sample_rate as f64
}

#[test]
fn it_convolves() {
    let filter = vec!(1.0, 1.0, 1.0);
    let input = vec!(0.0, 0.0, 3.0, 0.0, 3.0, 0.0, 0.0);
    let output = vec!(0.0, 3.0, 3.0, 6.0, 3.0, 3.0, 0.0);
    assert_eq!(convolve(filter, input), output);
}

#[test]
fn it_does_elementwise_addition_of_two_samples() {
    let a = vec!(1.0, -1.0, -8.0);
    let b = vec!(-1.0, 5.0, 3.0);
    let expected = vec!(0.0, 4.0, -5.0);
    assert_eq!(add(a, b), expected);
}
<|endoftext|>


<commit_before>
use std::fmt;
use std::io::Read;  // Trait providing read_to_string()
use std::env;

use url;
use hyper;
use serde;
use serde_json;

// use Groups;

use ::errors::*;

pub const API_VERSION: u16 = 3;

#[derive(Default, Clone, Copy, Debug)]
pub struct Pagination {
    pub page: u16,
    pub per_page: u16,
}

pub struct GitLab {
    url: url::Url,
    private_token: String,
    pagination: Option<Pagination>,
    client: hyper::Client,
}

// Explicitly implement Debug trait for GitLab so we can hide the token.
impl fmt::Debug for GitLab {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "GitLab {{ scheme: {}, domain: {}, port: {}, private_token: XXXXXXXXXXXXXXXXXXXX, \
                pagination: {:?} }}",
               self.url.scheme(),
               self.url.domain().unwrap_or("bad hostname provided"),
               self.url
                   .port()
                   .map(|port_u16| port_u16.to_string())
                   .unwrap_or("no port provided".to_string()),
               self.pagination)
    }
}

fn validate_url(scheme: &str, domain: &str, port: u16) -> Result<url::Url> {

    match domain.find('.') {
        None => {
            // pass
        }
        Some(index) => {
            if index == 0 {
                bail!(format!("invalid domain: '{}' cannot start with a dot", domain));
            }
        }
    };

    if domain.ends_with('.') {
        bail!(format!("invalid domain: '{}' cannot end with a dot", domain));
    }

    let url_string = format!("{}://{}/api/v{}/", scheme, domain, API_VERSION);
    let mut url = url::Url::parse(&url_string)
        .chain_err(|| format!("failure to parse URL '{}'", url_string))?;
    url.set_port(Some(port)).expect("bad port provided");

    {
        let url_host = url.host_str();
        if url_host.is_none() {
            bail!("failure to get URL's hostname");
        }
        if url_host.unwrap() != domain {
            bail!(format!("invalid hostname '{}'", domain));
        }
    }

    Ok(url)
}

impl GitLab {
    pub fn _new(scheme: &str, domain: &str, port: u16, private_token: &str) -> Result<GitLab> {
        if private_token.len() != 20 {
            bail!(format!("private token should be a 20 characters string (not {})",
                          private_token.len()));
        }

        let url: url::Url = validate_url(scheme, domain, port).chain_err(|| "invalid URL")?;

        Ok(GitLab {
            url: url,
            private_token: private_token.to_string(),
            pagination: None,
            client: match env::var("HTTP_PROXY") {
                Ok(proxy) => {
                    let proxy: Vec<&str> = proxy.trim_left_matches("http://").split(':').collect();
                    let hostname = proxy[0].to_string();
                    let port = proxy[1].parse()
                        .chain_err(|| format!("failure to set port to {}", port))?;

                    hyper::Client::with_http_proxy(hostname, port)
                }
                Err(_) => hyper::Client::new(),
            },
        })
    }

    pub fn new_insecure(domain: &str, private_token: &str) -> Result<GitLab> {
        warn!("Using insecure http:// protocol: Token will be sent in clear!");
        GitLab::_new("http", domain, 80, private_token)
    }

    pub fn new(domain: &str, private_token: &str) -> Result<GitLab> {
        GitLab::_new("https", domain, 443, private_token)
    }

    pub fn port(mut self, port: u16) -> Self {
        self.url.set_port(Some(port)).unwrap();
        self
    }

    pub fn scheme(mut self, scheme: &str) -> Self {
        self.url.set_scheme(scheme).unwrap();
        self
    }

    /// Build a URL used to access GitLab instance, including some parameters.
    ///
    /// # Examples
    ///
    /// Example from GitLab: https://docs.gitlab.com/ce/api/#basic-usage
    ///
    /// ```
    /// use gitlab_api::GitLab;
    ///
    /// let expected_url = "https://gitlab.example.com\
    ///                     /api/v3/groups?order_by=path&private_token=XXXXXXXXXXXXXXXXXXXX";
    ///
    /// let gl = GitLab::new("gitlab.example.com", "XXXXXXXXXXXXXXXXXXXX").unwrap();
    ///
    /// assert_eq!(gl.build_url("groups?order_by=path").unwrap(), expected_url);
    /// ```
    pub fn build_url(&self, query: &str) -> Result<String> {
        let mut new_url = self.url
            .clone()
            .join(query)
            .chain_err(|| {
                format!("Failure to join query '{}' to url {}",
                        query,
                        self.url.as_str())
            })?;
        new_url.query_pairs_mut().append_pair("private_token", &self.private_token);
        self.pagination.as_ref().map(|pagination| {
            new_url.query_pairs_mut().append_pair("page", &pagination.page.to_string());
            new_url.query_pairs_mut().append_pair("per_page", &pagination.per_page.to_string());
        });

        Ok(new_url.into_string())
    }

    // pub fn attempt_connection(&self) -> Result<hyper::client::Response, hyper::Error> {
    //     let url = self.build_url("version");
    //     // Close connections after each GET.
    //     self.client.get(&url).header(hyper::header::Connection::close()).send()
    // }

    /// Set pagination information
    ///
    /// # Examples
    ///
    /// ```
    /// use gitlab_api::{GitLab, Pagination};
    ///
    /// let expected_url = "https://gitlab.example.com\
    ///                     /api/v3/groups?order_by=path&\
    ///                     private_token=XXXXXXXXXXXXXXXXXXXX&page=2&per_page=5";
    ///
    /// let mut gl = GitLab::new("gitlab.example.com", "XXXXXXXXXXXXXXXXXXXX").unwrap();
    /// gl.set_pagination(Pagination {page: 2, per_page: 5});
    /// assert_eq!(gl.build_url("groups?order_by=path").unwrap(), expected_url);
    /// ```
    pub fn set_pagination(&mut self, pagination: Pagination) {
        self.pagination = Some(pagination);
    }

    pub fn get<T>(&self, query: &str) -> Result<T>
        where T: serde::Deserialize
    {
        let url = self.build_url(query)
            .chain_err(|| format!("failure to build url for query '{}'", query))?;
        info!("url: {:?}", url);

        // Close connections after each GET.
        let mut res: hyper::client::Response = self.client
            .get(&url)
            .header(hyper::header::Connection::close())
            .send()
            .chain_err(|| format!("cannot send request '{}' to {:?}", query, self))?;
        info!("res.status: {:?}", res.status);
        debug!("res.headers: {:?}", res.headers);
        debug!("res.url: {:?}", res.url);

        let mut body = String::new();
        res.read_to_string(&mut body).chain_err(|| "cannot read response body")?;
        debug!("body:\n{:?}", body);

        // assert_eq!(res.status, hyper::status::StatusCode::Ok);
        if res.status != hyper::status::StatusCode::Ok {
            bail!(format!("status code ({}) not Ok()", res.status));
        }

        serde_json::from_str(body.as_str())
            .chain_err(|| format!("cannot build Rust struct from JSON data: {}", body))
    }

    pub fn version(&self) -> Result<::Version> {
        self.get("version").chain_err(|| "cannot query 'version'")
    }

    pub fn groups(&self) -> ::groups::GroupsLister {
        ::groups::GroupsLister::new(self)
    }

    pub fn projects(&self) -> ::projects::ProjectsLister {
        ::projects::ProjectsLister::new(self)
    }

    pub fn issues(&self) -> ::issues::IssuesLister {
        ::issues::IssuesLister::new(self)
    }

    pub fn merge_requests(&self, project_id: i64) -> ::merge_requests::MergeRequestsLister {
        ::merge_requests::MergeRequestsLister::new(self, project_id)
    }

    // pub fn groups(&mut self, listing: ::groups::Listing) -> Result<Groups, serde_json::Error> {
    //     let query = listing.build_query();
    //     // self.get(&query)
    //     unimplemented!();
    // }

    // pub fn owned_groups(&mut self) -> Result<Groups, serde_json::Error> {
    //     let query = ::groups::owned_groups::Listing::new().build_query();
    //     info!("query: {:?}", query);
    //     self.get(&query)
    // }
}

#[cfg(test)]
mod tests {
    use std::fmt;
    use gitlab::*;
    use errors::*;

    fn verify_ok<T>(result: &Result<T>) {
        if let &Err(ref e) = result {
            println!("error: {}", e);

            for e in e.iter().skip(1) {
                println!("caused by: {}", e);
            }

            // The backtrace is not always generated. Try to run this example
            // with `RUST_BACKTRACE=1`.
            if let Some(backtrace) = e.backtrace() {
                println!("backtrace: {:?}", backtrace);
            }
        }
        assert!(result.is_ok());
    }

    fn verify_err<T>(result: &Result<T>)
        where T: fmt::Debug
    {
        match result {
            &Err(_) => {
                // pass
            }
            &Ok(ref t) => {
                panic!(format!("Expected an Err(), got an Ok(t), with t: {:?}", t));
            }
        }
    }

    #[test]
    fn new_valid() {
        let gl = GitLab::new("gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_ok(&gl);

        let gl = GitLab::new_insecure("gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_ok(&gl);

        let gl = GitLab::new("localhost", "XXXXXXXXXXXXXXXXXXXX");
        verify_ok(&gl);

        let gl = GitLab::new_insecure("localhost", "XXXXXXXXXXXXXXXXXXXX");
        verify_ok(&gl);
    }

    #[test]
    fn new_invalid_url_1() {
        let gl = GitLab::new("", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_2() {
        let gl = GitLab::new("gitla/b.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("gitla/b.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_3() {
        let gl = GitLab::new("/gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("/gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_4() {
        let gl = GitLab::new("http:/gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("http:/gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_5() {
        let gl = GitLab::new("http:///gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("http:///gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_6() {
        let gl = GitLab::new(".gitlab", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure(".gitlab", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_7() {
        let gl = GitLab::new(".gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure(".gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_8() {
        let gl = GitLab::new("gitlab.", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("gitlab.", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_10() {
        let gl = GitLab::new("gitlab.com.", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("gitlab.com.", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_token() {
        let gl = GitLab::new("gitlab.com", "");
        assert!(gl.is_err());

        let gl = GitLab::new("gitlab.com", "X");
        assert!(gl.is_err());

        let gl = GitLab::new("gitlab.com", "XXXXXXXXXXXXXXXXXXX");
        assert!(gl.is_err());

        let gl = GitLab::new("gitlab.com", "XXXXXXXXXXXXXXXXXXXXX");
        assert!(gl.is_err());
    }
}
<commit_msg>Clearer error message<commit_after>
use std::fmt;
use std::io::Read;  // Trait providing read_to_string()
use std::env;

use url;
use hyper;
use serde;
use serde_json;

// use Groups;

use ::errors::*;

pub const API_VERSION: u16 = 3;

#[derive(Default, Clone, Copy, Debug)]
pub struct Pagination {
    pub page: u16,
    pub per_page: u16,
}

pub struct GitLab {
    url: url::Url,
    private_token: String,
    pagination: Option<Pagination>,
    client: hyper::Client,
}

// Explicitly implement Debug trait for GitLab so we can hide the token.
impl fmt::Debug for GitLab {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "GitLab {{ scheme: {}, domain: {}, port: {}, private_token: XXXXXXXXXXXXXXXXXXXX, \
                pagination: {:?} }}",
               self.url.scheme(),
               self.url.domain().unwrap_or("bad hostname provided"),
               self.url
                   .port()
                   .map(|port_u16| port_u16.to_string())
                   .unwrap_or("no port provided".to_string()),
               self.pagination)
    }
}

fn validate_url(scheme: &str, domain: &str, port: u16) -> Result<url::Url> {

    match domain.find('.') {
        None => {
            // pass
        }
        Some(index) => {
            if index == 0 {
                bail!(format!("invalid domain: '{}' cannot start with a dot", domain));
            }
        }
    };

    if domain.ends_with('.') {
        bail!(format!("invalid domain: '{}' cannot end with a dot", domain));
    }

    let url_string = format!("{}://{}/api/v{}/", scheme, domain, API_VERSION);
    let mut url = url::Url::parse(&url_string)
        .chain_err(|| format!("failure to parse URL '{}'", url_string))?;
    url.set_port(Some(port)).expect("bad port provided");

    {
        let url_host = url.host_str();
        if url_host.is_none() {
            bail!("failure to get URL's hostname");
        }
        if url_host.unwrap() != domain {
            bail!(format!("invalid hostname '{}'", domain));
        }
    }

    Ok(url)
}

impl GitLab {
    pub fn _new(scheme: &str, domain: &str, port: u16, private_token: &str) -> Result<GitLab> {
        if private_token.len() != 20 {
            bail!(format!("private token should be a 20 characters string (not {})",
                          private_token.len()));
        }

        let url: url::Url = validate_url(scheme, domain, port).chain_err(|| "invalid URL")?;

        Ok(GitLab {
            url: url,
            private_token: private_token.to_string(),
            pagination: None,
            client: match env::var("HTTP_PROXY") {
                Ok(proxy) => {
                    let proxy: Vec<&str> = proxy.trim_left_matches("http://").split(':').collect();
                    let hostname = proxy[0].to_string();
                    let port = proxy[1].parse()
                        .chain_err(|| format!("failure to set port to {}", port))?;

                    hyper::Client::with_http_proxy(hostname, port)
                }
                Err(_) => hyper::Client::new(),
            },
        })
    }

    pub fn new_insecure(domain: &str, private_token: &str) -> Result<GitLab> {
        warn!("Using insecure http:// protocol: Token will be sent in clear!");
        GitLab::_new("http", domain, 80, private_token)
    }

    pub fn new(domain: &str, private_token: &str) -> Result<GitLab> {
        GitLab::_new("https", domain, 443, private_token)
    }

    pub fn port(mut self, port: u16) -> Self {
        self.url.set_port(Some(port)).unwrap();
        self
    }

    pub fn scheme(mut self, scheme: &str) -> Self {
        self.url.set_scheme(scheme).unwrap();
        self
    }

    /// Build a URL used to access GitLab instance, including some parameters.
    ///
    /// # Examples
    ///
    /// Example from GitLab: https://docs.gitlab.com/ce/api/#basic-usage
    ///
    /// ```
    /// use gitlab_api::GitLab;
    ///
    /// let expected_url = "https://gitlab.example.com\
    ///                     /api/v3/groups?order_by=path&private_token=XXXXXXXXXXXXXXXXXXXX";
    ///
    /// let gl = GitLab::new("gitlab.example.com", "XXXXXXXXXXXXXXXXXXXX").unwrap();
    ///
    /// assert_eq!(gl.build_url("groups?order_by=path").unwrap(), expected_url);
    /// ```
    pub fn build_url(&self, query: &str) -> Result<String> {
        let mut new_url = self.url
            .clone()
            .join(query)
            .chain_err(|| {
                format!("Failure to join query '{}' to url {}",
                        query,
                        self.url.as_str())
            })?;
        new_url.query_pairs_mut().append_pair("private_token", &self.private_token);
        self.pagination.as_ref().map(|pagination| {
            new_url.query_pairs_mut().append_pair("page", &pagination.page.to_string());
            new_url.query_pairs_mut().append_pair("per_page", &pagination.per_page.to_string());
        });

        Ok(new_url.into_string())
    }

    // pub fn attempt_connection(&self) -> Result<hyper::client::Response, hyper::Error> {
    //     let url = self.build_url("version");
    //     // Close connections after each GET.
    //     self.client.get(&url).header(hyper::header::Connection::close()).send()
    // }

    /// Set pagination information
    ///
    /// # Examples
    ///
    /// ```
    /// use gitlab_api::{GitLab, Pagination};
    ///
    /// let expected_url = "https://gitlab.example.com\
    ///                     /api/v3/groups?order_by=path&\
    ///                     private_token=XXXXXXXXXXXXXXXXXXXX&page=2&per_page=5";
    ///
    /// let mut gl = GitLab::new("gitlab.example.com", "XXXXXXXXXXXXXXXXXXXX").unwrap();
    /// gl.set_pagination(Pagination {page: 2, per_page: 5});
    /// assert_eq!(gl.build_url("groups?order_by=path").unwrap(), expected_url);
    /// ```
    pub fn set_pagination(&mut self, pagination: Pagination) {
        self.pagination = Some(pagination);
    }

    pub fn get<T>(&self, query: &str) -> Result<T>
        where T: serde::Deserialize
    {
        let url = self.build_url(query)
            .chain_err(|| format!("failure to build url for query '{}'", query))?;
        info!("url: {:?}", url);

        // Close connections after each GET.
        let mut res: hyper::client::Response = self.client
            .get(&url)
            .header(hyper::header::Connection::close())
            .send()
            .chain_err(|| format!("cannot send request '{}' to {:?}", query, self))?;
        info!("res.status: {:?}", res.status);
        debug!("res.headers: {:?}", res.headers);
        debug!("res.url: {:?}", res.url);

        let mut body = String::new();
        res.read_to_string(&mut body).chain_err(|| "cannot read response body")?;
        debug!("body:\n{:?}", body);

        // assert_eq!(res.status, hyper::status::StatusCode::Ok);
        if res.status != hyper::status::StatusCode::Ok {
            bail!(format!("status code '{}', not '200 OK'", res.status));
        }

        serde_json::from_str(body.as_str())
            .chain_err(|| format!("cannot build Rust struct from JSON data: {}", body))
    }

    pub fn version(&self) -> Result<::Version> {
        self.get("version").chain_err(|| "cannot query 'version'")
    }

    pub fn groups(&self) -> ::groups::GroupsLister {
        ::groups::GroupsLister::new(self)
    }

    pub fn projects(&self) -> ::projects::ProjectsLister {
        ::projects::ProjectsLister::new(self)
    }

    pub fn issues(&self) -> ::issues::IssuesLister {
        ::issues::IssuesLister::new(self)
    }

    pub fn merge_requests(&self, project_id: i64) -> ::merge_requests::MergeRequestsLister {
        ::merge_requests::MergeRequestsLister::new(self, project_id)
    }

    // pub fn groups(&mut self, listing: ::groups::Listing) -> Result<Groups, serde_json::Error> {
    //     let query = listing.build_query();
    //     // self.get(&query)
    //     unimplemented!();
    // }

    // pub fn owned_groups(&mut self) -> Result<Groups, serde_json::Error> {
    //     let query = ::groups::owned_groups::Listing::new().build_query();
    //     info!("query: {:?}", query);
    //     self.get(&query)
    // }
}

#[cfg(test)]
mod tests {
    use std::fmt;
    use gitlab::*;
    use errors::*;

    fn verify_ok<T>(result: &Result<T>) {
        if let &Err(ref e) = result {
            println!("error: {}", e);

            for e in e.iter().skip(1) {
                println!("caused by: {}", e);
            }

            // The backtrace is not always generated. Try to run this example
            // with `RUST_BACKTRACE=1`.
            if let Some(backtrace) = e.backtrace() {
                println!("backtrace: {:?}", backtrace);
            }
        }
        assert!(result.is_ok());
    }

    fn verify_err<T>(result: &Result<T>)
        where T: fmt::Debug
    {
        match result {
            &Err(_) => {
                // pass
            }
            &Ok(ref t) => {
                panic!(format!("Expected an Err(), got an Ok(t), with t: {:?}", t));
            }
        }
    }

    #[test]
    fn new_valid() {
        let gl = GitLab::new("gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_ok(&gl);

        let gl = GitLab::new_insecure("gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_ok(&gl);

        let gl = GitLab::new("localhost", "XXXXXXXXXXXXXXXXXXXX");
        verify_ok(&gl);

        let gl = GitLab::new_insecure("localhost", "XXXXXXXXXXXXXXXXXXXX");
        verify_ok(&gl);
    }

    #[test]
    fn new_invalid_url_1() {
        let gl = GitLab::new("", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_2() {
        let gl = GitLab::new("gitla/b.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("gitla/b.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_3() {
        let gl = GitLab::new("/gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("/gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_4() {
        let gl = GitLab::new("http:/gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("http:/gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_5() {
        let gl = GitLab::new("http:///gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("http:///gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_6() {
        let gl = GitLab::new(".gitlab", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure(".gitlab", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_7() {
        let gl = GitLab::new(".gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure(".gitlab.com", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_8() {
        let gl = GitLab::new("gitlab.", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("gitlab.", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_url_10() {
        let gl = GitLab::new("gitlab.com.", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);

        let gl = GitLab::new_insecure("gitlab.com.", "XXXXXXXXXXXXXXXXXXXX");
        verify_err(&gl);
    }

    #[test]
    fn new_invalid_token() {
        let gl = GitLab::new("gitlab.com", "");
        assert!(gl.is_err());

        let gl = GitLab::new("gitlab.com", "X");
        assert!(gl.is_err());

        let gl = GitLab::new("gitlab.com", "XXXXXXXXXXXXXXXXXXX");
        assert!(gl.is_err());

        let gl = GitLab::new("gitlab.com", "XXXXXXXXXXXXXXXXXXXXX");
        assert!(gl.is_err());
    }
}
<|endoftext|>


<commit_before>use std::fs;
use std::env;
use std::ffi::OsStr;

use clap::{App, Arg, ArgMatches};
use console::style;

use prelude::*;
use api::{Api, NewRelease};
use config::Config;
use utils::{ArgExt, SourceMapProcessor, get_codepush_package, get_codepush_release};

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b> {
    app.about("uploads react-native projects for codepush")
        .org_project_args()
        .arg(Arg::with_name("deployment")
            .long("deployment")
            .value_name("DEPLOYMENT")
            .help("The name of the deployment (Production, Staging)"))
        .arg(Arg::with_name("bundle_id")
             .value_name("BUNDLE_ID")
             .long("bundle-id")
             .help("Explicitly provide the bundle ID instead of \
                    parsing the source projects.  This allows you to push \
                    codepush releases for iOS on platforms without xcode."))
        .arg(Arg::with_name("app_name")
            .value_name("APP_NAME")
            .index(1)
            .required(true)
            .help("The name of the code-push application"))
        .arg(Arg::with_name("platform")
            .value_name("PLATFORM")
            .index(2)
            .required(true)
            .help("The name of the code-push platform (ios, android)"))
        .arg(Arg::with_name("paths")
            .value_name("PATH")
            .index(3)
            .required(true)
            .multiple(true)
            .help("A list of folders with assets that should be processed."))
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> Result<()> {
    let here = env::current_dir()?;
    let here_str: &str = &here.to_string_lossy();
    let (org, project) = config.get_org_and_project(matches)?;
    let app = matches.value_of("app_name").unwrap();
    let platform = matches.value_of("platform").unwrap();
    let deployment = matches.value_of("deployment").unwrap_or("Staging");
    let api = Api::new(config);

    println!("{} Fetching latest code-push package info", style(">").dim());
    let package = get_codepush_package(app, deployment)?;
    let release = get_codepush_release(&package, platform, matches.value_of("bundle_id"))?;

    println!("{} Processing react-native code-push sourcemaps",
             style(">").dim());

    let mut processor = SourceMapProcessor::new();
    for path in matches.values_of("paths").unwrap() {
        for entry in fs::read_dir(path)? {
            if_chain! {
                if let Ok(entry) = entry;
                if let Some(filename) = entry.file_name().to_str();
                if let Some(ext) = entry.path().extension();
                if ext == OsStr::new("jsbundle") ||
                   ext == OsStr::new("map") ||
                   ext == OsStr::new("bundle");
                then {
                    let url = format!("~/{}", filename);
                    processor.add(&url, &entry.path())?;
                }
            }
        }
    }

    processor.rewrite(&vec![here_str])?;
    processor.add_sourcemap_references()?;

    let release = api.new_release(&org, &NewRelease {
        version: release.to_string(),
        projects: vec![project.to_string()],
        ..Default::default()
    })?;
    processor.upload(&api, &org, Some(&project), &release.version, None)?;

    Ok(())
}
<commit_msg>Added --print-release-name to react-native codepush<commit_after>use std::fs;
use std::env;
use std::ffi::OsStr;

use clap::{App, Arg, ArgMatches};
use console::style;

use prelude::*;
use api::{Api, NewRelease};
use config::Config;
use utils::{ArgExt, SourceMapProcessor, get_codepush_package, get_codepush_release};

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b> {
    app.about("uploads react-native projects for codepush")
        .org_project_args()
        .arg(Arg::with_name("deployment")
            .long("deployment")
            .value_name("DEPLOYMENT")
            .help("The name of the deployment (Production, Staging)"))
        .arg(Arg::with_name("bundle_id")
            .value_name("BUNDLE_ID")
            .long("bundle-id")
            .help("Explicitly provide the bundle ID instead of \
                   parsing the source projects.  This allows you to push \
                   codepush releases for iOS on platforms without xcode."))
        .arg(Arg::with_name("print_release_name")
            .long("print-release-name")
            .help("Print out the release name instead."))
        .arg(Arg::with_name("app_name")
            .value_name("APP_NAME")
            .index(1)
            .required(true)
            .help("The name of the code-push application"))
        .arg(Arg::with_name("platform")
            .value_name("PLATFORM")
            .index(2)
            .required(true)
            .help("The name of the code-push platform (ios, android)"))
        .arg(Arg::with_name("paths")
            .value_name("PATH")
            .index(3)
            .required(true)
            .multiple(true)
            .help("A list of folders with assets that should be processed."))
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> Result<()> {
    let here = env::current_dir()?;
    let here_str: &str = &here.to_string_lossy();
    let (org, project) = config.get_org_and_project(matches)?;
    let app = matches.value_of("app_name").unwrap();
    let platform = matches.value_of("platform").unwrap();
    let deployment = matches.value_of("deployment").unwrap_or("Staging");
    let api = Api::new(config);
    let print_release_name = matches.is_present("print_release_name");

    if !print_release_name {
        println!("{} Fetching latest code-push package info", style(">").dim());
    }

    let package = get_codepush_package(app, deployment)?;
    let release = get_codepush_release(&package, platform, matches.value_of("bundle_id"))?;
    if print_release_name {
        println!("{}", release);
        return Ok(());
    }

    println!("{} Processing react-native code-push sourcemaps",
             style(">").dim());

    let mut processor = SourceMapProcessor::new();
    for path in matches.values_of("paths").unwrap() {
        for entry in fs::read_dir(path)? {
            if_chain! {
                if let Ok(entry) = entry;
                if let Some(filename) = entry.file_name().to_str();
                if let Some(ext) = entry.path().extension();
                if ext == OsStr::new("jsbundle") ||
                   ext == OsStr::new("map") ||
                   ext == OsStr::new("bundle");
                then {
                    let url = format!("~/{}", filename);
                    processor.add(&url, &entry.path())?;
                }
            }
        }
    }

    processor.rewrite(&vec![here_str])?;
    processor.add_sourcemap_references()?;

    let release = api.new_release(&org, &NewRelease {
        version: release.to_string(),
        projects: vec![project.to_string()],
        ..Default::default()
    })?;
    processor.upload(&api, &org, Some(&project), &release.version, None)?;

    Ok(())
}
<|endoftext|>


<commit_before>use std::io::{stderr, Write};

extern crate clap;
use clap::{App, Arg};

fn main() {
    let matches = App::new("qotd")
        .author("Justinas Stankevicius")
        .arg(Arg::with_name("port").short("p").takes_value(true))
        .get_matches();

    let port = matches.value_of("port").unwrap_or("7")
        .parse::<u16>().ok().unwrap_or_else(|| {
            write!(stderr(), "An invalid port number supplied, defaulting to 7.\n");
            7
        });

    println!("{:?}", port);
}
<commit_msg>[daytime] Run an event loop with a TCP listener<commit_after>use std::collections::HashMap;
use std::io::{stderr, Write};
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::str::FromStr;

extern crate clap;
use clap::{App, Arg};

extern crate mio;
use mio::{EventLoop, EventSet, Handler, Token};
use mio::tcp::TcpListener;

const SERVER: Token = Token(0);

struct EchoHandler(TcpListener);

impl Handler for EchoHandler {
    type Message = ();
    type Timeout = ();

    fn ready(&mut self, event_loop: &mut EventLoop<Self>, token: Token, events: EventSet) {
    }
}

fn main() {
    let matches = App::new("qotd")
        .author("Justinas Stankevicius")
        .arg(Arg::with_name("port").short("p").takes_value(true))
        .get_matches();

    let port = matches.value_of("port").unwrap_or("7")
        .parse::<u16>().ok().unwrap_or_else(|| {
            write!(stderr(), "An invalid port number supplied, defaulting to 7.\n");
            7
        });

    let ip = Ipv4Addr::new(127, 0, 0, 1);
    let addr = SocketAddrV4::new(ip, port);
    let listener = TcpListener::bind(&SocketAddr::V4(addr)).unwrap();

    let mut event_loop = EventLoop::new().unwrap();
    event_loop.register(&listener, SERVER).unwrap();
    event_loop.run(&mut EchoHandler(listener)).unwrap();
}
<|endoftext|>