<commit_before>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#![feature(test)]

extern crate pest;
extern crate test;

use test::Bencher;

use pest::ParserState;

#[allow(dead_code, non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    test_rule
}

#[bench]
fn find(b: &mut Bencher) {
    b.iter(|| {
        let state: Box<ParserState<Rule>> = ParserState::new("aaaaaaaaab");
        state.skip_until("b").unwrap()
    });
}

#[bench]
fn repeated_skip(b: &mut Bencher) {
    b.iter(|| {
        let state: Box<ParserState<Rule>> = ParserState::new("aaaaaaaaab");
        state
            .sequence(|state| {
                state
                    .repeat(|state| {
                        state.sequence(|state| {
                            state
                                .lookahead(false, |state| state.match_string("b"))
                                .and_then(|state| state.skip(1))
                        })
                    })
                    .and_then(|state| state.match_string("b"))
            })
            .unwrap()
    });
}
<commit_msg>delete the pest benchmarks<commit_after><|endoftext|>


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

#![feature(thread_local)]

#![allow(missing_copy_implementations)]
#![allow(unstable)]

#[macro_use]
extern crate log;

extern crate compositing;
extern crate devtools;
extern crate net;
extern crate msg;
#[macro_use]
extern crate util;
extern crate script;
extern crate layout;
extern crate gfx;
extern crate libc;
extern crate url;

use compositing::CompositorEventListener;
use compositing::windowing::{WindowEvent, WindowMethods};

#[cfg(not(test))]
use compositing::{CompositorProxy, CompositorTask, Constellation};
#[cfg(not(test))]
use msg::constellation_msg::Msg as ConstellationMsg;
#[cfg(not(test))]
use msg::constellation_msg::ConstellationChan;
#[cfg(not(test))]
use script::dom::bindings::codegen::RegisterBindings;

#[cfg(not(test))]
use net::image_cache_task::ImageCacheTask;
#[cfg(not(test))]
use net::resource_task::new_resource_task;
#[cfg(not(test))]
use net::storage_task::{StorageTaskFactory, StorageTask};
#[cfg(not(test))]
use gfx::font_cache_task::FontCacheTask;
#[cfg(not(test))]
use util::time::TimeProfiler;
#[cfg(not(test))]
use util::memory::MemoryProfiler;
#[cfg(not(test))]
use util::opts;
#[cfg(not(test))]
use util::taskpool::TaskPool;

#[cfg(not(test))]
use std::os;
#[cfg(not(test))]
use std::rc::Rc;
#[cfg(not(test))]
use std::sync::mpsc::channel;
#[cfg(not(test))]
use std::thread::Builder;

pub struct Browser<Window> {
    compositor: Box<CompositorEventListener + 'static>,
}

impl<Window> Browser<Window> where Window: WindowMethods + 'static {
    #[cfg(not(test))]
    pub fn new(window: Option<Rc<Window>>) -> Browser<Window> {
        ::util::opts::set_experimental_enabled(opts::get().enable_experimental);
        let opts = opts::get();
        RegisterBindings::RegisterProxyHandlers();

        let shared_task_pool = TaskPool::new(8);

        let (compositor_proxy, compositor_receiver) =
            WindowMethods::create_compositor_channel(&window);
        let time_profiler_chan = TimeProfiler::create(opts.time_profiler_period);
        let memory_profiler_chan = MemoryProfiler::create(opts.memory_profiler_period);
        let devtools_chan = opts.devtools_port.map(|port| {
            devtools::start_server(port)
        });

        let opts_clone = opts.clone();
        let time_profiler_chan_clone = time_profiler_chan.clone();

        let (result_chan, result_port) = channel();
        let compositor_proxy_for_constellation = compositor_proxy.clone_compositor_proxy();
        Builder::new()
            .spawn(move || {
            let opts = &opts_clone;
            // Create a Servo instance.
            let resource_task = new_resource_task(opts.user_agent.clone());
            // If we are emitting an output file, then we need to block on
            // image load or we risk emitting an output file missing the
            // image.
            let image_cache_task = if opts.output_file.is_some() {
                ImageCacheTask::new_sync(resource_task.clone(), shared_task_pool)
            } else {
                ImageCacheTask::new(resource_task.clone(), shared_task_pool)
            };
            let font_cache_task = FontCacheTask::new(resource_task.clone());
            let storage_task: StorageTask = StorageTaskFactory::new();
            let constellation_chan = Constellation::<layout::layout_task::LayoutTask,
                                                     script::script_task::ScriptTask>::start(
                                                          compositor_proxy_for_constellation,
                                                          resource_task,
                                                          image_cache_task,
                                                          font_cache_task,
                                                          time_profiler_chan_clone,
                                                          devtools_chan,
                                                          storage_task);

            // Send the URL command to the constellation.
            let cwd = os::getcwd().unwrap();
            for url in opts.urls.iter() {
                let url = match url::Url::parse(url.as_slice()) {
                    Ok(url) => url,
                    Err(url::ParseError::RelativeUrlWithoutBase)
                    => url::Url::from_file_path(&cwd.join(url.as_slice())).unwrap(),
                    Err(_) => panic!("URL parsing failed"),
                };

                let ConstellationChan(ref chan) = constellation_chan;
                chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap();
            }

            // Send the constallation Chan as the result
            result_chan.send(constellation_chan).unwrap();
        });

        let constellation_chan = result_port.recv().unwrap();

        debug!("preparing to enter main loop");
        let compositor = CompositorTask::create(window,
                                                compositor_proxy,
                                                compositor_receiver,
                                                constellation_chan,
                                                time_profiler_chan,
                                                memory_profiler_chan);

        Browser {
            compositor: compositor,
        }
    }

    pub fn handle_event(&mut self, event: WindowEvent) -> bool {
        self.compositor.handle_event(event)
    }

    pub fn repaint_synchronously(&mut self) {
        self.compositor.repaint_synchronously()
    }

    pub fn pinch_zoom_level(&self) -> f32 {
        self.compositor.pinch_zoom_level()
    }

    pub fn get_title_for_main_frame(&self) {
        self.compositor.get_title_for_main_frame()
    }

    pub fn shutdown(mut self) {
        self.compositor.shutdown();
    }
}

<commit_msg>Fix some warnings in servo/lib.rs.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(core, env, libc, path, rustc_private, std_misc, thread_local)]

#![allow(missing_copy_implementations)]

#[macro_use]
extern crate log;

extern crate compositing;
extern crate devtools;
extern crate net;
extern crate msg;
#[macro_use]
extern crate util;
extern crate script;
extern crate layout;
extern crate gfx;
extern crate libc;
extern crate url;

use compositing::CompositorEventListener;
use compositing::windowing::{WindowEvent, WindowMethods};

#[cfg(not(test))]
use compositing::{CompositorProxy, CompositorTask, Constellation};
#[cfg(not(test))]
use msg::constellation_msg::Msg as ConstellationMsg;
#[cfg(not(test))]
use msg::constellation_msg::ConstellationChan;
#[cfg(not(test))]
use script::dom::bindings::codegen::RegisterBindings;

#[cfg(not(test))]
use net::image_cache_task::ImageCacheTask;
#[cfg(not(test))]
use net::resource_task::new_resource_task;
#[cfg(not(test))]
use net::storage_task::{StorageTaskFactory, StorageTask};
#[cfg(not(test))]
use gfx::font_cache_task::FontCacheTask;
#[cfg(not(test))]
use util::time::TimeProfiler;
#[cfg(not(test))]
use util::memory::MemoryProfiler;
#[cfg(not(test))]
use util::opts;
#[cfg(not(test))]
use util::taskpool::TaskPool;

#[cfg(not(test))]
use std::rc::Rc;
#[cfg(not(test))]
use std::sync::mpsc::channel;
#[cfg(not(test))]
use std::thread::Builder;

pub struct Browser<Window> {
    compositor: Box<CompositorEventListener + 'static>,
}

