<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Joao Oliveira <joaoxsouls@gmail.com>
// (c) Jian Zeng <anonymousknight96 AT gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// last synced with: uname (GNU coreutils) 8.21

// spell-checker:ignore (ToDO) nodename kernelname kernelrelease kernelversion sysname hwplatform mnrsv

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, Arg};
use platform_info::*;

const ABOUT: &str = "Print certain system information.  With no OPTION, same as -s.";

pub mod options {
    pub static ALL: &str = "all";
    pub static KERNELNAME: &str = "kernel-name";
    pub static NODENAME: &str = "nodename";
    pub static KERNELVERSION: &str = "kernel-version";
    pub static KERNELRELEASE: &str = "kernel-release";
    pub static MACHINE: &str = "machine";
    pub static PROCESSOR: &str = "processor";
    pub static HWPLATFORM: &str = "hardware-platform";
    pub static OS: &str = "operating-system";
}

#[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "")))]
const HOST_OS: &str = "GNU/Linux";
#[cfg(all(target_os = "linux", not(any(target_env = "gnu", target_env = ""))))]
const HOST_OS: &str = "Linux";
#[cfg(target_os = "windows")]
const HOST_OS: &str = "Windows NT";
#[cfg(target_os = "freebsd")]
const HOST_OS: &str = "FreeBSD";
#[cfg(target_os = "openbsd")]
const HOST_OS: &str = "OpenBSD";
#[cfg(target_vendor = "apple")]
const HOST_OS: &str = "Darwin";
#[cfg(target_os = "fuchsia")]
const HOST_OS: &str = "Fuchsia";
#[cfg(target_os = "redox")]
const HOST_OS: &str = "Redox";

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = format!("{} [OPTION]...", executable!());
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let uname = return_if_err!(1, PlatformInfo::new());
    let mut output = String::new();

    let all = matches.is_present(options::ALL);
    let kernelname = matches.is_present(options::KERNELNAME);
    let nodename = matches.is_present(options::NODENAME);
    let kernelrelease = matches.is_present(options::KERNELRELEASE);
    let kernelversion = matches.is_present(options::KERNELVERSION);
    let machine = matches.is_present(options::MACHINE);
    let processor = matches.is_present(options::PROCESSOR);
    let hwplatform = matches.is_present(options::HWPLATFORM);
    let os = matches.is_present(options::OS);

    let none = !(all
        || kernelname
        || nodename
        || kernelrelease
        || kernelversion
        || machine
        || os
        || processor
        || hwplatform);

    if kernelname || all || none {
        output.push_str(&uname.sysname());
        output.push(' ');
    }

    if nodename || all {
        output.push_str(&uname.nodename());
        output.push(' ');
    }
    if kernelrelease || all {
        output.push_str(&uname.release());
        output.push(' ');
    }
    if kernelversion || all {
        output.push_str(&uname.version());
        output.push(' ');
    }
    if machine || all {
        output.push_str(&uname.machine());
        output.push(' ');
    }
    if processor || all {
        // According to https://stackoverflow.com/posts/394271/revisions
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if hwplatform || all {
        // According to https://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if os || all {
        output.push_str(HOST_OS);
        output.push(' ');
    }
    println!("{}", output.trim_end());

    0
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(executable!())
        .version(crate_version!())
        .about(ABOUT)
        .arg(Arg::with_name(options::ALL)
            .short("a")
            .long(options::ALL)
            .help("Behave as though all of the options -mnrsv were specified."))
        .arg(Arg::with_name(options::KERNELNAME)
            .short("s")
            .long(options::KERNELNAME)
            .alias("sysname") // Obsolescent option in GNU uname
            .help("print the kernel name."))
        .arg(Arg::with_name(options::NODENAME)
            .short("n")
            .long(options::NODENAME)
            .help("print the nodename (the nodename may be a name that the system is known by to a communications network)."))
        .arg(Arg::with_name(options::KERNELRELEASE)
            .short("r")
            .long(options::KERNELRELEASE)
            .alias("release") // Obsolescent option in GNU uname
            .help("print the operating system release."))
        .arg(Arg::with_name(options::KERNELVERSION)
            .short("v")
            .long(options::KERNELVERSION)
            .help("print the operating system version."))
        .arg(Arg::with_name(options::HWPLATFORM)
            .short("i")
            .long(options::HWPLATFORM)
            .help("print the hardware platform (non-portable)"))
        .arg(Arg::with_name(options::MACHINE)
            .short("m")
            .long(options::MACHINE)
            .help("print the machine hardware name."))
        .arg(Arg::with_name(options::PROCESSOR)
            .short("p")
            .long(options::PROCESSOR)
            .help("print the processor type (non-portable)"))
        .arg(Arg::with_name(options::OS)
            .short("o")
            .long(options::OS)
            .help("print the operating system name."))
}
<commit_msg>uname: add NetBSD to operating systems list<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Joao Oliveira <joaoxsouls@gmail.com>
// (c) Jian Zeng <anonymousknight96 AT gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// last synced with: uname (GNU coreutils) 8.21

// spell-checker:ignore (ToDO) nodename kernelname kernelrelease kernelversion sysname hwplatform mnrsv

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, Arg};
use platform_info::*;

const ABOUT: &str = "Print certain system information.  With no OPTION, same as -s.";

pub mod options {
    pub static ALL: &str = "all";
    pub static KERNELNAME: &str = "kernel-name";
    pub static NODENAME: &str = "nodename";
    pub static KERNELVERSION: &str = "kernel-version";
    pub static KERNELRELEASE: &str = "kernel-release";
    pub static MACHINE: &str = "machine";
    pub static PROCESSOR: &str = "processor";
    pub static HWPLATFORM: &str = "hardware-platform";
    pub static OS: &str = "operating-system";
}

#[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "")))]
const HOST_OS: &str = "GNU/Linux";
#[cfg(all(target_os = "linux", not(any(target_env = "gnu", target_env = ""))))]
const HOST_OS: &str = "Linux";
#[cfg(target_os = "windows")]
const HOST_OS: &str = "Windows NT";
#[cfg(target_os = "freebsd")]
const HOST_OS: &str = "FreeBSD";
#[cfg(target_os = "netbsd")]
const HOST_OS: &str = "NetBSD";
#[cfg(target_os = "openbsd")]
const HOST_OS: &str = "OpenBSD";
#[cfg(target_vendor = "apple")]
const HOST_OS: &str = "Darwin";
#[cfg(target_os = "fuchsia")]
const HOST_OS: &str = "Fuchsia";
#[cfg(target_os = "redox")]
const HOST_OS: &str = "Redox";

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = format!("{} [OPTION]...", executable!());
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let uname = return_if_err!(1, PlatformInfo::new());
    let mut output = String::new();

    let all = matches.is_present(options::ALL);
    let kernelname = matches.is_present(options::KERNELNAME);
    let nodename = matches.is_present(options::NODENAME);
    let kernelrelease = matches.is_present(options::KERNELRELEASE);
    let kernelversion = matches.is_present(options::KERNELVERSION);
    let machine = matches.is_present(options::MACHINE);
    let processor = matches.is_present(options::PROCESSOR);
    let hwplatform = matches.is_present(options::HWPLATFORM);
    let os = matches.is_present(options::OS);

    let none = !(all
        || kernelname
        || nodename
        || kernelrelease
        || kernelversion
        || machine
        || os
        || processor
        || hwplatform);

    if kernelname || all || none {
        output.push_str(&uname.sysname());
        output.push(' ');
    }

    if nodename || all {
        output.push_str(&uname.nodename());
        output.push(' ');
    }
    if kernelrelease || all {
        output.push_str(&uname.release());
        output.push(' ');
    }
    if kernelversion || all {
        output.push_str(&uname.version());
        output.push(' ');
    }
    if machine || all {
        output.push_str(&uname.machine());
        output.push(' ');
    }
    if processor || all {
        // According to https://stackoverflow.com/posts/394271/revisions
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if hwplatform || all {
        // According to https://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if os || all {
        output.push_str(HOST_OS);
        output.push(' ');
    }
    println!("{}", output.trim_end());

    0
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(executable!())
        .version(crate_version!())
        .about(ABOUT)
        .arg(Arg::with_name(options::ALL)
            .short("a")
            .long(options::ALL)
            .help("Behave as though all of the options -mnrsv were specified."))
        .arg(Arg::with_name(options::KERNELNAME)
            .short("s")
            .long(options::KERNELNAME)
            .alias("sysname") // Obsolescent option in GNU uname
            .help("print the kernel name."))
        .arg(Arg::with_name(options::NODENAME)
            .short("n")
            .long(options::NODENAME)
            .help("print the nodename (the nodename may be a name that the system is known by to a communications network)."))
        .arg(Arg::with_name(options::KERNELRELEASE)
            .short("r")
            .long(options::KERNELRELEASE)
            .alias("release") // Obsolescent option in GNU uname
            .help("print the operating system release."))
        .arg(Arg::with_name(options::KERNELVERSION)
            .short("v")
            .long(options::KERNELVERSION)
            .help("print the operating system version."))
        .arg(Arg::with_name(options::HWPLATFORM)
            .short("i")
            .long(options::HWPLATFORM)
            .help("print the hardware platform (non-portable)"))
        .arg(Arg::with_name(options::MACHINE)
            .short("m")
            .long(options::MACHINE)
            .help("print the machine hardware name."))
        .arg(Arg::with_name(options::PROCESSOR)
            .short("p")
            .long(options::PROCESSOR)
            .help("print the processor type (non-portable)"))
        .arg(Arg::with_name(options::OS)
            .short("o")
            .long(options::OS)
            .help("print the operating system name."))
}
<|endoftext|>


