<commit_before>// Copyright 2016 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::collections::HashMap;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_LOG_DIR: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory_path<P: AsRef<Path>>(directory: P) -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(directory);
            Ok(log_dir)
        }
        None => Err(io::Error::new(
            io::ErrorKind::NotFound,
            "No standard logging directory known for this platform",
        )),
    }
}

fn setup_logging(logging_path_result: Result<PathBuf, io::Error>) -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
                record.target(),
                record.level(),
                message,
            ))
        }).level(level_filter)
        .chain(io::stderr());

    if let Ok(logging_file_path) = &logging_path_result {
        // Ensure the logging directory is created
        let parent_path = logging_file_path.parent().ok_or(io::Error::new(
            io::ErrorKind::InvalidInput,
            format!(
                "Unable to get the parent of the following Path: {}",
                logging_file_path.display(),
            ),
        ))?;
        fs::create_dir_all(parent_path)?;
        // Attach it to fern
        fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?);
    };

    // Start fern
    fern_dispatch.apply()?;
    info!("Logging with fern is setup");

    // Log details of the logging_file_path result using fern/log
    // Either logging the path fern is outputting to or the error from obtaining the path
    match &logging_path_result {
        Err(e) => {
            let message = "There was an issue getting the path for the log file";
            warn!("{}: {:?}, falling back to stderr.", message, e);
        }
        Ok(logging_file_path) => {
            info!(
                "Logging to the following file: {}",
                logging_file_path.display()
            );
        }
    }
    Ok(())
}

fn prepare_logging_path(logfile_config: LogfileConfig) -> Result<PathBuf, io::Error> {
    // Use the file name set in logfile_config or fallback to the default
    let logfile_file_name = match logfile_config.file {
        Some(file_name) => file_name,
        None => XI_LOG_FILE.to_string(),
    };
    // Use the directory name set in logfile_config or fallback to the default
    let logfile_directory_name = match logfile_config.directory {
        Some(dir) => dir,
        None => XI_LOG_DIR.to_string(),
    };

    let mut logging_directory_path = get_logging_directory_path(logfile_directory_name)?;

    // Add the file name & return the full path
    logging_directory_path.push(logfile_file_name);
    Ok(logging_directory_path)
}

struct LogfileConfig {
    directory: Option<String>,
    file: Option<String>,
}

fn get_flags() -> HashMap<String, Option<String>> {
    let mut flags: HashMap<String, Option<String>> = HashMap::new();

    let flag_prefix = "-";
    let mut args_itterator = std::env::args().peekable();
    while let Some(arg) = args_itterator.next() {
        if arg.starts_with(flag_prefix) {
            let key = arg.trim_left_matches(flag_prefix).to_string();

            // Check the next argument doesn't start with the flag prefix
            // map_or accounts for peek returning an Option
            let next_arg_not_a_flag: bool = args_itterator
                .peek()
                .map_or(false, |val| !val.starts_with(flag_prefix));
            if next_arg_not_a_flag {
                flags.insert(key, args_itterator.next());
            }
        }
    }
    flags
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    let flags: HashMap<String, Option<String>> = get_flags();

    // If the key is set, get the Option within
    let log_dir_flag_option = flags.get("log-dir").cloned().unwrap_or(None);
    let log_file_flag_option = flags.get("log-file").cloned().unwrap_or(None);

    let logfile_config = LogfileConfig {
        directory: log_dir_flag_option,
        file: log_file_flag_option,
    };

    let logging_path: Result<PathBuf, io::Error> = prepare_logging_path(logfile_config);
    if let Err(e) = setup_logging(logging_path) {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<commit_msg>Swapped the order of the fern logging success/error match.<commit_after>// Copyright 2016 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::collections::HashMap;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_LOG_DIR: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory_path<P: AsRef<Path>>(directory: P) -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(directory);
            Ok(log_dir)
        }
        None => Err(io::Error::new(
            io::ErrorKind::NotFound,
            "No standard logging directory known for this platform",
        )),
    }
}

fn setup_logging(logging_path_result: Result<PathBuf, io::Error>) -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
                record.target(),
                record.level(),
                message,
            ))
        }).level(level_filter)
        .chain(io::stderr());

    if let Ok(logging_file_path) = &logging_path_result {
        // Ensure the logging directory is created
        let parent_path = logging_file_path.parent().ok_or(io::Error::new(
            io::ErrorKind::InvalidInput,
            format!(
                "Unable to get the parent of the following Path: {}",
                logging_file_path.display(),
            ),
        ))?;
        fs::create_dir_all(parent_path)?;
        // Attach it to fern
        fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?);
    };

    // Start fern
    fern_dispatch.apply()?;
    info!("Logging with fern is setup");

    // Log details of the logging_file_path result using fern/log
    // Either logging the path fern is outputting to or the error from obtaining the path
    match &logging_path_result {
        Ok(logging_file_path) => {
            info!(
                "Logging to the following file: {}",
                logging_file_path.display()
            );
        }
        Err(e) => {
            let message = "There was an issue getting the path for the log file";
            warn!("{}: {:?}, falling back to stderr.", message, e);
        }
    }
    Ok(())
}

fn prepare_logging_path(logfile_config: LogfileConfig) -> Result<PathBuf, io::Error> {
    // Use the file name set in logfile_config or fallback to the default
    let logfile_file_name = match logfile_config.file {
        Some(file_name) => file_name,
        None => XI_LOG_FILE.to_string(),
    };
    // Use the directory name set in logfile_config or fallback to the default
    let logfile_directory_name = match logfile_config.directory {
        Some(dir) => dir,
        None => XI_LOG_DIR.to_string(),
    };

    let mut logging_directory_path = get_logging_directory_path(logfile_directory_name)?;

    // Add the file name & return the full path
    logging_directory_path.push(logfile_file_name);
    Ok(logging_directory_path)
}

struct LogfileConfig {
    directory: Option<String>,
    file: Option<String>,
}

fn get_flags() -> HashMap<String, Option<String>> {
    let mut flags: HashMap<String, Option<String>> = HashMap::new();

    let flag_prefix = "-";
    let mut args_itterator = std::env::args().peekable();
    while let Some(arg) = args_itterator.next() {
        if arg.starts_with(flag_prefix) {
            let key = arg.trim_left_matches(flag_prefix).to_string();

            // Check the next argument doesn't start with the flag prefix
            // map_or accounts for peek returning an Option
            let next_arg_not_a_flag: bool = args_itterator
                .peek()
                .map_or(false, |val| !val.starts_with(flag_prefix));
            if next_arg_not_a_flag {
                flags.insert(key, args_itterator.next());
            }
        }
    }
    flags
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    let flags: HashMap<String, Option<String>> = get_flags();

    // If the key is set, get the Option within
    let log_dir_flag_option = flags.get("log-dir").cloned().unwrap_or(None);
    let log_file_flag_option = flags.get("log-file").cloned().unwrap_or(None);

    let logfile_config = LogfileConfig {
        directory: log_dir_flag_option,
        file: log_file_flag_option,
    };

    let logging_path: Result<PathBuf, io::Error> = prepare_logging_path(logfile_config);
    if let Err(e) = setup_logging(logging_path) {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<|endoftext|>


<commit_before>use num::Num;
use create::{clone, create};

#[inline(always)]
pub fn rotation_x<'a, 'b, T: Num>(out: &'b [T; 4]) -> T {
    (T::from_isize(2isize) * out[0] * out[3] + T::from_isize(2isize) * out[1] * out[2])
        .atan2(T::one() - T::from_isize(2isize) * (out[2] * out[2] + out[3] * out[3]))
}

#[inline(always)]
pub fn rotation_y<'a, 'b, T: Num>(out: &'b [T; 4]) -> T {
    let theta = T::from_isize(2isize) * (out[0] * out[2] + out[3] * out[1]);
    (if theta < -T::one() {-T::one()} else if theta > T::one() {T::one()} else {theta}).asin()
}

#[inline(always)]
pub fn rotation_z<'a, 'b, T: Num>(out: &'b [T; 4]) -> T {
    (T::from_isize(2isize) * out[0] * out[1] + T::from_isize(2isize) * out[2] * out[3])
        .atan2(T::one() - T::from_isize(2isize) * (out[1] * out[1] + out[2] * out[2]))
}

#[inline(always)]
pub fn rotate_x<'a, 'b, T: Num>(out: &'a mut [T; 4], a: &'b [T; 4], angle: T) -> &'a mut [T; 4] {
    let ax = a[0];
    let ay = a[1];
    let az = a[2];
    let aw = a[3];
    let half_angle = angle / T::from_isize(2isize);
    let bx = half_angle.sin();
    let bw = half_angle.cos();

    out[0] = ax * bw + aw * bx;
    out[1] = ay * bw + az * bx;
    out[2] = az * bw - ay * bx;
    out[3] = aw * bw - ax * bx;
    out
}

#[inline(always)]
pub fn rotate_y<'a, 'b, T: Num>(out: &'a mut [T; 4], a: &'b [T; 4], angle: T) -> &'a mut [T; 4] {
    let ax = a[0];
    let ay = a[1];
    let az = a[2];
    let aw = a[3];
    let half_angle = angle / T::from_isize(2isize);
    let by = half_angle.sin();
    let bw = half_angle.cos();

    out[0] = ax * bw - az * by;
    out[1] = ay * bw + aw * by;
    out[2] = az * bw + ax * by;
    out[3] = aw * bw - ay * by;
    out
}

#[inline(always)]
pub fn rotate_z<'a, 'b, T: Num>(out: &'a mut [T; 4], a: &'b [T; 4], angle: T) -> &'a mut [T; 4] {
    let ax = a[0];
    let ay = a[1];
    let az = a[2];
    let aw = a[3];
    let half_angle = angle / T::from_isize(2isize);
    let bz = half_angle.sin();
    let bw = half_angle.cos();

    out[0] = ax * bw + ay * bz;
    out[1] = ay * bw - ax * bz;
    out[2] = az * bw + aw * bz;
    out[3] = aw * bw - az * bz;
    out
}

