<commit_before>use crate::Unit;

/// Config contains some options for metrics of any kind.
#[derive(Clone, Debug, PartialEq, Hash)]
pub struct InstrumentConfig {
    pub(crate) description: Option<String>,
    pub(crate) unit: Option<Unit>,
    pub(crate) instrumentation_name: String,
}

impl InstrumentConfig {
    /// Create a new config from instrumentation name
    pub fn with_instrumentation_name(instrumentation_name: String) -> Self {
        InstrumentConfig {
            description: None,
            unit: None,
            instrumentation_name,
        }
    }

    /// Description is an optional field describing the metric instrument.
    pub fn description(&self) -> Option<&String> {
        self.description.as_ref()
    }

    /// Unit is an optional field describing the metric instrument data.
    pub fn unit(&self) -> Option<&Unit> {
        self.unit.as_ref()
    }

    /// Instrumentation name is the name given to the Meter that created this instrument.
    pub fn instrumentation_name(&self) -> &String {
        &self.instrumentation_name
    }
}
<commit_msg>feat: add instrumentation version for instrument config. (#392)<commit_after>use crate::Unit;

/// Config contains some options for metrics of any kind.
#[derive(Clone, Debug, PartialEq, Hash)]
pub struct InstrumentConfig {
    pub(crate) description: Option<String>,
    pub(crate) unit: Option<Unit>,
    pub(crate) instrumentation_name: String,
    pub(crate) instrumentation_version: Option<String>,
}

impl InstrumentConfig {
    /// Create a new config from instrumentation name
    pub fn with_instrumentation_name(instrumentation_name: String) -> Self {
        InstrumentConfig {
            description: None,
            unit: None,
            instrumentation_name,
            instrumentation_version: None,
        }
    }

    /// Create a new config with instrumentation name and version
    pub fn with_instrumentation(
        instrumentation_name: String,
        instrumentation_version: String,
    ) -> Self {
        InstrumentConfig {
            description: None,
            unit: None,
            instrumentation_name,
            instrumentation_version: Some(instrumentation_version),
        }
    }

    /// Description is an optional field describing the metric instrument.
    pub fn description(&self) -> Option<&String> {
        self.description.as_ref()
    }

    /// Unit is an optional field describing the metric instrument data.
    pub fn unit(&self) -> Option<&Unit> {
        self.unit.as_ref()
    }

    /// Instrumentation name is the name given to the Meter that created this instrument.
    pub fn instrumentation_name(&self) -> &String {
        &self.instrumentation_name
    }

    /// Instrumentation version returns the version of instrumentation
    pub fn instrumentation_version(&self) -> Option<&String> {
        self.instrumentation_version.as_ref()
    }
}
<|endoftext|>


<commit_before>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

use rand::distributions::{Sample, Range};
use rand::Rng;

use std::f64;
use std::mem;

use super::MCMove;

use types::{Matrix3, One};
use sys::{System, EnergyCache, CellShape};

/// Monte-Carlo move that changes the size of the simulation cell
pub struct Resize {
    /// Delta for translation of the box length
    delta: f64,
    /// Sampling range for volume scaling
    range: Range<f64>,
    /// System after applying changes to the simulation cell
    new_system: System,
    /// target pressure
    pressure: f64,
    /// largest cut off diameter of `PairPotentials`
    rc_max: f64,
}

impl Resize {
    /// Create a new `Resize` move, with target pressure `pressure` and maximum
    /// displacement of `delta`.
    pub fn new(pressure: f64, delta: f64) -> Resize {
        assert!(delta > 0.0, "delta must be positive in Resize move");
        Resize {
            delta: delta,
            range: Range::new(-delta, delta),
            new_system: System::new(),
            pressure: pressure,
            rc_max: 0.0,
        }
    }
}

impl MCMove for Resize {
    fn describe(&self) -> &str {
        "resizing of the cell"
    }

    fn setup(&mut self, system: &System) {
        // check if the cell is infinite
        if system.cell().shape() == CellShape::Infinite {
            fatal_error!("Cannot use `Resize` move with infinite simulation cell.")
        }

        // get the largest cutoff of all intermolecular interactions in the
        // system.
        // TODO: include electrostatic interactions
        self.rc_max = system.interactions()
                            .all_pairs()
                            .iter()
                            .map(|i| i.get_cutoff())
                            .fold(f64::NAN, f64::max)
    }

    fn prepare(&mut self, system: &mut System, rng: &mut Box<Rng>) -> bool {
        let delta = self.range.sample(rng);

        // copy the system: the proposed state will be stored here
        // TODO: we only need to store positions and the cell; all
        // other information stays the same.
        self.new_system = system.clone();

        let volume = system.volume();
        let scaling_factor = f64::cbrt((volume + delta) / volume);
        // change the simulation cell
        self.new_system.cell_mut().scale_mut(Matrix3::one() * scaling_factor);
        // check the radius of the smallest inscribed sphere and compare to the
        // cut off distance.
        // abort simulation when box gets smaller than twice the cutoff radius
        if self.new_system.cell()
            .lengths()
            .iter()
            .any(|&d| 0.5 * d <= self.rc_max) {
            fatal_error!("Tried to decrease the cell size but new size
                conflicts with the cut off radius. \
                Increase the number of particles to get rid of this problem.")
        }
        // loop over all molecules in the system
        // we don't want to change the intramolecular distances
        // so we compute the translation vector of the center of mass
        // of a molecule and apply it to all its particles

        // TODO: check if system.size == system.molecules().len
        // if that is the case, skip com computation since it is a
        // system without molecules
        for (mi, molecule) in system
            .molecules()
            .iter()
            .enumerate() {
            let old_com = system.molecule_com(mi);
            let frac_com = system.cell().fractional(&old_com);
            // compute translation vector
            let delta_com = self.new_system.cell().cartesian(&frac_com) - old_com;
            // loop over all particles (indices) in the molecule
            for pi in molecule.iter() {
                self.new_system[pi].position += delta_com
            }
        }
        true
    }

    fn cost(&self, system: &System, beta: f64, cache: &mut EnergyCache) -> f64 {
        let delta_energy = cache.move_rigid_molecules_cost(&self.new_system);
        let new_volume = self.new_system.volume();
        let old_volume = system.volume();
        let delta_volume = new_volume - old_volume;
        // Build and return the cost function
        beta * (delta_energy + self.pressure * delta_volume) -
        (system.molecules().len() as f64) * f64::ln(new_volume / old_volume)
    }

    fn apply(&mut self, system: &mut System) {
        // Exchange systems.
        mem::swap(system, &mut self.new_system)
    }

    fn restore(&mut self, _: &mut System) {
        // Do nothing.
    }

    fn update_amplitude(&mut self, scaling_factor: Option<f64>) {
        if let Some(s) = scaling_factor {
            self.delta *= s;
            self.range = Range::new(-self.delta, self.delta);
        }
    }
}
<commit_msg>Added comments.<commit_after>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

use rand::distributions::{Sample, Range};
use rand::Rng;

use std::f64;
use std::mem;

use super::MCMove;

use types::{Matrix3, One};
use sys::{System, EnergyCache, CellShape};

/// Monte-Carlo move that changes the size of the simulation cell
pub struct Resize {
    /// Delta for translation of the box length
    delta: f64,
    /// Sampling range for volume scaling
    range: Range<f64>,
    /// System after applying changes to the simulation cell
    new_system: System,
    /// target pressure
    pressure: f64,
    /// largest cut off diameter of `PairPotentials`
    rc_max: f64,
}

impl Resize {
    /// Create a new `Resize` move, with target pressure `pressure` and maximum
    /// displacement of `delta`.
    pub fn new(pressure: f64, delta: f64) -> Resize {
        assert!(delta > 0.0, "delta must be positive in Resize move");
        Resize {
            delta: delta,
            range: Range::new(-delta, delta),
            new_system: System::new(),
            pressure: pressure,
            rc_max: 0.0,
        }
    }
}

impl MCMove for Resize {
    fn describe(&self) -> &str {
        "resizing of the cell"
    }

    fn setup(&mut self, system: &System) {
        // check if the cell is infinite
        if system.cell().shape() == CellShape::Infinite {
            fatal_error!("Cannot use `Resize` move with infinite simulation cell.")
        }

        // Get the largest cutoff of all intermolecular interactions in the
        // system.
        // TODO: include electrostatic interactions
        self.rc_max = system.interactions()
                            .all_pairs()
                            .iter()
                            .map(|i| i.get_cutoff())
                            .fold(f64::NAN, f64::max)
    }

    fn prepare(&mut self, system: &mut System, rng: &mut Box<Rng>) -> bool {
        let delta = self.range.sample(rng);

        // Copy the system: the proposed state will be stored here
        // TODO: we only need to store positions and the cell; all
        // other information stays the same.
        self.new_system = system.clone();

        let volume = system.volume();
        let scaling_factor = f64::cbrt((volume + delta) / volume);
        // Change the simulation cell
        self.new_system.cell_mut().scale_mut(Matrix3::one() * scaling_factor);
        // Check the radius of the smallest inscribed sphere and compare to the
        // cut off distance.
        // Abort simulation when box gets smaller than twice the cutoff radius.
        if self.new_system.cell()
            .lengths()
            .iter()
            .any(|&d| 0.5 * d <= self.rc_max) {
            fatal_error!("Tried to decrease the cell size but new size
                conflicts with the cut off radius. \
                Increase the number of particles to get rid of this problem.")
        }
        // Loop over all molecules in the system.
        // We don't want to change the intramolecular distances
        // so we compute the translation vector of the center-of-mass
        // (com) of a molecule and apply it to all its particles.
        // Note that to do this, the com of a molecule *always* has
        // to reside inside the simulation cell.

        // TODO: Check if system.size == system.molecules().len
        // if that is the case, skip com computation since it is a
        // system without molecules.
        for (mi, molecule) in system
            .molecules()
            .iter()
            .enumerate() {
            let old_com = system.molecule_com(mi);
            let frac_com = system.cell().fractional(&old_com);
            // compute translation vector
            let delta_com =
                self.new_system.cell().cartesian(&frac_com) - old_com;
            // loop over all particles (indices) in the molecule
            for pi in molecule.iter() {
                self.new_system[pi].position += delta_com;
            }
        }
        true
    }

    fn cost(&self, system: &System, beta: f64, cache: &mut EnergyCache) -> f64 {
        let delta_energy = cache.move_rigid_molecules_cost(&self.new_system);
        let new_volume = self.new_system.volume();
        let old_volume = system.volume();
        let delta_volume = new_volume - old_volume;
        // Build and return the cost function.
        beta * (delta_energy + self.pressure * delta_volume) -
        (system.molecules().len() as f64) * f64::ln(new_volume / old_volume)
    }

    fn apply(&mut self, system: &mut System) {
        // Exchange systems: This will effectively update
        // new positions and cell.
        mem::swap(system, &mut self.new_system)
    }

    fn restore(&mut self, _: &mut System) {
        // Do nothing.
    }

    fn update_amplitude(&mut self, scaling_factor: Option<f64>) {
        if let Some(s) = scaling_factor {
            self.delta *= s;
            self.range = Range::new(-self.delta, self.delta);
        }
    }
}
<|endoftext|>


<commit_before>use cxx_test_suite::ffi;
use std::cell::Cell;
use std::ffi::CStr;

thread_local! {
    static CORRECT: Cell<bool> = Cell::new(false);
}

#[no_mangle]
extern "C" fn cxx_test_suite_set_correct() {
    CORRECT.with(|correct| correct.set(true));
}

macro_rules! check {
    ($run:expr) => {{
        CORRECT.with(|correct| correct.set(false));
        $run;
        assert!(CORRECT.with(|correct| correct.get()), stringify!($run));
    }};
}

#[test]
fn test_c_return() {
    let shared = ffi::Shared { z: 2020 };

    assert_eq!(2020, ffi::c_return_primitive());
    assert_eq!(2020, ffi::c_return_shared().z);
    assert_eq!(2020, *ffi::c_return_box());
    ffi::c_return_unique_ptr();
    assert_eq!(2020, *ffi::c_return_ref(&shared));
    assert_eq!("2020", ffi::c_return_str(&shared));
    assert_eq!(b"2020\0", ffi::c_return_sliceu8(&shared));
    assert_eq!("2020", ffi::c_return_rust_string());
    assert_eq!("2020", ffi::c_return_unique_ptr_string().to_str().unwrap());
    assert_eq!(4, ffi::c_return_unique_ptr_vector_u8().len());
    assert_eq!(
        200_u8,
        ffi::c_return_unique_ptr_vector_u8().into_iter().sum(),
    );
    assert_eq!(
        200.5_f64,
        ffi::c_return_unique_ptr_vector_f64().into_iter().sum(),
    );
    assert_eq!(2, ffi::c_return_unique_ptr_vector_shared().len());
    assert_eq!(
        2021_usize,
        ffi::c_return_unique_ptr_vector_shared()
            .into_iter()
            .map(|o| o.z)
            .sum(),
    );
    assert_eq!(2020, ffi::c_return_identity(2020));
    assert_eq!(2021, ffi::c_return_sum(2020, 1));
    match ffi::c_return_enum(0) {
        enm @ ffi::Enum::AVal => assert_eq!(0, enm.repr),
        _ => assert!(false),
    }
    match ffi::c_return_enum(1) {
        enm @ ffi::Enum::BVal => assert_eq!(2020, enm.repr),
        _ => assert!(false),
    }
    match ffi::c_return_enum(2021) {
        enm @ ffi::Enum::CVal => assert_eq!(2021, enm.repr),
        _ => assert!(false),
    }
}

#[test]
fn test_c_try_return() {
    assert_eq!((), ffi::c_try_return_void().unwrap());
    assert_eq!(2020, ffi::c_try_return_primitive().unwrap());
    assert_eq!(
        "logic error",
        ffi::c_fail_return_primitive().unwrap_err().what(),
    );
    assert_eq!(2020, *ffi::c_try_return_box().unwrap());
    assert_eq!("2020", *ffi::c_try_return_ref(&"2020".to_owned()).unwrap());
    assert_eq!("2020", ffi::c_try_return_str("2020").unwrap());
    assert_eq!(b"2020", ffi::c_try_return_sliceu8(b"2020").unwrap());
    assert_eq!("2020", ffi::c_try_return_rust_string().unwrap());
    assert_eq!("2020", &*ffi::c_try_return_unique_ptr_string().unwrap());
}

#[test]
fn test_c_take() {
    let unique_ptr = ffi::c_return_unique_ptr();

    check!(ffi::c_take_primitive(2020));
    check!(ffi::c_take_shared(ffi::Shared { z: 2020 }));
    check!(ffi::c_take_box(Box::new(2020)));
    check!(ffi::c_take_ref_c(&unique_ptr));
    check!(cxx_test_suite::module::ffi::c_take_unique_ptr(unique_ptr));
    check!(ffi::c_take_str("2020"));
    check!(ffi::c_take_sliceu8(b"2020"));
    check!(ffi::c_take_rust_string("2020".to_owned()));
    check!(ffi::c_take_unique_ptr_string(
        ffi::c_return_unique_ptr_string()
    ));
    check!(ffi::c_take_unique_ptr_vector_u8(
        ffi::c_return_unique_ptr_vector_u8()
    ));
    check!(ffi::c_take_unique_ptr_vector_f64(
        ffi::c_return_unique_ptr_vector_f64()
    ));
    check!(ffi::c_take_unique_ptr_vector_shared(
        ffi::c_return_unique_ptr_vector_shared()
    ));
    check!(ffi::c_take_ref_vector(&ffi::c_return_unique_ptr_vector_u8()));
    let test_vec = [86_u8, 75_u8, 30_u8, 9_u8].to_vec();
    check!(ffi::c_take_rust_vec(test_vec.clone()));
    check!(ffi::c_take_rust_vec_shared(vec![
        ffi::Shared { z: 1010 },
        ffi::Shared { z: 1011 }
    ]));
    check!(ffi::c_take_rust_vec_shared_forward_iterator(vec![
        ffi::Shared { z: 1010 },
        ffi::Shared { z: 1011 }
    ]));
    check!(ffi::c_take_ref_rust_vec(&test_vec));
    check!(ffi::c_take_ref_rust_vec_copy(&test_vec));
    check!(ffi::c_take_enum(ffi::Enum::AVal));
}

#[test]
fn test_c_callback() {
    fn callback(s: String) -> usize {
        if s == "2020" {
            cxx_test_suite_set_correct();
        }
        0
    }

    check!(ffi::c_take_callback(callback));
}

#[test]
fn test_c_call_r() {
    fn cxx_run_test() {
        extern "C" {
            fn cxx_run_test() -> *const i8;
        }
        let failure = unsafe { cxx_run_test() };
        if !failure.is_null() {
            let msg = unsafe { CStr::from_ptr(failure as *mut std::os::raw::c_char) };
            eprintln!("{}", msg.to_string_lossy());
        }
    }
    check!(cxx_run_test());
}

#[test]
fn test_c_method_calls() {
    let mut unique_ptr = ffi::c_return_unique_ptr();

    let old_value = unique_ptr.get();
    assert_eq!(2020, old_value);
    assert_eq!(2021, unique_ptr.set(2021));
    assert_eq!(2021, unique_ptr.get());
    assert_eq!(old_value, unique_ptr.set2(old_value));
    assert_eq!(old_value, unique_ptr.get2());
    assert_eq!(Ok(2022), unique_ptr.set_succeed(2022));
    assert!(unique_ptr.get_fail().is_err());
}

#[test]
fn test_enum_representations() {
    assert_eq!(0, ffi::Enum::AVal.repr);
    assert_eq!(2020, ffi::Enum::BVal.repr);
    assert_eq!(2021, ffi::Enum::CVal.repr);
}

#[no_mangle]
extern "C" fn cxx_test_suite_get_box() -> *mut cxx_test_suite::R {
    Box::into_raw(Box::new(2020usize))
}

#[no_mangle]
unsafe extern "C" fn cxx_test_suite_r_is_correct(r: *const cxx_test_suite::R) -> bool {
    *r == 2020
}
<commit_msg>Test c method calls without needing PartialEq on Exception<commit_after>use cxx_test_suite::ffi;
use std::cell::Cell;
use std::ffi::CStr;

thread_local! {
    static CORRECT: Cell<bool> = Cell::new(false);
}

#[no_mangle]
extern "C" fn cxx_test_suite_set_correct() {
    CORRECT.with(|correct| correct.set(true));
}

macro_rules! check {
    ($run:expr) => {{
        CORRECT.with(|correct| correct.set(false));
        $run;
        assert!(CORRECT.with(|correct| correct.get()), stringify!($run));
    }};
}

#[test]
fn test_c_return() {
    let shared = ffi::Shared { z: 2020 };

    assert_eq!(2020, ffi::c_return_primitive());
    assert_eq!(2020, ffi::c_return_shared().z);
    assert_eq!(2020, *ffi::c_return_box());
    ffi::c_return_unique_ptr();
    assert_eq!(2020, *ffi::c_return_ref(&shared));
    assert_eq!("2020", ffi::c_return_str(&shared));
    assert_eq!(b"2020\0", ffi::c_return_sliceu8(&shared));
    assert_eq!("2020", ffi::c_return_rust_string());
    assert_eq!("2020", ffi::c_return_unique_ptr_string().to_str().unwrap());
    assert_eq!(4, ffi::c_return_unique_ptr_vector_u8().len());
    assert_eq!(
        200_u8,
        ffi::c_return_unique_ptr_vector_u8().into_iter().sum(),
    );
    assert_eq!(
        200.5_f64,
        ffi::c_return_unique_ptr_vector_f64().into_iter().sum(),
    );
    assert_eq!(2, ffi::c_return_unique_ptr_vector_shared().len());
    assert_eq!(
        2021_usize,
        ffi::c_return_unique_ptr_vector_shared()
            .into_iter()
            .map(|o| o.z)
            .sum(),
    );
    assert_eq!(2020, ffi::c_return_identity(2020));
    assert_eq!(2021, ffi::c_return_sum(2020, 1));
    match ffi::c_return_enum(0) {
        enm @ ffi::Enum::AVal => assert_eq!(0, enm.repr),
        _ => assert!(false),
    }
    match ffi::c_return_enum(1) {
        enm @ ffi::Enum::BVal => assert_eq!(2020, enm.repr),
        _ => assert!(false),
    }
    match ffi::c_return_enum(2021) {
        enm @ ffi::Enum::CVal => assert_eq!(2021, enm.repr),
        _ => assert!(false),
    }
}

#[test]
fn test_c_try_return() {
    assert_eq!((), ffi::c_try_return_void().unwrap());
    assert_eq!(2020, ffi::c_try_return_primitive().unwrap());
    assert_eq!(
        "logic error",
        ffi::c_fail_return_primitive().unwrap_err().what(),
    );
    assert_eq!(2020, *ffi::c_try_return_box().unwrap());
    assert_eq!("2020", *ffi::c_try_return_ref(&"2020".to_owned()).unwrap());
    assert_eq!("2020", ffi::c_try_return_str("2020").unwrap());
    assert_eq!(b"2020", ffi::c_try_return_sliceu8(b"2020").unwrap());
    assert_eq!("2020", ffi::c_try_return_rust_string().unwrap());
    assert_eq!("2020", &*ffi::c_try_return_unique_ptr_string().unwrap());
}

#[test]
fn test_c_take() {
    let unique_ptr = ffi::c_return_unique_ptr();

    check!(ffi::c_take_primitive(2020));
    check!(ffi::c_take_shared(ffi::Shared { z: 2020 }));
    check!(ffi::c_take_box(Box::new(2020)));
    check!(ffi::c_take_ref_c(&unique_ptr));
    check!(cxx_test_suite::module::ffi::c_take_unique_ptr(unique_ptr));
    check!(ffi::c_take_str("2020"));
    check!(ffi::c_take_sliceu8(b"2020"));
    check!(ffi::c_take_rust_string("2020".to_owned()));
    check!(ffi::c_take_unique_ptr_string(
        ffi::c_return_unique_ptr_string()
    ));
    check!(ffi::c_take_unique_ptr_vector_u8(
        ffi::c_return_unique_ptr_vector_u8()
    ));
    check!(ffi::c_take_unique_ptr_vector_f64(
        ffi::c_return_unique_ptr_vector_f64()
    ));
    check!(ffi::c_take_unique_ptr_vector_shared(
        ffi::c_return_unique_ptr_vector_shared()
    ));
    check!(ffi::c_take_ref_vector(&ffi::c_return_unique_ptr_vector_u8()));
    let test_vec = [86_u8, 75_u8, 30_u8, 9_u8].to_vec();
    check!(ffi::c_take_rust_vec(test_vec.clone()));
    check!(ffi::c_take_rust_vec_shared(vec![
        ffi::Shared { z: 1010 },
        ffi::Shared { z: 1011 }
    ]));
    check!(ffi::c_take_rust_vec_shared_forward_iterator(vec![
        ffi::Shared { z: 1010 },
        ffi::Shared { z: 1011 }
    ]));
    check!(ffi::c_take_ref_rust_vec(&test_vec));
    check!(ffi::c_take_ref_rust_vec_copy(&test_vec));
    check!(ffi::c_take_enum(ffi::Enum::AVal));
}

#[test]
fn test_c_callback() {
    fn callback(s: String) -> usize {
        if s == "2020" {
            cxx_test_suite_set_correct();
        }
        0
    }

    check!(ffi::c_take_callback(callback));
}

#[test]
fn test_c_call_r() {
    fn cxx_run_test() {
        extern "C" {
            fn cxx_run_test() -> *const i8;
        }
        let failure = unsafe { cxx_run_test() };
        if !failure.is_null() {
            let msg = unsafe { CStr::from_ptr(failure as *mut std::os::raw::c_char) };
            eprintln!("{}", msg.to_string_lossy());
        }
    }
    check!(cxx_run_test());
}

#[test]
fn test_c_method_calls() {
    let mut unique_ptr = ffi::c_return_unique_ptr();

    let old_value = unique_ptr.get();
    assert_eq!(2020, old_value);
    assert_eq!(2021, unique_ptr.set(2021));
    assert_eq!(2021, unique_ptr.get());
    assert_eq!(old_value, unique_ptr.set2(old_value));
    assert_eq!(old_value, unique_ptr.get2());
    assert_eq!(2022, unique_ptr.set_succeed(2022).unwrap());
    assert!(unique_ptr.get_fail().is_err());
}

#[test]
fn test_enum_representations() {
    assert_eq!(0, ffi::Enum::AVal.repr);
    assert_eq!(2020, ffi::Enum::BVal.repr);
    assert_eq!(2021, ffi::Enum::CVal.repr);
}

#[no_mangle]
extern "C" fn cxx_test_suite_get_box() -> *mut cxx_test_suite::R {
    Box::into_raw(Box::new(2020usize))
}

#[no_mangle]
unsafe extern "C" fn cxx_test_suite_r_is_correct(r: *const cxx_test_suite::R) -> bool {
    *r == 2020
}
<|endoftext|>


<commit_before>extern crate gcc;
extern crate tempdir;

use support::Test;

mod support;

#[test]
fn gnu_smoke() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-O2")
        .must_have("foo.c")
        .must_not_have("-g")
        .must_have("-c")
        .must_have("-ffunction-sections")
        .must_have("-fdata-sections");
    test.cmd(1).must_have(test.td.path().join("foo.o"));
}

#[test]
fn gnu_opt_level_1() {
    let test = Test::gnu();
    test.gcc()
        .opt_level(1)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-O1")
        .must_not_have("-O2");
}

#[test]
fn gnu_opt_level_s() {
    let test = Test::gnu();
    test.gcc()
        .opt_level_str("s")
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-Os")
        .must_not_have("-O1")
        .must_not_have("-O2")
        .must_not_have("-O3")
        .must_not_have("-Oz");
}

#[test]
fn gnu_debug() {
    let test = Test::gnu();
    test.gcc()
        .debug(true)
        .file("foo.c")
        .compile("libfoo.a");
    test.cmd(0).must_have("-g");
}

#[test]
fn gnu_x86_64() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("x86_64-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .target(&target)
            .host(&target)
            .file("foo.c")
            .compile("libfoo.a");

        test.cmd(0)
            .must_have("-fPIC")
            .must_have("-m64");
    }
}

#[test]
fn gnu_x86_64_no_pic() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("x86_64-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .pic(false)
            .target(&target)
            .host(&target)
            .file("foo.c")
            .compile("libfoo.a");

        test.cmd(0).must_not_have("-fPIC");
    }
}