impl<Window> Browser<Window> where Window: WindowMethods + 'static {
    #[cfg(not(test))]
    pub fn new(window: Option<Rc<Window>>) -> Browser<Window> {
        use std::env;

        ::util::opts::set_experimental_enabled(opts::get().enable_experimental);
        let opts = opts::get();
        RegisterBindings::RegisterProxyHandlers();

        let shared_task_pool = TaskPool::new(8);

        let (compositor_proxy, compositor_receiver) =
            WindowMethods::create_compositor_channel(&window);
        let time_profiler_chan = TimeProfiler::create(opts.time_profiler_period);
        let memory_profiler_chan = MemoryProfiler::create(opts.memory_profiler_period);
        let devtools_chan = opts.devtools_port.map(|port| {
            devtools::start_server(port)
        });

        let opts_clone = opts.clone();
        let time_profiler_chan_clone = time_profiler_chan.clone();

        let (result_chan, result_port) = channel();
        let compositor_proxy_for_constellation = compositor_proxy.clone_compositor_proxy();
        Builder::new()
            .spawn(move || {
            let opts = &opts_clone;
            // Create a Servo instance.
            let resource_task = new_resource_task(opts.user_agent.clone());
            // If we are emitting an output file, then we need to block on
            // image load or we risk emitting an output file missing the
            // image.
            let image_cache_task = if opts.output_file.is_some() {
                ImageCacheTask::new_sync(resource_task.clone(), shared_task_pool)
            } else {
                ImageCacheTask::new(resource_task.clone(), shared_task_pool)
            };
            let font_cache_task = FontCacheTask::new(resource_task.clone());
            let storage_task: StorageTask = StorageTaskFactory::new();
            let constellation_chan = Constellation::<layout::layout_task::LayoutTask,
                                                     script::script_task::ScriptTask>::start(
                                                          compositor_proxy_for_constellation,
                                                          resource_task,
                                                          image_cache_task,
                                                          font_cache_task,
                                                          time_profiler_chan_clone,
                                                          devtools_chan,
                                                          storage_task);

            // Send the URL command to the constellation.
            let cwd = env::current_dir().unwrap();
            for url in opts.urls.iter() {
                let url = match url::Url::parse(&*url) {
                    Ok(url) => url,
                    Err(url::ParseError::RelativeUrlWithoutBase)
                    => url::Url::from_file_path(&cwd.join(&*url)).unwrap(),
                    Err(_) => panic!("URL parsing failed"),
                };

                let ConstellationChan(ref chan) = constellation_chan;
                chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap();
            }

            // Send the constallation Chan as the result
            result_chan.send(constellation_chan).unwrap();
        });

        let constellation_chan = result_port.recv().unwrap();

        debug!("preparing to enter main loop");
        let compositor = CompositorTask::create(window,
                                                compositor_proxy,
                                                compositor_receiver,
                                                constellation_chan,
                                                time_profiler_chan,
                                                memory_profiler_chan);

        Browser {
            compositor: compositor,
        }
    }

    pub fn handle_event(&mut self, event: WindowEvent) -> bool {
        self.compositor.handle_event(event)
    }

    pub fn repaint_synchronously(&mut self) {
        self.compositor.repaint_synchronously()
    }

    pub fn pinch_zoom_level(&self) -> f32 {
        self.compositor.pinch_zoom_level()
    }

    pub fn get_title_for_main_frame(&self) {
        self.compositor.get_title_for_main_frame()
    }

    pub fn shutdown(mut self) {
        self.compositor.shutdown();
    }
}

<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::time::{Duration, Instant};
use std::mem;
use std::io::{stderr, Write};
use std::iter::repeat;
use std::collections::{HashSet};
use std::default::Default;
use std::iter::FromIterator;
use std::sync::{RwLock, atomic::{AtomicBool, Ordering}};
use lazy_static::lazy_static;

/// Set profiling filter. It specifies descriptions allowed to profile.
/// This is helpful when call stack has too many nested profiling scopes.
/// Additionally filter can specify maximum depth of profiling scopes nesting.
///
/// #Example
/// ```
/// use ra_prof::set_filter;
/// use ra_prof::Filter;
/// let max_depth = 2;
/// let allowed = vec!["profile1".to_string(), "profile2".to_string()];
/// let f = Filter::new( max_depth, allowed );
/// set_filter(f);
/// ```
///
pub fn set_filter(f: Filter) {
    PROFILING_ENABLED.store(f.depth > 0, Ordering::SeqCst);
    let set = HashSet::from_iter(f.allowed.iter().cloned());
    let mut old = FILTER.write().unwrap();
    let filter_data = FilterData {
        depth: f.depth,
        allowed: set,
        longer_than: f.longer_than,
        version: old.version + 1,
    };
    *old = filter_data;
}

/// This function starts a profiling scope in the current execution stack with a given description.
/// It returns a Profile structure and measure elapsed time between this method invocation and Profile structure drop.
/// It supports nested profiling scopes in case when this function invoked multiple times at the execution stack. In this case the profiling information will be nested at the output.
/// Profiling information is being printed in the stderr.
///
/// #Example
/// ```
/// use ra_prof::profile;
/// use ra_prof::set_filter;
/// use ra_prof::Filter;
///
/// let allowed = vec!["profile1".to_string(), "profile2".to_string()];
/// let f = Filter::new(2, allowed);
/// set_filter(f);
/// profiling_function1();
///
/// fn profiling_function1() {
///     let _p = profile("profile1");
///     profiling_function2();
/// }
///
/// fn profiling_function2() {
///     let _p = profile("profile2");
/// }
/// ```
/// This will print in the stderr the following:
/// ```text
///  0ms - profile
///      0ms - profile2
/// ```
///
pub fn profile(desc: &str) -> Profiler {
    assert!(!desc.is_empty());
    if !PROFILING_ENABLED.load(Ordering::Relaxed) {
        return Profiler { desc: None };
    }

    PROFILE_STACK.with(|stack| {
        let mut stack = stack.borrow_mut();
        if stack.starts.len() == 0 {
            match FILTER.try_read() {
                Ok(f) => {
                    if f.version > stack.filter_data.version {
                        stack.filter_data = f.clone();
                    }
                }
                Err(_) => (),
            };
        }

        if stack.starts.len() > stack.filter_data.depth {
            return Profiler { desc: None };
        }

        if stack.filter_data.allowed.is_empty() || stack.filter_data.allowed.contains(desc) {
            stack.starts.push(Instant::now());
            Profiler { desc: Some(desc.to_string()) }
        } else {
            Profiler { desc: None }
        }
    })
}

pub struct Profiler {
    desc: Option<String>,
}

pub struct Filter {
    depth: usize,
    allowed: Vec<String>,
    longer_than: Duration,
}

impl Filter {
    // Filtering syntax
    // env RA_PROFILE=*             // dump everything
    // env RA_PROFILE=foo|bar|baz   // enabled only selected entries
    // env RA_PROFILE=*@3>10        // dump everything, up to depth 3, if it takes more than 10 ms
    pub fn from_spec(mut spec: &str) -> Filter {
        let longer_than = if let Some(idx) = spec.rfind(">") {
            let longer_than = spec[idx + 1..].parse().expect("invalid profile longer_than");
            spec = &spec[..idx];
            Duration::from_millis(longer_than)
        } else {
            Duration::new(0, 0)
        };

        let depth = if let Some(idx) = spec.rfind("@") {
            let depth: usize = spec[idx + 1..].parse().expect("invalid profile depth");
            spec = &spec[..idx];
            depth
        } else {
            999
        };
        let allowed =
            if spec == "*" { Vec::new() } else { spec.split("|").map(String::from).collect() };
        Filter::new(depth, allowed, longer_than)
    }

    pub fn disabled() -> Filter {
        Filter::new(0, Vec::new(), Duration::new(0, 0))
    }

    pub fn new(depth: usize, allowed: Vec<String>, longer_than: Duration) -> Filter {
        Filter { depth, allowed, longer_than }
    }
}

struct ProfileStack {
    starts: Vec<Instant>,
    messages: Vec<Message>,
    filter_data: FilterData,
}

struct Message {
    level: usize,
    duration: Duration,
    message: String,
}

impl ProfileStack {
    fn new() -> ProfileStack {
        ProfileStack { starts: Vec::new(), messages: Vec::new(), filter_data: Default::default() }
    }
}

#[derive(Default, Clone)]
struct FilterData {
    depth: usize,
    version: usize,
    allowed: HashSet<String>,
    longer_than: Duration,
}

static PROFILING_ENABLED: AtomicBool = AtomicBool::new(false);

lazy_static! {
    static ref FILTER: RwLock<FilterData> = RwLock::new(Default::default());
}

thread_local!(static PROFILE_STACK: RefCell<ProfileStack> = RefCell::new(ProfileStack::new()));

impl Drop for Profiler {
    fn drop(&mut self) {
        match self {
            Profiler { desc: Some(desc) } => {
                PROFILE_STACK.with(|stack| {
                    let mut stack = stack.borrow_mut();
                    let start = stack.starts.pop().unwrap();
                    let duration = start.elapsed();
                    let level = stack.starts.len();
                    let message = mem::replace(desc, String::new());
                    stack.messages.push(Message { level, duration, message });
                    if level == 0 {
                        let stdout = stderr();
                        if duration >= stack.filter_data.longer_than {
                            print(0, &stack.messages, &mut stdout.lock());
                        }
                        stack.messages.clear();
                    }
                });
            }
            Profiler { desc: None } => (),
        }
    }
}

fn print(lvl: usize, msgs: &[Message], out: &mut impl Write) {
    let mut last = 0;
    let indent = repeat("    ").take(lvl + 1).collect::<String>();
    for (i, &Message { level: l, duration: dur, message: ref msg }) in msgs.iter().enumerate() {
        if l != lvl {
            continue;
        }
        writeln!(out, "{} {:6}ms - {}", indent, dur.as_millis(), msg)
            .expect("printing profiling info to stdout");

        print(lvl + 1, &msgs[last..i], out);
        last = i;
    }
}

#[cfg(test)]
mod tests {

    use super::profile;
    use super::set_filter;
    use super::Filter;

    #[test]
    fn test_basic_profile() {
        let s = vec!["profile1".to_string(), "profile2".to_string()];
        let f = Filter::new(2, s);
        set_filter(f);
        profiling_function1();
    }

    fn profiling_function1() {
        let _p = profile("profile1");
        profiling_function2();
    }

    fn profiling_function2() {
        let _p = profile("profile2");
    }
}
<commit_msg>fix test<commit_after>use std::cell::RefCell;
use std::time::{Duration, Instant};
use std::mem;
use std::io::{stderr, Write};
use std::iter::repeat;
use std::collections::{HashSet};
use std::default::Default;
use std::iter::FromIterator;
use std::sync::{RwLock, atomic::{AtomicBool, Ordering}};
use lazy_static::lazy_static;