#[inline(always)]
pub fn rotate<'a, 'b, T: Num>(out: &'a mut [T; 4], a: &'b [T; 4], x: T, y: T, z: T) -> &'a mut [T; 4] {
    let mut tmp_a = clone(a);
    let mut tmp_b = create(T::zero(), T::zero(), T::zero(), T::one());
    rotate_z(&mut tmp_a, &a, z);
    rotate_x(&mut tmp_b, &tmp_a, x);
    rotate_y(out, &tmp_b, y);
    out
}

#[inline(always)]
pub fn look_rotation<'a, 'b, T: Num>(out: &'a mut [T; 4], forward: [T; 3], up: [T; 3]) -> &'a mut [T; 4] {
    let fx = forward[0];
    let fy = forward[1];
    let fz = forward[2];
    let ux = up[0];
    let uy = up[1];
    let uz = up[2];

    let ax = uy * fz - uz * fy;
    let ay = uz * fx - ux * fz;
    let az = ux * fy - uy * fx;

    let d = (T::one() + ux * fx + uy * fy + uz * fz) * T::from_isize(2isize);
    let dsq = d * d;
    let s = if dsq != T::zero() {T::one() / dsq} else {dsq};

    out[0] = ax * s;
    out[1] = ay * s;
    out[2] = az * s;
    out[3] = dsq / T::from_isize(2isize);
    out
}

#[inline(always)]
pub fn from_axis_angle<'a, 'b, T: Num>(out: &'a mut [T; 4], axis: [T; 3], angle: T) -> &'a mut [T; 4] {
    let half_angle = angle / T::from_isize(2isize);
    let s = half_angle.sin();

    out[0] = axis[0] * s;
    out[1] = axis[1] * s;
    out[2] = axis[2] * s;
    out[3] = half_angle.cos();
    out
}

#[inline(always)]
pub fn from_mat<'a, 'b, T: Num>(
    out: &'a mut [T; 4],
    m11: T, m12: T, m13: T,
    m21: T, m22: T, m23: T,
    m31: T, m32: T, m33: T
) -> &'a mut [T; 4] {
    let trace = m11 + m22 + m33;

    if trace > T::zero() {
        let s = T::from_f32(0.5f32) / (trace + T::one()).sqrt();

        out[3] = T::from_f32(0.25f32) / s;
        out[0] = (m32 - m23) * s;
        out[1] = (m13 - m31) * s;
        out[2] = (m21 - m12) * s;
    } else if m11 > m22 && m11 > m33 {
        let s = T::from_isize(2isize) * (T::one() + m11 - m22 - m33).sqrt();
        let inv_s = T::one() / s;

        out[3] = (m32 - m23) * inv_s;
        out[0] = s / T::from_isize(4isize);
        out[1] = (m12 + m21) * inv_s;
        out[2] = (m13 + m31) * inv_s;
    } else if m22 > m33 {
        let s = T::from_isize(2isize) * (T::one() + m22 - m11 - m33).sqrt();
        let inv_s = T::one() / s;

        out[3] = (m13 - m31) * inv_s;
        out[0] = (m12 + m21) * inv_s;
        out[1] = s / T::from_isize(4isize);
        out[2] = (m23 + m32) * inv_s;
    } else {
        let s = T::from_isize(2isize) * (T::one() + m33 - m11 - m22).sqrt();
        let inv_s = T::one() / s;

        out[3] = (m21 - m12) * inv_s;
        out[0] = (m13 + m31) * inv_s;
        out[1] = (m23 + m32) * inv_s;
        out[2] = s / T::from_isize(4isize);
    }
    out
}

#[inline(always)]
pub fn from_mat2<'a, 'b, T: Num>(out: &'a mut [T; 4], m: &'b [T; 4]) -> &'a mut [T; 4] {
    from_mat(
        out,
        m[0], m[2], T::zero(),
        m[1], m[3], T::zero(),
        T::zero(), T::zero(), T::one()
    )
}

#[inline(always)]
pub fn from_mat32<'a, 'b, T: Num>(out: &'a mut [T; 4], m: [T; 6]) -> &'a mut [T; 4] {
    from_mat(
        out,
        m[0], m[2], T::zero(),
        m[1], m[3], T::zero(),
        T::zero(), T::zero(), T::one()
    )
}

#[inline(always)]
pub fn from_mat3<'a, 'b, T: Num>(out: &'a mut [T; 4], m: [T; 9]) -> &'a mut [T; 4] {
    from_mat(
        out,
        m[0], m[3], m[6],
        m[1], m[4], m[7],
        m[2], m[5], m[8]
    )
}

#[inline(always)]
pub fn from_mat4<'a, 'b, T: Num>(out: &'a mut [T; 4], m: [T; 16]) -> &'a mut [T; 4] {
    from_mat(
        out,
        m[0], m[4], m[8],
        m[1], m[5], m[9],
        m[2], m[6], m[10]
    )
}
<commit_msg>updates<commit_after>use num::Num;
use create::{clone, create};

#[inline(always)]
pub fn rotation_x<'a, 'b, T: Num>(out: &'b [T; 4]) -> T {
    (T::from_isize(2isize) * out[0] * out[3] + T::from_isize(2isize) * out[1] * out[2])
        .atan2(T::one() - T::from_isize(2isize) * (out[2] * out[2] + out[3] * out[3]))
}

#[inline(always)]
pub fn rotation_y<'a, 'b, T: Num>(out: &'b [T; 4]) -> T {
    let theta = T::from_isize(2isize) * (out[0] * out[2] + out[3] * out[1]);
    (if theta < -T::one() {-T::one()} else if theta > T::one() {T::one()} else {theta}).asin()
}

#[inline(always)]
pub fn rotation_z<'a, 'b, T: Num>(out: &'b [T; 4]) -> T {
    (T::from_isize(2isize) * out[0] * out[1] + T::from_isize(2isize) * out[2] * out[3])
        .atan2(T::one() - T::from_isize(2isize) * (out[1] * out[1] + out[2] * out[2]))
}

#[inline(always)]
pub fn rotate_x<'a, 'b, T: Num>(out: &'a mut [T; 4], a: &'b [T; 4], angle: T) -> &'a mut [T; 4] {
    let ax = a[0];
    let ay = a[1];
    let az = a[2];
    let aw = a[3];
    let half_angle = angle / T::from_isize(2isize);
    let bx = half_angle.sin();
    let bw = half_angle.cos();

    out[0] = ax * bw + aw * bx;
    out[1] = ay * bw + az * bx;
    out[2] = az * bw - ay * bx;
    out[3] = aw * bw - ax * bx;
    out
}

#[inline(always)]
pub fn rotate_y<'a, 'b, T: Num>(out: &'a mut [T; 4], a: &'b [T; 4], angle: T) -> &'a mut [T; 4] {
    let ax = a[0];
    let ay = a[1];
    let az = a[2];
    let aw = a[3];
    let half_angle = angle / T::from_isize(2isize);
    let by = half_angle.sin();
    let bw = half_angle.cos();

    out[0] = ax * bw - az * by;
    out[1] = ay * bw + aw * by;
    out[2] = az * bw + ax * by;
    out[3] = aw * bw - ay * by;
    out
}

#[inline(always)]
pub fn rotate_z<'a, 'b, T: Num>(out: &'a mut [T; 4], a: &'b [T; 4], angle: T) -> &'a mut [T; 4] {
    let ax = a[0];
    let ay = a[1];
    let az = a[2];
    let aw = a[3];
    let half_angle = angle / T::from_isize(2isize);
    let bz = half_angle.sin();
    let bw = half_angle.cos();

    out[0] = ax * bw + ay * bz;
    out[1] = ay * bw - ax * bz;
    out[2] = az * bw + aw * bz;
    out[3] = aw * bw - az * bz;
    out
}

#[inline(always)]
pub fn rotate<'a, 'b, T: Num>(out: &'a mut [T; 4], a: &'b [T; 4], x: T, y: T, z: T) -> &'a mut [T; 4] {
    let mut tmp_a = clone(a);
    let mut tmp_b = create(T::zero(), T::zero(), T::zero(), T::one());
    rotate_z(&mut tmp_a, &a, z);
    rotate_x(&mut tmp_b, &tmp_a, x);
    rotate_y(out, &tmp_b, y);
    out
}

#[inline(always)]
pub fn look_rotation<'a, 'b, T: Num>(out: &'a mut [T; 4], forward: &'b [T; 3], up: &'b [T; 3]) -> &'a mut [T; 4] {
    let fx = forward[0];
    let fy = forward[1];
    let fz = forward[2];
    let ux = up[0];
    let uy = up[1];
    let uz = up[2];

    let ax = uy * fz - uz * fy;
    let ay = uz * fx - ux * fz;
    let az = ux * fy - uy * fx;

    let d = (T::one() + ux * fx + uy * fy + uz * fz) * T::from_isize(2isize);
    let dsq = d * d;
    let s = if dsq != T::zero() {T::one() / dsq} else {dsq};

    out[0] = ax * s;
    out[1] = ay * s;
    out[2] = az * s;
    out[3] = dsq / T::from_isize(2isize);
    out
}

#[inline(always)]
pub fn from_axis_angle<'a, 'b, T: Num>(out: &'a mut [T; 4], axis: &'b [T; 3], angle: T) -> &'a mut [T; 4] {
    let half_angle = angle / T::from_isize(2isize);
    let s = half_angle.sin();

    out[0] = axis[0] * s;
    out[1] = axis[1] * s;
    out[2] = axis[2] * s;
    out[3] = half_angle.cos();
    out
}