<commit_before>use ::alsa::PollDescriptors;
use ::alsa::mixer::{Mixer, SelemId, SelemChannelId};
use ::alsa::ctl::Ctl;

use format::data::Format;
use widget::base::Sender;

use std::sync::{Arc, RwLock};
use std::thread;
use std::ffi::CString;

use libc::{pollfd, poll}; // TODO use mio/epoll?

use super::{VolumeBackend, VolumeState};

pub struct ALSA {
    last_value: Arc<RwLock<Format>>,
}

impl ALSA {
    pub fn new() -> ALSA {
        ALSA {
            last_value: Arc::new(RwLock::new(Format::Str("".to_owned()))),
        }
    }

    fn get_volume_state() -> VolumeState {
        let mixer = Mixer::new("default", false).unwrap();
        let selem_id = SelemId::new("Master", 0);
        let selem = mixer.find_selem(&selem_id).unwrap();
        let (min, max) = selem.get_playback_volume_range();
        let volume = selem.get_playback_volume(SelemChannelId::FrontLeft).unwrap();
        let switch = selem.get_playback_switch(SelemChannelId::FrontLeft).unwrap();
        VolumeState {
            volume: (volume as f64 / (max - min) as f64) as f32,
            muted: switch == 0,
        }
    }
}

impl<F> VolumeBackend<F> for ALSA
    where F: Fn(VolumeState) -> Format + Sync + Send + 'static {

    fn current_value(&self) -> Format {
        (*self.last_value).read().unwrap().clone()
    }

    fn spawn_notifier(&mut self, tx: Sender<()>, updater: Arc<Box<F>>) {
        let ctl = Ctl::open(CString::new("default").unwrap().as_ref(), false).unwrap();
        ctl.subscribe_events(true).unwrap();

        let mut fds = Vec::<pollfd>::with_capacity(ctl.count());
        fds.resize(ctl.count(), pollfd {fd: 0, events: 0, revents: 0});
        let filled = ctl.fill(&mut fds).unwrap();
        assert!(filled == ctl.count());

        let last_value = self.last_value.clone();
        thread::spawn(move || {
            loop {
                unsafe {
                    let err = poll(fds.as_mut_ptr(), fds.len() as u64, -1);
                    // TODO check error
                }

                match ctl.read() {
                    Ok(Some(_)) => {
                        let state = ALSA::get_volume_state();

                        let mut writer = last_value.write().unwrap();
                        *writer = (*updater)(state);
                        let _ = tx.send(());
                    },
                    _ => continue
                }
            }
        });
    }
}

pub fn default_volume() -> ALSA {
    ALSA::new()
}
<commit_msg>calculate an initial volume for alsa<commit_after>use ::alsa::PollDescriptors;
use ::alsa::mixer::{Mixer, SelemId, SelemChannelId};
use ::alsa::ctl::Ctl;

use format::data::Format;
use widget::base::Sender;

use std::sync::{Arc, RwLock};
use std::thread;
use std::ffi::CString;

use libc::{pollfd, poll}; // TODO use mio/epoll?

use super::{VolumeBackend, VolumeState};

pub struct ALSA {
    last_value: Arc<RwLock<Format>>,
}

impl ALSA {
    pub fn new() -> ALSA {
        ALSA {
            last_value: Arc::new(RwLock::new(Format::Str("".to_owned()))),
        }
    }

    fn get_volume_state() -> VolumeState {
        let mixer = Mixer::new("default", false).unwrap();
        let selem_id = SelemId::new("Master", 0);
        let selem = mixer.find_selem(&selem_id).unwrap();
        let (min, max) = selem.get_playback_volume_range();
        let volume = selem.get_playback_volume(SelemChannelId::FrontLeft).unwrap();
        let switch = selem.get_playback_switch(SelemChannelId::FrontLeft).unwrap();
        VolumeState {
            volume: (volume as f64 / (max - min) as f64) as f32,
            muted: switch == 0,
        }
    }
}

impl<F> VolumeBackend<F> for ALSA
    where F: Fn(VolumeState) -> Format + Sync + Send + 'static {

    fn current_value(&self) -> Format {
        (*self.last_value).read().unwrap().clone()
    }

    fn spawn_notifier(&mut self, tx: Sender<()>, updater: Arc<Box<F>>) {
        let ctl = Ctl::open(CString::new("default").unwrap().as_ref(), false).unwrap();
        ctl.subscribe_events(true).unwrap();

        let mut fds = Vec::<pollfd>::with_capacity(ctl.count());
        fds.resize(ctl.count(), pollfd {fd: 0, events: 0, revents: 0});
        let filled = ctl.fill(&mut fds).unwrap();
        assert!(filled == ctl.count());

        let initial_state = ALSA::get_volume_state();
        {
            let mut writer = self.last_value.write().unwrap();
            *writer = (*updater)(initial_state);
        }

        let last_value = self.last_value.clone();
        thread::spawn(move || {
            loop {
                unsafe {
                    let err = poll(fds.as_mut_ptr(), fds.len() as u64, -1);
                    // TODO check error
                }

                match ctl.read() {
                    Ok(Some(_)) => {
                        let state = ALSA::get_volume_state();

                        let mut writer = last_value.write().unwrap();
                        *writer = (*updater)(state);
                        let _ = tx.send(());
                    },
                    _ => continue
                }
            }
        });
    }
}

pub fn default_volume() -> ALSA {
    ALSA::new()
}
<|endoftext|>


<commit_before>use std::{
    cmp::PartialEq,
    error::Error as StdError,
    fmt::{self, Display},
    io,
};

use crate::{
    pagecache::{DiskPtr, PageView},
    IVec,
};

/// The top-level result type for dealing with
/// the `PageCache`.
pub type Result<T> = std::result::Result<T, Error>;

/// A compare and swap result.  If the CAS is successful,
/// the new `PagePtr` will be returned as `Ok`.  Otherwise,
/// the `Err` will contain a tuple of the current `PagePtr`
/// and the old value that could not be set atomically.
pub(crate) type CasResult<'a, R> =
    std::result::Result<PageView<'a>, Option<(PageView<'a>, R)>>;

/// An Error type encapsulating various issues that may come up
/// in both the expected and unexpected operation of a `PageCache`.
#[derive(Debug)]
pub enum Error {
    /// The underlying collection no longer exists.
    CollectionNotFound(IVec),
    /// The system has been used in an unsupported way.
    Unsupported(String),
    /// An unexpected bug has happened. Please open an issue on github!
    ReportableBug(String),
    /// A read or write error has happened when interacting with the file
    /// system.
    Io(io::Error),
    /// Corruption has been detected in the storage file.
    Corruption {
        /// The file location that corrupted data was found at.
        at: DiskPtr,
    },
    // a failpoint has been triggered for testing purposes
    #[doc(hidden)]
    #[cfg(feature = "failpoints")]
    FailPoint,
}