#[test]
fn gnu_i686() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("i686-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .target(&target)
            .host(&target)
            .file("foo.c")
            .compile("libfoo.a");

        test.cmd(0)
            .must_have("-m32");
    }
}

#[test]
fn gnu_i686_pic() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("i686-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .pic(true)
            .target(&target)
            .host(&target)
            .file("foo.c")
            .compile("libfoo.a");

        test.cmd(0).must_have("-fPIC");
    }
}

#[test]
fn gnu_set_stdlib() {
    let test = Test::gnu();
    test.gcc()
        .cpp_set_stdlib(Some("foo"))
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_not_have("-stdlib=foo");
}

#[test]
fn gnu_include() {
    let test = Test::gnu();
    test.gcc()
        .include("foo/bar")
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("-I").must_have("foo/bar");
}

#[test]
fn gnu_define() {
    let test = Test::gnu();
    test.gcc()
        .define("FOO", Some("bar"))
        .define("BAR", None)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
}

#[test]
fn gnu_compile_assembly() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.S")
        .compile("libfoo.a");
    test.cmd(0).must_have("foo.S");
}

#[test]
fn gnu_shared() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.c")
        .shared_flag(true)
        .static_flag(false)
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-shared")
        .must_not_have("-static");
}

#[test]
fn gnu_flag_if_supported() {
    if cfg!(windows) {
        return
    }
    let test = Test::gnu();
    test.gcc()
        .file("foo.c")
        .flag_if_supported("-Wall")
        .flag_if_supported("-Wflag-does-not-exist")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-Wall")
        .must_not_have("-Wflag-does-not-exist");
}