/// Set profiling filter. It specifies descriptions allowed to profile.
/// This is helpful when call stack has too many nested profiling scopes.
/// Additionally filter can specify maximum depth of profiling scopes nesting.
///
/// #Example
/// ```
/// use ra_prof::{set_filter, Filter};
/// let f = Filter::from_spec("profile1|profile2@2");
/// set_filter(f);
/// ```
pub fn set_filter(f: Filter) {
    PROFILING_ENABLED.store(f.depth > 0, Ordering::SeqCst);
    let set = HashSet::from_iter(f.allowed.iter().cloned());
    let mut old = FILTER.write().unwrap();
    let filter_data = FilterData {
        depth: f.depth,
        allowed: set,
        longer_than: f.longer_than,
        version: old.version + 1,
    };
    *old = filter_data;
}

/// This function starts a profiling scope in the current execution stack with a given description.
/// It returns a Profile structure and measure elapsed time between this method invocation and Profile structure drop.
/// It supports nested profiling scopes in case when this function invoked multiple times at the execution stack. In this case the profiling information will be nested at the output.
/// Profiling information is being printed in the stderr.
///
/// #Example
/// ```
/// use ra_prof::{profile, set_filter, Filter};
///
/// let f = Filter::from_spec("profile1|profile2@2");
/// set_filter(f);
/// profiling_function1();
///
/// fn profiling_function1() {
///     let _p = profile("profile1");
///     profiling_function2();
/// }
///
/// fn profiling_function2() {
///     let _p = profile("profile2");
/// }
/// ```
/// This will print in the stderr the following:
/// ```text
///  0ms - profile
///      0ms - profile2
/// ```
pub fn profile(desc: &str) -> Profiler {
    assert!(!desc.is_empty());
    if !PROFILING_ENABLED.load(Ordering::Relaxed) {
        return Profiler { desc: None };
    }

    PROFILE_STACK.with(|stack| {
        let mut stack = stack.borrow_mut();
        if stack.starts.len() == 0 {
            match FILTER.try_read() {
                Ok(f) => {
                    if f.version > stack.filter_data.version {
                        stack.filter_data = f.clone();
                    }
                }
                Err(_) => (),
            };
        }

        if stack.starts.len() > stack.filter_data.depth {
            return Profiler { desc: None };
        }

        if stack.filter_data.allowed.is_empty() || stack.filter_data.allowed.contains(desc) {
            stack.starts.push(Instant::now());
            Profiler { desc: Some(desc.to_string()) }
        } else {
            Profiler { desc: None }
        }
    })
}

pub struct Profiler {
    desc: Option<String>,
}

pub struct Filter {
    depth: usize,
    allowed: Vec<String>,
    longer_than: Duration,
}

impl Filter {
    // Filtering syntax
    // env RA_PROFILE=*             // dump everything
    // env RA_PROFILE=foo|bar|baz   // enabled only selected entries
    // env RA_PROFILE=*@3>10        // dump everything, up to depth 3, if it takes more than 10 ms
    pub fn from_spec(mut spec: &str) -> Filter {
        let longer_than = if let Some(idx) = spec.rfind(">") {
            let longer_than = spec[idx + 1..].parse().expect("invalid profile longer_than");
            spec = &spec[..idx];
            Duration::from_millis(longer_than)
        } else {
            Duration::new(0, 0)
        };

        let depth = if let Some(idx) = spec.rfind("@") {
            let depth: usize = spec[idx + 1..].parse().expect("invalid profile depth");
            spec = &spec[..idx];
            depth
        } else {
            999
        };
        let allowed =
            if spec == "*" { Vec::new() } else { spec.split("|").map(String::from).collect() };
        Filter::new(depth, allowed, longer_than)
    }

    pub fn disabled() -> Filter {
        Filter::new(0, Vec::new(), Duration::new(0, 0))
    }

    pub fn new(depth: usize, allowed: Vec<String>, longer_than: Duration) -> Filter {
        Filter { depth, allowed, longer_than }
    }
}

struct ProfileStack {
    starts: Vec<Instant>,
    messages: Vec<Message>,
    filter_data: FilterData,
}

struct Message {
    level: usize,
    duration: Duration,
    message: String,
}

impl ProfileStack {
    fn new() -> ProfileStack {
        ProfileStack { starts: Vec::new(), messages: Vec::new(), filter_data: Default::default() }
    }
}

#[derive(Default, Clone)]
struct FilterData {
    depth: usize,
    version: usize,
    allowed: HashSet<String>,
    longer_than: Duration,
}

static PROFILING_ENABLED: AtomicBool = AtomicBool::new(false);

lazy_static! {
    static ref FILTER: RwLock<FilterData> = RwLock::new(Default::default());
}

thread_local!(static PROFILE_STACK: RefCell<ProfileStack> = RefCell::new(ProfileStack::new()));

impl Drop for Profiler {
    fn drop(&mut self) {
        match self {
            Profiler { desc: Some(desc) } => {
                PROFILE_STACK.with(|stack| {
                    let mut stack = stack.borrow_mut();
                    let start = stack.starts.pop().unwrap();
                    let duration = start.elapsed();
                    let level = stack.starts.len();
                    let message = mem::replace(desc, String::new());
                    stack.messages.push(Message { level, duration, message });
                    if level == 0 {
                        let stdout = stderr();
                        if duration >= stack.filter_data.longer_than {
                            print(0, &stack.messages, &mut stdout.lock());
                        }
                        stack.messages.clear();
                    }
                });
            }
            Profiler { desc: None } => (),
        }
    }
}

fn print(lvl: usize, msgs: &[Message], out: &mut impl Write) {
    let mut last = 0;
    let indent = repeat("    ").take(lvl + 1).collect::<String>();
    for (i, &Message { level: l, duration: dur, message: ref msg }) in msgs.iter().enumerate() {
        if l != lvl {
            continue;
        }
        writeln!(out, "{} {:6}ms - {}", indent, dur.as_millis(), msg)
            .expect("printing profiling info to stdout");

        print(lvl + 1, &msgs[last..i], out);
        last = i;
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_basic_profile() {
        let s = vec!["profile1".to_string(), "profile2".to_string()];
        let f = Filter::new(2, s, Duration::new(0, 0));
        set_filter(f);
        profiling_function1();
    }

    fn profiling_function1() {
        let _p = profile("profile1");
        profiling_function2();
    }

    fn profiling_function2() {
        let _p = profile("profile2");
    }
}
<|endoftext|>


<commit_before>
mod api {

    pub type Target = u32;

    pub enum FeatureType {
        Boolean,
        Category,
        Number
    }

    pub trait RecordMeta {

        fn some_record_meta(&self) -> bool;

    }

    pub struct DataSetMeta {
        pub target_count: usize,
        pub features: Vec<(usize, FeatureType)>
    }

    pub struct DataSet<T: RecordMeta> {
        records: Vec<(T, Target)>,
        meta: DataSetMeta,
    }

    pub struct DataSetIterator<'a, T: 'a> {
        records: &'a Vec<(T, Target)>,
        current: usize,
        max: usize
    }

    impl<T: RecordMeta> DataSet<T> {

        pub fn new(meta: DataSetMeta, records: Vec<(T, Target)>) -> DataSet<T> {
            // here we should check that all records has the same meta
            DataSet{records: records, meta: meta}
        }

        pub fn is_empty(&self) -> bool {
            self.records.is_empty()
        }

        pub fn target_count(&self) -> usize {
            self.meta.target_count
        }

        pub fn records(&self) -> DataSetIterator<T> {
            DataSetIterator{records: &self.records, current: 0, max: self.records.len()}
        }

    }

    impl<'a, T: RecordMeta> Iterator for DataSetIterator<'a, T> {

        type Item = &'a (T, Target);

        fn next(&mut self) -> Option<&'a (T, Target)> {
            if self.current < self.max {
                let result = Some(&self.records[self.current]);
                self.current = self.current + 1;
                return result
            } else {
                return None
            }
        }

    }

}

mod data {

    use ::api;

    #[derive(Debug)]
    pub struct Record {
        pub zopa: u32
    }

    impl api::RecordMeta for Record {

        fn some_record_meta(&self) -> bool {
            true
        }

    }

    pub fn get_data() -> api::DataSet<Record> {
        api::DataSet::new(
            api::DataSetMeta {
                target_count: 2,
                features: vec![
                    (0, api::FeatureType::Number),
                    (1, api::FeatureType::Boolean)
                ]
            },
            vec![
                (Record{zopa: 0}, 0),
                (Record{zopa: 1}, 1)
            ]
        )
    }

}

fn test<T: api::RecordMeta>(ds: &api::DataSet<T>) {
    println!("{}", ds.target_count());
    for record in ds.records() {
        println!("{}", record.0.some_record_meta());
    }
}

fn main() {
    use data;
    println!("Hello, API!");
    let ds = data::get_data();
    println!("is_empty = {}, target_count = {}", ds.is_empty(), ds.target_count());
    for record in ds.records() {
        println!("{:?}", record);
    }
    test(&ds);
}<commit_msg>DataSetView draft added to API draft<commit_after>
mod api {

    use std::collections::HashSet;

    pub type Target = u32;

    pub enum FeatureType {
        Boolean,
        Category,
        Number
    }

    pub trait RecordMeta {

        fn some_record_meta(&self) -> bool;

    }

    pub struct DataSetMeta {
        pub target_count: usize,
        pub features: Vec<(usize, FeatureType)>
    }

    pub struct DataSet<T: RecordMeta> {
        records: Vec<(T, Target)>,
        meta: DataSetMeta,
    }

    pub struct DataSetIterator<'a, T: 'a> {
        records: &'a Vec<(T, Target)>,
        current: usize,
        max: usize,
        view: Option<&'a DataSetView>
    }

    pub struct DataSetView {
        indexes: HashSet<usize> // bitset should be here
    }

    impl DataSetView {