#[inline(always)]
pub fn from_mat<'a, 'b, T: Num>(
    out: &'a mut [T; 4],
    m11: T, m12: T, m13: T,
    m21: T, m22: T, m23: T,
    m31: T, m32: T, m33: T
) -> &'a mut [T; 4] {
    let trace = m11 + m22 + m33;

    if trace > T::zero() {
        let s = T::from_f32(0.5f32) / (trace + T::one()).sqrt();

        out[3] = T::from_f32(0.25f32) / s;
        out[0] = (m32 - m23) * s;
        out[1] = (m13 - m31) * s;
        out[2] = (m21 - m12) * s;
    } else if m11 > m22 && m11 > m33 {
        let s = T::from_isize(2isize) * (T::one() + m11 - m22 - m33).sqrt();
        let inv_s = T::one() / s;

        out[3] = (m32 - m23) * inv_s;
        out[0] = s / T::from_isize(4isize);
        out[1] = (m12 + m21) * inv_s;
        out[2] = (m13 + m31) * inv_s;
    } else if m22 > m33 {
        let s = T::from_isize(2isize) * (T::one() + m22 - m11 - m33).sqrt();
        let inv_s = T::one() / s;

        out[3] = (m13 - m31) * inv_s;
        out[0] = (m12 + m21) * inv_s;
        out[1] = s / T::from_isize(4isize);
        out[2] = (m23 + m32) * inv_s;
    } else {
        let s = T::from_isize(2isize) * (T::one() + m33 - m11 - m22).sqrt();
        let inv_s = T::one() / s;

        out[3] = (m21 - m12) * inv_s;
        out[0] = (m13 + m31) * inv_s;
        out[1] = (m23 + m32) * inv_s;
        out[2] = s / T::from_isize(4isize);
    }
    out
}

#[inline(always)]
pub fn from_mat2<'a, 'b, T: Num>(out: &'a mut [T; 4], m: &'b [T; 4]) -> &'a mut [T; 4] {
    from_mat(
        out,
        m[0], m[2], T::zero(),
        m[1], m[3], T::zero(),
        T::zero(), T::zero(), T::one()
    )
}

#[inline(always)]
pub fn from_mat32<'a, 'b, T: Num>(out: &'a mut [T; 4], m: &'b [T; 6]) -> &'a mut [T; 4] {
    from_mat(
        out,
        m[0], m[2], T::zero(),
        m[1], m[3], T::zero(),
        T::zero(), T::zero(), T::one()
    )
}

#[inline(always)]
pub fn from_mat3<'a, 'b, T: Num>(out: &'a mut [T; 4], m: &'b [T; 9]) -> &'a mut [T; 4] {
    from_mat(
        out,
        m[0], m[3], m[6],
        m[1], m[4], m[7],
        m[2], m[5], m[8]
    )
}

#[inline(always)]
pub fn from_mat4<'a, 'b, T: Num>(out: &'a mut [T; 4], m: &'b [T; 16]) -> &'a mut [T; 4] {
    from_mat(
        out,
        m[0], m[4], m[8],
        m[1], m[5], m[9],
        m[2], m[6], m[10]
    )
}
<|endoftext|>


<commit_before>
use vertex::{RawVertex, Vertex};
use edge::{Edge, EdgeProxy};
use graph::TraversableToVertex;
use path::{Path, GraphElement};
// define a traversal as a series of stages

pub struct GraphQuery {
	// many paths
    pub paths: Vec<Path>
}

impl GraphQuery {
    pub fn new(vertices: Vec<Vertex>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let mut paths = Vec::new();
        for p in vertices {
			let mut path = Path::new(p);
            paths.push(path)
        }
        GraphQuery{paths:paths}
    }

    pub fn empty() -> GraphQuery {
        // return an empty graph query
        GraphQuery{paths:Vec::new()}
    }

	pub fn get_paths(&self) -> &Vec<Path> {
		&self.paths
	}
	pub fn push(&mut self, path:Path) {
		self.paths.push(path)
	}

	/*
	generic mapper for our queries
	future this may use worker threads to perform
	traversals
	 */
    fn full_map<F: Fn(&Path) -> Vec<Path>>(&self, closure: F) -> GraphQuery  {
        let mut result = GraphQuery::empty(); // result
		for x in self.paths.iter() {
			let mut tmp = closure(x);
			result.paths.append(&mut tmp)
		}
		result
    }

	/*
	accepts a proxy and a closure, per
	takes the last element
	 */
	fn map<F: Fn(&GraphElement) -> Vec<GraphElement>>(&self, closure: F)
		-> GraphQuery {
		let mut result = GraphQuery::empty();
		for path in self.paths.iter() {
			// apply the closure to the last element in each map
			// if nothing is returned, we should not use the path anymore
			let element = path.path.last().unwrap();
			let mut tmp = closure(element);
			let new_path = path.clone();
			result.push(new_path);
		}
		result
	}

	/*
        TODO: rewrite to use map()
	 */
    pub fn outV(&self) -> GraphQuery {
		let f = |path: &Path| {
			println!("applying outV");
			let mut result : Vec<Path> = Vec::new();
			//take the final element in the path
			let element = path.path.last().unwrap();

			match element {
				&GraphElement::RawVertex(ref v) => {
					println!("matched vertex");
					let mut tmp = v.outV();
					for vertex in tmp {
						println!("adding path based on vertex match");
						let new_path = path.clone();
						result.push(new_path);
					}
				},
				&GraphElement::Edge(ref e) => {

				}
			}
			// apply outV

			result
		};
		self.full_map(f)
    }

//	pub fn inV(&self) -> GraphQuery {
//		let g = GraphQuery::empty();
//		let f = |element: &GraphElement| {
//			element.inV()
//		};
//		self.map(f)
//	}
}
<commit_msg>fixing up map<commit_after>
use vertex::{RawVertex, Vertex};
use edge::{Edge, EdgeProxy};
use graph::TraversableToVertex;
use path::{Path, GraphElement};
// define a traversal as a series of stages

pub struct GraphQuery {
	// many paths
    pub paths: Vec<Path>
}

impl GraphQuery {
    pub fn new(vertices: Vec<Vertex>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let mut paths = Vec::new();
        for p in vertices {
			let mut path = Path::new(p);
            paths.push(path)
        }
        GraphQuery{paths:paths}
    }

    pub fn empty() -> GraphQuery {
        // return an empty graph query
        GraphQuery{paths:Vec::new()}
    }

	pub fn get_paths(&self) -> &Vec<Path> {
		&self.paths
	}
	pub fn push(&mut self, path:Path) {
		self.paths.push(path)
	}

	/*
	generic mapper for our queries
	future this may use worker threads to perform
	traversals
	 */
    fn full_map<F: Fn(&Path) -> Vec<Path>>(&self, closure: F) -> GraphQuery  {
        let mut result = GraphQuery::empty(); // result
		for x in self.paths.iter() {
			let mut tmp = closure(x);
			result.paths.append(&mut tmp)
		}
		result
    }

	/*
	accepts an Path and a closure
	applies the closure to the path
	gets an Option back: a bunch of paths or None
	if None comes back we don't include the paths in the new GraphQuery
	that is returned
	*/
	fn map<F: Fn(&Path) -> Option<Vec<Path>>>(&self, closure: F)
		-> GraphQuery {
		let mut result = GraphQuery::empty();
		for path in self.paths.iter() {
			// apply the closure to the last element in each map
			// if nothing is returned, we should not use the path anymore
			let mut tmp = closure(&path);
			let new_path = path.clone();
			result.push(new_path);
		}
		result
	}

	/*
        TODO: rewrite to use map()
	 */
    pub fn outV(&self) -> GraphQuery {
		let f = |path: &Path| {
			println!("applying outV");
			let mut result : Vec<Path> = Vec::new();
			//take the final element in the path
			let element = path.path.last().unwrap();

			match element {
				&GraphElement::RawVertex(ref v) => {
					println!("matched vertex");
					let mut tmp = v.outV();
					for vertex in tmp {
						println!("adding path based on vertex match");
						let new_path = path.clone();
						result.push(new_path);
					}
				},
				&GraphElement::Edge(ref e) => {

				}
			}
			// apply outV

			result
		};
		self.full_map(f)
    }

//	pub fn inV(&self) -> GraphQuery {
//		let g = GraphQuery::empty();
//		let f = |element: &GraphElement| {
//			element.inV()
//		};
//		self.map(f)
//	}
}
<|endoftext|>


<commit_before>// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [URL], the x-www-form-urlencoded format.
//! - [XML], the flexible machine-friendly W3C standard.
//!   *(deserialization only)*
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Redis], deserialize values from Redis when using [redis-rs].
//!   *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [XML]: https://github.com/RReverser/serde-xml-rs
//! [Envy]: https://github.com/softprops/envy
//! [Redis]: https://github.com/OneSignal/serde-redis
//! [Cargo]: http://doc.crates.io/manifest.html
//! [redis-rs]: https://crates.io/crates/redis

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.17")]

// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]

// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
#![cfg_attr(feature = "alloc", feature(alloc))]

#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(
    cast_lossless,
    doc_markdown,
    linkedlist,
    type_complexity,
    unreadable_literal,
    zero_prefixed_literal,
))]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "cargo-clippy", allow(
// integer and float ser/de requires these sorts of casts
    cast_possible_truncation,
    cast_possible_wrap,
    cast_precision_loss,
    cast_sign_loss,
// simplifies some macros
    invalid_upcast_comparisons,
// things are often more readable this way
    option_unwrap_used,
    result_unwrap_used,
    shadow_reuse,
    single_match_else,
    stutter,
    use_self,
// not practical
    missing_docs_in_private_items,
// alternative is not stable
    empty_enum,
    use_debug,
))]

// Blacklisted Rust lints.
#![deny(missing_docs, unused_imports)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