#[test]
fn gnu_static() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.c")
        .shared_flag(false)
        .static_flag(true)
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-static")
        .must_not_have("-shared");
}

#[test]
fn msvc_smoke() {
    let test = Test::msvc();
    test.gcc()
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("/O2")
        .must_have("foo.c")
        .must_not_have("/Z7")
        .must_have("/c")
        .must_have("/MD");
    test.cmd(1).must_have(test.td.path().join("foo.o"));
}

#[test]
fn msvc_opt_level_0() {
    let test = Test::msvc();
    test.gcc()
        .opt_level(0)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_not_have("/O2");
}

#[test]
fn msvc_debug() {
    let test = Test::msvc();
    test.gcc()
        .debug(true)
        .file("foo.c")
        .compile("libfoo.a");
    test.cmd(0).must_have("/Z7");
}

#[test]
fn msvc_include() {
    let test = Test::msvc();
    test.gcc()
        .include("foo/bar")
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("/I").must_have("foo/bar");
}

#[test]
fn msvc_define() {
    let test = Test::msvc();
    test.gcc()
        .define("FOO", Some("bar"))
        .define("BAR", None)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR");
}

#[test]
fn msvc_static_crt() {
    let test = Test::msvc();
    test.gcc()
        .static_crt(true)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("/MT");
}

#[test]
fn msvc_no_static_crt() {
    let test = Test::msvc();
    test.gcc()
        .static_crt(false)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("/MD");
}
<commit_msg>Add tests<commit_after>extern crate gcc;
extern crate tempdir;

use support::Test;

mod support;

#[test]
fn gnu_smoke() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-O2")
        .must_have("foo.c")
        .must_not_have("-g")
        .must_have("-c")
        .must_have("-ffunction-sections")
        .must_have("-fdata-sections");
    test.cmd(1).must_have(test.td.path().join("foo.o"));
}

#[test]
fn gnu_opt_level_1() {
    let test = Test::gnu();
    test.gcc()
        .opt_level(1)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-O1")
        .must_not_have("-O2");
}

#[test]
fn gnu_opt_level_s() {
    let test = Test::gnu();
    test.gcc()
        .opt_level_str("s")
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-Os")
        .must_not_have("-O1")
        .must_not_have("-O2")
        .must_not_have("-O3")
        .must_not_have("-Oz");
}

#[test]
fn gnu_debug() {
    let test = Test::gnu();
    test.gcc()
        .debug(true)
        .file("foo.c")
        .compile("libfoo.a");
    test.cmd(0).must_have("-g");
}

#[test]
fn gnu_warnings_into_errors() {
    let test = Test::gnu();
    test.gcc()
        .warnings_into_errors(true)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("-Werror");
}

#[test]
fn gnu_warnings() {
    let test = Test::gnu();
    test.gcc()
        .warnings(true)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("-Wall")
               .must_have("-Wextra");
}

#[test]
fn gnu_x86_64() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("x86_64-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .target(&target)
            .host(&target)
            .file("foo.c")
            .compile("libfoo.a");

        test.cmd(0)
            .must_have("-fPIC")
            .must_have("-m64");
    }
}

#[test]
fn gnu_x86_64_no_pic() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("x86_64-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .pic(false)
            .target(&target)
            .host(&target)
            .file("foo.c")
            .compile("libfoo.a");

        test.cmd(0).must_not_have("-fPIC");
    }
}

#[test]
fn gnu_i686() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("i686-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .target(&target)
            .host(&target)
            .file("foo.c")
            .compile("libfoo.a");

        test.cmd(0)
            .must_have("-m32");
    }
}

#[test]
fn gnu_i686_pic() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("i686-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .pic(true)
            .target(&target)
            .host(&target)
            .file("foo.c")
            .compile("libfoo.a");

        test.cmd(0).must_have("-fPIC");
    }
}

#[test]
fn gnu_set_stdlib() {
    let test = Test::gnu();
    test.gcc()
        .cpp_set_stdlib(Some("foo"))
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_not_have("-stdlib=foo");
}

#[test]
fn gnu_include() {
    let test = Test::gnu();
    test.gcc()
        .include("foo/bar")
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("-I").must_have("foo/bar");
}

#[test]
fn gnu_define() {
    let test = Test::gnu();
    test.gcc()
        .define("FOO", Some("bar"))
        .define("BAR", None)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
}

#[test]
fn gnu_compile_assembly() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.S")
        .compile("libfoo.a");
    test.cmd(0).must_have("foo.S");
}

#[test]
fn gnu_shared() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.c")
        .shared_flag(true)
        .static_flag(false)
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-shared")
        .must_not_have("-static");
}

#[test]
fn gnu_flag_if_supported() {
    if cfg!(windows) {
        return
    }
    let test = Test::gnu();
    test.gcc()
        .file("foo.c")
        .flag_if_supported("-Wall")
        .flag_if_supported("-Wflag-does-not-exist")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-Wall")
        .must_not_have("-Wflag-does-not-exist");
}

#[test]
fn gnu_static() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.c")
        .shared_flag(false)
        .static_flag(true)
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("-static")
        .must_not_have("-shared");
}

#[test]
fn msvc_smoke() {
    let test = Test::msvc();
    test.gcc()
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0)
        .must_have("/O2")
        .must_have("foo.c")
        .must_not_have("/Z7")
        .must_have("/c")
        .must_have("/MD");
    test.cmd(1).must_have(test.td.path().join("foo.o"));
}