        pub fn empty() -> Self {
            DataSetView{indexes: HashSet::new()}
        }

        pub fn new(indexes: Vec<usize>) -> Self {
            let mut is = HashSet::new();
            for index in indexes {
                is.insert(index);
            }
            DataSetView{indexes: is}
        }

        pub fn add_index(&mut self, index: usize) {
            self.indexes.insert(index);
        }

    }

    impl<T: RecordMeta> DataSet<T> {

        pub fn new(meta: DataSetMeta, records: Vec<(T, Target)>) -> Self {
            // here we should check that all records has the same meta
            DataSet{records: records, meta: meta}
        }

        pub fn is_empty(&self) -> bool {
            self.records.is_empty()
        }

        pub fn len(&self) -> usize {
            self.records.len()
        }

        pub fn target_count(&self) -> usize {
            self.meta.target_count
        }

        pub fn records(&self) -> DataSetIterator<T> {
            DataSetIterator{records: &self.records, current: 0, max: self.records.len(), view: None}
        }

        pub fn view_records<'a>(&'a self, view: &'a DataSetView) -> DataSetIterator<T> {
            DataSetIterator{records: &self.records, current: 0, max: self.records.len(), view: Some(view)}
        }

    }

    impl<'a, T: RecordMeta> Iterator for DataSetIterator<'a, T> {

        type Item = &'a (T, Target);

        fn next(&mut self) -> Option<&'a (T, Target)> {
            if self.current < self.max {
                match self.view {
                    Some(ref view) => {
                        while view.indexes.contains(&self.current) {
                            self.current = self.current + 1;
                        };
                    }
                    Node => {}
                }
                let result = Some(&self.records[self.current]);
                self.current = self.current + 1;
                return result
            } else {
                return None
            }
        }

    }

}

mod data {

    use ::api;

    #[derive(Debug)]
    pub struct Record {
        pub zopa: u32
    }

    impl api::RecordMeta for Record {

        fn some_record_meta(&self) -> bool {
            true
        }

    }

    pub fn get_data() -> api::DataSet<Record> {
        api::DataSet::new(
            api::DataSetMeta {
                target_count: 2,
                features: vec![
                    (0, api::FeatureType::Number),
                    (1, api::FeatureType::Boolean)
                ]
            },
            vec![
                (Record{zopa: 0}, 0),
                (Record{zopa: 1}, 1)
            ]
        )
    }

}

fn test<T: api::RecordMeta>(ds: &api::DataSet<T>) {
    println!("{}", ds.target_count());
    for record in ds.records() {
        println!("{}", record.0.some_record_meta());
    }
}

fn test2<T: api::RecordMeta>(ds: &api::DataSet<T>, view: &mut api::DataSetView, index: usize) {
    if ds.len() == index {
        return
    }
    for record in ds.view_records(view) {
        println!("{}: {}", index, record.0.some_record_meta());
    }
    view.add_index(index);
    test2(ds, view, index + 1)
}

fn main() {
    use data;
    println!("Hello, API!");
    let ds = data::get_data();
    println!("is_empty = {}, target_count = {}", ds.is_empty(), ds.target_count());
    for record in ds.records() {
        println!("{:?}", record);
    }
    for record in ds.view_records(&api::DataSetView::new(vec![0])) {
        println!("{:?}", record);
    }
    test(&ds);
    test2(&ds, &mut api::DataSetView::empty(), 0);
}
<|endoftext|>


<commit_before>#[cfg(feature = "postgres")]
extern crate url;

use support::{database, project};

#[test]
fn reset_drops_the_database() {
    let p = project("reset_drops_the_database")
        .folder("migrations")
        .build();
    let db = database(&p.database_url()).create();
    db.execute("CREATE TABLE posts ( id INTEGER )");

    assert!(db.table_exists("posts"));

    let result = p.command("database").arg("reset").run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);
    assert!(!db.table_exists("posts"));
}

#[test]
fn reset_runs_database_setup() {
    let p = project("reset_runs_database_setup")
        .folder("migrations")
        .build();
    let db = database(&p.database_url()).create();

    db.execute("CREATE TABLE posts ( id INTEGER )");
    db.execute("CREATE TABLE users ( id INTEGER )");
    p.create_migration(
        "12345_create_users_table",
        "CREATE TABLE users ( id INTEGER )",
        "DROP TABLE users",
    );

    assert!(db.table_exists("posts"));
    assert!(db.table_exists("users"));

    let result = p.command("database").arg("reset").run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);
    assert!(!db.table_exists("posts"));
    assert!(db.table_exists("users"));
    assert!(db.table_exists("__diesel_schema_migrations"));
}

#[test]
#[cfg(feature = "postgres")]
fn reset_handles_postgres_urls_with_username_and_password() {
    let p = project("handles_postgres_urls")
        .folder("migrations")
        .build();
    let db = database(&p.database_url()).create();

    db.execute("DROP ROLE IF EXISTS foo");
    db.execute("CREATE ROLE foo WITH LOGIN SUPERUSER PASSWORD 'password'");

    let database_url = {
        let mut new_url = url::Url::parse(&p.database_url()).expect("invalid url");
        new_url.set_username("foo").expect("could not set username");
        new_url
            .set_password(Some("password"))
            .expect("could not set password");
        new_url.to_string()
    };

    let result = p
        .command("database")
        .arg("reset")
        .env("DATABASE_URL", &database_url)
        .run();

    assert!(
        result.is_success(),
        "Result was unsuccessful {:?}",
        result.stdout()
    );
    assert!(
        result.stdout().contains("Dropping database:"),
        "Unexpected stdout {}",
        result.stdout()
    );
    assert!(
        result.stdout().contains("Creating database:"),
        "Unexpected stdout {}",
        result.stdout()
    );
}

#[test]
fn reset_works_with_migration_dir_by_arg() {
    let p = project("reset_works_with_migration_dir_by_arg")
        .folder("foo")
        .build();
    let db = database(&p.database_url()).create();

    db.execute("CREATE TABLE posts ( id INTEGER )");
    db.execute("CREATE TABLE users ( id INTEGER )");
    p.create_migration_in_directory(
        "foo",
        "12345_create_users_table",
        "CREATE TABLE users ( id INTEGER )",
        "DROP TABLE users",
    );

    assert!(db.table_exists("posts"));
    assert!(db.table_exists("users"));

    let result = p
        .command("database")
        .arg("reset")
        .arg("--migration-dir=foo")
        .run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);
    assert!(!db.table_exists("posts"));
    assert!(db.table_exists("users"));
    assert!(db.table_exists("__diesel_schema_migrations"));
}

#[test]
fn reset_works_with_migration_dir_by_env() {
    let p = project("reset_works_with_migration_dir_by_env")
        .folder("bar")
        .build();
    let db = database(&p.database_url()).create();

    db.execute("CREATE TABLE posts ( id INTEGER )");
    db.execute("CREATE TABLE users ( id INTEGER )");
    p.create_migration_in_directory(
        "bar",
        "12345_create_users_table",
        "CREATE TABLE users ( id INTEGER )",
        "DROP TABLE users",
    );

    assert!(db.table_exists("posts"));
    assert!(db.table_exists("users"));

    let result = p
        .command("database")
        .arg("reset")
        .env("MIGRATION_DIRECTORY", "bar")
        .run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);
    assert!(!db.table_exists("posts"));
    assert!(db.table_exists("users"));
    assert!(db.table_exists("__diesel_schema_migrations"));
}

#[test]
fn reset_sanitize_database_name() {
    let p = project("name-with-dashes").folder("migrations").build();
    let _db = database(&p.database_url()).create();

    let result = p.command("database").arg("reset").run();

    assert!(
        result.is_success(),
        "Result was unsuccessful {:?}",
        result.stdout()
    );
    assert!(
        result.stdout().contains("Dropping database:"),
        "Unexpected stdout {}",
        result.stdout()
    );
    assert!(
        result.stdout().contains("Creating database:"),
        "Unexpected stdout {}",
        result.stdout()
    );
}

#[test]
fn reset_updates_schema_if_config_present() {
    let p = project("reset_updates_schema_if_config_present")
        .folder("migrations")
        .file(
            "diesel.toml",
            r#"
            [print_schema]
            file = "src/my_schema.rs"
            "#,
        )
        .build();

    let result = p.command("database").arg("reset").run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);

    assert!(p.has_file("src/my_schema.rs"));
}
<commit_msg>Add test for database reset<commit_after>#[cfg(feature = "postgres")]
extern crate url;

use support::{database, project};

#[test]
fn reset_drops_the_database() {
    let p = project("reset_drops_the_database")
        .folder("migrations")
        .build();
    let db = database(&p.database_url()).create();
    db.execute("CREATE TABLE posts ( id INTEGER )");

    assert!(db.table_exists("posts"));

    let result = p.command("database").arg("reset").run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);
    assert!(!db.table_exists("posts"));
}

#[test]
fn reset_runs_database_setup() {
    let p = project("reset_runs_database_setup")
        .folder("migrations")
        .build();
    let db = database(&p.database_url()).create();

    db.execute("CREATE TABLE posts ( id INTEGER )");
    db.execute("CREATE TABLE users ( id INTEGER )");
    p.create_migration(
        "12345_create_users_table",
        "CREATE TABLE users ( id INTEGER )",
        "DROP TABLE users",
    );

    assert!(db.table_exists("posts"));
    assert!(db.table_exists("users"));

    let result = p.command("database").arg("reset").run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);
    assert!(!db.table_exists("posts"));
    assert!(db.table_exists("users"));
    assert!(db.table_exists("__diesel_schema_migrations"));
}