#[cfg(all(feature = "unstable", feature = "std"))]
extern crate core;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(feature = "std")]
        pub use std::*;
        #[cfg(not(feature = "std"))]
        pub use core::*;
    }

    pub use self::core::{cmp, iter, mem, ops, slice, str};
    pub use self::core::{i8, i16, i32, i64, isize};
    pub use self::core::{u8, u16, u32, u64, usize};
    pub use self::core::{f32, f64};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};

    #[cfg(feature = "std")]
    pub use std::string::String;
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};

    #[cfg(feature = "std")]
    pub use std::vec::Vec;
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;

    #[cfg(feature = "std")]
    pub use std::boxed::Box;
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;

    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::Rc;
    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::Rc;

    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::Arc;
    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::arc::Arc;

    #[cfg(feature = "std")]
    pub use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CString, CStr, OsString, OsStr};
    #[cfg(feature = "std")]
    pub use std::hash::{Hash, BuildHasher};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};

    #[cfg(feature = "unstable")]
    pub use core::nonzero::{NonZero, Zeroable};
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

pub mod ser;
pub mod de;

#[doc(inline)]
pub use ser::{Serialize, Serializer};
#[doc(inline)]
pub use de::{Deserialize, Deserializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

// Re-export #[derive(Serialize, Deserialize)].
//
// This is a workaround for https://github.com/rust-lang/cargo/issues/1286.
// Without this re-export, crates that put Serde derives behind a cfg_attr would
// need to use some silly feature name that depends on both serde and
// serde_derive.
//
//     [features]
//     serde-impls = ["serde", "serde_derive"]
//
//     [dependencies]
//     serde = { version = "1.0", optional = true }
//     serde_derive = { version = "1.0", optional = true }
//
//     # Used like this:
//     # #[cfg(feature = "serde-impls")]
//     # #[macro_use]
//     # extern crate serde_derive;
//     #
//     # #[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
//     # struct S { /* ... */ }
//
// The re-exported derives allow crates to use "serde" as the name of their
// Serde feature which is more intuitive.
//
//     [dependencies]
//     serde = { version = "1.0", optional = true, features = ["derive"] }
//
//     # Used like this:
//     # #[cfg(feature = "serde")]
//     # #[macro_use]
//     # extern crate serde;
//     #
//     # #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
//     # struct S { /* ... */ }
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<commit_msg>Whitelist const_static_lifetime<commit_after>// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [URL], the x-www-form-urlencoded format.
//! - [XML], the flexible machine-friendly W3C standard.
//!   *(deserialization only)*
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Redis], deserialize values from Redis when using [redis-rs].
//!   *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [XML]: https://github.com/RReverser/serde-xml-rs
//! [Envy]: https://github.com/softprops/envy
//! [Redis]: https://github.com/OneSignal/serde-redis
//! [Cargo]: http://doc.crates.io/manifest.html
//! [redis-rs]: https://crates.io/crates/redis

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.17")]

// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]

// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
#![cfg_attr(feature = "alloc", feature(alloc))]

#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(
    cast_lossless,
    const_static_lifetime,
    doc_markdown,
    linkedlist,
    type_complexity,
    unreadable_literal,
    zero_prefixed_literal,
))]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "cargo-clippy", allow(
// integer and float ser/de requires these sorts of casts
    cast_possible_truncation,
    cast_possible_wrap,
    cast_precision_loss,
    cast_sign_loss,
// simplifies some macros
    invalid_upcast_comparisons,
// things are often more readable this way
    option_unwrap_used,
    result_unwrap_used,
    shadow_reuse,
    single_match_else,
    stutter,
    use_self,
// not practical
    missing_docs_in_private_items,
// alternative is not stable
    empty_enum,
    use_debug,
))]

// Blacklisted Rust lints.
#![deny(missing_docs, unused_imports)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

#[cfg(all(feature = "unstable", feature = "std"))]
extern crate core;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(feature = "std")]
        pub use std::*;
        #[cfg(not(feature = "std"))]
        pub use core::*;
    }

    pub use self::core::{cmp, iter, mem, ops, slice, str};
    pub use self::core::{i8, i16, i32, i64, isize};
    pub use self::core::{u8, u16, u32, u64, usize};
    pub use self::core::{f32, f64};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};

    #[cfg(feature = "std")]
    pub use std::string::String;
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};

    #[cfg(feature = "std")]
    pub use std::vec::Vec;
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;

    #[cfg(feature = "std")]
    pub use std::boxed::Box;
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;

    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::Rc;
    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::Rc;

    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::Arc;
    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::arc::Arc;

    #[cfg(feature = "std")]
    pub use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CString, CStr, OsString, OsStr};
    #[cfg(feature = "std")]
    pub use std::hash::{Hash, BuildHasher};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};

    #[cfg(feature = "unstable")]
    pub use core::nonzero::{NonZero, Zeroable};
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

pub mod ser;
pub mod de;

#[doc(inline)]
pub use ser::{Serialize, Serializer};
#[doc(inline)]
pub use de::{Deserialize, Deserializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

// Re-export #[derive(Serialize, Deserialize)].
//
// This is a workaround for https://github.com/rust-lang/cargo/issues/1286.
// Without this re-export, crates that put Serde derives behind a cfg_attr would
// need to use some silly feature name that depends on both serde and
// serde_derive.
//
//     [features]
//     serde-impls = ["serde", "serde_derive"]
//
//     [dependencies]
//     serde = { version = "1.0", optional = true }
//     serde_derive = { version = "1.0", optional = true }
//
//     # Used like this:
//     # #[cfg(feature = "serde-impls")]
//     # #[macro_use]
//     # extern crate serde_derive;
//     #
//     # #[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
//     # struct S { /* ... */ }
//
// The re-exported derives allow crates to use "serde" as the name of their
// Serde feature which is more intuitive.
//
//     [dependencies]
//     serde = { version = "1.0", optional = true, features = ["derive"] }
//
//     # Used like this:
//     # #[cfg(feature = "serde")]
//     # #[macro_use]
//     # extern crate serde;
//     #
//     # #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
//     # struct S { /* ... */ }
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(overflowing_literals)]

use std::{i64, f32, f64};
use test;

mod parse;
mod rawfp;

// Take a float literal, turn it into a string in various ways (that are all trusted
// to be correct) and see if those strings are parsed back to the value of the literal.
// Requires a *polymorphic literal*, i.e. one that can serve as f64 as well as f32.
macro_rules! test_literal {
    ($x: expr) => ({
        let x32: f32 = $x;
        let x64: f64 = $x;
        let inputs = &[stringify!($x).into(), format!("{:?}", x64), format!("{:e}", x64)];
        for input in inputs {
            if input != "inf" {
                assert_eq!(input.parse(), Ok(x64));
                assert_eq!(input.parse(), Ok(x32));
                let neg_input = &format!("-{}", input);
                assert_eq!(neg_input.parse(), Ok(-x64));
                assert_eq!(neg_input.parse(), Ok(-x32));
            }
        }
    })
}

#[test]
fn ordinary() {
    test_literal!(1.0);
    test_literal!(3e-5);
    test_literal!(0.1);
    test_literal!(12345.);
    test_literal!(0.9999999);
    test_literal!(2.2250738585072014e-308);
}

#[test]
fn special_code_paths() {
    test_literal!(36893488147419103229.0); // 2^65 - 3, triggers half-to-even with even significand
    test_literal!(101e-33); // Triggers the tricky underflow case in AlgorithmM (for f32)
    test_literal!(1e23); // Triggers AlgorithmR
    test_literal!(2075e23); // Triggers another path through AlgorithmR
    test_literal!(8713e-23); // ... and yet another.
}

#[test]
fn large() {
    test_literal!(1e300);
    test_literal!(123456789.34567e250);
    test_literal!(943794359898089732078308743689303290943794359843568973207830874368930329.);
}

#[test]
fn subnormals() {
    test_literal!(5e-324);
    test_literal!(91e-324);
    test_literal!(1e-322);
    test_literal!(13245643e-320);
    test_literal!(2.22507385851e-308);
    test_literal!(2.1e-308);
    test_literal!(4.9406564584124654e-324);
}

#[test]
fn infinity() {
    test_literal!(1e400);
    test_literal!(1e309);
    test_literal!(2e308);
    test_literal!(1.7976931348624e308);
}

#[test]
fn zero() {
    test_literal!(0.0);
    test_literal!(1e-325);
    test_literal!(1e-326);
    test_literal!(1e-500);
}

#[test]
fn fast_path_correct() {
    // This number triggers the fast path and is handled incorrectly when compiling on
    // x86 without SSE2 (i.e., using the x87 FPU stack).
    test_literal!(1.448997445238699);
}

#[test]
fn lonely_dot() {
    assert!(".".parse::<f32>().is_err());
    assert!(".".parse::<f64>().is_err());
}

#[test]
fn lonely_sign() {
    assert!("+".parse::<f32>().is_err());
    assert!("-".parse::<f64>().is_err());
}

#[test]
fn whitespace() {
    assert!(" 1.0".parse::<f32>().is_err());
    assert!("1.0 ".parse::<f64>().is_err());
}

#[test]
fn nan() {
    assert!("NaN".parse::<f32>().unwrap().is_nan());
    assert!("NaN".parse::<f64>().unwrap().is_nan());
}

#[test]
fn inf() {
    assert_eq!("inf".parse(), Ok(f64::INFINITY));
    assert_eq!("-inf".parse(), Ok(f64::NEG_INFINITY));
    assert_eq!("inf".parse(), Ok(f32::INFINITY));
    assert_eq!("-inf".parse(), Ok(f32::NEG_INFINITY));
}

#[test]
fn massive_exponent() {
    let max = i64::MAX;
    assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY));
    assert_eq!(format!("1e-{}000", max).parse(), Ok(0.0));
    assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY));
}

#[test]
fn borderline_overflow() {
    let mut s = "0.".to_string();
    for _ in 0..375 {
        s.push('3');
    }
    // At the time of this writing, this returns Err(..), but this is a bug that should be fixed.
    // It makes no sense to enshrine that in a test, the important part is that it doesn't panic.
    let _ = s.parse::<f64>();
}