#[test]
fn msvc_opt_level_0() {
    let test = Test::msvc();
    test.gcc()
        .opt_level(0)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_not_have("/O2");
}

#[test]
fn msvc_debug() {
    let test = Test::msvc();
    test.gcc()
        .debug(true)
        .file("foo.c")
        .compile("libfoo.a");
    test.cmd(0).must_have("/Z7");
}

#[test]
fn msvc_include() {
    let test = Test::msvc();
    test.gcc()
        .include("foo/bar")
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("/I").must_have("foo/bar");
}

#[test]
fn msvc_define() {
    let test = Test::msvc();
    test.gcc()
        .define("FOO", Some("bar"))
        .define("BAR", None)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR");
}

#[test]
fn msvc_static_crt() {
    let test = Test::msvc();
    test.gcc()
        .static_crt(true)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("/MT");
}

#[test]
fn msvc_no_static_crt() {
    let test = Test::msvc();
    test.gcc()
        .static_crt(false)
        .file("foo.c")
        .compile("libfoo.a");

    test.cmd(0).must_have("/MD");
}
<|endoftext|>


<commit_before>extern crate piston;
extern crate dyon;
extern crate current;
extern crate graphics;

use std::any::Any;
use std::sync::Arc;
use self::dyon::*;
use self::current::Current;
use self::piston::input::*;
use self::piston::window::*;
use self::graphics::{Context, Graphics};

pub const NO_EVENT: &'static str = "No event";

pub fn add_functions<W: Any + AdvancedWindow>(module: &mut Module) {
    module.add(Arc::new("window_size".into()), window_size::<W>, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Vec4
    });
    module.add(Arc::new("window_draw_size".into()), window_draw_size::<W>, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Vec4
    });
    module.add(Arc::new("render".into()), render, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool
    });
    module.add(Arc::new("update".into()), update, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool
    });
    module.add(Arc::new("press".into()), press, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool
    });
    module.add(Arc::new("release".into()), release, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool
    });
    module.add(Arc::new("focus".into()), focus, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool,
    });
    module.add(Arc::new("focus_arg".into()), focus_arg, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Option(Box::new(Type::Bool)),
    });
    module.add(Arc::new("set_title".into()),
        set_title::<W>, PreludeFunction {
            lts: vec![Lt::Default],
            tys: vec![Type::Text],
            ret: Type::Void
        });
    module.add(Arc::new("update_dt".into()),
        update_dt, PreludeFunction {
            lts: vec![],
            tys: vec![],
            ret: Type::Option(Box::new(Type::F64))
        });
    module.add(Arc::new("press_keyboard_key".into()),
        press_keyboard_key, PreludeFunction {
            lts: vec![],
            tys: vec![],
            ret: Type::Option(Box::new(Type::F64))
        });
    module.add(Arc::new("release_keyboard_key".into()),
        release_keyboard_key, PreludeFunction {
            lts: vec![],
            tys: vec![],
            ret: Type::Option(Box::new(Type::F64))
        });
}

pub fn window_size<W: Any + Window>(rt: &mut Runtime) -> Result<(), String> {
    let size = unsafe { Current::<W>::new() }.size();
    rt.push_vec4([size.width as f32, size.height as f32, 0.0, 0.0]);
    Ok(())
}

pub fn window_draw_size<W: Any + Window>(rt: &mut Runtime) -> Result<(), String> {
    let draw_size = unsafe { Current::<W>::new() }.draw_size();
    rt.push_vec4([draw_size.width as f32, draw_size.height as f32, 0.0, 0.0]);
    Ok(())
}

pub fn render(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).render_args().is_some() });
    Ok(())
}

pub fn update(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).update_args().is_some() });
    Ok(())
}

pub fn press(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).press_args().is_some() });
    Ok(())
}

pub fn release(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).release_args().is_some() });
    Ok(())
}

pub fn focus(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).focus_args().is_some() });
    Ok(())
}

pub fn focus_arg(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).focus_args() });
    Ok(())
}

pub fn update_dt(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).update_args().map(|args| args.dt) });
    Ok(())
}

pub fn press_keyboard_key(rt: &mut Runtime) -> Result<(), String> {
    let e = unsafe { &*Current::<Option<Event>>::new() };
    if let &Some(ref e) = e {
        if let Some(Button::Keyboard(key)) = e.press_args() {
            rt.push(Some(key as u64 as f64));
        } else {
            rt.push::<Option<f64>>(None);
        }
        Ok(())
    } else {
        Err(NO_EVENT.into())
    }
}

pub fn release_keyboard_key(rt: &mut Runtime) -> Result<(), String> {
    let e = unsafe { &*Current::<Option<Event>>::new() };
    if let &Some(ref e) = e {
        if let Some(Button::Keyboard(key)) = e.release_args() {
            rt.push(Some(key as u64 as f64));
        } else {
            rt.push::<Option<f64>>(None);
        }
        Ok(())
    } else {
        Err(NO_EVENT.into())
    }
}

pub fn set_title<W: Any + AdvancedWindow>(rt: &mut Runtime) -> Result<(), String> {
    use std::sync::Arc;

    let window = unsafe { &mut *Current::<W>::new() };
    let title: Arc<String> = try!(rt.pop());
    window.set_title((*title).clone());
    Ok(())
}

/// Helper method for drawing 2D in Dyon environment.
pub fn draw_2d<G: Graphics>(rt: &mut Runtime, c: Context, g: &mut G) -> Result<(), String> {
    use self::graphics::*;
    use self::graphics::types::Matrix2d;

    let draw_list = rt.stack.pop().expect("There is no value on the stack");
    let arr = rt.resolve(&draw_list);
    let mut transform = c.transform;
    if let &Variable::Array(ref arr) = arr {
        for it in &**arr {
            let it = rt.resolve(it);
            if let &Variable::Array(ref it) = it {
                let ty: Arc<String> = try!(rt.var(&it[0]));
                match &**ty {
                    "clear" => {
                        let color: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        clear(color, g);
                    }
                    "transform_rx_ry" => {
                        // Changes transform matrix.
                        let rx: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        let ry: [f32; 4] = try!(rt.var_vec4(&it[2]));
                        let t: Matrix2d = [
                            [rx[0] as f64, rx[1] as f64, rx[2] as f64],
                            [ry[0] as f64, ry[1] as f64, ry[2] as f64]
                        ];
                        transform = math::multiply(c.transform, t);
                    }
                    "line_color_radius_from_to" => {
                        let color: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        let radius: f64 = try!(rt.var(&it[2]));
                        let from: [f64; 2] = try!(rt.var_vec4(&it[3]));
                        let to: [f64; 2] = try!(rt.var_vec4(&it[4]));
                        line(color, radius, [from[0], from[1], to[0], to[1]], transform, g);
                    }
                    "rectangle_color_corner_size" => {
                        let color: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        let corner: [f64; 2] = try!(rt.var_vec4(&it[2]));
                        let size: [f64; 2] = try!(rt.var_vec4(&it[3]));
                        rectangle(color, [corner[0], corner[1], size[0], size[1]], transform, g);
                    }
                    "ellipse_color_corner_size_resolution" => {
                        let color: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        let corner: [f64; 2] = try!(rt.var_vec4(&it[2]));
                        let size: [f64; 2] = try!(rt.var_vec4(&it[3]));
                        let resolution: u32 = try!(rt.var(&it[4]));
                        Ellipse::new(color)
                        .resolution(resolution as u32)
                        .draw([corner[0], corner[1], size[0], size[1]], &c.draw_state, transform, g);
                    }
                    _ => {}
                }
            }
        }
    }
    return Ok(())
}
<commit_msg>Added "ellipse_border_color_corner_size_resolution"<commit_after>extern crate piston;
extern crate dyon;
extern crate current;
extern crate graphics;

use std::any::Any;
use std::sync::Arc;
use self::dyon::*;
use self::current::Current;
use self::piston::input::*;
use self::piston::window::*;
use self::graphics::{Context, Graphics};

pub const NO_EVENT: &'static str = "No event";

pub fn add_functions<W: Any + AdvancedWindow>(module: &mut Module) {
    module.add(Arc::new("window_size".into()), window_size::<W>, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Vec4
    });
    module.add(Arc::new("window_draw_size".into()), window_draw_size::<W>, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Vec4
    });
    module.add(Arc::new("render".into()), render, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool
    });
    module.add(Arc::new("update".into()), update, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool
    });
    module.add(Arc::new("press".into()), press, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool
    });
    module.add(Arc::new("release".into()), release, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool
    });
    module.add(Arc::new("focus".into()), focus, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Bool,
    });
    module.add(Arc::new("focus_arg".into()), focus_arg, PreludeFunction {
        lts: vec![],
        tys: vec![],
        ret: Type::Option(Box::new(Type::Bool)),
    });
    module.add(Arc::new("set_title".into()),
        set_title::<W>, PreludeFunction {
            lts: vec![Lt::Default],
            tys: vec![Type::Text],
            ret: Type::Void
        });
    module.add(Arc::new("update_dt".into()),
        update_dt, PreludeFunction {
            lts: vec![],
            tys: vec![],
            ret: Type::Option(Box::new(Type::F64))
        });
    module.add(Arc::new("press_keyboard_key".into()),
        press_keyboard_key, PreludeFunction {
            lts: vec![],
            tys: vec![],
            ret: Type::Option(Box::new(Type::F64))
        });
    module.add(Arc::new("release_keyboard_key".into()),
        release_keyboard_key, PreludeFunction {
            lts: vec![],
            tys: vec![],
            ret: Type::Option(Box::new(Type::F64))
        });
}

pub fn window_size<W: Any + Window>(rt: &mut Runtime) -> Result<(), String> {
    let size = unsafe { Current::<W>::new() }.size();
    rt.push_vec4([size.width as f32, size.height as f32, 0.0, 0.0]);
    Ok(())
}

pub fn window_draw_size<W: Any + Window>(rt: &mut Runtime) -> Result<(), String> {
    let draw_size = unsafe { Current::<W>::new() }.draw_size();
    rt.push_vec4([draw_size.width as f32, draw_size.height as f32, 0.0, 0.0]);
    Ok(())
}

pub fn render(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).render_args().is_some() });
    Ok(())
}

pub fn update(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).update_args().is_some() });
    Ok(())
}

pub fn press(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).press_args().is_some() });
    Ok(())
}

pub fn release(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).release_args().is_some() });
    Ok(())
}

pub fn focus(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).focus_args().is_some() });
    Ok(())
}

pub fn focus_arg(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).focus_args() });
    Ok(())
}

pub fn update_dt(rt: &mut Runtime) -> Result<(), String> {
    rt.push(unsafe { Current::<Option<Event>>::new()
        .as_ref().expect(NO_EVENT).update_args().map(|args| args.dt) });
    Ok(())
}

pub fn press_keyboard_key(rt: &mut Runtime) -> Result<(), String> {
    let e = unsafe { &*Current::<Option<Event>>::new() };
    if let &Some(ref e) = e {
        if let Some(Button::Keyboard(key)) = e.press_args() {
            rt.push(Some(key as u64 as f64));
        } else {
            rt.push::<Option<f64>>(None);
        }
        Ok(())
    } else {
        Err(NO_EVENT.into())
    }
}