#[test]
#[cfg(feature = "postgres")]
fn reset_handles_postgres_urls_with_username_and_password() {
    let p = project("handles_postgres_urls")
        .folder("migrations")
        .build();
    let db = database(&p.database_url()).create();

    db.execute("DROP ROLE IF EXISTS foo");
    db.execute("CREATE ROLE foo WITH LOGIN SUPERUSER PASSWORD 'password'");

    let database_url = {
        let mut new_url = url::Url::parse(&p.database_url()).expect("invalid url");
        new_url.set_username("foo").expect("could not set username");
        new_url
            .set_password(Some("password"))
            .expect("could not set password");
        new_url.to_string()
    };

    let result = p
        .command("database")
        .arg("reset")
        .env("DATABASE_URL", &database_url)
        .run();

    assert!(
        result.is_success(),
        "Result was unsuccessful {:?}",
        result.stdout()
    );
    assert!(
        result.stdout().contains("Dropping database:"),
        "Unexpected stdout {}",
        result.stdout()
    );
    assert!(
        result.stdout().contains("Creating database:"),
        "Unexpected stdout {}",
        result.stdout()
    );
}

#[test]
fn reset_works_with_migration_dir_by_arg() {
    let p = project("reset_works_with_migration_dir_by_arg")
        .folder("foo")
        .build();
    let db = database(&p.database_url()).create();

    db.execute("CREATE TABLE posts ( id INTEGER )");
    db.execute("CREATE TABLE users ( id INTEGER )");
    p.create_migration_in_directory(
        "foo",
        "12345_create_users_table",
        "CREATE TABLE users ( id INTEGER )",
        "DROP TABLE users",
    );

    assert!(db.table_exists("posts"));
    assert!(db.table_exists("users"));

    let result = p
        .command("database")
        .arg("reset")
        .arg("--migration-dir=foo")
        .run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);
    assert!(!db.table_exists("posts"));
    assert!(db.table_exists("users"));
    assert!(db.table_exists("__diesel_schema_migrations"));
}

#[test]
fn reset_works_with_migration_dir_by_env() {
    let p = project("reset_works_with_migration_dir_by_env")
        .folder("bar")
        .build();
    let db = database(&p.database_url()).create();

    db.execute("CREATE TABLE posts ( id INTEGER )");
    db.execute("CREATE TABLE users ( id INTEGER )");
    p.create_migration_in_directory(
        "bar",
        "12345_create_users_table",
        "CREATE TABLE users ( id INTEGER )",
        "DROP TABLE users",
    );

    assert!(db.table_exists("posts"));
    assert!(db.table_exists("users"));

    let result = p
        .command("database")
        .arg("reset")
        .env("MIGRATION_DIRECTORY", "bar")
        .run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);
    assert!(!db.table_exists("posts"));
    assert!(db.table_exists("users"));
    assert!(db.table_exists("__diesel_schema_migrations"));
}

#[test]
fn reset_sanitize_database_name() {
    let p = project("name-with-dashes").folder("migrations").build();
    let _db = database(&p.database_url()).create();

    let result = p.command("database").arg("reset").run();

    assert!(
        result.is_success(),
        "Result was unsuccessful {:?}",
        result.stdout()
    );
    assert!(
        result.stdout().contains("Dropping database:"),
        "Unexpected stdout {}",
        result.stdout()
    );
    assert!(
        result.stdout().contains("Creating database:"),
        "Unexpected stdout {}",
        result.stdout()
    );
}

#[test]
fn reset_updates_schema_if_config_present() {
    let p = project("reset_updates_schema_if_config_present")
        .folder("migrations")
        .file(
            "diesel.toml",
            r#"
            [print_schema]
            file = "src/my_schema.rs"
            "#,
        )
        .build();

    let result = p.command("database").arg("reset").run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);

    assert!(p.has_file("src/my_schema.rs"));
}

#[test]
fn reset_respects_migrations_dir_from_diesel_toml() {
    let p = project("reset_respects_migrations_dir_from_diesel_toml")
        .folder("custom_migrations")
        .file(
            "diesel.toml",
            r#"
            [migrations_directory]
            file = "custom_migrations"
            "#,
        )
        .build();
    let db = database(&p.database_url()).create();

    db.execute("CREATE TABLE posts ( id INTEGER )");
    db.execute("CREATE TABLE users ( id INTEGER )");

    p.create_migration_in_directory(
        "custom_migrations",
        "12345_create_users_table",
        "CREATE TABLE users ( id INTEGER )",
        "DROP TABLE users",
    );

    assert!(db.table_exists("posts"));
    assert!(db.table_exists("users"));

    let result = p
        .command("database")
        .arg("reset")
        .run();

    assert!(result.is_success(), "Result was unsuccessful {:?}", result);
    assert!(!db.table_exists("posts"));
    assert!(db.table_exists("users"));
    assert!(db.table_exists("__diesel_schema_migrations"));
}<|endoftext|>


<commit_before>use ::cairo;
use ::glib::translate::*;
use ::libc;

use error::*;
use length::*;
use transform::*;
use parsers::Parse;

pub enum RsvgPropertyBag {}

extern "C" {
    fn rsvg_property_bag_lookup (pbag: *const RsvgPropertyBag, key: *const libc::c_char) -> *const libc::c_char;
    fn rsvg_property_bag_dup (pbag: *const RsvgPropertyBag) -> *mut RsvgPropertyBag;
    fn rsvg_property_bag_free (pbag: *mut RsvgPropertyBag);
}

pub fn lookup (pbag: *const RsvgPropertyBag, key: &str) -> Option<String> {
    unsafe {
        let c_value = rsvg_property_bag_lookup (pbag, key.to_glib_none ().0);
        from_glib_none (c_value)
    }
}

pub fn dup (pbag: *const RsvgPropertyBag) -> *mut RsvgPropertyBag {
    unsafe {
        rsvg_property_bag_dup (pbag)
    }
}

pub fn free (pbag: *mut RsvgPropertyBag) {
    unsafe {
        rsvg_property_bag_free (pbag);
    }
}

pub fn parse_or_none<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data) -> Result <Option<T>, NodeError>
    where T: Parse<Err = AttributeError>
{
    let value = lookup (pbag, key);

    match value {
        Some (v) => {
            T::parse (&v, data).map (|v| Some (v))
                .map_err (|e| NodeError::attribute_error (key, e))
        },

        None => Ok (None)
    }
}

pub fn parse_or_default<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data) -> Result <T, NodeError>
    where T: Default + Parse<Err = AttributeError> + Copy
{
    parse_or_value (pbag, key, data, T::default ())
}

pub fn parse_or_value<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data, value: T) -> Result <T, NodeError>
    where T: Default + Parse<Err = AttributeError> + Copy
{
    let r = parse_or_none::<T> (pbag, key, data);

    match r {
        Ok (Some (v)) => Ok (v),
        Ok (None)     => Ok (value),
        Err (e)       => Err (e)
    }
}
<commit_msg>Remove unused imports<commit_after>use ::cairo;
use ::glib::translate::*;
use ::libc;

use error::*;
use parsers::Parse;

pub enum RsvgPropertyBag {}

extern "C" {
    fn rsvg_property_bag_lookup (pbag: *const RsvgPropertyBag, key: *const libc::c_char) -> *const libc::c_char;
    fn rsvg_property_bag_dup (pbag: *const RsvgPropertyBag) -> *mut RsvgPropertyBag;
    fn rsvg_property_bag_free (pbag: *mut RsvgPropertyBag);
}

pub fn lookup (pbag: *const RsvgPropertyBag, key: &str) -> Option<String> {
    unsafe {
        let c_value = rsvg_property_bag_lookup (pbag, key.to_glib_none ().0);
        from_glib_none (c_value)
    }
}

pub fn dup (pbag: *const RsvgPropertyBag) -> *mut RsvgPropertyBag {
    unsafe {
        rsvg_property_bag_dup (pbag)
    }
}

pub fn free (pbag: *mut RsvgPropertyBag) {
    unsafe {
        rsvg_property_bag_free (pbag);
    }
}

pub fn parse_or_none<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data) -> Result <Option<T>, NodeError>
    where T: Parse<Err = AttributeError>
{
    let value = lookup (pbag, key);

    match value {
        Some (v) => {
            T::parse (&v, data).map (|v| Some (v))
                .map_err (|e| NodeError::attribute_error (key, e))
        },

        None => Ok (None)
    }
}

pub fn parse_or_default<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data) -> Result <T, NodeError>
    where T: Default + Parse<Err = AttributeError> + Copy
{
    parse_or_value (pbag, key, data, T::default ())
}

pub fn parse_or_value<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data, value: T) -> Result <T, NodeError>
    where T: Default + Parse<Err = AttributeError> + Copy
{
    let r = parse_or_none::<T> (pbag, key, data);

    match r {
        Ok (Some (v)) => Ok (v),
        Ok (None)     => Ok (value),
        Err (e)       => Err (e)
    }
}
<|endoftext|>


<commit_before>#[doc="Constructs a DOM tree from an incoming token stream."]

import dom::base::{Attr, Element, ElementData, ElementKind, HTMLDivElement, HTMLHeadElement,
                   HTMLScriptElement};
import dom::base::{HTMLImageElement, Node, NodeScope, Text, TreeReadMethods, TreeWriteMethods};
import dom::base::{UnknownElement};
import dom::rcu::WriterMethods;
import geom::size::Size2D;
import gfx::geometry;
import gfx::geometry::au;
import parser = parser::html_lexer;
import parser::Token;
import dom::style::Stylesheet;
import vec::{push, push_all_move, flat_map};