#[bench]
fn bench_0(b: &mut test::Bencher) {
    b.iter(|| "0.0".parse::<f64>());
}

#[bench]
fn bench_42(b: &mut test::Bencher) {
    b.iter(|| "42".parse::<f64>());
}

#[bench]
fn bench_huge_int(b: &mut test::Bencher) {
    // 2^128 - 1
    b.iter(|| "170141183460469231731687303715884105727".parse::<f64>());
}

#[bench]
fn bench_short_decimal(b: &mut test::Bencher) {
    b.iter(|| "1234.5678".parse::<f64>());
}

#[bench]
fn bench_pi_long(b: &mut test::Bencher) {
    b.iter(|| "3.14159265358979323846264338327950288".parse::<f64>());
}

#[bench]
fn bench_pi_short(b: &mut test::Bencher) {
    b.iter(|| "3.141592653589793".parse::<f64>())
}

#[bench]
fn bench_1e150(b: &mut test::Bencher) {
    b.iter(|| "1e150".parse::<f64>());
}

#[bench]
fn bench_long_decimal_and_exp(b: &mut test::Bencher) {
    b.iter(|| "727501488517303786137132964064381141071e-123".parse::<f64>());
}

#[bench]
fn bench_min_subnormal(b: &mut test::Bencher) {
    b.iter(|| "5e-324".parse::<f64>());
}

#[bench]
fn bench_min_normal(b: &mut test::Bencher) {
    b.iter(|| "2.2250738585072014e-308".parse::<f64>());
}

#[bench]
fn bench_max(b: &mut test::Bencher) {
    b.iter(|| "1.7976931348623157e308".parse::<f64>());
}
<commit_msg>Enable unit tests for literals that overflow. I have no idea why this condition was ever added.<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(overflowing_literals)]

use std::{i64, f32, f64};
use test;

mod parse;
mod rawfp;

// Take a float literal, turn it into a string in various ways (that are all trusted
// to be correct) and see if those strings are parsed back to the value of the literal.
// Requires a *polymorphic literal*, i.e. one that can serve as f64 as well as f32.
macro_rules! test_literal {
    ($x: expr) => ({
        let x32: f32 = $x;
        let x64: f64 = $x;
        let inputs = &[stringify!($x).into(), format!("{:?}", x64), format!("{:e}", x64)];
        for input in inputs {
            assert_eq!(input.parse(), Ok(x64));
            assert_eq!(input.parse(), Ok(x32));
            let neg_input = &format!("-{}", input);
            assert_eq!(neg_input.parse(), Ok(-x64));
            assert_eq!(neg_input.parse(), Ok(-x32));
        }
    })
}

#[test]
fn ordinary() {
    test_literal!(1.0);
    test_literal!(3e-5);
    test_literal!(0.1);
    test_literal!(12345.);
    test_literal!(0.9999999);
    test_literal!(2.2250738585072014e-308);
}

#[test]
fn special_code_paths() {
    test_literal!(36893488147419103229.0); // 2^65 - 3, triggers half-to-even with even significand
    test_literal!(101e-33); // Triggers the tricky underflow case in AlgorithmM (for f32)
    test_literal!(1e23); // Triggers AlgorithmR
    test_literal!(2075e23); // Triggers another path through AlgorithmR
    test_literal!(8713e-23); // ... and yet another.
}

#[test]
fn large() {
    test_literal!(1e300);
    test_literal!(123456789.34567e250);
    test_literal!(943794359898089732078308743689303290943794359843568973207830874368930329.);
}

#[test]
fn subnormals() {
    test_literal!(5e-324);
    test_literal!(91e-324);
    test_literal!(1e-322);
    test_literal!(13245643e-320);
    test_literal!(2.22507385851e-308);
    test_literal!(2.1e-308);
    test_literal!(4.9406564584124654e-324);
}

#[test]
fn infinity() {
    test_literal!(1e400);
    test_literal!(1e309);
    test_literal!(2e308);
    test_literal!(1.7976931348624e308);
}

#[test]
fn zero() {
    test_literal!(0.0);
    test_literal!(1e-325);
    test_literal!(1e-326);
    test_literal!(1e-500);
}

#[test]
fn fast_path_correct() {
    // This number triggers the fast path and is handled incorrectly when compiling on
    // x86 without SSE2 (i.e., using the x87 FPU stack).
    test_literal!(1.448997445238699);
}

#[test]
fn lonely_dot() {
    assert!(".".parse::<f32>().is_err());
    assert!(".".parse::<f64>().is_err());
}

#[test]
fn lonely_sign() {
    assert!("+".parse::<f32>().is_err());
    assert!("-".parse::<f64>().is_err());
}

#[test]
fn whitespace() {
    assert!(" 1.0".parse::<f32>().is_err());
    assert!("1.0 ".parse::<f64>().is_err());
}

#[test]
fn nan() {
    assert!("NaN".parse::<f32>().unwrap().is_nan());
    assert!("NaN".parse::<f64>().unwrap().is_nan());
}

#[test]
fn inf() {
    assert_eq!("inf".parse(), Ok(f64::INFINITY));
    assert_eq!("-inf".parse(), Ok(f64::NEG_INFINITY));
    assert_eq!("inf".parse(), Ok(f32::INFINITY));
    assert_eq!("-inf".parse(), Ok(f32::NEG_INFINITY));
}

#[test]
fn massive_exponent() {
    let max = i64::MAX;
    assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY));
    assert_eq!(format!("1e-{}000", max).parse(), Ok(0.0));
    assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY));
}

#[test]
fn borderline_overflow() {
    let mut s = "0.".to_string();
    for _ in 0..375 {
        s.push('3');
    }
    // At the time of this writing, this returns Err(..), but this is a bug that should be fixed.
    // It makes no sense to enshrine that in a test, the important part is that it doesn't panic.
    let _ = s.parse::<f64>();
}

#[bench]
fn bench_0(b: &mut test::Bencher) {
    b.iter(|| "0.0".parse::<f64>());
}

#[bench]
fn bench_42(b: &mut test::Bencher) {
    b.iter(|| "42".parse::<f64>());
}

#[bench]
fn bench_huge_int(b: &mut test::Bencher) {
    // 2^128 - 1
    b.iter(|| "170141183460469231731687303715884105727".parse::<f64>());
}

#[bench]
fn bench_short_decimal(b: &mut test::Bencher) {
    b.iter(|| "1234.5678".parse::<f64>());
}

#[bench]
fn bench_pi_long(b: &mut test::Bencher) {
    b.iter(|| "3.14159265358979323846264338327950288".parse::<f64>());
}

#[bench]
fn bench_pi_short(b: &mut test::Bencher) {
    b.iter(|| "3.141592653589793".parse::<f64>())
}

#[bench]
fn bench_1e150(b: &mut test::Bencher) {
    b.iter(|| "1e150".parse::<f64>());
}

#[bench]
fn bench_long_decimal_and_exp(b: &mut test::Bencher) {
    b.iter(|| "727501488517303786137132964064381141071e-123".parse::<f64>());
}

#[bench]
fn bench_min_subnormal(b: &mut test::Bencher) {
    b.iter(|| "5e-324".parse::<f64>());
}

#[bench]
fn bench_min_normal(b: &mut test::Bencher) {
    b.iter(|| "2.2250738585072014e-308".parse::<f64>());
}

#[bench]
fn bench_max(b: &mut test::Bencher) {
    b.iter(|| "1.7976931348623157e308".parse::<f64>());
}
<|endoftext|>


<commit_before>use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use std::borrow::Borrow;

lazy_static! {
    static ref SYMBOLICATOR: Symbolicator = Symbolicator::new();
}

struct Symbolicator(Arc<Mutex<InnerSymbolicator>>);

impl Symbolicator {
    fn new() -> Self {
        let inner = InnerSymbolicator::new();
        Self(Arc::new(Mutex::new(inner)))
    }

    pub fn symbolicate<S: Into<String>>(&self, string: S) -> Symbol {
        let string = string.into();
        let mut inner = self.0.lock().unwrap();
        if let Some(existing_id) = inner.symbols.get(&string) {
            return Symbol(*existing_id)
        }
        let next_id = inner.symbols.len() as u32;
        inner.symbols.insert(string, next_id);
        Symbol(next_id)
    }
}

type SymbolId = u32;

pub struct Symbol(SymbolId);

// Trick trait to enforce that the `Symbolicator` is thread-safe.
trait MustBeSendAndSync: Send + Sync {}

impl MustBeSendAndSync for Symbolicator {}

struct InnerSymbolicator {
    symbols: HashMap<String, SymbolId>,
}

impl InnerSymbolicator {
    pub fn new() -> Self {
        Self {
            symbols: HashMap::new(),
        }
    }
}
<commit_msg>Implement desymbolication to convert a symbol back to a string<commit_after>use std::sync::{Arc, Mutex};
use std::collections::HashMap;

lazy_static! {
    static ref SYMBOLICATOR: Symbolicator = Symbolicator::new();
}

struct Symbolicator(Arc<Mutex<InnerSymbolicator>>);

impl Symbolicator {
    fn new() -> Self {
        let inner = InnerSymbolicator::new();
        Self(Arc::new(Mutex::new(inner)))
    }

    pub fn symbolicate<S: Into<String>>(&self, string: S) -> Symbol {
        let string = string.into();
        let mut inner = self.0.lock().unwrap();
        if let Some(existing_id) = inner.symbols.get(&string) {
            return Symbol(*existing_id)
        }
        let next_id = inner.symbols.len() as u32;
        inner.symbols.insert(string, next_id);
        Symbol(next_id)
    }

    pub fn desymbolicate(&self, symbol: Symbol) -> Option<String> {
        let inner = self.0.lock().unwrap();
        for (key, value) in inner.symbols.iter() {
            if *value == symbol.0 {
                return Some(key.clone())
            }
        }
        None
    }
}

type SymbolId = u32;

pub struct Symbol(SymbolId);