pub fn release_keyboard_key(rt: &mut Runtime) -> Result<(), String> {
    let e = unsafe { &*Current::<Option<Event>>::new() };
    if let &Some(ref e) = e {
        if let Some(Button::Keyboard(key)) = e.release_args() {
            rt.push(Some(key as u64 as f64));
        } else {
            rt.push::<Option<f64>>(None);
        }
        Ok(())
    } else {
        Err(NO_EVENT.into())
    }
}

pub fn set_title<W: Any + AdvancedWindow>(rt: &mut Runtime) -> Result<(), String> {
    use std::sync::Arc;

    let window = unsafe { &mut *Current::<W>::new() };
    let title: Arc<String> = try!(rt.pop());
    window.set_title((*title).clone());
    Ok(())
}

/// Helper method for drawing 2D in Dyon environment.
pub fn draw_2d<G: Graphics>(rt: &mut Runtime, c: Context, g: &mut G) -> Result<(), String> {
    use self::graphics::*;
    use self::graphics::types::Matrix2d;

    let draw_list = rt.stack.pop().expect("There is no value on the stack");
    let arr = rt.resolve(&draw_list);
    let mut transform = c.transform;
    if let &Variable::Array(ref arr) = arr {
        for it in &**arr {
            let it = rt.resolve(it);
            if let &Variable::Array(ref it) = it {
                let ty: Arc<String> = try!(rt.var(&it[0]));
                match &**ty {
                    "clear" => {
                        let color: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        clear(color, g);
                    }
                    "transform_rx_ry" => {
                        // Changes transform matrix.
                        let rx: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        let ry: [f32; 4] = try!(rt.var_vec4(&it[2]));
                        let t: Matrix2d = [
                            [rx[0] as f64, rx[1] as f64, rx[2] as f64],
                            [ry[0] as f64, ry[1] as f64, ry[2] as f64]
                        ];
                        transform = math::multiply(c.transform, t);
                    }
                    "line_color_radius_from_to" => {
                        let color: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        let radius: f64 = try!(rt.var(&it[2]));
                        let from: [f64; 2] = try!(rt.var_vec4(&it[3]));
                        let to: [f64; 2] = try!(rt.var_vec4(&it[4]));
                        line(color, radius, [from[0], from[1], to[0], to[1]], transform, g);
                    }
                    "rectangle_color_corner_size" => {
                        let color: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        let corner: [f64; 2] = try!(rt.var_vec4(&it[2]));
                        let size: [f64; 2] = try!(rt.var_vec4(&it[3]));
                        rectangle(color, [corner[0], corner[1], size[0], size[1]], transform, g);
                    }
                    "ellipse_color_corner_size_resolution" => {
                        let color: [f32; 4] = try!(rt.var_vec4(&it[1]));
                        let corner: [f64; 2] = try!(rt.var_vec4(&it[2]));
                        let size: [f64; 2] = try!(rt.var_vec4(&it[3]));
                        let resolution: u32 = try!(rt.var(&it[4]));
                        Ellipse::new(color)
                        .resolution(resolution as u32)
                        .draw([corner[0], corner[1], size[0], size[1]], &c.draw_state, transform, g);
                    }
                    "ellipse_border_color_corner_size_resolution" => {
                        let border: f64 = try!(rt.var(&it[1]));
                        let color: [f32; 4] = try!(rt.var_vec4(&it[2]));
                        let corner: [f64; 2] = try!(rt.var_vec4(&it[3]));
                        let size: [f64; 2] = try!(rt.var_vec4(&it[4]));
                        let resolution: u32 = try!(rt.var(&it[5]));
                        Ellipse::new_border(color, border)
                        .resolution(resolution as u32)
                        .draw([corner[0], corner[1], size[0], size[1]], &c.draw_state, transform, g);
                    }
                    _ => {}
                }
            }
        }
    }
    return Ok(())
}
<|endoftext|>


<commit_before>#![feature(old_path, old_io, env, core)]

extern crate "pkg-config" as pkg_config;

use std::env;
use std::old_io::{self, fs, Command};
use std::old_io::process::InheritFd;

fn main() {
    register_dep("SSH2");
    register_dep("OPENSSL");

    match pkg_config::Config::new().atleast_version("0.22.0").find("libgit2") {
        Ok(_) => return,
        Err(..) => {}
    }

    let mut cflags = env::var("CFLAGS").unwrap_or(String::new());
    let target = env::var("TARGET").unwrap();
    let mingw = target.contains("windows-gnu");
    cflags.push_str(" -ffunction-sections -fdata-sections");

    if target.contains("i686") {
        cflags.push_str(" -m32");
    } else if target.as_slice().contains("x86_64") {
        cflags.push_str(" -m64");
    }
    if !target.contains("i686") {
        cflags.push_str(" -fPIC");
    }

    let src = Path::new(env::var("CARGO_MANIFEST_DIR").unwrap());
    let dst = Path::new(env::var("OUT_DIR").unwrap());
    let _ = fs::mkdir(&dst.join("build"), old_io::USER_DIR);

    let mut cmd = Command::new("cmake");
    cmd.arg(src.join("libgit2"))
       .cwd(&dst.join("build"));
    if mingw {
        cmd.arg("-G").arg("Unix Makefiles");
    }
    let profile = match env::var("PROFILE").unwrap().as_slice() {
        "bench" | "release" => "Release",
        _ => "Debug",
    };
    run(cmd.arg("-DTHREADSAFE=ON")
           .arg("-DBUILD_SHARED_LIBS=OFF")
           .arg("-DBUILD_CLAR=OFF")
           .arg(format!("-DCMAKE_BUILD_TYPE={}", profile))
           .arg(format!("-DCMAKE_INSTALL_PREFIX={}", dst.display()))
           .arg("-DBUILD_EXAMPLES=OFF")
           .arg(format!("-DCMAKE_C_FLAGS={}", cflags)), "cmake");
    run(Command::new("cmake")
                .arg("--build").arg(".")
                .arg("--target").arg("install")
                .cwd(&dst.join("build")), "cmake");

    println!("cargo:root={}", dst.display());
    if mingw || target.contains("windows") {
        println!("cargo:rustc-flags=-l winhttp -l rpcrt4 -l ole32 \
                                    -l ws2_32 -l bcrypt -l crypt32 \
                                    -l git2:static -L {}",
                 dst.join("lib").display());
        return
    }

    if env::var("HOST") == env::var("TARGET") {
        append("PKG_CONFIG_PATH", dst.join("lib/pkgconfig"));
        if pkg_config::Config::new().statik(true).find("libgit2").is_ok() {
            return
        }
    }

    println!("cargo:rustc-flags=-l git2:static");
    println!("cargo:rustc-flags=-L {}", dst.join("lib").display());
    if target.contains("apple") {
        println!("cargo:rustc-flags:-l iconv");
    }
}

fn run(cmd: &mut Command, program: &str) {
    println!("running: {:?}", cmd);
    let status = match cmd.stdout(InheritFd(1)).stderr(InheritFd(2)).status() {
        Ok(status) => status,
        Err(ref e) if e.kind == old_io::FileNotFound => {
            fail(&format!("failed to execute command: {}\nis `{}` not installed?",
                          e, program));
        }
        Err(e) => fail(&format!("failed to execute command: {}", e)),
    };
    if !status.success() {
        fail(&format!("command did not execute successfully, got: {}", status));
    }
}

fn register_dep(dep: &str) {
    match env::var(format!("DEP_{}_ROOT", dep).as_slice()) {
        Ok(s) => {
            append("CMAKE_PREFIX_PATH", Path::new(s.as_slice()));
            append("PKG_CONFIG_PATH", Path::new(s.as_slice()).join("lib/pkgconfig"));
        }
        Err(..) => {}
    }
}

fn append(var: &str, val: Path) {
    let prefix = env::var(var).unwrap_or(String::new());
    let val = env::join_paths(env::split_paths(&prefix)
                                  .chain(Some(val).into_iter())).unwrap();
    env::set_var(var, &val);
}

fn fail(s: &str) -> ! {
    println!("{}", s);
    env::set_exit_status(1);
    old_io::stdio::set_stderr(Box::new(old_io::util::NullWriter));
    panic!()
}
<commit_msg>fix osx libgit2-sys rustc flags<commit_after>#![feature(old_path, old_io, env, core)]

extern crate "pkg-config" as pkg_config;

use std::env;
use std::old_io::{self, fs, Command};
use std::old_io::process::InheritFd;

fn main() {
    register_dep("SSH2");
    register_dep("OPENSSL");

    match pkg_config::Config::new().atleast_version("0.22.0").find("libgit2") {
        Ok(_) => return,
        Err(..) => {}
    }

    let mut cflags = env::var("CFLAGS").unwrap_or(String::new());
    let target = env::var("TARGET").unwrap();
    let mingw = target.contains("windows-gnu");
    cflags.push_str(" -ffunction-sections -fdata-sections");

    if target.contains("i686") {
        cflags.push_str(" -m32");
    } else if target.as_slice().contains("x86_64") {
        cflags.push_str(" -m64");
    }
    if !target.contains("i686") {
        cflags.push_str(" -fPIC");
    }

    let src = Path::new(env::var("CARGO_MANIFEST_DIR").unwrap());
    let dst = Path::new(env::var("OUT_DIR").unwrap());
    let _ = fs::mkdir(&dst.join("build"), old_io::USER_DIR);

    let mut cmd = Command::new("cmake");
    cmd.arg(src.join("libgit2"))
       .cwd(&dst.join("build"));
    if mingw {
        cmd.arg("-G").arg("Unix Makefiles");
    }
    let profile = match env::var("PROFILE").unwrap().as_slice() {
        "bench" | "release" => "Release",
        _ => "Debug",
    };
    run(cmd.arg("-DTHREADSAFE=ON")
           .arg("-DBUILD_SHARED_LIBS=OFF")
           .arg("-DBUILD_CLAR=OFF")
           .arg(format!("-DCMAKE_BUILD_TYPE={}", profile))
           .arg(format!("-DCMAKE_INSTALL_PREFIX={}", dst.display()))
           .arg("-DBUILD_EXAMPLES=OFF")
           .arg(format!("-DCMAKE_C_FLAGS={}", cflags)), "cmake");
    run(Command::new("cmake")
                .arg("--build").arg(".")
                .arg("--target").arg("install")
                .cwd(&dst.join("build")), "cmake");

    println!("cargo:root={}", dst.display());
    if mingw || target.contains("windows") {
        println!("cargo:rustc-flags=-l winhttp -l rpcrt4 -l ole32 \
                                    -l ws2_32 -l bcrypt -l crypt32 \
                                    -l git2:static -L {}",
                 dst.join("lib").display());
        return
    }

    if env::var("HOST") == env::var("TARGET") {
        append("PKG_CONFIG_PATH", dst.join("lib/pkgconfig"));
        if pkg_config::Config::new().statik(true).find("libgit2").is_ok() {
            return
        }
    }

    println!("cargo:rustc-flags=-l git2:static");
    println!("cargo:rustc-flags=-L {}", dst.join("lib").display());
    if target.contains("apple") {
        println!("cargo:rustc-flags=-l iconv");
    }
}