import dvec::extensions;

enum CSSMessage {
    File(~str),
    Exit
}

enum js_message {
    js_file(~str),
    js_exit
}

#[warn(no_non_implicitly_copyable_typarams)]
fn link_up_attribute(scope: NodeScope, node: Node, -key: ~str, -value: ~str) {
    // TODO: Implement atoms so that we don't always perform string comparisons.
    scope.read(node, |node_contents| {
        alt *node_contents.kind {
          Element(element) {
            element.attrs.push(~Attr(copy key, copy value));
            alt *element.kind {
              HTMLImageElement(img) if key == ~"width" {
                alt int::from_str(value) {
                  none {
                    // Drop on the floor.
                  }
                  some(s) { img.size.width = geometry::px_to_au(s); }
                }
              }
              HTMLImageElement(img) if key == ~"height" {
                alt int::from_str(value) {
                  none {
                    // Drop on the floor.
                  }
                  some(s) {
                    img.size.height = geometry::px_to_au(s);
                  }
                }
              }
              HTMLDivElement | HTMLImageElement(*) | HTMLHeadElement |
              HTMLScriptElement | UnknownElement {
                // Drop on the floor.
              }
            }
          }

          Text(*) {
            fail ~"attempt to link up an attribute to a text node"
          }
        }
    })
}

fn build_element_kind(tag_name: ~str) -> ~ElementKind {
    alt tag_name {
      ~"div" { ~HTMLDivElement }
      ~"img" {
        ~HTMLImageElement({
            mut size: Size2D(geometry::px_to_au(100),
                             geometry::px_to_au(100))
        })
      }
      ~"script" { ~HTMLScriptElement }
      ~"head" { ~HTMLHeadElement }
      _ { ~UnknownElement  }
    }
}

#[doc="Runs a task that coordinates parsing links to css stylesheets.

This function should be spawned in a separate task and spins waiting
for the html builder to find links to css stylesheets and sends off
tasks to parse each link.  When the html process finishes, it notifies
the listener, who then collects the css rules from each task it
spawned, collates them, and sends them to the given result channel.

# Arguments

* `to_parent` - A channel on which to send back the full set of rules.
* `from_parent` - A port on which to receive new links.

"]
fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::port<CSSMessage>) {
    let mut result_vec = ~[];

    loop {
        alt from_parent.recv() {
          File(filename) {
            let result_port = comm::port();
            let result_chan = comm::chan(result_port);
            let filename = copy filename;
            task::spawn(|| {
                //TODO: deal with extraneous copies
                let filename <- copy filename;
                let css_stream = css_lexer::spawn_css_lexer_task(filename);
                let mut css_rules = css_builder::build_stylesheet(css_stream);
                result_chan.send(css_rules);
            });

            push(result_vec, result_port);
          }
          Exit {
            break;
          }
        }
    }

    let css_rules = flat_map(result_vec, |result_port| { result_port.recv() });

    to_parent.send(css_rules);
}

fn js_script_listener(to_parent : chan<~[~[u8]]>, from_parent : comm::port<js_message>) {
    let mut result_vec = ~[];

    loop {
        alt from_parent.recv() {
          js_file(filename) {
            let result_port = comm::port();
            let result_chan = comm::chan(result_port);
            let filename = copy filename;
            do task::spawn {
                let filename <- copy filename;
                let file_try = io::read_whole_file(filename);
                if (file_try.is_ok()) {
                    result_chan.send(file_try.get());
                } else {
                    #error("error loading script %s", filename);
                }
            }
            push(result_vec, result_port);
          }
          js_exit {
            break;
          }
        }
    }

    let js_scripts = vec::map(result_vec, |result_port| result_port.recv());
    to_parent.send(js_scripts);
}

#[warn(no_non_implicitly_copyable_typarams)]
fn build_dom(scope: NodeScope, stream: comm::port<Token>) -> (Node, comm::port<Stylesheet>, comm::port<~[~[u8]]>) {
    // The current reference node.
    let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement)));
    // We will spawn a separate task to parse any css that is
    // encountered, each link to a stylesheet is sent to the waiting
    // task.  After the html sheet has been fully read, the spawned
    // task will collect the results of all linked style data and send
    // it along the returned port.
    let style_port = comm::port();
    let child_chan = comm::chan(style_port);
    let style_chan = task::spawn_listener(|child_port| {
        css_link_listener(child_chan, child_port);
    });

    let js_port = comm::port();
    let child_chan = comm::chan(js_port);
    let js_chan = task::spawn_listener(|child_port| {
        js_script_listener(child_chan, child_port);
    });

    loop {
        let token = stream.recv();
        alt token {
          parser::Eof { break; }
          parser::StartOpeningTag(tag_name) {
            #debug["starting tag %s", tag_name];
            let element_kind = build_element_kind(tag_name);
            let new_node = scope.new_node(Element(ElementData(copy tag_name, element_kind)));
            scope.add_child(cur_node, new_node);
            cur_node = new_node;
          }
          parser::Attr(key, value) {
            #debug["attr: %? = %?", key, value];
            link_up_attribute(scope, cur_node, copy key, copy value);
          }
          parser::EndOpeningTag {
            #debug("end opening tag");
          }
          // TODO: Fail more gracefully (i.e. according to the HTML5
          //       spec) if we close more tags than we open.
          parser::SelfCloseTag {
            //TODO: check for things other than the link tag
            scope.read(cur_node, |n| {
                alt *n.kind {
                  Element(elmt) if elmt.tag_name == ~"link" {
                    alt elmt.get_attr(~"rel") {
                      some(r) if r == ~"stylesheet" {
                        alt elmt.get_attr(~"href") {
                          some(filename) {
                            #debug["Linking to a css sheet named: %s", filename];
                            style_chan.send(File(copy filename));
                          }
                          none { /* fall through*/ }
                        }
                      }
                      _ { /* fall through*/ }
                    }
                  }
                  _ { /* fall through*/ }
                }
            });
            cur_node = scope.get_parent(cur_node).get();
          }
          parser::EndTag(tag_name) {
            // TODO: Assert that the closing tag has the right name.
            scope.read(cur_node, |n| {
                alt *n.kind {
                  Element(elmt) if elmt.tag_name == ~"script" {
                    alt elmt.get_attr(~"src") {
                      some(filename) {
                        #debug["Linking to a js script named: %s", filename];
                        js_chan.send(js_file(copy filename));
                      }
                      none { /* fall through */ }
                    }
                  }
                  _ { /* fall though */ }
                }
            });
            cur_node = scope.get_parent(cur_node).get();
          }
          parser::Text(s) if !s.is_whitespace() {
            let new_node = scope.new_node(Text(copy s));
            scope.add_child(cur_node, new_node);
          }
          parser::Text(_) {
            // FIXME: Whitespace should not be ignored.
          }
          parser::Doctype {
            // TODO: Do something here...
          }
        }
    }

    style_chan.send(Exit);
    js_chan.send(js_exit);

    ret (cur_node, style_port, js_port);
}
<commit_msg>Fix compile error<commit_after>#[doc="Constructs a DOM tree from an incoming token stream."]

import dom::base::{Attr, Element, ElementData, ElementKind, HTMLDivElement, HTMLHeadElement,
                   HTMLScriptElement};
import dom::base::{HTMLImageElement, Node, NodeScope, Text, TreeReadMethods, TreeWriteMethods};
import dom::base::{UnknownElement};
import dom::rcu::WriterMethods;
import geom::size::Size2D;
import gfx::geometry;
import gfx::geometry::au;
import parser = parser::html_lexer;
import parser::Token;
import dom::style::Stylesheet;
import vec::{push, push_all_move, flat_map};

import dvec::extensions;

enum CSSMessage {
    File(~str),
    Exit
}

enum js_message {
    js_file(~str),
    js_exit
}

#[warn(no_non_implicitly_copyable_typarams)]
fn link_up_attribute(scope: NodeScope, node: Node, -key: ~str, -value: ~str) {
    // TODO: Implement atoms so that we don't always perform string comparisons.
    scope.read(node, |node_contents| {
        alt *node_contents.kind {
          Element(element) {
            element.attrs.push(~Attr(copy key, copy value));
            alt *element.kind {
              HTMLImageElement(img) if key == ~"width" {
                alt int::from_str(value) {
                  none {
                    // Drop on the floor.
                  }
                  some(s) { img.size.width = geometry::px_to_au(s); }
                }
              }
              HTMLImageElement(img) if key == ~"height" {
                alt int::from_str(value) {
                  none {
                    // Drop on the floor.
                  }
                  some(s) {
                    img.size.height = geometry::px_to_au(s);
                  }
                }
              }
              HTMLDivElement | HTMLImageElement(*) | HTMLHeadElement |
              HTMLScriptElement | UnknownElement {
                // Drop on the floor.
              }
            }
          }

          Text(*) {
            fail ~"attempt to link up an attribute to a text node"
          }
        }
    })
}

fn build_element_kind(tag_name: ~str) -> ~ElementKind {
    alt tag_name {
      ~"div" { ~HTMLDivElement }
      ~"img" {
        ~HTMLImageElement({
            mut size: Size2D(geometry::px_to_au(100),
                             geometry::px_to_au(100))
        })
      }
      ~"script" { ~HTMLScriptElement }
      ~"head" { ~HTMLHeadElement }
      _ { ~UnknownElement  }
    }
}

#[doc="Runs a task that coordinates parsing links to css stylesheets.