impl Clone for Error {
    fn clone(&self) -> Self {
        use self::Error::*;

        match self {
            Io(ioe) => Io(io::Error::new(ioe.kind(), format!("{:?}", ioe))),
            CollectionNotFound(name) => CollectionNotFound(name.clone()),
            Unsupported(why) => Unsupported(why.clone()),
            ReportableBug(what) => ReportableBug(what.clone()),
            Corruption { at } => Corruption { at: *at },
            #[cfg(feature = "failpoints")]
            FailPoint => FailPoint,
        }
    }
}

impl Eq for Error {}

impl PartialEq for Error {
    fn eq(&self, other: &Self) -> bool {
        use self::Error::*;

        match *self {
            CollectionNotFound(ref l) => {
                if let CollectionNotFound(ref r) = *other {
                    l == r
                } else {
                    false
                }
            }
            Unsupported(ref l) => {
                if let Unsupported(ref r) = *other {
                    l == r
                } else {
                    false
                }
            }
            ReportableBug(ref l) => {
                if let ReportableBug(ref r) = *other {
                    l == r
                } else {
                    false
                }
            }
            #[cfg(feature = "failpoints")]
            FailPoint => {
                if let FailPoint = *other {
                    true
                } else {
                    false
                }
            }
            Corruption { at: l } => {
                if let Corruption { at: r } = *other {
                    l == r
                } else {
                    false
                }
            }
            Io(_) => false,
        }
    }
}

impl From<io::Error> for Error {
    #[inline]
    fn from(io_error: io::Error) -> Self {
        Error::Io(io_error)
    }
}

impl StdError for Error {
    fn description(&self) -> &str {
        use self::Error::*;

        match *self {
            CollectionNotFound(_) => "Collection does not exist.",
            Unsupported(ref e) | ReportableBug(ref e) => &*e,
            #[cfg(feature = "failpoints")]
            FailPoint => "Fail point has been triggered.",
            Io(ref e) => e.description(),
            Corruption { .. } => "Read corrupted data.",
        }
    }
}

impl Display for Error {
    fn fmt(
        &self,
        f: &mut fmt::Formatter<'_>,
    ) -> std::result::Result<(), fmt::Error> {
        use self::Error::*;

        match *self {
            CollectionNotFound(ref name) => {
                write!(f, "Collection {:?} does not exist", name,)
            }
            Unsupported(ref e) => write!(f, "Unsupported: {}", e),
            ReportableBug(ref e) => write!(
                f,
                "Unexpected bug has happened: {}. \
                 PLEASE REPORT THIS BUG!",
                e
            ),
            #[cfg(feature = "failpoints")]
            FailPoint => write!(f, "Fail point has been triggered."),
            Io(ref e) => write!(f, "IO error: {}", e),
            Corruption { at } => {
                write!(f, "Read corrupted data at file offset {}", at)
            }
        }
    }
}
<commit_msg>feat(build):  is deprecated since 1.41.0: use the Display impl or to_string()<commit_after>use std::{
    cmp::PartialEq,
    error::Error as StdError,
    fmt::{self, Display},
    io,
};

use crate::{
    pagecache::{DiskPtr, PageView},
    IVec,
};

/// The top-level result type for dealing with
/// the `PageCache`.
pub type Result<T> = std::result::Result<T, Error>;

/// A compare and swap result.  If the CAS is successful,
/// the new `PagePtr` will be returned as `Ok`.  Otherwise,
/// the `Err` will contain a tuple of the current `PagePtr`
/// and the old value that could not be set atomically.
pub(crate) type CasResult<'a, R> =
    std::result::Result<PageView<'a>, Option<(PageView<'a>, R)>>;

/// An Error type encapsulating various issues that may come up
/// in both the expected and unexpected operation of a `PageCache`.
#[derive(Debug)]
pub enum Error {
    /// The underlying collection no longer exists.
    CollectionNotFound(IVec),
    /// The system has been used in an unsupported way.
    Unsupported(String),
    /// An unexpected bug has happened. Please open an issue on github!
    ReportableBug(String),
    /// A read or write error has happened when interacting with the file
    /// system.
    Io(io::Error),
    /// Corruption has been detected in the storage file.
    Corruption {
        /// The file location that corrupted data was found at.
        at: DiskPtr,
    },
    // a failpoint has been triggered for testing purposes
    #[doc(hidden)]
    #[cfg(feature = "failpoints")]
    FailPoint,
}

impl Clone for Error {
    fn clone(&self) -> Self {
        use self::Error::*;

        match self {
            Io(ioe) => Io(io::Error::new(ioe.kind(), format!("{:?}", ioe))),
            CollectionNotFound(name) => CollectionNotFound(name.clone()),
            Unsupported(why) => Unsupported(why.clone()),
            ReportableBug(what) => ReportableBug(what.clone()),
            Corruption { at } => Corruption { at: *at },
            #[cfg(feature = "failpoints")]
            FailPoint => FailPoint,
        }
    }
}

impl Eq for Error {}

impl PartialEq for Error {
    fn eq(&self, other: &Self) -> bool {
        use self::Error::*;

        match *self {
            CollectionNotFound(ref l) => {
                if let CollectionNotFound(ref r) = *other {
                    l == r
                } else {
                    false
                }
            }
            Unsupported(ref l) => {
                if let Unsupported(ref r) = *other {
                    l == r
                } else {
                    false
                }
            }
            ReportableBug(ref l) => {
                if let ReportableBug(ref r) = *other {
                    l == r
                } else {
                    false
                }
            }
            #[cfg(feature = "failpoints")]
            FailPoint => {
                if let FailPoint = *other {
                    true
                } else {
                    false
                }
            }
            Corruption { at: l } => {
                if let Corruption { at: r } = *other {
                    l == r
                } else {
                    false
                }
            }
            Io(_) => false,
        }
    }
}

impl From<io::Error> for Error {
    #[inline]
    fn from(io_error: io::Error) -> Self {
        Error::Io(io_error)
    }
}

impl StdError for Error {
    #[allow(deprecated, deprecated_in_future)]
    fn description(&self) -> &str {
        use self::Error::*;

        match *self {
            CollectionNotFound(_) => "Collection does not exist.",
            Unsupported(ref e) | ReportableBug(ref e) => &*e,
            #[cfg(feature = "failpoints")]
            FailPoint => "Fail point has been triggered.",
            Io(ref e) => e.description(),
            Corruption { .. } => "Read corrupted data.",
        }
    }
}

impl Display for Error {
    fn fmt(
        &self,
        f: &mut fmt::Formatter<'_>,
    ) -> std::result::Result<(), fmt::Error> {
        use self::Error::*;

        match *self {
            CollectionNotFound(ref name) => {
                write!(f, "Collection {:?} does not exist", name,)
            }
            Unsupported(ref e) => write!(f, "Unsupported: {}", e),
            ReportableBug(ref e) => write!(
                f,
                "Unexpected bug has happened: {}. \
                 PLEASE REPORT THIS BUG!",
                e
            ),
            #[cfg(feature = "failpoints")]
            FailPoint => write!(f, "Fail point has been triggered."),
            Io(ref e) => write!(f, "IO error: {}", e),
            Corruption { at } => {
                write!(f, "Read corrupted data at file offset {}", at)
            }
        }
    }
}
<|endoftext|>


<commit_before>use super::command::Command;
use super::command::Command::Select;
use std::iter::IntoIterator;
use std::collections::HashMap;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct SelectCommand {
    command: Command,
    arguments: HashMap<String, String>,
    table: String,
}

impl Default for SelectCommand {
    fn default() -> SelectCommand {
        SelectCommand {
            command: Select,
            arguments: HashMap::new(),
            table: "".to_string(),
        }
    }
}

impl SelectCommand {
    pub fn new(table: String) -> SelectCommand {
        let default: SelectCommand = Default::default();
        SelectCommand {
            command: default.command,
            arguments: default.arguments,
            table: table
        }
    }

    pub fn output_columns(mut self, columns: Vec<String>) -> SelectCommand {
        fn split_columns_vec(columns: Vec<String>) -> String {
            let string = columns.into_iter().collect::<Vec<String>>()
                .join(",").to_owned();
            string.clone()
        }

        let string = split_columns_vec(columns);
        self.arguments.insert("output_columns".to_string(), string.clone());
        self
    }