fn run(cmd: &mut Command, program: &str) {
    println!("running: {:?}", cmd);
    let status = match cmd.stdout(InheritFd(1)).stderr(InheritFd(2)).status() {
        Ok(status) => status,
        Err(ref e) if e.kind == old_io::FileNotFound => {
            fail(&format!("failed to execute command: {}\nis `{}` not installed?",
                          e, program));
        }
        Err(e) => fail(&format!("failed to execute command: {}", e)),
    };
    if !status.success() {
        fail(&format!("command did not execute successfully, got: {}", status));
    }
}

fn register_dep(dep: &str) {
    match env::var(format!("DEP_{}_ROOT", dep).as_slice()) {
        Ok(s) => {
            append("CMAKE_PREFIX_PATH", Path::new(s.as_slice()));
            append("PKG_CONFIG_PATH", Path::new(s.as_slice()).join("lib/pkgconfig"));
        }
        Err(..) => {}
    }
}

fn append(var: &str, val: Path) {
    let prefix = env::var(var).unwrap_or(String::new());
    let val = env::join_paths(env::split_paths(&prefix)
                                  .chain(Some(val).into_iter())).unwrap();
    env::set_var(var, &val);
}

fn fail(s: &str) -> ! {
    println!("{}", s);
    env::set_exit_status(1);
    old_io::stdio::set_stderr(Box::new(old_io::util::NullWriter));
    panic!()
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Ben Ashford
 *
 * 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.
 */

//! Implementation of ElasticSearch Mapping operation

use std::collections::HashMap;

use ::Client;
use ::error::EsError;

pub type Properties<'a> = HashMap<&'a str, HashMap<&'a str, &'a str>>;

/// An indexing operation
pub struct MappingOperation<'a, 'b> {
    /// The HTTP client that this operation will use
    client:     &'a mut Client,

    /// The index that will be created and eventually mapped
    index:      &'b str,

    /// The type that will be mapped
    doc_type:   &'b str,

    /// The actual mapping
    properties: &'b Properties<'b>
}

impl<'a, 'b> MappingOperation<'a, 'b> {
    pub fn new(client: &'a mut Client, index: &'b str, doc_type: &'b str, properties: &'b Properties) -> MappingOperation<'a, 'b> {
        MappingOperation {
            client:     client,
            index:      index,
            doc_type:   doc_type,
            properties: properties
        }
    }

    pub fn send(&'b mut self) -> Result<MappingResult, EsError> {
        let body = hashmap! {
            "mappings" => hashmap! {
                self.doc_type => hashmap! {
                    "properties" => self.properties
                }
            }
        };

        let url = format!("{}", self.index);
        let (_, _) = try!(self.client.put_body_op(&url, &body));
        Ok(MappingResult)
    }
}

/// The result of a mapping operation
#[derive(Debug)]
pub struct MappingResult;

#[cfg(test)]
pub mod tests {
    extern crate env_logger;

    use std::collections::HashMap;

    use super::MappingOperation;

    #[test]
    fn test_mapping() {
        let index_name = "tests_test_mapping";
        let mut client = ::tests::make_client();

        client.delete_op(&format!("/{}", index_name)).unwrap();

        let mapping = hashmap! {
            "created_at" => hashmap! {
                "type" => "date",
                "format" => "strict_date_optional_time"
            },

            "title" => hashmap! {
                "type" => "string",
                "index" => "not_analyzed"
            }
        };

        let result = MappingOperation::new(&mut client, index_name, "sample", &mapping).send();
        assert!(result.is_ok());
    }
}
<commit_msg>Refactor mapping structure and make tests pass in ES 1.7<commit_after>/*
 * Copyright 2016 Ben Ashford
 *
 * 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.
 */

//! Implementation of ElasticSearch Mapping operation

use std::collections::HashMap;

use ::Client;
use ::error::EsError;

pub type DocType<'a>    = HashMap<&'a str, HashMap<&'a str, &'a str>>;
pub type DocTypes<'a>   = HashMap<&'a str, DocType<'a>>;
pub type Mapping<'a>    = HashMap<&'a str, DocTypes<'a>>;

/// An indexing operation
pub struct MappingOperation<'a, 'b> {
    /// The HTTP client that this operation will use
    client:    &'a mut Client,

    /// The index that will be created and eventually mapped
    index:     &'b str,

    /// A map containing the doc types and their type mapping
    doc_types: &'b DocTypes<'b>
}

impl<'a, 'b> MappingOperation<'a, 'b> {
    pub fn new(client: &'a mut Client, index: &'b str, doc_types: &'b DocTypes) -> MappingOperation<'a, 'b> {
        MappingOperation {
            client:    client,
            index:     index,
            doc_types: doc_types
        }
    }

    pub fn send(&'b mut self) -> Result<MappingResult, EsError> {
        let mut mappings: Mapping = HashMap::new();
        for (type_name, mapping) in self.doc_types.into_iter() {
            let doc_type = hashmap! { "properties" => mapping.clone() };
            mappings.insert(type_name, doc_type.to_owned());
        }

        let url    = format!("{}", self.index);
        let (_, _) = try!(self.client.put_body_op(&url, &mappings));
        Ok(MappingResult)
    }
}

/// The result of a mapping operation
#[derive(Debug)]
pub struct MappingResult;

#[cfg(test)]
pub mod tests {
    extern crate env_logger;

    use std::collections::HashMap;

    use super::MappingOperation;

    #[test]
    fn test_mapping() {
        let index_name = "tests_test_mapping";
        let mut client = ::tests::make_client();

        client.delete_op(&format!("/{}", index_name)).unwrap();

        let mapping = hashmap! { // DocTypes
            "post" => hashmap! { // DocType
                "created_at" => hashmap! {
                    "type" => "date",
                    "format" => "date_time"
                },

                "title" => hashmap! {
                    "type" => "string",
                    "index" => "not_analyzed"
                }
            },

            "author" => hashmap! { // DocType
                "name" => hashmap! {
                    "type" => "string",
                }
            },
        };

        let result = MappingOperation::new(&mut client, index_name, &mapping).send();
        assert!(result.is_ok());
    }
}
<|endoftext|>


<commit_before>
use std::fmt;

use parser::ast;
use parser::ast::{AstKind, AstNode};
use parser::input_stream::{InputStream, StreamPosition};
use parser::precedence::Precedence;
use parser::token_kind::TokenKind;
use parser::tokenizer::{Token, TokenError, TokenLocation, Tokenizer, TokenizerMode,
                        TokenizerPosition};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FullToken {
    kind: TokenKind,
    location: TokenLocation
}
impl FullToken {
    pub fn new(kind: TokenKind, location: TokenLocation) -> FullToken {
        FullToken { kind, location }
    }

    pub fn location(&self) -> &TokenLocation {
        &self.location
    }
}
impl Token for FullToken {
    fn make(kind: TokenKind, location: TokenLocation) -> FullToken {
        FullToken::new(kind, location)
    }
    fn kind(&self) -> TokenKind {
        self.kind
    }
    fn start_offset(&self) -> StreamPosition {
        self.location.start_offset()
    }
    fn write_token(&self, w: &mut fmt::Write) -> Result<(), fmt::Error> {
        write!(w, "Token({}@{})", self.kind.name(), self.location.range_string())
    }
}

pub struct FullTokenizerMode {
}
impl TokenizerMode for FullTokenizerMode {
    type Tok = FullToken;

    fn cares_about_newline(&self) -> bool {
        false
    }
    fn note_newline(&mut self) {}
}

#[derive(Debug, Clone)]
pub enum ParseError {
    Unspecified,
    ErrorToken(FullToken),
    TokenizerError(TokenError),
    UnexpectedToken{expected:TokenKind, got:TokenKind},
    ExpectedVariableName,
    ExpectedCommaOrSemicolon,
    ExpectedExpression
}
pub type ParseResult<T> = Result<T, ParseError>;
pub type MaybeParseResult<T> = ParseResult<Option<T>>;

pub struct AstBuilder<STREAM: InputStream> {
    tokenizer: Tokenizer<STREAM, FullTokenizerMode>
}
impl<STREAM: InputStream> AstBuilder<STREAM> {
    pub fn new(stream: STREAM) -> AstBuilder<STREAM> {
        AstBuilder {
            tokenizer: Tokenizer::new(stream, FullTokenizerMode{})
        }
    }

    pub fn read_and_print_tokens(&mut self) {
        // Just read tokens and print them out until we're done, then return Error.
        loop {
            let token = self.next_token().unwrap();
            println!("Token: {}", token.kind().name());
            if token.kind().is_error() {
                panic!("Got token error: {:?}", self.tokenizer.get_error());
            }
            if token.kind().is_end() {
                break;
            }
        }
    }

    pub fn parse_program(&mut self) -> ParseResult<Box<ast::ProgramNode>> {
        let mut program_node = ast::ProgramNode::new();
        loop {
            match self.try_parse_statement()? {
                Some(boxed_source_element) => {
                    program_node.add_source_element(boxed_source_element);
                }
                None => {
                    break;
                }
            }
        }

        // Must have reached end of stream.
        self.must_expect_token(TokenKind::end())?;

        Ok(Box::new(program_node))
    }

    fn try_parse_statement(&mut self) -> MaybeParseResult<Box<AstNode>> {
        let begin_position = self.mark_position();
        let tok = self.next_token()?;
        if tok.kind().is_open_brace() {
            // FIXME: parse either a block or an object literal.
            // The spec says a '{' at the statement level can only be a block,
            // but practical implementations seem to allow bare object literals.
            return Ok(Some(self.parse_block_statement()?));
        }
        if tok.kind().is_var_keyword() {
            return Ok(Some(self.parse_var_statement()?));
        }
        if tok.kind().is_semicolon() {
            return Ok(Some(Box::new(ast::EmptyStmtNode::new())));
        }
        if tok.kind().is_if_keyword() {
            return Ok(Some(self.parse_if_statement()?));
        }

        if let Some(boxed_expr) = self.try_parse_expression(tok, Precedence::lowest())? {
            return Ok(Some(Box::new(ast::ExprStmtNode::new(boxed_expr))));
        }

        self.rewind_position(begin_position);
        Ok(None)
    }

    fn parse_block_statement(&mut self) -> ParseResult<Box<ast::BlockStmtNode>> {
        // FIXME: Parse list of statements.
        self.must_expect_token(TokenKind::close_brace())?;
        Ok(Box::new(ast::BlockStmtNode::new()))
    }

    fn parse_var_statement(&mut self) -> ParseResult<Box<ast::VarStmtNode>> {
        let mut var_statement = Box::new(ast::VarStmtNode::new());
        loop {
            // FIXME: Support initializer expressions.
            // For now, we match only a VarName ("," VarName)* ";"
            let name_token = match self.expect_get_token(TokenKind::identifier())? {
                Some(token) => token,
                None => { return Err(ParseError::ExpectedVariableName); }
            };
            var_statement.add_variable(name_token);

            let next_tok = self.next_token()?;
            if next_tok.kind().is_semicolon() {
                break;
            }
            if next_tok.kind().is_comma() {
                continue;
            }
            return Err(ParseError::ExpectedCommaOrSemicolon);
        }
        Ok(var_statement)
    }

    fn parse_if_statement(&mut self) -> ParseResult<Box<AstNode>> {
        // FIXME: implement this after expression parsing is supported.
        panic!("parse_if_statement is not implemented.")
    }

    fn parse_expression(&mut self, precedence: Precedence) -> ParseResult<Box<AstNode>> {
        let token = self.next_token()?;
        if let Some(boxed_expr) = self.try_parse_expression(token, precedence)? {
            return Ok(boxed_expr);
        }

        Err(ParseError::ExpectedExpression)
    }

    fn try_parse_expression(&mut self, tok: FullToken, precedence: Precedence)
        -> MaybeParseResult<Box<AstNode>>
    {
        if tok.kind().is_identifier() {
            let name_expr = Box::new(ast::NameExprNode::new(tok));
            return Ok(Some(self.parse_rest_of_expression(name_expr, precedence)?));
        }
        Ok(None)
    }

    fn parse_rest_of_expression(&mut self, left_expr: Box<AstNode>, precedence: Precedence)
        -> ParseResult<Box<AstNode>>
    {
        assert!(left_expr.is_expression());

        let mut cur_expr = left_expr;
        loop {
            let position = self.mark_position();
            let tok = self.next_token()?;
            if tok.kind().is_comma() {
                if precedence >= Precedence::comma() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::comma())?;
                cur_expr = Box::new(ast::CommaExprNode::new(cur_expr, right_expr));
                continue;
            }

            if tok.kind().is_assignment_op() {
                // FIXME: Check that cur_expr is a valid lvalue expression.
                // Return syntax error if not.

                // Assignment associates right-to-left, so we use '>' for precedence
                // instead of '>='.
                if precedence > Precedence::assignment() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::assignment())?;
                cur_expr = Box::new(ast::AssignExprNode::new(tok, cur_expr, right_expr));
                continue;
            }

            if tok.kind().is_question() {
                if precedence > Precedence::conditional() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let if_expr = self.parse_expression(Precedence::assignment())?;
                self.must_expect_token(TokenKind::colon())?;
                let else_expr = self.parse_expression(Precedence::assignment())?;
                cur_expr = Box::new(ast::CondExprNode::new(cur_expr, if_expr, else_expr));
                continue;
            }

            if tok.kind().is_logical_or() {
                if precedence >= Precedence::logical_or() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::logical_or())?;
                cur_expr = Box::new(ast::BinaryOpExprNode::new(tok, cur_expr, right_expr));
                continue;
            }

            if tok.kind().is_logical_and() {
                if precedence >= Precedence::logical_and() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::logical_and())?;
                cur_expr = Box::new(ast::BinaryOpExprNode::new(tok, cur_expr, right_expr));
                continue;
            }

            // Unknown token terminates expression.
            self.rewind_position(position);
            break;
        }

        Ok(cur_expr)
    }

    fn must_expect_token(&mut self, kind: TokenKind) -> ParseResult<()> {
        // Mark the position so we can backtrack.
        let position = self.mark_position();
        let token = self.next_token()?;
        if token.kind() == kind {
            Ok(())
        } else {
            self.rewind_position(position);
            Err(ParseError::UnexpectedToken {expected: kind, got: token.kind()})
        }
    }

    fn expect_token(&mut self, kind: TokenKind) -> ParseResult<bool> {
        // Mark the position so we can backtrack.
        let position = self.mark_position();
        let token = self.next_token()?;
        if token.kind() == kind {
            Ok(true)
        } else {
            self.rewind_position(position);
            Ok(false)
        }
    }
    fn expect_get_token(&mut self, kind: TokenKind) -> ParseResult<Option<FullToken>> {
        // Mark the position so we can backtrack.
        let position = self.mark_position();
        let token = self.next_token()?;
        if token.kind() == kind {
            Ok(Some(token))
        } else {
            self.rewind_position(position);
            Ok(None)
        }
    }

    fn mark_position(&mut self) -> TokenizerPosition {
        self.tokenizer.mark_position()
    }
    fn rewind_position(&mut self, position: TokenizerPosition) {
        self.tokenizer.rewind_position(position)
    }

    fn next_token(&mut self) -> ParseResult<FullToken> {
        self.next_token_impl(/* check_kw = */ true, /* want_newlines = */ false)
    }
    fn next_token_no_keywords(&mut self) -> ParseResult<FullToken> {
        self.next_token_impl(/* check_kw = */ true, /* want_newlines = */ false)
    }

    fn next_token_impl(&mut self, check_kw: bool, want_newlines: bool) -> ParseResult<FullToken> {
        loop {
            let token = self.tokenizer.next_token(/* check_kw = */ true);
            let kind = token.kind();
            // Ignore whitespace and comment and newline tokens.
            if kind.is_whitespace() || kind.is_comment() {
                continue;
            }
            if !want_newlines && kind.is_newline() {
                continue;
            }
            if kind.is_error() {
                return Err(ParseError::ErrorToken(token));
            }
            let kw_str = if check_kw { "kw" } else { "no-kw" };
            let nl_str = if want_newlines { "nl" } else { "no-nl" };
            println!("next_token({}, {}): {}", kw_str, nl_str, token.token_string());
            return Ok(token);
        }
    }
}
<commit_msg>Parse support for bit_or, bit_xor, and bit_and expressions.<commit_after>
use std::fmt;