This function should be spawned in a separate task and spins waiting
for the html builder to find links to css stylesheets and sends off
tasks to parse each link.  When the html process finishes, it notifies
the listener, who then collects the css rules from each task it
spawned, collates them, and sends them to the given result channel.

# Arguments

* `to_parent` - A channel on which to send back the full set of rules.
* `from_parent` - A port on which to receive new links.

"]
fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::port<CSSMessage>) {
    let mut result_vec = ~[];

    loop {
        alt from_parent.recv() {
          File(filename) {
            let result_port = comm::port();
            let result_chan = comm::chan(result_port);
            let filename = copy filename;
            task::spawn(|| {
                //TODO: deal with extraneous copies
                let filename <- copy filename;
                let css_stream = css_lexer::spawn_css_lexer_task(filename);
                let mut css_rules = css_builder::build_stylesheet(css_stream);
                result_chan.send(css_rules);
            });

            push(result_vec, result_port);
          }
          Exit {
            break;
          }
        }
    }

    let css_rules = flat_map(result_vec, |result_port| { result_port.recv() });

    to_parent.send(css_rules);
}

fn js_script_listener(to_parent : comm::chan<~[~[u8]]>, from_parent : comm::port<js_message>) {
    let mut result_vec = ~[];

    loop {
        alt from_parent.recv() {
          js_file(filename) {
            let result_port = comm::port();
            let result_chan = comm::chan(result_port);
            let filename = copy filename;
            do task::spawn {
                let filename <- copy filename;
                let file_try = io::read_whole_file(filename);
                if (file_try.is_ok()) {
                    result_chan.send(file_try.get());
                } else {
                    #error("error loading script %s", filename);
                }
            }
            push(result_vec, result_port);
          }
          js_exit {
            break;
          }
        }
    }

    let js_scripts = vec::map(result_vec, |result_port| result_port.recv());
    to_parent.send(js_scripts);
}

#[warn(no_non_implicitly_copyable_typarams)]
fn build_dom(scope: NodeScope, stream: comm::port<Token>) -> (Node, comm::port<Stylesheet>, comm::port<~[~[u8]]>) {
    // The current reference node.
    let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement)));
    // We will spawn a separate task to parse any css that is
    // encountered, each link to a stylesheet is sent to the waiting
    // task.  After the html sheet has been fully read, the spawned
    // task will collect the results of all linked style data and send
    // it along the returned port.
    let style_port = comm::port();
    let child_chan = comm::chan(style_port);
    let style_chan = task::spawn_listener(|child_port| {
        css_link_listener(child_chan, child_port);
    });

    let js_port = comm::port();
    let child_chan = comm::chan(js_port);
    let js_chan = task::spawn_listener(|child_port| {
        js_script_listener(child_chan, child_port);
    });

    loop {
        let token = stream.recv();
        alt token {
          parser::Eof { break; }
          parser::StartOpeningTag(tag_name) {
            #debug["starting tag %s", tag_name];
            let element_kind = build_element_kind(tag_name);
            let new_node = scope.new_node(Element(ElementData(copy tag_name, element_kind)));
            scope.add_child(cur_node, new_node);
            cur_node = new_node;
          }
          parser::Attr(key, value) {
            #debug["attr: %? = %?", key, value];
            link_up_attribute(scope, cur_node, copy key, copy value);
          }
          parser::EndOpeningTag {
            #debug("end opening tag");
          }
          // TODO: Fail more gracefully (i.e. according to the HTML5
          //       spec) if we close more tags than we open.
          parser::SelfCloseTag {
            //TODO: check for things other than the link tag
            scope.read(cur_node, |n| {
                alt *n.kind {
                  Element(elmt) if elmt.tag_name == ~"link" {
                    alt elmt.get_attr(~"rel") {
                      some(r) if r == ~"stylesheet" {
                        alt elmt.get_attr(~"href") {
                          some(filename) {
                            #debug["Linking to a css sheet named: %s", filename];
                            style_chan.send(File(copy filename));
                          }
                          none { /* fall through*/ }
                        }
                      }
                      _ { /* fall through*/ }
                    }
                  }
                  _ { /* fall through*/ }
                }
            });
            cur_node = scope.get_parent(cur_node).get();
          }
          parser::EndTag(tag_name) {
            // TODO: Assert that the closing tag has the right name.
            scope.read(cur_node, |n| {
                alt *n.kind {
                  Element(elmt) if elmt.tag_name == ~"script" {
                    alt elmt.get_attr(~"src") {
                      some(filename) {
                        #debug["Linking to a js script named: %s", filename];
                        js_chan.send(js_file(copy filename));
                      }
                      none { /* fall through */ }
                    }
                  }
                  _ { /* fall though */ }
                }
            });
            cur_node = scope.get_parent(cur_node).get();
          }
          parser::Text(s) if !s.is_whitespace() {
            let new_node = scope.new_node(Text(copy s));
            scope.add_child(cur_node, new_node);
          }
          parser::Text(_) {
            // FIXME: Whitespace should not be ignored.
          }
          parser::Doctype {
            // TODO: Do something here...
          }
        }
    }

    style_chan.send(Exit);
    js_chan.send(js_exit);

    ret (cur_node, style_port, js_port);
}
<|endoftext|>


<commit_before>use std::ops::{Index, IndexMut};
use std::iter::{Iterator, repeat};

use graph::{Edge, Graph};

pub struct AdjacencyMatrix {
    rows: Vec<Vec<u32>>,
}

impl AdjacencyMatrix {
    fn new(size: usize) -> AdjacencyMatrix {
        let row = vec![0; size];
        let rows = repeat(row).take(size).collect();

        AdjacencyMatrix { rows: rows }
    }

    pub fn from_graph(g: &Graph) -> AdjacencyMatrix {
        let mut m = AdjacencyMatrix::new(g.vertex_count);

        for &Edge { x, y } in &g.edges {
            m[x][y] = 1;
            if !g.directed {
                m[y][x] = 1;
            }
        }

        m
    }

    pub fn size(&self) -> usize {
        self.rows.len()
    }
}

// For convenience, enable writing matrix[x] instead of matrix.rows[x].

impl Index<usize> for AdjacencyMatrix {
    type Output = Vec<u32>;

    fn index<'a>(&'a self, _index: usize) -> &'a Vec<u32> {
        &self.rows[_index]
    }
}

impl IndexMut<usize> for AdjacencyMatrix {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut Vec<u32> {
        &mut self.rows[_index]
    }
}

// Breadth-first search.

struct BreadthFirstSearch<'a> {
    matrix: &'a AdjacencyMatrix,
    visited: Vec<bool>,
    queue: Vec<usize>,
    y: usize,
}

impl AdjacencyMatrix {
    pub fn breadth_first_search(&self, start: usize) -> BreadthFirstSearch {
        let mut visited = vec!(false; self.size());
        visited[start] = true;

        BreadthFirstSearch {
            matrix: self,
            visited: visited,
            queue: vec![start],
            y: 0
        }
    }
}

impl<'a> Iterator for BreadthFirstSearch<'a> {
    type Item = Edge;

    fn next(&mut self) -> Option<Edge> {
        while !self.queue.is_empty() {
            let x = self.queue[0];

            for y in self.y..self.matrix.size() {
                if self.visited[y] || self.matrix[x][y] == 0 {
                    continue;
                }
                self.visited[y] = true;
                self.queue.push(y);
                self.y = y + 1;
                return Some(Edge { x: x, y: y });
            }

            // Process the next element in the queue.
            self.queue.remove(0);
            self.y = 0;
        }

        None
    }
}

// Breadth-first search using std::iter::Unfold. In this situation there's no reason to use it over
// implementing Iterator directly. Unfold seems to shine in situations where we can just pass it a
// closure, but here we cannot use a closure because we need to return an iterator (see
// http://is.gd/2MDM1r).

// struct BFS<'a> {
//     matrix: &'a AdjacencyMatrix,
//     visited: Vec<bool>,
//     queue: Vec<usize>,
//     y: usize,
// }

// impl AdjacencyMatrix {
//     pub fn breadth_first_search(&self, start: usize) ->
//         Unfold<BFS, fn(&mut BFS) -> Option<Edge>> {

//         let mut visited = vec!(false; self.size());
//         visited[start] = true;

//         let state = BFS {
//             matrix: self,
//             visited: visited,
//             queue: vec![start],
//             y: 0
//         };

//         Unfold::new(state, unfold_breadth_first_search)
//     }
// }

// fn unfold_breadth_first_search(state: &mut BFS) -> Option<Edge> {
//     while !state.queue.is_empty() {
//         let x = state.queue[0];

//         for y in state.y..state.matrix.size() {
//             if state.visited[y] || state.matrix[x][y] == 0 {
//                 continue;
//             }

//             state.visited[y] = true;
//             state.queue.push(y);
//             state.y = y + 1;

//             return Some(Edge { x: x, y: y });
//         }

//         // Process the next element in the queue.
//         state.queue.remove(0);
//         state.y = 0;
//     }

//     None
// }

// Breadth-first search using a callback closure. The implementation is much simpler than the
// iterator-based BFS, however the external API is not as nice (forced to use a callback closure
// instead of a classic for loop).

// impl AdjacencyMatrix {
//     pub fn breadth_first_search<C>(&self, start: usize, mut callback: C)
//        where C: FnMut(Edge) -> bool {

//         let mut visited = vec!(false; self.size());
//         visited[start] = true;

//         let mut queue = vec![start];

//         while queue.len() > 0 {
//             // Dequeue first element.
//             let x = queue.remove(0);