// Trick trait to enforce that the `Symbolicator` is thread-safe.
trait MustBeSendAndSync: Send + Sync {}

impl MustBeSendAndSync for Symbolicator {}

struct InnerSymbolicator {
    symbols: HashMap<String, SymbolId>,
}

impl InnerSymbolicator {
    pub fn new() -> Self {
        Self {
            symbols: HashMap::new(),
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::VecDeque;
use std::io::Write;
use std::mem::zeroed;
use std::os::raw::{c_int, c_uchar};
use std::rc::Rc;

use client::{ClientW, Rect};
use config::Config;
use layout::Layout;
use util;

use x11::xlib;

pub enum FocusShift {
    Forward,
    Backward,
}

pub struct Workspace {
    anchor_window: xlib::Window,
    pub config: Rc<Config>,
    client_current: Option<ClientW>,
    clients_prev: VecDeque<ClientW>,
    clients_next: VecDeque<ClientW>,
    layout: Box<Layout + 'static>,
    pub tag: c_uchar,
}

impl Workspace {
    pub fn new(config: Rc<Config>,
               anchor_window: xlib::Window,
               tag: c_uchar,
               layout: Box<Layout + 'static>)
               -> Self {
        Workspace {
            anchor_window: anchor_window,
            client_current: None,
            clients_prev: VecDeque::new(),
            clients_next: VecDeque::new(),
            config: config,
            layout: layout,
            tag: tag,
        }
    }

    pub fn circle_focus(&mut self, direction: FocusShift) {
        match direction {
            FocusShift::Forward => {
                if self.clients_next.len() > 0 {
                    self.shift_focus(direction);
                } else {
                    while self.clients_prev.len() > 0 {
                        self.shift_focus(FocusShift::Backward);
                    }
                }
            }
            FocusShift::Backward => {
                if self.clients_prev.len() > 0 {
                    self.shift_focus(direction);
                } else {
                    while self.clients_next.len() > 0 {
                        self.shift_focus(FocusShift::Forward);
                    }
                }
            }
        }
        self.restack();
    }

    pub fn clear(&mut self) {
        self.clients_prev.clear();
        self.clients_next.clear();
        self.client_current = None;
    }

    pub fn detach_current(&mut self) -> Option<ClientW> {
        if self.client_current.is_some() {
            if self.clients_next.len() > 0 {
                self.shift_focus(FocusShift::Forward);
                return self.clients_prev.pop_back();
            } else if self.clients_prev.len() > 0 {
                self.shift_focus(FocusShift::Backward);
                return self.clients_next.pop_front();
            }
        }
        self.client_current.take()
    }

    pub fn get_client_by_window(&self, window: xlib::Window) -> Option<ClientW> {
        if let &Some(ref c) = &self.client_current {
            if c.window() == window {
                return Some(c.clone());
            }
        }

        for c in &self.clients_prev {
            if c.window() == window {
                return Some(c.clone());
            }
        }

        for c in &self.clients_next {
            if c.window() == window {
                return Some(c.clone());
            }
        }

        None
    }

    pub fn get_current_focused(&self) -> Option<ClientW> {
        if let &Some(ref c) = &self.client_current {
            return Some(c.clone());
        }
        None
    }

    pub fn get_layout(&self, rect: Rect) -> Vec<(ClientW, Rect)> {
        self.layout.layout(self, rect)
    }

    pub fn kill_client(&mut self) {
        if let Some(client) = self.detach_current() {
            let atom = client.atoms().wm_delete;
            if !client.send_event(atom) {
                x_disable_error_unsafe!(client.display(), {
                    xlib::XSetCloseDownMode(client.display(), xlib::DestroyAll);
                    xlib::XKillClient(client.display(), client.borrow().window);
                });
            }
        }
    }

    pub fn new_client(&mut self, client: ClientW, at_focus: bool) {
        if !at_focus {
            self.clients_prev.push_front(client);
            while self.clients_prev.len() > 0 {
                self.shift_focus(FocusShift::Backward);
            }
        } else {
            self.clients_prev.push_back(client);
            self.shift_focus(FocusShift::Backward);
        }
    }

    fn push_next(&mut self, client: Option<ClientW>) {
        if let Some(c) = client {
            self.clients_next.push_front(c);
        }
    }

    fn push_prev(&mut self, client: Option<ClientW>) {
        if let Some(c) = client {
            self.clients_prev.push_back(c);
        }
    }

    pub fn remove_client(&mut self, client: ClientW) {
        if let Some(position) = self.clients_prev
            .iter()
            .position(|c| c.window() == client.window()) {
            self.clients_prev.remove(position);
            return;
        }
        if let Some(position) = self.clients_next
            .iter()
            .position(|c| c.window() == client.window()) {
            self.clients_next.remove(position);
            return;
        }
        let cmp = self.client_current.clone().map(|c| c.window() == client.window());
        if cmp.is_some() && cmp.unwrap() {
            self.detach_current();
        }
    }

    pub fn restack(&mut self) {
        if let Some(focus) = self.get_current_focused() {
            focus.focus(true);
            if focus.is_floating() {
                focus.raise_window();
                return;
            }

            let mut to_restack = vec![self.anchor_window, focus.window()];
            to_restack.extend(
                self.select_clients(&|c| {
                        c.window() != focus.window() && !c.is_floating()
                    }).iter().map(|c| c.window()));
            unsafe {
                xlib::XRestackWindows(focus.display(),
                                      to_restack.as_mut_ptr(),
                                      to_restack.len() as c_int);
                let mut xevent: xlib::XEvent = zeroed();
                xlib::XSync(focus.display(), 0);
                while xlib::XCheckMaskEvent(focus.display(),
                                            xlib::EnterWindowMask,
                                            &mut xevent) != 0 {}
            }
        }
    }

    pub fn set_focus(&mut self, client: ClientW) {
        if let &mut Some(ref mut c) = &mut self.client_current {
            if c.window() == client.window() {
                // c.focus(true);
                c.grab_buttons(true);
                return;
            }
        }
        if let Some(position) = self.clients_prev
            .iter()
            .position(|c| c.window() == client.window()) {
            for _ in 0..self.clients_prev.len() - position {
                self.shift_focus(FocusShift::Backward);
            }
            return;
        }
        if let Some(position) = self.clients_next
            .iter()
            .position(|c| c.window() == client.window()) {
            for _ in 0..position + 1 {
                self.shift_focus(FocusShift::Forward);
            }
            return;
        }
    }

    pub fn select_clients(&self, pred: &Fn(&&ClientW) -> bool) -> Vec<ClientW> {
        let mut result: Vec<ClientW> =
            self.clients_prev.iter().filter(pred).map(|c| c.clone()).collect();
        if let &Some(ref c) = &self.client_current {
            if pred(&c) {
                result.push(c.clone());
            }
        }
        result.extend(self.clients_next
            .iter()
            .filter(pred)
            .map(|c| c.clone())
            .collect::<Vec<ClientW>>());
        result
    }

    pub fn show(&mut self, visible: bool) {
        for c in &mut self.clients_prev {
            c.show(visible);
        }

        if let &mut Some(ref mut c) = &mut self.client_current {
            c.show(visible);
        }

        for c in &mut self.clients_next {
            c.show(visible);
        }
    }

    pub fn shift_focus(&mut self, shift: FocusShift) {
        match shift {
            FocusShift::Forward => {
                if let Some(mut next_client) = self.clients_next.pop_front() {
                    let current = self.client_current.take();
                    // next_client.focus(true);
                    next_client.grab_buttons(true);
                    self.client_current = Some(next_client);
                    self.push_prev(current.map(|c| {
                        c.focus(false);
                        c.clone().grab_buttons(false);
                        c
                    }));
                }
            }
            FocusShift::Backward => {
                if let Some(mut prev_client) = self.clients_prev.pop_back() {
                    let current = self.client_current.take();
                    // prev_client.focus(true);
                    prev_client.grab_buttons(true);
                    self.client_current = Some(prev_client);
                    self.push_next(current.map(|c| {
                        c.focus(false);
                        c.clone().grab_buttons(false);
                        c
                    }));
                }
            }
        }
    }

    pub fn zoom(&mut self) {
        if let Some(c) = self.detach_current() {
            self.new_client(c, false);
        }
    }
}<commit_msg>minor refactor of workspace code.<commit_after>use std::collections::VecDeque;
use std::io::Write;
use std::mem::zeroed;
use std::os::raw::{c_int, c_uchar};
use std::rc::Rc;

use client::{ClientW, Rect};
use config::Config;
use layout::Layout;
use util;

use x11::xlib;

pub enum FocusShift {
    Forward,
    Backward,
}

pub struct Workspace {
    anchor_window: xlib::Window,
    pub config: Rc<Config>,
    client_current: Option<ClientW>,
    clients_prev: VecDeque<ClientW>,
    clients_next: VecDeque<ClientW>,
    layout: Box<Layout + 'static>,
    pub tag: c_uchar,
}

impl Workspace {
    pub fn new(config: Rc<Config>,
               anchor_window: xlib::Window,
               tag: c_uchar,
               layout: Box<Layout + 'static>)
               -> Self {
        Workspace {
            anchor_window: anchor_window,
            client_current: None,
            clients_prev: VecDeque::new(),
            clients_next: VecDeque::new(),
            config: config,
            layout: layout,
            tag: tag,
        }
    }

    pub fn circle_focus(&mut self, direction: FocusShift) {
        match direction {
            FocusShift::Forward => {
                if self.clients_next.len() > 0 {
                    self.shift_focus(direction);
                } else {
                    while self.clients_prev.len() > 0 {
                        self.shift_focus(FocusShift::Backward);
                    }
                }
            }
            FocusShift::Backward => {
                if self.clients_prev.len() > 0 {
                    self.shift_focus(direction);
                } else {
                    while self.clients_next.len() > 0 {
                        self.shift_focus(FocusShift::Forward);
                    }
                }
            }
        }
        self.restack();
    }

    pub fn clear(&mut self) {
        self.clients_prev.clear();
        self.clients_next.clear();
        self.client_current = None;
    }

    pub fn detach_current(&mut self) -> Option<ClientW> {
        if self.client_current.is_some() {
            if self.clients_next.len() > 0 {
                self.shift_focus(FocusShift::Forward);
                return self.clients_prev.pop_back();
            } else if self.clients_prev.len() > 0 {
                self.shift_focus(FocusShift::Backward);
                return self.clients_next.pop_front();
            }
        }
        self.client_current.take()
    }

    pub fn get_client_by_window(&self, window: xlib::Window) -> Option<ClientW> {
        if let Some(c) = self.client_current.as_ref() {
            if c.window() == window {
                return Some(c.clone());
            }
        }
        self.clients_prev
            .iter()
            .find(|c| c.window() == window)
            .map(|c| c.clone())
            .or_else(|| {
                self.clients_next
                    .iter()
                    .find(|c| c.window() == window)
                    .map(|c| c.clone())
            })
    }

    pub fn get_current_focused(&self) -> Option<ClientW> {
        self.client_current.as_ref().map(|c| c.clone())
    }

    pub fn get_layout(&self, rect: Rect) -> Vec<(ClientW, Rect)> {
        self.layout.layout(self, rect)
    }

    pub fn kill_client(&mut self) {
        self.detach_current().map(|client| {
            let atom = client.atoms().wm_delete;
            if !client.send_event(atom) {
                x_disable_error_unsafe!(client.display(), {
                    xlib::XSetCloseDownMode(client.display(), xlib::DestroyAll);
                    xlib::XKillClient(client.display(), client.borrow().window);
                });
            }
        });
    }

    pub fn new_client(&mut self, client: ClientW, at_focus: bool) {
        if !at_focus {
            self.clients_prev.push_front(client);
            while self.clients_prev.len() > 0 {
                self.shift_focus(FocusShift::Backward);
            }
        } else {
            self.clients_prev.push_back(client);
            self.shift_focus(FocusShift::Backward);
        }
    }

    fn push_next(&mut self, client: Option<ClientW>) {
        if let Some(c) = client {
            self.clients_next.push_front(c);
        }
    }

    fn push_prev(&mut self, client: Option<ClientW>) {
        if let Some(c) = client {
            self.clients_prev.push_back(c);
        }
    }

    pub fn remove_client(&mut self, client: ClientW) {
        if let Some(position) = self.clients_prev
            .iter()
            .position(|c| c.window() == client.window()) {
            self.clients_prev.remove(position);
            return;
        }
        if let Some(position) = self.clients_next
            .iter()
            .position(|c| c.window() == client.window()) {
            self.clients_next.remove(position);
            return;
        }
        let cmp = self.client_current.clone().map(|c| c.window() == client.window());
        if cmp.is_some() && cmp.unwrap() {
            self.detach_current();
        }
    }

    pub fn restack(&mut self) {
        if let Some(focus) = self.get_current_focused() {
            focus.focus(true);
            if focus.is_floating() {
                focus.raise_window();
                return;
            }

            let mut to_restack = vec![self.anchor_window, focus.window()];
            to_restack.extend(
                self.select_clients(&|c| {
                        c.window() != focus.window() && !c.is_floating()
                    }).iter().map(|c| c.window()));
            unsafe {
                xlib::XRestackWindows(focus.display(),
                                      to_restack.as_mut_ptr(),
                                      to_restack.len() as c_int);
                let mut xevent: xlib::XEvent = zeroed();
                xlib::XSync(focus.display(), 0);
                while xlib::XCheckMaskEvent(focus.display(),
                                            xlib::EnterWindowMask,
                                            &mut xevent) != 0 {}
            }
        }
    }

    pub fn set_focus(&mut self, client: ClientW) {
        if let &mut Some(ref mut c) = &mut self.client_current {
            if c.window() == client.window() {
                // c.focus(true);
                c.grab_buttons(true);
                return;
            }
        }
        if let Some(position) = self.clients_prev
            .iter()
            .position(|c| c.window() == client.window()) {
            for _ in 0..self.clients_prev.len() - position {
                self.shift_focus(FocusShift::Backward);
            }
            return;
        }
        if let Some(position) = self.clients_next
            .iter()
            .position(|c| c.window() == client.window()) {
            for _ in 0..position + 1 {
                self.shift_focus(FocusShift::Forward);
            }
            return;
        }
    }

    pub fn select_clients(&self, pred: &Fn(&&ClientW) -> bool) -> Vec<ClientW> {
        let mut result: Vec<ClientW> =
            self.clients_prev.iter().filter(pred).map(|c| c.clone()).collect();
        if let &Some(ref c) = &self.client_current {
            if pred(&c) {
                result.push(c.clone());
            }
        }
        result.extend(self.clients_next
            .iter()
            .filter(pred)
            .map(|c| c.clone())
            .collect::<Vec<ClientW>>());
        result
    }

    pub fn show(&mut self, visible: bool) {
        for c in &mut self.clients_prev {
            c.show(visible);
        }

        if let Some(c) = self.client_current.as_mut() {
            c.show(visible);
        }

        for c in &mut self.clients_next {
            c.show(visible);
        }
    }

    pub fn shift_focus(&mut self, shift: FocusShift) {
        match shift {
            FocusShift::Forward => {
                if let Some(mut next_client) = self.clients_next.pop_front() {
                    let current = self.client_current.take();
                    next_client.grab_buttons(true);
                    self.client_current = Some(next_client);
                    self.push_prev(current.map(|c| {
                        c.focus(false);
                        c.clone().grab_buttons(false);
                        c
                    }));
                }
            }
            FocusShift::Backward => {
                if let Some(mut prev_client) = self.clients_prev.pop_back() {
                    let current = self.client_current.take();
                    prev_client.grab_buttons(true);
                    self.client_current = Some(prev_client);
                    self.push_next(current.map(|c| {
                        c.focus(false);
                        c.clone().grab_buttons(false);
                        c
                    }));
                }
            }
        }
    }

    pub fn zoom(&mut self) {
        self.detach_current().map(|c| self.new_client(c, false));
    }
}<|endoftext|>


<commit_before>
use c;
use std::str;
use std::ffi::{CStr};

/// The string wrapper from Exempi.
/// It is meant to be used for output parameter.
/// But gives you ownership of the string.
pub struct XmpString {
    ptr: *mut c::XmpString
}

impl XmpString {
    /// Create a new XmpString
    pub fn new() -> XmpString {
        XmpString { ptr: unsafe { c::xmp_string_new() } }
    }

    /// Native pointer is NULL
    pub fn is_null(&self) -> bool {
        self.ptr.is_null()
    }

    /// Return the native pointer
    pub fn as_ptr(&self) -> *const c::XmpString {
        self.ptr
    }

    /// Return the mutable native pointer
    pub fn as_mut_ptr(&mut self) -> *mut c::XmpString {
        self.ptr
    }

    /// Return the length of the string
    pub fn len(&self) -> usize {
        if self.ptr.is_null() {
            return 0;
        }
        unsafe { c::xmp_string_len(self.ptr) }
    }

    /// Convert to a str
    // XXX properly deal with the utf8 error
    pub fn to_str(&self) -> &str {
        unsafe {
            let s = CStr::from_ptr(c::xmp_string_cstr(self.ptr));
            // we are supposed to receive UTF8 from the library.
            str::from_utf8_unchecked(s.to_bytes())
        }
    }
}

impl ToString for XmpString {
    fn to_string(&self) -> String {
        String::from(self.to_str())
    }
}

impl Drop for XmpString {
    /// Will deallocate properly the underlying object
    fn drop(&mut self) {
        if !self.is_null() {
            unsafe { c::xmp_string_free(self.ptr) };
        }
    }
}

impl Eq for XmpString {

}
impl PartialEq for XmpString {
    fn eq(&self, other: &XmpString) -> bool {
        self.to_str() == other.to_str()
    }
}
<commit_msg>XmpString example<commit_after>
use c;
use std::fmt;
use std::str;
use std::ffi::{CStr};

/// The string wrapper from Exempi. It is meant to be used for output parameter.
/// But gives you ownership of the string.
/// Because of the way the C API of Exempi is implemented, we provide
/// this type instead of using std::string::String to avoid copying of strings
/// until needed.
/// They are mostly returned in an Option<XmpString> enum.
/// XmpString support several of the standard traits.
///
/// ```no_run
/// use exempi::{Xmp,PropFlags};
///
/// let xmp = Xmp::new();
/// let mut flags = PropFlags::empty();
///
/// if let Some(ref xmpstring) = xmp.get_property("http://rust.figuiere.net/ns/rust/", "rust", &mut flags) {
///    println!("property value is {}, flags {}", xmpstring, flags.bits());
///    println!("string len: {}", xmpstring.len());
///    let s = String::from(xmpstring.to_str());
///    println!("converted to std::String: {}", s);
/// }
/// ```
pub struct XmpString {
    ptr: *mut c::XmpString
}

impl XmpString {
    /// Create a new XmpString
    pub fn new() -> XmpString {
        XmpString { ptr: unsafe { c::xmp_string_new() } }
    }

    /// Native pointer is NULL
    pub fn is_null(&self) -> bool {
        self.ptr.is_null()
    }

    /// Return the native pointer
    pub fn as_ptr(&self) -> *const c::XmpString {
        self.ptr
    }

    /// Return the mutable native pointer
    pub fn as_mut_ptr(&mut self) -> *mut c::XmpString {
        self.ptr
    }

    /// Return the length of the string
    pub fn len(&self) -> usize {
        if self.ptr.is_null() {
            return 0;
        }
        unsafe { c::xmp_string_len(self.ptr) }
    }

    /// Convert to a str
    // XXX properly deal with the utf8 error
    pub fn to_str(&self) -> &str {
        unsafe {
            let s = CStr::from_ptr(c::xmp_string_cstr(self.ptr));
            // we are supposed to receive UTF8 from the library.
            str::from_utf8_unchecked(s.to_bytes())
        }
    }
}

impl Drop for XmpString {
    /// Will deallocate properly the underlying object
    fn drop(&mut self) {
        if !self.is_null() {
            unsafe { c::xmp_string_free(self.ptr) };
        }
    }
}

impl Eq for XmpString {

}
impl PartialEq for XmpString {
    fn eq(&self, other: &XmpString) -> bool {
        self.to_str() == other.to_str()
    }
}

impl fmt::Display for XmpString {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.to_str())
    }
}
<|endoftext|>


<commit_before>/**
 * String conversions
 */

fn to_str(num: float, digits: uint) -> str {
    let accum = if num < 0.0 { num = -num; "-" } else { "" };
    let trunc = num as uint;
    let frac = num - (trunc as float);
    accum += uint::str(trunc);
    if frac == 0.0 || digits == 0u { ret accum; }
    accum += ".";
    while digits > 0u && frac > 0.0 {
        frac *= 10.0;
        let digit = frac as uint;
        accum += uint::str(digit);
        frac -= digit as float;
        digits -= 1u;
    }
    ret accum;
}

/**
 * Convert a string to a float
 *
 * This function accepts strings such as
 * * "3.14"
 * * "+3.14", equivalent to "3.14"
 * * "-3.14"
 * * "2.5E10", or equivalently, "2.5e10"
 * * "2.5E-10"
 * * "", or, equivalently, "." (understood as 0)
 * * "5."
 * * ".5", or, equivalently,  "0.5"
 *
 * @param num A string, possibly empty.
 * @return [NaN] if the string did not represent a valid number.
 * @return Otherwise, the floating-point number represented [num].
 */
fn from_str(num: str) -> float {
   let pos = 0u;                  //Current byte position in the string.
                                  //Used to walk the string in O(n).
   let len = str::byte_len(num);  //Length of the string, in bytes.

   if len == 0u { ret 0.; }
   let total = 0f;                //Accumulated result
   let c     = 'z';               //Latest char.

   //Determine if first char is '-'/'+'. Set [pos] and [neg] accordingly.
   let neg = false;               //Sign of the result
   alt str::char_at(num, 0u) {
      '-' {
          neg = true;
          pos = 1u;
      }
      '+' {
          pos = 1u;
      }
      _ {}
   }

   //Examine the following chars until '.', 'e', 'E'
   while(pos < len) {
       let char_range = str::char_range_at(num, pos);
       c   = char_range.ch;
       pos = char_range.next;
       alt c {
          '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9'  {
           total = total * 10f;
           total += ((c as int) - ('0' as int)) as float;
         }
         _ {
           break;
         }
       }
   }

   if c == '.' {//Examine decimal part
      let decimal = 1.f;
      while(pos < len) {
         let char_range = str::char_range_at(num, pos);
         c = char_range.ch;
         pos = char_range.next;
         alt c {
            '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9'  {
                 decimal /= 10.f;
                 total += (((c as int) - ('0' as int)) as float)*decimal;
             }
             _ {
                 break;
             }
         }
      }
   }

   if (c == 'e') | (c == 'E') {//Examine exponent
      let exponent = 0u;
      let neg_exponent = false;
      if(pos < len) {
          let char_range = str::char_range_at(num, pos);
          c   = char_range.ch;
          alt c  {
             '+' {
                pos = char_range.next;
             }
             '-' {
                pos = char_range.next;
                neg_exponent = true;
             }
             _ {}
          }
          while(pos < len) {
             let char_range = str::char_range_at(num, pos);
             c = char_range.ch;
             pos = char_range.next;
             alt c {
                 '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9' {
                     exponent *= 10u;
                     exponent += ((c as uint) - ('0' as uint));
                 }
                 _ {
                     break;
                 }
             }
          }
          let multiplier = pow_uint_to_uint_as_float(10u, exponent);
              //Note: not [int::pow], otherwise, we'll quickly
              //end up with a nice overflow
          if neg_exponent {
             total = total / multiplier;
          } else {
             total = total * multiplier;
          }
      }
   }

   if(pos < len) {
     ret NaN();
   } else {
     if(neg) {
        total *= -1f;
     }
     ret total;
   }
}

/**
 * Arithmetics
 */

/**
 * Compute the exponentiation of an integer by another integer as a float.
 *
 *
 * @param x The base.
 * @param pow The exponent.
 * @return [NaN] of both [x] and [pow] are [0u], otherwise [x^pow].
 */
fn pow_uint_to_uint_as_float(x: uint, pow: uint) -> float {
   if x == 0u {
      if pow == 0u {
        ret NaN();
      }
       ret 0.;
   }
   let my_pow     = pow;
   let total      = 1f;
   let multiplier = x as float;
   while (my_pow > 0u) {
     if my_pow % 2u == 1u {
       total = total * multiplier;
     }
     my_pow     /= 2u;
     multiplier *= multiplier;
   }
   ret total;
}

/**
 * Constants
 */

//TODO: Once this is possible, replace the body of these functions
//by an actual constant.

fn NaN() -> float {
   ret 0./0.;
}

fn infinity() -> float {
   ret 1./0.;
}

fn neg_infinity() -> float {
   ret -1./0.;
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>Clean up character pattern in float.rs<commit_after>/**
 * String conversions
 */

fn to_str(num: float, digits: uint) -> str {
    let accum = if num < 0.0 { num = -num; "-" } else { "" };
    let trunc = num as uint;
    let frac = num - (trunc as float);
    accum += uint::str(trunc);
    if frac == 0.0 || digits == 0u { ret accum; }
    accum += ".";
    while digits > 0u && frac > 0.0 {
        frac *= 10.0;
        let digit = frac as uint;
        accum += uint::str(digit);
        frac -= digit as float;
        digits -= 1u;
    }
    ret accum;
}

/**
 * Convert a string to a float
 *
 * This function accepts strings such as
 * * "3.14"
 * * "+3.14", equivalent to "3.14"
 * * "-3.14"
 * * "2.5E10", or equivalently, "2.5e10"
 * * "2.5E-10"
 * * "", or, equivalently, "." (understood as 0)
 * * "5."
 * * ".5", or, equivalently,  "0.5"
 *
 * @param num A string, possibly empty.
 * @return [NaN] if the string did not represent a valid number.
 * @return Otherwise, the floating-point number represented [num].
 */
fn from_str(num: str) -> float {
   let pos = 0u;                  //Current byte position in the string.
                                  //Used to walk the string in O(n).
   let len = str::byte_len(num);  //Length of the string, in bytes.

   if len == 0u { ret 0.; }
   let total = 0f;                //Accumulated result
   let c     = 'z';               //Latest char.

   //Determine if first char is '-'/'+'. Set [pos] and [neg] accordingly.
   let neg = false;               //Sign of the result
   alt str::char_at(num, 0u) {
      '-' {
          neg = true;
          pos = 1u;
      }
      '+' {
          pos = 1u;
      }
      _ {}
   }

   //Examine the following chars until '.', 'e', 'E'
   while(pos < len) {
       let char_range = str::char_range_at(num, pos);
       c   = char_range.ch;
       pos = char_range.next;
       alt c {
         '0' to '9' {
           total = total * 10f;
           total += ((c as int) - ('0' as int)) as float;
         }
         _ {
           break;
         }
       }
   }

   if c == '.' {//Examine decimal part
      let decimal = 1.f;
      while(pos < len) {
         let char_range = str::char_range_at(num, pos);
         c = char_range.ch;
         pos = char_range.next;
         alt c {
            '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9'  {
                 decimal /= 10.f;
                 total += (((c as int) - ('0' as int)) as float)*decimal;
             }
             _ {
                 break;
             }
         }
      }
   }

   if (c == 'e') | (c == 'E') {//Examine exponent
      let exponent = 0u;
      let neg_exponent = false;
      if(pos < len) {
          let char_range = str::char_range_at(num, pos);
          c   = char_range.ch;
          alt c  {
             '+' {
                pos = char_range.next;
             }
             '-' {
                pos = char_range.next;
                neg_exponent = true;
             }
             _ {}
          }
          while(pos < len) {
             let char_range = str::char_range_at(num, pos);
             c = char_range.ch;
             pos = char_range.next;
             alt c {
                 '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9' {
                     exponent *= 10u;
                     exponent += ((c as uint) - ('0' as uint));
                 }
                 _ {
                     break;
                 }
             }
          }
          let multiplier = pow_uint_to_uint_as_float(10u, exponent);
              //Note: not [int::pow], otherwise, we'll quickly
              //end up with a nice overflow
          if neg_exponent {
             total = total / multiplier;
          } else {
             total = total * multiplier;
          }
      }
   }

   if(pos < len) {
     ret NaN();
   } else {
     if(neg) {
        total *= -1f;
     }
     ret total;
   }
}

/**
 * Arithmetics
 */

/**
 * Compute the exponentiation of an integer by another integer as a float.
 *
 *
 * @param x The base.
 * @param pow The exponent.
 * @return [NaN] of both [x] and [pow] are [0u], otherwise [x^pow].
 */
fn pow_uint_to_uint_as_float(x: uint, pow: uint) -> float {
   if x == 0u {
      if pow == 0u {
        ret NaN();
      }
       ret 0.;
   }
   let my_pow     = pow;
   let total      = 1f;
   let multiplier = x as float;
   while (my_pow > 0u) {
     if my_pow % 2u == 1u {
       total = total * multiplier;
     }
     my_pow     /= 2u;
     multiplier *= multiplier;
   }
   ret total;
}

/**
 * Constants
 */

//TODO: Once this is possible, replace the body of these functions
//by an actual constant.

fn NaN() -> float {
   ret 0./0.;
}

fn infinity() -> float {
   ret 1./0.;
}

fn neg_infinity() -> float {
   ret -1./0.;
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>