use parser::ast;
use parser::ast::{AstKind, AstNode};
use parser::input_stream::{InputStream, StreamPosition};
use parser::precedence::Precedence;
use parser::token_kind::TokenKind;
use parser::tokenizer::{Token, TokenError, TokenLocation, Tokenizer, TokenizerMode,
                        TokenizerPosition};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FullToken {
    kind: TokenKind,
    location: TokenLocation
}
impl FullToken {
    pub fn new(kind: TokenKind, location: TokenLocation) -> FullToken {
        FullToken { kind, location }
    }

    pub fn location(&self) -> &TokenLocation {
        &self.location
    }
}
impl Token for FullToken {
    fn make(kind: TokenKind, location: TokenLocation) -> FullToken {
        FullToken::new(kind, location)
    }
    fn kind(&self) -> TokenKind {
        self.kind
    }
    fn start_offset(&self) -> StreamPosition {
        self.location.start_offset()
    }
    fn write_token(&self, w: &mut fmt::Write) -> Result<(), fmt::Error> {
        write!(w, "Token({}@{})", self.kind.name(), self.location.range_string())
    }
}

pub struct FullTokenizerMode {
}
impl TokenizerMode for FullTokenizerMode {
    type Tok = FullToken;

    fn cares_about_newline(&self) -> bool {
        false
    }
    fn note_newline(&mut self) {}
}

#[derive(Debug, Clone)]
pub enum ParseError {
    Unspecified,
    ErrorToken(FullToken),
    TokenizerError(TokenError),
    UnexpectedToken{expected:TokenKind, got:TokenKind},
    ExpectedVariableName,
    ExpectedCommaOrSemicolon,
    ExpectedExpression
}
pub type ParseResult<T> = Result<T, ParseError>;
pub type MaybeParseResult<T> = ParseResult<Option<T>>;

pub struct AstBuilder<STREAM: InputStream> {
    tokenizer: Tokenizer<STREAM, FullTokenizerMode>
}
impl<STREAM: InputStream> AstBuilder<STREAM> {
    pub fn new(stream: STREAM) -> AstBuilder<STREAM> {
        AstBuilder {
            tokenizer: Tokenizer::new(stream, FullTokenizerMode{})
        }
    }

    pub fn read_and_print_tokens(&mut self) {
        // Just read tokens and print them out until we're done, then return Error.
        loop {
            let token = self.next_token().unwrap();
            println!("Token: {}", token.kind().name());
            if token.kind().is_error() {
                panic!("Got token error: {:?}", self.tokenizer.get_error());
            }
            if token.kind().is_end() {
                break;
            }
        }
    }

    pub fn parse_program(&mut self) -> ParseResult<Box<ast::ProgramNode>> {
        let mut program_node = ast::ProgramNode::new();
        loop {
            match self.try_parse_statement()? {
                Some(boxed_source_element) => {
                    program_node.add_source_element(boxed_source_element);
                }
                None => {
                    break;
                }
            }
        }

        // Must have reached end of stream.
        self.must_expect_token(TokenKind::end())?;

        Ok(Box::new(program_node))
    }

    fn try_parse_statement(&mut self) -> MaybeParseResult<Box<AstNode>> {
        let begin_position = self.mark_position();
        let tok = self.next_token()?;
        if tok.kind().is_open_brace() {
            // FIXME: parse either a block or an object literal.
            // The spec says a '{' at the statement level can only be a block,
            // but practical implementations seem to allow bare object literals.
            return Ok(Some(self.parse_block_statement()?));
        }
        if tok.kind().is_var_keyword() {
            return Ok(Some(self.parse_var_statement()?));
        }
        if tok.kind().is_semicolon() {
            return Ok(Some(Box::new(ast::EmptyStmtNode::new())));
        }
        if tok.kind().is_if_keyword() {
            return Ok(Some(self.parse_if_statement()?));
        }

        if let Some(boxed_expr) = self.try_parse_expression(tok, Precedence::lowest())? {
            return Ok(Some(Box::new(ast::ExprStmtNode::new(boxed_expr))));
        }

        self.rewind_position(begin_position);
        Ok(None)
    }

    fn parse_block_statement(&mut self) -> ParseResult<Box<ast::BlockStmtNode>> {
        // FIXME: Parse list of statements.
        self.must_expect_token(TokenKind::close_brace())?;
        Ok(Box::new(ast::BlockStmtNode::new()))
    }

    fn parse_var_statement(&mut self) -> ParseResult<Box<ast::VarStmtNode>> {
        let mut var_statement = Box::new(ast::VarStmtNode::new());
        loop {
            // FIXME: Support initializer expressions.
            // For now, we match only a VarName ("," VarName)* ";"
            let name_token = match self.expect_get_token(TokenKind::identifier())? {
                Some(token) => token,
                None => { return Err(ParseError::ExpectedVariableName); }
            };
            var_statement.add_variable(name_token);

            let next_tok = self.next_token()?;
            if next_tok.kind().is_semicolon() {
                break;
            }
            if next_tok.kind().is_comma() {
                continue;
            }
            return Err(ParseError::ExpectedCommaOrSemicolon);
        }
        Ok(var_statement)
    }

    fn parse_if_statement(&mut self) -> ParseResult<Box<AstNode>> {
        // FIXME: implement this after expression parsing is supported.
        panic!("parse_if_statement is not implemented.")
    }

    fn parse_expression(&mut self, precedence: Precedence) -> ParseResult<Box<AstNode>> {
        let token = self.next_token()?;
        if let Some(boxed_expr) = self.try_parse_expression(token, precedence)? {
            return Ok(boxed_expr);
        }

        Err(ParseError::ExpectedExpression)
    }

    fn try_parse_expression(&mut self, tok: FullToken, precedence: Precedence)
        -> MaybeParseResult<Box<AstNode>>
    {
        if tok.kind().is_identifier() {
            let name_expr = Box::new(ast::NameExprNode::new(tok));
            return Ok(Some(self.parse_rest_of_expression(name_expr, precedence)?));
        }
        Ok(None)
    }