//             for y in 0..self.size() {
//                 if visited[y] || self[x][y] == 0 {
//                     continue;
//                 }
//                 visited[y] = true;
//                 queue.push(y);
//                 // The edge callback can return true to abort the current graph traversal.
//                 if callback(Edge { x: x, y: y }) {
//                     return;
//                 }
//             }
//         }
//     }
// }
<commit_msg>[edge_connectivity/rust] Rename m to matrix for clarity<commit_after>use std::ops::{Index, IndexMut};
use std::iter::{Iterator, repeat};

use graph::{Edge, Graph};

pub struct AdjacencyMatrix {
    rows: Vec<Vec<u32>>,
}

impl AdjacencyMatrix {
    fn new(size: usize) -> AdjacencyMatrix {
        let row = vec![0; size];
        let rows = repeat(row).take(size).collect();

        AdjacencyMatrix { rows: rows }
    }

    pub fn from_graph(g: &Graph) -> AdjacencyMatrix {
        let mut matrix = AdjacencyMatrix::new(g.vertex_count);

        for &Edge { x, y } in &g.edges {
            matrix[x][y] = 1;
            if !g.directed {
                matrix[y][x] = 1;
            }
        }

        matrix
    }

    pub fn size(&self) -> usize {
        self.rows.len()
    }
}

// For convenience, enable writing matrix[x] instead of matrix.rows[x].

impl Index<usize> for AdjacencyMatrix {
    type Output = Vec<u32>;

    fn index<'a>(&'a self, _index: usize) -> &'a Vec<u32> {
        &self.rows[_index]
    }
}

impl IndexMut<usize> for AdjacencyMatrix {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut Vec<u32> {
        &mut self.rows[_index]
    }
}

// Breadth-first search.

struct BreadthFirstSearch<'a> {
    matrix: &'a AdjacencyMatrix,
    visited: Vec<bool>,
    queue: Vec<usize>,
    y: usize,
}

impl AdjacencyMatrix {
    pub fn breadth_first_search(&self, start: usize) -> BreadthFirstSearch {
        let mut visited = vec!(false; self.size());
        visited[start] = true;

        BreadthFirstSearch {
            matrix: self,
            visited: visited,
            queue: vec![start],
            y: 0
        }
    }
}

impl<'a> Iterator for BreadthFirstSearch<'a> {
    type Item = Edge;

    fn next(&mut self) -> Option<Edge> {
        while !self.queue.is_empty() {
            let x = self.queue[0];

            for y in self.y..self.matrix.size() {
                if self.visited[y] || self.matrix[x][y] == 0 {
                    continue;
                }
                self.visited[y] = true;
                self.queue.push(y);
                self.y = y + 1;
                return Some(Edge { x: x, y: y });
            }

            // Process the next element in the queue.
            self.queue.remove(0);
            self.y = 0;
        }

        None
    }
}

// Breadth-first search using std::iter::Unfold. In this situation there's no reason to use it over
// implementing Iterator directly. Unfold seems to shine in situations where we can just pass it a
// closure, but here we cannot use a closure because we need to return an iterator (see
// http://is.gd/2MDM1r).

// struct BFS<'a> {
//     matrix: &'a AdjacencyMatrix,
//     visited: Vec<bool>,
//     queue: Vec<usize>,
//     y: usize,
// }

// impl AdjacencyMatrix {
//     pub fn breadth_first_search(&self, start: usize) ->
//         Unfold<BFS, fn(&mut BFS) -> Option<Edge>> {

//         let mut visited = vec!(false; self.size());
//         visited[start] = true;

//         let state = BFS {
//             matrix: self,
//             visited: visited,
//             queue: vec![start],
//             y: 0
//         };

//         Unfold::new(state, unfold_breadth_first_search)
//     }
// }

// fn unfold_breadth_first_search(state: &mut BFS) -> Option<Edge> {
//     while !state.queue.is_empty() {
//         let x = state.queue[0];

//         for y in state.y..state.matrix.size() {
//             if state.visited[y] || state.matrix[x][y] == 0 {
//                 continue;
//             }

//             state.visited[y] = true;
//             state.queue.push(y);
//             state.y = y + 1;

//             return Some(Edge { x: x, y: y });
//         }

//         // Process the next element in the queue.
//         state.queue.remove(0);
//         state.y = 0;
//     }

//     None
// }

// Breadth-first search using a callback closure. The implementation is much simpler than the
// iterator-based BFS, however the external API is not as nice (forced to use a callback closure
// instead of a classic for loop).

// impl AdjacencyMatrix {
//     pub fn breadth_first_search<C>(&self, start: usize, mut callback: C)
//        where C: FnMut(Edge) -> bool {

//         let mut visited = vec!(false; self.size());
//         visited[start] = true;

//         let mut queue = vec![start];

//         while queue.len() > 0 {
//             // Dequeue first element.
//             let x = queue.remove(0);

//             for y in 0..self.size() {
//                 if visited[y] || self[x][y] == 0 {
//                     continue;
//                 }
//                 visited[y] = true;
//                 queue.push(y);
//                 // The edge callback can return true to abort the current graph traversal.
//                 if callback(Edge { x: x, y: y }) {
//                     return;
//                 }
//             }
//         }
//     }
// }
<|endoftext|>


<commit_before>
extern crate cpython;
extern crate numpy;

use numpy::*;

#[test]
fn new() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let n = 3;
    let m = 5;
    let arr = PyArray::new(gil.python(), &np, &[n, m], NPY_TYPES::NPY_DOUBLE);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [m as isize * 8, 8]);
}

#[test]
fn zeros() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let n = 3;
    let m = 5;
    let arr = PyArray::zeros(gil.python(),
                             &np,
                             &[n, m],
                             NPY_TYPES::NPY_DOUBLE,
                             NPY_ORDER::NPY_CORDER);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [m as isize * 8, 8]);

    let arr = PyArray::zeros(gil.python(),
                             &np,
                             &[n, m],
                             NPY_TYPES::NPY_DOUBLE,
                             NPY_ORDER::NPY_FORTRANORDER);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [8, n as isize * 8]);
}

#[test]
fn arange() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::arange(gil.python(), &np, 0.0, 1.0, 0.1, NPY_TYPES::NPY_DOUBLE);
    println!("ndim = {:?}", arr.ndim());
    println!("dims = {:?}", arr.dims());
    println!("array = {:?}", arr.as_slice::<f64>().unwrap());
}

#[test]
fn as_array() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::zeros(gil.python(),
                             &np,
                             &[3, 2, 4],
                             NPY_TYPES::NPY_DOUBLE,
                             NPY_ORDER::NPY_CORDER);
    let a = arr.as_array::<f64>().unwrap();
    assert_eq!(arr.shape(), a.shape());
    assert_eq!(arr.strides().iter().map(|x| x / 8).collect::<Vec<_>>(),
               a.strides());
}

#[test]
#[should_panic]
fn as_array_panic() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::zeros(gil.python(),
                             &np,
                             &[3, 2, 4],
                             NPY_TYPES::NPY_INT,
                             NPY_ORDER::NPY_CORDER);
    let _a = arr.as_array::<f32>().unwrap();
}

#[test]
fn into_pyarray() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();

    let a = vec![1, 2, 3];
    let arr = a.into_pyarray(gil.python(), &np);
    println!("arr.shape = {:?}", arr.shape());
    println!("arr = {:?}", arr.as_slice::<i32>().unwrap());
    panic!("into_pyarray!")
}
<commit_msg>Remove panic<commit_after>
extern crate cpython;
extern crate numpy;

use numpy::*;

#[test]
fn new() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let n = 3;
    let m = 5;
    let arr = PyArray::new(gil.python(), &np, &[n, m], NPY_TYPES::NPY_DOUBLE);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [m as isize * 8, 8]);
}

#[test]
fn zeros() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let n = 3;
    let m = 5;
    let arr = PyArray::zeros(gil.python(),
                             &np,
                             &[n, m],
                             NPY_TYPES::NPY_DOUBLE,
                             NPY_ORDER::NPY_CORDER);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [m as isize * 8, 8]);

    let arr = PyArray::zeros(gil.python(),
                             &np,
                             &[n, m],
                             NPY_TYPES::NPY_DOUBLE,
                             NPY_ORDER::NPY_FORTRANORDER);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [8, n as isize * 8]);
}

#[test]
fn arange() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::arange(gil.python(), &np, 0.0, 1.0, 0.1, NPY_TYPES::NPY_DOUBLE);
    println!("ndim = {:?}", arr.ndim());
    println!("dims = {:?}", arr.dims());
    println!("array = {:?}", arr.as_slice::<f64>().unwrap());
}

#[test]
fn as_array() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::zeros(gil.python(),
                             &np,
                             &[3, 2, 4],
                             NPY_TYPES::NPY_DOUBLE,
                             NPY_ORDER::NPY_CORDER);
    let a = arr.as_array::<f64>().unwrap();
    assert_eq!(arr.shape(), a.shape());
    assert_eq!(arr.strides().iter().map(|x| x / 8).collect::<Vec<_>>(),
               a.strides());
}

#[test]
#[should_panic]
fn as_array_panic() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::zeros(gil.python(),
                             &np,
                             &[3, 2, 4],
                             NPY_TYPES::NPY_INT,
                             NPY_ORDER::NPY_CORDER);
    let _a = arr.as_array::<f32>().unwrap();
}

#[test]
fn into_pyarray() {
    let gil = cpython::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();

    let a = vec![1, 2, 3];
    let arr = a.into_pyarray(gil.python(), &np);
    println!("arr.shape = {:?}", arr.shape());
    println!("arr = {:?}", arr.as_slice::<i32>().unwrap());
}
<|endoftext|>