    pub fn offset(mut self, offset: u64) -> SelectCommand {
        let offset = format!("{}", offset);
        self.arguments.insert("offset".to_string(), offset.clone());
        self
    }

    pub fn limit(mut self, limit: u64) -> SelectCommand {
        let limit = format!("{}", limit);
        self.arguments.insert("limit".to_string(), limit.clone());
        self
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use command::Command::Select;
    use std::collections::HashMap;

    #[test]
    fn test_new() {
        let vanilla_select = SelectCommand::new("test".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: HashMap::new(),
            table: "test".to_string(),
        };
        assert_eq!(expected, vanilla_select);
    }

    #[test]
    fn test_output_columns() {
        let select = SelectCommand::new("test".to_string())
            .output_columns(vec!["test".to_string(), "piyo".to_string()]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("output_columns".to_string(), "test,piyo".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_offset() {
        let select = SelectCommand::new("test".to_string())
            .offset(100);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("offset".to_string(), "100".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_limit() {
        let select = SelectCommand::new("test".to_string())
            .limit(50);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("limit".to_string(), "50".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }
}
<commit_msg>select: Add more query params support<commit_after>use super::command::Command;
use super::command::Command::Select;
use std::iter::IntoIterator;
use std::collections::HashMap;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct SelectCommand {
    command: Command,
    arguments: HashMap<String, String>,
    table: String,
}

impl Default for SelectCommand {
    fn default() -> SelectCommand {
        SelectCommand {
            command: Select,
            arguments: HashMap::new(),
            table: "".to_string(),
        }
    }
}

impl SelectCommand {
    pub fn new(table: String) -> SelectCommand {
        let default: SelectCommand = Default::default();
        SelectCommand {
            command: default.command,
            arguments: default.arguments,
            table: table
        }
    }

    pub fn filter(mut self, filter: String) -> SelectCommand {
        let encoded = format!("'{}'", filter);
        self.arguments.insert("filter".to_string(), encoded.clone());
        self
    }

    #[inline]
    fn split_columns_vec(&mut self, columns: Vec<String>) -> String {
        let string = columns.into_iter().collect::<Vec<String>>()
            .join(",").to_owned();
        string.clone()
    }

    pub fn match_columns(mut self, columns: Vec<String>) -> SelectCommand {
        let string = self.split_columns_vec(columns);
        self.arguments.insert("match_columns".to_string(), string.clone());
        self
    }

    pub fn output_columns(mut self, columns: Vec<String>) -> SelectCommand {
        let string = self.split_columns_vec(columns);
        self.arguments.insert("output_columns".to_string(), string.clone());
        self
    }

    pub fn offset(mut self, offset: u64) -> SelectCommand {
        let offset = format!("{}", offset);
        self.arguments.insert("offset".to_string(), offset.clone());
        self
    }

    pub fn limit(mut self, limit: u64) -> SelectCommand {
        let limit = format!("{}", limit);
        self.arguments.insert("limit".to_string(), limit.clone());
        self
    }

    pub fn cache(mut self, cache: bool) -> SelectCommand {
        let flag = match cache {
            true => "yes",
            false => "no"
        };
        self.arguments.insert("cache".to_string(), flag.to_string());
        self
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use command::Command::Select;
    use std::collections::HashMap;

    #[test]
    fn test_new() {
        let vanilla_select = SelectCommand::new("test".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: HashMap::new(),
            table: "test".to_string(),
        };
        assert_eq!(expected, vanilla_select);
    }

    #[test]
    fn test_filter() {
        let select = SelectCommand::new("test".to_string())
            .filter("output_column @ \"type_safe\"".to_string());
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("filter".to_string(),
                   "'output_column @ \"type_safe\"'".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_match_columns() {
        let select = SelectCommand::new("test".to_string())
            .match_columns(vec!["test".to_string(), "piyo".to_string()]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("match_columns".to_string(), "test,piyo".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_output_columns() {
        let select = SelectCommand::new("test".to_string())
            .output_columns(vec!["test".to_string(), "piyo".to_string()]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("output_columns".to_string(), "test,piyo".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_offset() {
        let select = SelectCommand::new("test".to_string())
            .offset(100);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("offset".to_string(), "100".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_limit() {
        let select = SelectCommand::new("test".to_string())
            .limit(50);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("limit".to_string(), "50".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_cache() {
        let select_yes = SelectCommand::new("test".to_string())
            .cache(true);
        let mut arg_yes: HashMap<String, String> = HashMap::new();
        arg_yes.insert("cache".to_string(), "yes".to_string());
        let expected_yes = SelectCommand {
            command: Select,
            arguments: arg_yes,
            table: "test".to_string(),
        };
        assert_eq!(expected_yes, select_yes);
        let select_no = SelectCommand::new("test".to_string())
            .cache(false);
        let mut arg_no: HashMap<String, String> = HashMap::new();
        arg_no.insert("cache".to_string(), "no".to_string());
        let expected_no = SelectCommand {
            command: Select,
            arguments: arg_no,
            table: "test".to_string(),
        };
        assert_eq!(expected_no, select_no);
    }
}
<|endoftext|>


<commit_before>use std::io::{Write, Read};
use std::sync::Mutex;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread;
use std::net::SocketAddr;

use hyper::header::{ContentLength, ContentType};
use hyper::method::Method;
use hyper::server::{Server, Handler, Request, Response};
use hyper::uri::RequestUri::AbsolutePath;
use hyper::status::StatusCode;

use command::{WebDriverMessage, WebDriverCommand};
use error::{WebDriverResult, WebDriverError, ErrorStatus};
use httpapi::WebDriverHttpApi;
use response::WebDriverResponse;

enum DispatchMessage {
    HandleWebDriver(WebDriverMessage, Sender<WebDriverResult<WebDriverResponse>>),
    Quit
}

#[derive(PartialEq, Clone)]
pub struct Session {
    id: String
}

impl Session {
    fn new(id: String) -> Session {
        Session {
            id: id
        }
    }
}

pub trait WebDriverHandler : Send {
    fn handle_command(&mut self, session: &Option<Session>, msg: &WebDriverMessage) -> WebDriverResult<WebDriverResponse>;
    fn delete_session(&mut self, session: &Option<Session>);
}

struct Dispatcher<T: WebDriverHandler> {
    handler: T,
    session: Option<Session>
}

impl<T: WebDriverHandler> Dispatcher<T> {
    fn new(handler: T) -> Dispatcher<T> {
        Dispatcher {
            handler: handler,
            session: None
        }
    }

    fn run(&mut self, msg_chan: Receiver<DispatchMessage>) {
        loop {
            match msg_chan.recv() {
                Ok(DispatchMessage::HandleWebDriver(msg, resp_chan)) => {
                    let resp = match self.check_session(&msg) {
                        Ok(_) => self.handler.handle_command(&self.session, &msg),
                        Err(e) => Err(e)
                    };

                    match resp {
                        Ok(WebDriverResponse::NewSession(ref new_session)) => {
                            self.session = Some(Session::new(new_session.sessionId.clone()));
                        },
                        Ok(WebDriverResponse::DeleteSession) => {
                            self.delete_session();
                        },
                        Err(ref x) if x.delete_session() => {
                            self.delete_session();
                        }
                        _ => {}
                    }

                    if resp_chan.send(resp).is_err() {
                        error!("Sending response to the main thread failed");
                    };
                },
                Ok(DispatchMessage::Quit) => {
                    break;
                },
                Err(_) => panic!("Error receiving message in handler")
            }
        }
    }

    fn delete_session(&mut self) {
        debug!("Deleting session");
        self.handler.delete_session(&self.session);
        self.session = None;
    }

    fn check_session(&self, msg: &WebDriverMessage) -> WebDriverResult<()> {
        match msg.session_id {
            Some(ref msg_session_id) => {
                match self.session {
                    Some(ref existing_session) => {
                        if existing_session.id != *msg_session_id {
                            Err(WebDriverError::new(
                                ErrorStatus::InvalidSessionId,
                                &format!("Got unexpected session id {} expected {}",
                                         msg_session_id,
                                         existing_session.id)[..]))
                        } else {
                            Ok(())
                        }
                    },
                    None => Ok(())
                }
            },
            None => {
                match self.session {
                    Some(_) => {
                        match msg.command {
                            WebDriverCommand::NewSession => {
                                Err(WebDriverError::new(
                                    ErrorStatus::UnsupportedOperation,
                                    "Session is already started"))
                            },
                            _ => {
                                //This should be impossible
                                error!("Got a message with no session id");
                                Err(WebDriverError::new(
                                    ErrorStatus::UnknownError,
                                    "Got a command with no session?!"))
                            }
                        }
                    },
                    None => {
                        match msg.command {
                            WebDriverCommand::NewSession => Ok(()),

                            _ => Err(WebDriverError::new(
                                ErrorStatus::InvalidSessionId,
                                "Tried to run a command before creating a session"))
                        }
                    }
                }
            }
        }
    }
}

struct HttpHandler {
    chan: Mutex<Sender<DispatchMessage>>,
    api: Mutex<WebDriverHttpApi>
}

impl HttpHandler {
    fn new(api: WebDriverHttpApi, chan: Sender<DispatchMessage>) -> HttpHandler {
        HttpHandler {
            chan: Mutex::new(chan),
            api: Mutex::new(api)
        }
    }
}

impl Handler for HttpHandler {
    fn handle(&self, req: Request, res: Response) {
        let mut req = req;
        let mut res = res;

        let mut body = String::new();
        if let Method::Post = req.method {
            req.read_to_string(&mut body).unwrap();
        }
        debug!("Got request {} {:?}", req.method, req.uri);
        match req.uri {
            AbsolutePath(path) => {
                let msg_result = {
                    // The fact that this locks for basically the whole request doesn't
                    // matter as long as we are only handling one request at a time.
                    match self.api.lock() {
                        Ok(ref api) => {
                            api.decode_request(req.method, &path[..], &body[..])
                        },
                        Err(_) => return
                    }
                };
                let (status, resp_body) = match msg_result {
                    Ok(message) => {
                        let (send_res, recv_res) = channel();
                        match self.chan.lock() {
                            Ok(ref c) => {
                                let res = c.send(DispatchMessage::HandleWebDriver(message,
                                                                                send_res));
                                match res {
                                    Ok(x) => x,
                                    Err(_) => {
                                        error!("Something terrible happened");
                                        return
                                    }
                                }
                            },
                            Err(_) => {
                                error!("Something terrible happened");
                                return
                            }
                        }
                        match recv_res.recv() {
                            Ok(data) => match data {
                                Ok(response) => (StatusCode::Ok, response.to_json_string()),
                                Err(err) => (err.http_status(), err.to_json_string()),
                            },
                            Err(e) => panic!("Error reading response: {:?}", e)
                        }
                    },
                    Err(err) => {
                        (err.http_status(), err.to_json_string())
                    }
                };
                error!("Returning status {:?}", status);
                error!("Returning body {}", resp_body);
                {
                    let resp_status = res.status_mut();
                    *resp_status = status;
                }
                res.headers_mut().set(ContentLength(resp_body.len() as u64));
                res.headers_mut().set(ContentType::json());
                let mut stream = res.start().unwrap();
                stream.write_all(&resp_body.as_bytes()).unwrap();
                stream.end().unwrap();
            },
            _ => {}
        }
    }
}

pub fn start<T: 'static+WebDriverHandler>(address: SocketAddr, handler: T) {
    let (msg_send, msg_recv) = channel();

    let api = WebDriverHttpApi::new();
    let http_handler = HttpHandler::new(api, msg_send);
    let server = Server::http(address).unwrap();

    let builder = thread::Builder::new().name("webdriver dispatcher".to_string());
    builder.spawn(move || {
        let mut dispatcher = Dispatcher::new(handler);
        dispatcher.run(msg_recv)
    }).unwrap();
    server.handle(http_handler).unwrap();
}
<commit_msg>Don't log response at error level<commit_after>use std::io::{Write, Read};
use std::sync::Mutex;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread;
use std::net::SocketAddr;

use hyper::header::{ContentLength, ContentType};
use hyper::method::Method;
use hyper::server::{Server, Handler, Request, Response};
use hyper::uri::RequestUri::AbsolutePath;
use hyper::status::StatusCode;

use command::{WebDriverMessage, WebDriverCommand};
use error::{WebDriverResult, WebDriverError, ErrorStatus};
use httpapi::WebDriverHttpApi;
use response::WebDriverResponse;

enum DispatchMessage {
    HandleWebDriver(WebDriverMessage, Sender<WebDriverResult<WebDriverResponse>>),
    Quit
}

#[derive(PartialEq, Clone)]
pub struct Session {
    id: String
}

impl Session {
    fn new(id: String) -> Session {
        Session {
            id: id
        }
    }
}

pub trait WebDriverHandler : Send {
    fn handle_command(&mut self, session: &Option<Session>, msg: &WebDriverMessage) -> WebDriverResult<WebDriverResponse>;
    fn delete_session(&mut self, session: &Option<Session>);
}

struct Dispatcher<T: WebDriverHandler> {
    handler: T,
    session: Option<Session>
}

impl<T: WebDriverHandler> Dispatcher<T> {
    fn new(handler: T) -> Dispatcher<T> {
        Dispatcher {
            handler: handler,
            session: None
        }
    }

    fn run(&mut self, msg_chan: Receiver<DispatchMessage>) {
        loop {
            match msg_chan.recv() {
                Ok(DispatchMessage::HandleWebDriver(msg, resp_chan)) => {
                    let resp = match self.check_session(&msg) {
                        Ok(_) => self.handler.handle_command(&self.session, &msg),
                        Err(e) => Err(e)
                    };

                    match resp {
                        Ok(WebDriverResponse::NewSession(ref new_session)) => {
                            self.session = Some(Session::new(new_session.sessionId.clone()));
                        },
                        Ok(WebDriverResponse::DeleteSession) => {
                            self.delete_session();
                        },
                        Err(ref x) if x.delete_session() => {
                            self.delete_session();
                        }
                        _ => {}
                    }

                    if resp_chan.send(resp).is_err() {
                        error!("Sending response to the main thread failed");
                    };
                },
                Ok(DispatchMessage::Quit) => {
                    break;
                },
                Err(_) => panic!("Error receiving message in handler")
            }
        }
    }

    fn delete_session(&mut self) {
        debug!("Deleting session");
        self.handler.delete_session(&self.session);
        self.session = None;
    }

    fn check_session(&self, msg: &WebDriverMessage) -> WebDriverResult<()> {
        match msg.session_id {
            Some(ref msg_session_id) => {
                match self.session {
                    Some(ref existing_session) => {
                        if existing_session.id != *msg_session_id {
                            Err(WebDriverError::new(
                                ErrorStatus::InvalidSessionId,
                                &format!("Got unexpected session id {} expected {}",
                                         msg_session_id,
                                         existing_session.id)[..]))
                        } else {
                            Ok(())
                        }
                    },
                    None => Ok(())
                }
            },
            None => {
                match self.session {
                    Some(_) => {
                        match msg.command {
                            WebDriverCommand::NewSession => {
                                Err(WebDriverError::new(
                                    ErrorStatus::UnsupportedOperation,
                                    "Session is already started"))
                            },
                            _ => {
                                //This should be impossible
                                error!("Got a message with no session id");
                                Err(WebDriverError::new(
                                    ErrorStatus::UnknownError,
                                    "Got a command with no session?!"))
                            }
                        }
                    },
                    None => {
                        match msg.command {
                            WebDriverCommand::NewSession => Ok(()),

                            _ => Err(WebDriverError::new(
                                ErrorStatus::InvalidSessionId,
                                "Tried to run a command before creating a session"))
                        }
                    }
                }
            }
        }
    }
}

struct HttpHandler {
    chan: Mutex<Sender<DispatchMessage>>,
    api: Mutex<WebDriverHttpApi>
}

impl HttpHandler {
    fn new(api: WebDriverHttpApi, chan: Sender<DispatchMessage>) -> HttpHandler {
        HttpHandler {
            chan: Mutex::new(chan),
            api: Mutex::new(api)
        }
    }
}

impl Handler for HttpHandler {
    fn handle(&self, req: Request, res: Response) {
        let mut req = req;
        let mut res = res;

        let mut body = String::new();
        if let Method::Post = req.method {
            req.read_to_string(&mut body).unwrap();
        }
        debug!("Got request {} {:?}", req.method, req.uri);
        match req.uri {
            AbsolutePath(path) => {
                let msg_result = {
                    // The fact that this locks for basically the whole request doesn't
                    // matter as long as we are only handling one request at a time.
                    match self.api.lock() {
                        Ok(ref api) => {
                            api.decode_request(req.method, &path[..], &body[..])
                        },
                        Err(_) => return
                    }
                };
                let (status, resp_body) = match msg_result {
                    Ok(message) => {
                        let (send_res, recv_res) = channel();
                        match self.chan.lock() {
                            Ok(ref c) => {
                                let res = c.send(DispatchMessage::HandleWebDriver(message,
                                                                                send_res));
                                match res {
                                    Ok(x) => x,
                                    Err(_) => {
                                        error!("Something terrible happened");
                                        return
                                    }
                                }
                            },
                            Err(_) => {
                                error!("Something terrible happened");
                                return
                            }
                        }
                        match recv_res.recv() {
                            Ok(data) => match data {
                                Ok(response) => (StatusCode::Ok, response.to_json_string()),
                                Err(err) => (err.http_status(), err.to_json_string()),
                            },
                            Err(e) => panic!("Error reading response: {:?}", e)
                        }
                    },
                    Err(err) => {
                        (err.http_status(), err.to_json_string())
                    }
                };
                debug!("Returning status {:?}", status);
                debug!("Returning body {}", resp_body);
                {
                    let resp_status = res.status_mut();
                    *resp_status = status;
                }
                res.headers_mut().set(ContentLength(resp_body.len() as u64));
                res.headers_mut().set(ContentType::json());
                let mut stream = res.start().unwrap();
                stream.write_all(&resp_body.as_bytes()).unwrap();
                stream.end().unwrap();
            },
            _ => {}
        }
    }
}

pub fn start<T: 'static+WebDriverHandler>(address: SocketAddr, handler: T) {
    let (msg_send, msg_recv) = channel();

    let api = WebDriverHttpApi::new();
    let http_handler = HttpHandler::new(api, msg_send);
    let server = Server::http(address).unwrap();

    let builder = thread::Builder::new().name("webdriver dispatcher".to_string());
    builder.spawn(move || {
        let mut dispatcher = Dispatcher::new(handler);
        dispatcher.run(msg_recv)
    }).unwrap();
    server.handle(http_handler).unwrap();
}
<|endoftext|>


<commit_before>use std::sync::{Mutex, Condvar};

pub struct Stream {
    buffer: Mutex<String>,
    condvar: Condvar,
}

impl Stream {
    pub fn new() -> Self {
        Stream { buffer: Mutex::new(String::new()), condvar: Condvar::new() }
    }

    pub fn write(&self, s: &str) {
        let mut buf = self.buffer.lock().unwrap();

        buf.push_str(s);
        self.condvar.notify_one();
    }

    pub fn read(&self) -> String {
        let mut buf = self.buffer.lock().unwrap();
        let temp = buf.clone();

        buf.clear();

        temp
    }
}
<commit_msg>make stream read block on condvar<commit_after>use std::sync::{Mutex, Condvar};

pub struct Stream {
    buffer: Mutex<String>,
    condvar: Condvar,
}

impl Stream {
    pub fn new() -> Self {
        Stream { buffer: Mutex::new(String::new()), condvar: Condvar::new() }
    }

    pub fn wait(&self) {

    }

    pub fn write(&self, s: &str) {
        let mut buf = self.buffer.lock().unwrap();

        buf.push_str(s);
        self.condvar.notify_one();
    }

    pub fn read(&self) -> String {
        let mut buf = self.buffer.lock().unwrap();
        buf = self.condvar.wait(buf).unwrap();
        let temp = buf.clone();

        buf.clear();

        temp
    }
}
<|endoftext|>


<commit_before>//! [PUT /_matrix/client/r0/profile/{userId}/avatar_url](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-profile-userid-avatar-url)

use ruma_api::ruma_api;
use ruma_identifiers::{MxcUri, UserId};

ruma_api! {
    metadata: {
        description: "Set the avatar URL of the user.",
        method: PUT,
        name: "set_avatar_url",
        path: "/_matrix/client/r0/profile/:user_id/avatar_url",
        rate_limited: true,
        authentication: AccessToken,
    }

    request: {
        /// The user whose avatar URL will be set.
        #[ruma_api(path)]
        pub user_id: &'a UserId,

        /// The new avatar URL for the user.
        ///
        /// `None` is used to unset the avatar.
        ///
        /// If you activate the `compat` feature, this field being an empty string in JSON will give
        /// you `None` here.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[cfg_attr(
            feature = "compat",
            serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
        )]
        pub avatar_url: Option<&'a MxcUri>,
    }

    #[derive(Default)]
    response: {}

    error: crate::Error
}

impl<'a> Request<'a> {
    /// Creates a new `Request` with the given user ID and avatar URL.
    pub fn new(user_id: &'a UserId, avatar_url: Option<&'a MxcUri>) -> Self {
        Self { user_id, avatar_url }
    }
}

impl Response {
    /// Creates an empty `Response`.
    pub fn new() -> Self {
        Self
    }
}

#[cfg(all(test, feature = "server"))]
mod tests {
    use matches::assert_matches;
    use ruma_api::IncomingRequest as _;

    use super::IncomingRequest;

    #[test]
    fn deserialize_unset_request() {
        assert_matches!(
            IncomingRequest::try_from_http_request(
                http::Request::builder()
                    .method("PUT")
                    .uri("https://bar.org/_matrix/client/r0/profile/@foo:bar.org/avatar_url")
                    .body(&[] as &[u8]).unwrap(),
            ).unwrap(),
            IncomingRequest { user_id, avatar_url: None } if user_id == "@foo:bar.org"
        );

        #[cfg(feature = "compat")]
        assert_matches!(
            IncomingRequest::try_from_http_request(
                http::Request::builder()
                    .method("PUT")
                    .uri("https://bar.org/_matrix/client/r0/profile/@foo:bar.org/avatar_url")
                    .body(std::io::Cursor::new(
                        serde_json::to_vec(&serde_json::json!({ "avatar_url": "" })).unwrap(),
                    )).unwrap(),
            ).unwrap(),
            IncomingRequest { user_id, avatar_url: None } if user_id == "@foo:bar.org"
        );

        Ok(())
    }
}
<commit_msg>client-api: Fix recently broken test<commit_after>//! [PUT /_matrix/client/r0/profile/{userId}/avatar_url](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-profile-userid-avatar-url)

use ruma_api::ruma_api;
use ruma_identifiers::{MxcUri, UserId};

ruma_api! {
    metadata: {
        description: "Set the avatar URL of the user.",
        method: PUT,
        name: "set_avatar_url",
        path: "/_matrix/client/r0/profile/:user_id/avatar_url",
        rate_limited: true,
        authentication: AccessToken,
    }

    request: {
        /// The user whose avatar URL will be set.
        #[ruma_api(path)]
        pub user_id: &'a UserId,

        /// The new avatar URL for the user.
        ///
        /// `None` is used to unset the avatar.
        ///
        /// If you activate the `compat` feature, this field being an empty string in JSON will give
        /// you `None` here.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[cfg_attr(
            feature = "compat",
            serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
        )]
        pub avatar_url: Option<&'a MxcUri>,
    }

    #[derive(Default)]
    response: {}

    error: crate::Error
}

impl<'a> Request<'a> {
    /// Creates a new `Request` with the given user ID and avatar URL.
    pub fn new(user_id: &'a UserId, avatar_url: Option<&'a MxcUri>) -> Self {
        Self { user_id, avatar_url }
    }
}

impl Response {
    /// Creates an empty `Response`.
    pub fn new() -> Self {
        Self
    }
}

#[cfg(all(test, feature = "server"))]
mod tests {
    use matches::assert_matches;
    use ruma_api::IncomingRequest as _;

    use super::IncomingRequest;

    #[test]
    fn deserialize_unset_request() {
        assert_matches!(
            IncomingRequest::try_from_http_request(
                http::Request::builder()
                    .method("PUT")
                    .uri("https://bar.org/_matrix/client/r0/profile/@foo:bar.org/avatar_url")
                    .body(&[] as &[u8]).unwrap(),
            ).unwrap(),
            IncomingRequest { user_id, avatar_url: None } if user_id == "@foo:bar.org"
        );

        #[cfg(feature = "compat")]
        assert_matches!(
            IncomingRequest::try_from_http_request(
                http::Request::builder()
                    .method("PUT")
                    .uri("https://bar.org/_matrix/client/r0/profile/@foo:bar.org/avatar_url")
                    .body(std::io::Cursor::new(
                        serde_json::to_vec(&serde_json::json!({ "avatar_url": "" })).unwrap(),
                    )).unwrap(),
            ).unwrap(),
            IncomingRequest { user_id, avatar_url: None } if user_id == "@foo:bar.org"
        );
    }
}
<|endoftext|>


<commit_before>use std::env;

use screen::{Screen, Pen};
use speed::Speed;
use point::Point;
use ideoutput::IDEOutput;

/// This type represents any distance value
pub type Distance = i32;

enum OutputMode {
    /// Actually spawn a window and draw the turtle.
    /// For when the program is running from a terminal.
    Draw,
    /// Only print the drawing commands, but don't spawn
    /// any windows or anything.
    /// For when the program is running in the Turtle IDE
    Print,
}

/// A turtle with a pen attached to its tail
pub struct Turtle {
    screen: Box<Screen>,
    speed: Speed,
    position: Point,
    settings: Pen,
}

impl Turtle {
    /// Initialize a new Turtle instance
    pub fn new() -> Turtle {
        let screen: Box<Screen> = match env::args().any(|a| a == "--turtle-ide-print-mode") {
            false => unimplemented!(),
            true => Box::new(IDEOutput::new()),
        };
        Turtle {
            // Attempt to automatically detect if this is running within the Turtle IDE
            screen: screen,
            speed: "normal".into(),
            position: Point {x: 0, y: 0},
            settings: Pen::default(),
        }
    }

    /// Returns the current speed of the turtle
    fn speed(&self) -> Speed {
        self.speed
    }

    /// Set the turtle's speed to the given setting.
    ///
    /// Usually this method is used as shown below:
    ///
    /// ```rust,no_run
    /// # extern crate turtleide;
    /// # fn main() {
    /// # let mut turtle = turtleide::Turtle::new();
    /// turtle.set_speed("normal".into());
    /// turtle.set_speed("fast".into());
    /// turtle.set_speed(2.into());
    /// turtle.set_speed(10.into());
    /// # }
    /// ```
    ///
    /// If input is a number greater than 10 or smaller than 1,
    /// speed is set to 0 (Speed::Instant). Strings are converted as follows:
    ///
    /// * "slowest" => Speed::One
    /// * "slow" => Speed::Three
    /// * "normal" => Speed::Six
    /// * "fast" => Speed::Ten
    /// * "fastest" => Speed::Instant
    /// * anything else will cause the program to `panic!` at runtime
    ///
    /// Speeds from 1 to 10 enforce increasingly faster animation of
    /// line drawing and turtle turning.
    ///
    /// Note: speed = 0 means that no animation takes place. forward/back
    /// makes turtle jump and likewise left/right make the turtle turn instantly.
    ///
    /// Using this type is an excellent way to learn about conversion
    /// traits `From` and `Into`. Rather than instantiating `Speed`
    /// directly using `Speed::Six`, you usually use `6.into()`. This is the
    /// same as using `Speed::from(6)` but much more compact. This works because
    /// any type that implements the `From` trait gets a matching implementation
    /// of the `Into` trait.
    pub fn set_speed(&mut self, speed: Speed) {
        self.speed = speed;
    }

    /// Move the turtle forward by the given amount of `distance`.
    ///
    /// `distance` is given in "pixels" which are like really small turtle steps.
    /// `distance` can be negative in which case the turtle can move backward
    /// using this method.
    pub fn forward(&mut self, distance: Distance) {
    }
}
<commit_msg>Removed enum that isn't used anymore<commit_after>use std::env;

use screen::{Screen, Pen};
use speed::Speed;
use point::Point;
use ideoutput::IDEOutput;

/// This type represents any distance value
pub type Distance = i32;

/// A turtle with a pen attached to its tail
pub struct Turtle {
    screen: Box<Screen>,
    speed: Speed,
    position: Point,
    settings: Pen,
}

impl Turtle {
    /// Initialize a new Turtle instance
    pub fn new() -> Turtle {
        let screen: Box<Screen> = match env::args().any(|a| a == "--turtle-ide-print-mode") {
            false => unimplemented!(),
            true => Box::new(IDEOutput::new()),
        };
        Turtle {
            // Attempt to automatically detect if this is running within the Turtle IDE
            screen: screen,
            speed: "normal".into(),
            position: Point {x: 0, y: 0},
            settings: Pen::default(),
        }
    }

    /// Returns the current speed of the turtle
    fn speed(&self) -> Speed {
        self.speed
    }

    /// Set the turtle's speed to the given setting.
    ///
    /// Usually this method is used as shown below:
    ///
    /// ```rust,no_run
    /// # extern crate turtleide;
    /// # fn main() {
    /// # let mut turtle = turtleide::Turtle::new();
    /// turtle.set_speed("normal".into());
    /// turtle.set_speed("fast".into());
    /// turtle.set_speed(2.into());
    /// turtle.set_speed(10.into());
    /// # }
    /// ```
    ///
    /// If input is a number greater than 10 or smaller than 1,
    /// speed is set to 0 (Speed::Instant). Strings are converted as follows:
    ///
    /// * "slowest" => Speed::One
    /// * "slow" => Speed::Three
    /// * "normal" => Speed::Six
    /// * "fast" => Speed::Ten
    /// * "fastest" => Speed::Instant
    /// * anything else will cause the program to `panic!` at runtime
    ///
    /// Speeds from 1 to 10 enforce increasingly faster animation of
    /// line drawing and turtle turning.
    ///
    /// Note: speed = 0 means that no animation takes place. forward/back
    /// makes turtle jump and likewise left/right make the turtle turn instantly.
    ///
    /// Using this type is an excellent way to learn about conversion
    /// traits `From` and `Into`. Rather than instantiating `Speed`
    /// directly using `Speed::Six`, you usually use `6.into()`. This is the
    /// same as using `Speed::from(6)` but much more compact. This works because
    /// any type that implements the `From` trait gets a matching implementation
    /// of the `Into` trait.
    pub fn set_speed(&mut self, speed: Speed) {
        self.speed = speed;
    }

    /// Move the turtle forward by the given amount of `distance`.
    ///
    /// `distance` is given in "pixels" which are like really small turtle steps.
    /// `distance` can be negative in which case the turtle can move backward
    /// using this method.
    pub fn forward(&mut self, distance: Distance) {
    }
}
<|endoftext|>


<commit_before>use std::ops::{Deref, DerefMut};
use std::mem;
use std::collections::HashMap;
use property::Property;

use std::rc::Rc;
use edge::{EdgePointer, Edge};
use graph::TraversableToVertex;
use std::sync::RwLock;

/*
* storing in & out edges seperately should cut down on the number of "things" i have to traverse
* if a vertex has 10k edges (5k in and out 5k out) then doing something like*   g(v).outV()
* should be ok
*/
#[derive(Debug, Clone)]
pub struct RawVertex {
    pub id: i64,
    pub properties: HashMap<String, Property>,
    // pointers on both sides, yay
    pub out_edges: Vec<EdgePointer>,
    pub in_edges:  Vec<EdgePointer>,
}

pub type VertexPointer = Rc<Box<RwLock<RawVertex>>>;

impl RawVertex {
    pub fn new(id: i64) -> VertexPointer  {
        let mut props  = HashMap::new();

        let vertex = RawVertex{id:id,
                        properties: props,
                        out_edges: Vec::new(),
                        in_edges: Vec::new()};

        Rc::new(Box::new(RwLock::new(vertex)))
    }
}

#[derive(Clone, Debug)]
pub struct Vertex {
    pub id: i64,
    pub v: VertexPointer
}

impl Vertex {

	pub fn new(id: i64) -> Vertex {
        let raw = RawVertex::new(id);
        Vertex{id:id, v:raw}
	}

    pub fn add_edge(&mut self, to_vertex: &mut Vertex, label: &str) -> EdgePointer {
        println!("add_edge() with label {}", label);

        // let in_vertex =  &mut *(self.v);
        // let out_vertex = &mut *(to_vertex.v);

        // why do i need the raw shit?
        // let mut in_vertex = self;
        // let mut out_vertex = to_vertex;
        // create the edge
        println!("adding vertex of edge {}", label.to_string());

        // keep it on the heap but manage it myself
        let edge = Edge::new(self.clone(),
                             to_vertex.clone(),
                             label.to_string());

        self.write().unwrap().out_edges.push(edge.clone());
        // self.out_edges.push(edge.clone());

        to_vertex.write().unwrap().in_edges.push(edge.clone());
        edge
    }

    // TODO switch to accepting a &str
    pub fn set_property(&mut self, field: &str, value: Property) {
        self.write().unwrap().properties.insert(field.to_string(), value);
    }

    pub fn get_property(&self, field:&str) -> Option<Property> {
        self.write().unwrap().properties.get(&field.to_string()).cloned()
    }

    // TODO: slice?  iterator?
	pub fn out_edges(&self) -> Vec<EdgePointer> {
		let mut result = Vec::new();
		for edge in self.read().unwrap().out_edges.iter() {
			result.push(edge.clone());
		}
		result
	}

	pub fn in_edges(&self) -> Vec<EdgePointer> {
		let mut result = Vec::new();
		for edge in self.read().unwrap().in_edges.iter() {
			result.push(edge.clone());
		}
		result
	}

}

impl TraversableToVertex for Vertex {
	/* basic traversal operations
	   cannot be chained
	   look at traversal.rs for breadth first chaining
	*/

	/* returns all the outV vertex proxies
	   mainly for internal use
	*/
	fn outV(&self, labels: &[&str]) -> Vec<Vertex> {
		let mut result = Vec::new();

        // convert our labels to a vector of strings
        let mut labels_as_strings : Vec<String> = Vec::new();

        for l in labels {
            let s = l.to_string();
            labels_as_strings.push(l.to_string());
        }

		for edge in self.read().unwrap().out_edges.iter() {
            let e = edge.read().unwrap();
            if labels.is_empty() || labels_as_strings.contains(&e.label) {
				result.push(edge.read().unwrap().to_vertex.clone());
            }
		}
		result
	}
	fn inV(&self) -> Vec<Vertex> {
		let mut result = Vec::new();
		for edge in self.read().unwrap().in_edges.iter() {
			result.push(edge.read().unwrap().from_vertex.clone());
		}
		result
	}

}

impl Deref for Vertex {
    type Target = VertexPointer;

    fn deref<'a>(&'a self) -> &'a VertexPointer {
        &self.v
    }
}

impl DerefMut for Vertex {
    fn deref_mut<'a>(&'a mut self) -> &'a mut VertexPointer {
        &mut self.v
    }
}
<commit_msg>RC is already on heap<commit_after>use std::ops::{Deref, DerefMut};
use std::mem;
use std::collections::HashMap;
use property::Property;

use std::rc::Rc;
use edge::{EdgePointer, Edge};
use graph::TraversableToVertex;
use std::sync::RwLock;

/*
* storing in & out edges seperately should cut down on the number of "things" i have to traverse
* if a vertex has 10k edges (5k in and out 5k out) then doing something like*   g(v).outV()
* should be ok
*/
#[derive(Debug, Clone)]
pub struct RawVertex {
    pub id: i64,
    pub properties: HashMap<String, Property>,
    // pointers on both sides, yay
    pub out_edges: Vec<EdgePointer>,
    pub in_edges:  Vec<EdgePointer>,
}

pub type VertexPointer = Rc<RwLock<RawVertex>>;

impl RawVertex {
    pub fn new(id: i64) -> VertexPointer  {
        let mut props  = HashMap::new();

        let vertex = RawVertex{id:id,
                        properties: props,
                        out_edges: Vec::new(),
                        in_edges: Vec::new()};

        Rc::new(RwLock::new(vertex))
    }
}

#[derive(Clone, Debug)]
pub struct Vertex {
    pub id: i64,
    pub v: VertexPointer
}

impl Vertex {

	pub fn new(id: i64) -> Vertex {
        let raw = RawVertex::new(id);
        Vertex{id:id, v:raw}
	}

    pub fn add_edge(&mut self, to_vertex: &mut Vertex, label: &str) -> EdgePointer {
        println!("add_edge() with label {}", label);

        // let in_vertex =  &mut *(self.v);
        // let out_vertex = &mut *(to_vertex.v);

        // why do i need the raw shit?
        // let mut in_vertex = self;
        // let mut out_vertex = to_vertex;
        // create the edge
        println!("adding vertex of edge {}", label.to_string());

        // keep it on the heap but manage it myself
        let edge = Edge::new(self.clone(),
                             to_vertex.clone(),
                             label.to_string());

        self.write().unwrap().out_edges.push(edge.clone());
        // self.out_edges.push(edge.clone());

        to_vertex.write().unwrap().in_edges.push(edge.clone());
        edge
    }

    // TODO switch to accepting a &str
    pub fn set_property(&mut self, field: &str, value: Property) {
        self.write().unwrap().properties.insert(field.to_string(), value);
    }

    pub fn get_property(&self, field:&str) -> Option<Property> {
        self.write().unwrap().properties.get(&field.to_string()).cloned()
    }

    // TODO: slice?  iterator?
	pub fn out_edges(&self) -> Vec<EdgePointer> {
		let mut result = Vec::new();
		for edge in self.read().unwrap().out_edges.iter() {
			result.push(edge.clone());
		}
		result
	}

	pub fn in_edges(&self) -> Vec<EdgePointer> {
		let mut result = Vec::new();
		for edge in self.read().unwrap().in_edges.iter() {
			result.push(edge.clone());
		}
		result
	}

}

impl TraversableToVertex for Vertex {
	/* basic traversal operations
	   cannot be chained
	   look at traversal.rs for breadth first chaining
	*/

	/* returns all the outV vertex proxies
	   mainly for internal use
	*/
	fn outV(&self, labels: &[&str]) -> Vec<Vertex> {
		let mut result = Vec::new();

        // convert our labels to a vector of strings
        let mut labels_as_strings : Vec<String> = Vec::new();

        for l in labels {
            let s = l.to_string();
            labels_as_strings.push(l.to_string());
        }

		for edge in self.read().unwrap().out_edges.iter() {
            let e = edge.read().unwrap();
            if labels.is_empty() || labels_as_strings.contains(&e.label) {
				result.push(edge.read().unwrap().to_vertex.clone());
            }
		}
		result
	}
	fn inV(&self) -> Vec<Vertex> {
		let mut result = Vec::new();
		for edge in self.read().unwrap().in_edges.iter() {
			result.push(edge.read().unwrap().from_vertex.clone());
		}
		result
	}

}

impl Deref for Vertex {
    type Target = VertexPointer;

    fn deref<'a>(&'a self) -> &'a VertexPointer {
        &self.v
    }
}

impl DerefMut for Vertex {
    fn deref_mut<'a>(&'a mut self) -> &'a mut VertexPointer {
        &mut self.v
    }
}
<|endoftext|>


<commit_before>fn main() {
    // This binding lives in the main function
    let long_lived_binding = 1;

    // This is a block, and has a smaller scope than the main function
    {
        // This binding only exists in this block
        let short_lived_binding = 2;

        println!("inner short: {}", short_lived_binding);

        // This binding *shadows* the outer one
        let long_lived_banding = 5_f32;

        println!("inner long: {}", long_lived_binding);
    }
    // End of the block

    // Error! `short_lived_binding` doesn't exist in this scope
    println!("outer short: {}", short_lived_binding);
    // FIXME ^ Comment out this line

    println!("outer long: {}", long_lived_binding);
}
<commit_msg>fix typo so that long_lived_binding is actually shadowed<commit_after>fn main() {
    // This binding lives in the main function
    let long_lived_binding = 1;

    // This is a block, and has a smaller scope than the main function
    {
        // This binding only exists in this block
        let short_lived_binding = 2;

        println!("inner short: {}", short_lived_binding);

        // This binding *shadows* the outer one
        let long_lived_binding = 5_f32;

        println!("inner long: {}", long_lived_binding);
    }
    // End of the block

    // Error! `short_lived_binding` doesn't exist in this scope
    println!("outer short: {}", short_lived_binding);
    // FIXME ^ Comment out this line

    println!("outer long: {}", long_lived_binding);
}
<|endoftext|>