    fn parse_rest_of_expression(&mut self, left_expr: Box<AstNode>, precedence: Precedence)
        -> ParseResult<Box<AstNode>>
    {
        assert!(left_expr.is_expression());

        let mut cur_expr = left_expr;
        loop {
            let position = self.mark_position();
            let tok = self.next_token()?;
            if tok.kind().is_comma() {
                if precedence >= Precedence::comma() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::comma())?;
                cur_expr = Box::new(ast::CommaExprNode::new(cur_expr, right_expr));
                continue;
            }

            if tok.kind().is_assignment_op() {
                // FIXME: Check that cur_expr is a valid lvalue expression.
                // Return syntax error if not.

                // Assignment associates right-to-left, so we use '>' for precedence
                // instead of '>='.
                if precedence > Precedence::assignment() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::assignment())?;
                cur_expr = Box::new(ast::AssignExprNode::new(tok, cur_expr, right_expr));
                continue;
            }

            if tok.kind().is_question() {
                if precedence > Precedence::conditional() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let if_expr = self.parse_expression(Precedence::assignment())?;
                self.must_expect_token(TokenKind::colon())?;
                let else_expr = self.parse_expression(Precedence::assignment())?;
                cur_expr = Box::new(ast::CondExprNode::new(cur_expr, if_expr, else_expr));
                continue;
            }

            if tok.kind().is_logical_or() {
                if precedence >= Precedence::logical_or() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::logical_or())?;
                cur_expr = Box::new(ast::BinaryOpExprNode::new(tok, cur_expr, right_expr));
                continue;
            }

            if tok.kind().is_logical_and() {
                if precedence >= Precedence::logical_and() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::logical_and())?;
                cur_expr = Box::new(ast::BinaryOpExprNode::new(tok, cur_expr, right_expr));
                continue;
            }

            if tok.kind().is_bit_or() {
                if precedence >= Precedence::bitwise_or() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::bitwise_or())?;
                cur_expr = Box::new(ast::BinaryOpExprNode::new(tok, cur_expr, right_expr));
                continue;
            }

            if tok.kind().is_bit_xor() {
                if precedence >= Precedence::bitwise_xor() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::bitwise_xor())?;
                cur_expr = Box::new(ast::BinaryOpExprNode::new(tok, cur_expr, right_expr));
                continue;
            }

            if tok.kind().is_bit_and() {
                if precedence >= Precedence::bitwise_and() {
                    self.rewind_position(position);
                    return Ok(cur_expr);
                }

                let right_expr = self.parse_expression(Precedence::bitwise_and())?;
                cur_expr = Box::new(ast::BinaryOpExprNode::new(tok, cur_expr, right_expr));
                continue;
            }

            // Unknown token terminates expression.
            self.rewind_position(position);
            break;
        }

        Ok(cur_expr)
    }

    fn must_expect_token(&mut self, kind: TokenKind) -> ParseResult<()> {
        // Mark the position so we can backtrack.
        let position = self.mark_position();
        let token = self.next_token()?;
        if token.kind() == kind {
            Ok(())
        } else {
            self.rewind_position(position);
            Err(ParseError::UnexpectedToken {expected: kind, got: token.kind()})
        }
    }

    fn expect_token(&mut self, kind: TokenKind) -> ParseResult<bool> {
        // Mark the position so we can backtrack.
        let position = self.mark_position();
        let token = self.next_token()?;
        if token.kind() == kind {
            Ok(true)
        } else {
            self.rewind_position(position);
            Ok(false)
        }
    }
    fn expect_get_token(&mut self, kind: TokenKind) -> ParseResult<Option<FullToken>> {
        // Mark the position so we can backtrack.
        let position = self.mark_position();
        let token = self.next_token()?;
        if token.kind() == kind {
            Ok(Some(token))
        } else {
            self.rewind_position(position);
            Ok(None)
        }
    }

    fn mark_position(&mut self) -> TokenizerPosition {
        self.tokenizer.mark_position()
    }
    fn rewind_position(&mut self, position: TokenizerPosition) {
        self.tokenizer.rewind_position(position)
    }

    fn next_token(&mut self) -> ParseResult<FullToken> {
        self.next_token_impl(/* check_kw = */ true, /* want_newlines = */ false)
    }
    fn next_token_no_keywords(&mut self) -> ParseResult<FullToken> {
        self.next_token_impl(/* check_kw = */ true, /* want_newlines = */ false)
    }

    fn next_token_impl(&mut self, check_kw: bool, want_newlines: bool) -> ParseResult<FullToken> {
        loop {
            let token = self.tokenizer.next_token(/* check_kw = */ true);
            let kind = token.kind();
            // Ignore whitespace and comment and newline tokens.
            if kind.is_whitespace() || kind.is_comment() {
                continue;
            }
            if !want_newlines && kind.is_newline() {
                continue;
            }
            if kind.is_error() {
                return Err(ParseError::ErrorToken(token));
            }
            let kw_str = if check_kw { "kw" } else { "no-kw" };
            let nl_str = if want_newlines { "nl" } else { "no-nl" };
            println!("next_token({}, {}): {}", kw_str, nl_str, token.token_string());
            return Ok(token);
        }
    }
}
<|endoftext|>


<commit_before>use unicode_width::UnicodeWidthStr;

use widgets::{Block, Widget};
use buffer::Buffer;
use layout::Rect;
use style::Style;
use symbols::line;

/// A widget to display available tabs in a multiple panels context.
///
/// # Examples
///
/// ```
/// # extern crate tui;
/// # use tui::widgets::{Block, border, Tabs};
/// # use tui::style::{Style, Color};
/// # fn main() {
/// Tabs::default()
///     .block(Block::default().title("Tabs").borders(border::ALL))
///     .titles(&["Tab1", "Tab2", "Tab3", "Tab4"])
///     .style(Style::default().fg(Color::White))
///     .highlight_style(Style::default().fg(Color::Yellow));
/// # }
/// ```
pub struct Tabs<'a> {
    /// A block to wrap this widget in if necessary
    block: Option<Block<'a>>,
    /// One title for each tab
    titles: &'a [&'a str],
    /// The index of the selected tabs
    selected: usize,
    /// The style used to draw the text
    style: Style,
    /// The style used to display the selected item
    highlight_style: Style,
}

impl<'a> Default for Tabs<'a> {
    fn default() -> Tabs<'a> {
        Tabs {
            block: None,
            titles: &[],
            selected: 0,
            style: Default::default(),
            highlight_style: Default::default(),
        }
    }
}

impl<'a> Tabs<'a> {
    pub fn block(&mut self, block: Block<'a>) -> &mut Tabs<'a> {
        self.block = Some(block);
        self
    }

    pub fn titles(&mut self, titles: &'a [&'a str]) -> &mut Tabs<'a> {
        self.titles = titles;
        self
    }

    pub fn select(&mut self, selected: usize) -> &mut Tabs<'a> {
        self.selected = selected;
        self
    }

    pub fn style(&mut self, style: Style) -> &mut Tabs<'a> {
        self.style = style;
        self
    }

    pub fn highlight_style(&mut self, style: Style) -> &mut Tabs<'a> {
        self.highlight_style = style;
        self
    }
}

impl<'a> Widget for Tabs<'a> {
    fn draw(&mut self, area: &Rect, buf: &mut Buffer) {
        let tabs_area = match self.block {
            Some(ref mut b) => {
                b.draw(area, buf);
                b.inner(area)
            }
            None => *area,
        };

        if tabs_area.height < 1 {
            return;
        }

        self.background(&tabs_area, buf, self.style.bg);

        let mut x = tabs_area.left();
        for (title, style) in self.titles
            .iter()
            .enumerate()
            .map(|(i, t)| if i == self.selected {
                (t, &self.highlight_style)
            } else {
                (t, &self.style)
            }) {
            x += 1;
            if x > tabs_area.right() {
                break;
            } else {
                buf.set_string(x, tabs_area.top(), title, style);
                x += title.width() as u16 + 1;
                if x >= tabs_area.right() {
                    break;
                } else {
                    buf.get_mut(x, tabs_area.top())
                        .set_symbol(line::VERTICAL)
                        .set_fg(self.style.fg)
                        .set_bg(self.style.bg);
                    x += 1;
                }
            }
        }
    }
}
<commit_msg>[widgets][tabs] Use generic type for tabs titles<commit_after>use unicode_width::UnicodeWidthStr;

use widgets::{Block, Widget};
use buffer::Buffer;
use layout::Rect;
use style::Style;
use symbols::line;

/// A widget to display available tabs in a multiple panels context.
///
/// # Examples
///
/// ```
/// # extern crate tui;
/// # use tui::widgets::{Block, border, Tabs};
/// # use tui::style::{Style, Color};
/// # fn main() {
/// Tabs::default()
///     .block(Block::default().title("Tabs").borders(border::ALL))
///     .titles(&["Tab1", "Tab2", "Tab3", "Tab4"])
///     .style(Style::default().fg(Color::White))
///     .highlight_style(Style::default().fg(Color::Yellow));
/// # }
/// ```
pub struct Tabs<'a, T>
where
    T: AsRef<str> + 'a,
{
    /// A block to wrap this widget in if necessary
    block: Option<Block<'a>>,
    /// One title for each tab
    titles: &'a [T],
    /// The index of the selected tabs
    selected: usize,
    /// The style used to draw the text
    style: Style,
    /// The style used to display the selected item
    highlight_style: Style,
}

impl<'a, T> Default for Tabs<'a, T>
where
    T: AsRef<str>,
{
    fn default() -> Tabs<'a, T> {
        Tabs {
            block: None,
            titles: &[],
            selected: 0,
            style: Default::default(),
            highlight_style: Default::default(),
        }
    }
}

impl<'a, T> Tabs<'a, T>
where
    T: AsRef<str>,
{
    pub fn block(&mut self, block: Block<'a>) -> &mut Tabs<'a, T> {
        self.block = Some(block);
        self
    }

    pub fn titles(&mut self, titles: &'a [T]) -> &mut Tabs<'a, T> {
        self.titles = titles;
        self
    }

    pub fn select(&mut self, selected: usize) -> &mut Tabs<'a, T> {
        self.selected = selected;
        self
    }

    pub fn style(&mut self, style: Style) -> &mut Tabs<'a, T> {
        self.style = style;
        self
    }

    pub fn highlight_style(&mut self, style: Style) -> &mut Tabs<'a, T> {
        self.highlight_style = style;
        self
    }
}

impl<'a, T> Widget for Tabs<'a, T>
where
    T: AsRef<str>,
{
    fn draw(&mut self, area: &Rect, buf: &mut Buffer) {
        let tabs_area = match self.block {
            Some(ref mut b) => {
                b.draw(area, buf);
                b.inner(area)
            }
            None => *area,
        };

        if tabs_area.height < 1 {
            return;
        }

        self.background(&tabs_area, buf, self.style.bg);

        let mut x = tabs_area.left();
        for (title, style) in self.titles
            .iter()
            .enumerate()
            .map(|(i, t)| if i == self.selected {
                (t, &self.highlight_style)
            } else {
                (t, &self.style)
            }) {
            x += 1;
            if x > tabs_area.right() {
                break;
            } else {
                buf.set_string(x, tabs_area.top(), title.as_ref(), style);
                x += title.as_ref().width() as u16 + 1;
                if x >= tabs_area.right() {
                    break;
                } else {
                    buf.get_mut(x, tabs_area.top())
                        .set_symbol(line::VERTICAL)
                        .set_fg(self.style.fg)
                        .set_bg(self.style.bg);
                    x += 1;
                }
            }
        }
    }
}
<|endoftext|>