<commit_before><commit_msg>oops, add cli stuff<commit_after>use std::thread::{JoinHandle, spawn};
use std::sync::mpsc::{Receiver, channel};
use std::io::{self, BufRead};
extern crate itertools;
use self::itertools::Itertools;
use std::sync::mpsc::TryRecvError;

extern crate either;

pub enum Decision {
    None,
    ImportLines(String),
    ShowCategories,
    ResetCursor,
    Respond,
    Tell(String),
    ConnectServer,
    ConnectIrc(String),
    ConnectDiscord(String),
}

pub fn new() -> Iter {
    let (sender, receiver) = channel();
    Iter{
        _thread: spawn(move || {
            let stdin = io::stdin();
            for line in stdin.lock().lines() {
                match line {
                    Ok(s) => {
                        if sender.send(s).is_err() {
                            break;
                        }
                    },
                    Err(_) => {
                        break;
                    }
                }
            }
        }),
        receiver: receiver,
    }
}

pub struct Iter {
    _thread: JoinHandle<()>,
    receiver: Receiver<String>,
}

impl Iterator for Iter {
    type Item = Decision;

    fn next(&mut self) -> Option<Decision> {
        match self.receiver.try_recv() {
            Ok(s) => {
                let params = s.split('`')
                    .enumerate()
                    .flat_map(|(iter, s)| {
                        // If we are not in a quotation
                        if iter % 2 == 0 {
                            either::Left(s.split(' '))
                        } else {
                            use std::iter::once;
                            either::Right(once(s))
                        }
                    })
                    .filter(|s| !s.is_empty()).collect_vec();

                match params.len() {
                    0 => {
                        println!("Available commands: import, connect, list, respond, tell");
                        Some(Decision::ResetCursor)
                    },
                    _ => {
                        match params[0] {
                            "import" => {
                                if params.len() != 3 {
                                    println!("Ignored: import takes 2 params");
                                    Some(Decision::ResetCursor)
                                } else {
                                    match params[1] {
                                        "lines" => {
                                            println!("Importing lines from `{}`...", params[2]);
                                            Some(Decision::ImportLines(params[2].to_string()))
                                        },
                                        _ => {
                                            println!("Ignored: Unrecognized import type");
                                            Some(Decision::ResetCursor)
                                        },
                                    }
                                }
                            },
                            "connect" => {
                                if params.len() < 2 {
                                    println!("Ignored: connect takes at least a connect type");
                                    println!("Connect types: server, irc, discord");
                                    Some(Decision::ResetCursor)
                                } else {
                                    match params[1] {
                                        "server" => {
                                            if params.len() != 2 {
                                                println!("Ignored: no extra parameters needed");
                                                Some(Decision::ResetCursor)
                                            } else {
                                                Some(Decision::ConnectServer)
                                            }
                                        },
                                        "irc" => {
                                            if params.len() != 3 {
                                                println!("Ignored: connect irc requires a config path");
                                                Some(Decision::ResetCursor)
                                            } else {
                                                Some(Decision::ConnectIrc(params[3].to_string()))
                                            }
                                        },
                                        "discord" => {
                                            if params.len() != 3 {
                                                println!("Ignored: connect discord requires a config path");
                                                Some(Decision::ResetCursor)
                                            } else {
                                                Some(Decision::ConnectDiscord(params[3].to_string()))
                                            }
                                        },
                                        _ => {
                                            println!("Ignored: Unrecognized connect type");
                                            Some(Decision::ResetCursor)
                                        },
                                    }
                                }
                            },
                            "list" => {
                                if params.len() != 2 {
                                    println!("Ignored: list takes 1 param");
                                    Some(Decision::ResetCursor)
                                } else {
                                    match params[1] {
                                        "categories" => {
                                            Some(Decision::ShowCategories)
                                        },
                                        _ => {
                                            println!("Ignored: Unrecognized list type");
                                            Some(Decision::ResetCursor)
                                        },
                                    }
                                }
                            },
                            "respond" => {
                                if params.len() != 1 {
                                    println!("Ignored: respond takes no params");
                                    Some(Decision::ResetCursor)
                                } else {
                                    Some(Decision::Respond)
                                }
                            },
                            "tell" => {
                                if params.len() != 2 {
                                    println!("Ignored: respond takes 1 param");
                                    Some(Decision::ResetCursor)
                                } else {
                                    Some(Decision::Tell(params[1].to_string()))
                                }
                            },
                            _ => {
                                println!("Ignored: Unrecognized command");
                                Some(Decision::ResetCursor)
                            },
                        }
                    }
                }
            },
            Err(TryRecvError::Empty) => {
                Some(Decision::None)
            },
            Err(TryRecvError::Disconnected) => {
                None
            },
        }
    }
}
<|endoftext|>


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

/// The result of a generator resumption.
///
/// This enum is returned from the `Generator::resume` method and indicates the
/// possible return values of a generator. Currently this corresponds to either
/// a suspension point (`Yielded`) or a termination point (`Complete`).
#[derive(Debug)]
#[cfg_attr(not(stage0), lang = "generator_state")]
#[unstable(feature = "generator_trait", issue = "43122")]
pub enum State<Y, R> {
    /// The generator suspended with a value.
    ///
    /// This state indicates that a generator has been suspended, and typically
    /// corresponds to a `yield` statement. The value provided in this variant
    /// corresponds to the expression passed to `yield` and allows generators to
    /// provide a value each time they yield.
    Yielded(Y),

    /// The generator completed with a return value.
    ///
    /// This state indicates that a generator has finished execution with the
    /// provided value. Once a generator has returned `Complete` it is
    /// considered a programmer error to call `resume` again.
    Complete(R),
}

/// The trait implemented by builtin generator types.
///
/// Generators, also commonly referred to as coroutines, are currently an
/// experimental language feature in Rust. Added in [RFC 2033] generators are
/// currently intended to primarily provide a building block for async/await
/// syntax but will likely extend to also providing an ergonomic definition for
/// iterators and other primitives.
///
/// The syntax and semantics for generators is unstable and will require a
/// further RFC for stabilization. At this time, though, the syntax is
/// closure-like:
///
/// ```rust
/// #![feature(generators, generator_trait)]
///
/// use std::ops::{Generator, State};
///
/// fn main() {
///     let mut generator = || {
///         yield 1;
///         return "foo"
///     };
///
///     match generator.resume() {
///         State::Yielded(1) => {}
///         _ => panic!("unexpected return from resume"),
///     }
///     match generator.resume() {
///         State::Complete("foo") => {}
///         _ => panic!("unexpected return from resume"),
///     }
/// }
/// ```
///
/// More documentation of generators can be found in the unstable book.
///
/// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
#[cfg_attr(not(stage0), lang = "generator")]
#[unstable(feature = "generator_trait", issue = "43122")]
#[fundamental]
pub trait Generator {
    /// The type of value this generator yields.
    ///
    /// This associated type corresponds to the `yield` expression and the
    /// values which are allowed to be returned each time a generator yields.
    /// For example an iterator-as-a-generator would likely have this type as
    /// `T`, the type being iterated over.
    type Yield;

    /// The type of value this generator returns.
    ///
    /// This corresponds to the type returned from a generator either with a
    /// `return` statement or implicitly as the last expression of a generator
    /// literal. For example futures would use this as `Result<T, E>` as it
    /// represents a completed future.
    type Return;

    /// Resumes the execution of this generator.
    ///
    /// This function will resume execution of the generator or start execution
    /// if it hasn't already. This call will return back into the generator's
    /// last suspension point, resuming execution from the latest `yield`. The
    /// generator will continue executing until it either yields or returns, at
    /// which point this function will return.
    ///
    /// # Return value
    ///
    /// The `State` enum returned from this function indicates what state the
    /// generator is in upon returning. If the `Yielded` variant is returned
    /// then the generator has reached a suspension point and a value has been
    /// yielded out. Generators in this state are available for resumption at a
    /// later point.
    ///
    /// If `Complete` is returned then the generator has completely finished
    /// with the value provided. It is invalid for the generator to be resumed
    /// again.
    ///
    /// # Panics
    ///
    /// This function may panic if it is called after the `Complete` variant has
    /// been returned previously. While generator literals in the language are
    /// guaranteed to panic on resuming after `Complete`, this is not guaranteed
    /// for all implementations of the `Generator` trait.
    fn resume(&mut self) -> State<Self::Yield, Self::Return>;
}

#[unstable(feature = "generator_trait", issue = "43122")]
impl<'a, T> Generator for &'a mut T
    where T: Generator + ?Sized
{
    type Yield = T::Yield;
    type Return = T::Return;
    fn resume(&mut self) -> State<Self::Yield, Self::Return> {
        (**self).resume()
    }
}
<commit_msg>Derive traits for State.<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// The result of a generator resumption.
///
/// This enum is returned from the `Generator::resume` method and indicates the
/// possible return values of a generator. Currently this corresponds to either
/// a suspension point (`Yielded`) or a termination point (`Complete`).
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[cfg_attr(not(stage0), lang = "generator_state")]
#[unstable(feature = "generator_trait", issue = "43122")]
pub enum State<Y, R> {
    /// The generator suspended with a value.
    ///
    /// This state indicates that a generator has been suspended, and typically
    /// corresponds to a `yield` statement. The value provided in this variant
    /// corresponds to the expression passed to `yield` and allows generators to
    /// provide a value each time they yield.
    Yielded(Y),

    /// The generator completed with a return value.
    ///
    /// This state indicates that a generator has finished execution with the
    /// provided value. Once a generator has returned `Complete` it is
    /// considered a programmer error to call `resume` again.
    Complete(R),
}

/// The trait implemented by builtin generator types.
///
/// Generators, also commonly referred to as coroutines, are currently an
/// experimental language feature in Rust. Added in [RFC 2033] generators are
/// currently intended to primarily provide a building block for async/await
/// syntax but will likely extend to also providing an ergonomic definition for
/// iterators and other primitives.
///
/// The syntax and semantics for generators is unstable and will require a
/// further RFC for stabilization. At this time, though, the syntax is
/// closure-like:
///
/// ```rust
/// #![feature(generators, generator_trait)]
///
/// use std::ops::{Generator, State};
///
/// fn main() {
///     let mut generator = || {
///         yield 1;
///         return "foo"
///     };
///
///     match generator.resume() {
///         State::Yielded(1) => {}
///         _ => panic!("unexpected return from resume"),
///     }
///     match generator.resume() {
///         State::Complete("foo") => {}
///         _ => panic!("unexpected return from resume"),
///     }
/// }
/// ```
///
/// More documentation of generators can be found in the unstable book.
///
/// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
#[cfg_attr(not(stage0), lang = "generator")]
#[unstable(feature = "generator_trait", issue = "43122")]
#[fundamental]
pub trait Generator {
    /// The type of value this generator yields.
    ///
    /// This associated type corresponds to the `yield` expression and the
    /// values which are allowed to be returned each time a generator yields.
    /// For example an iterator-as-a-generator would likely have this type as
    /// `T`, the type being iterated over.
    type Yield;

    /// The type of value this generator returns.
    ///
    /// This corresponds to the type returned from a generator either with a
    /// `return` statement or implicitly as the last expression of a generator
    /// literal. For example futures would use this as `Result<T, E>` as it
    /// represents a completed future.
    type Return;

    /// Resumes the execution of this generator.
    ///
    /// This function will resume execution of the generator or start execution
    /// if it hasn't already. This call will return back into the generator's
    /// last suspension point, resuming execution from the latest `yield`. The
    /// generator will continue executing until it either yields or returns, at
    /// which point this function will return.
    ///
    /// # Return value
    ///
    /// The `State` enum returned from this function indicates what state the
    /// generator is in upon returning. If the `Yielded` variant is returned
    /// then the generator has reached a suspension point and a value has been
    /// yielded out. Generators in this state are available for resumption at a
    /// later point.
    ///
    /// If `Complete` is returned then the generator has completely finished
    /// with the value provided. It is invalid for the generator to be resumed
    /// again.
    ///
    /// # Panics
    ///
    /// This function may panic if it is called after the `Complete` variant has
    /// been returned previously. While generator literals in the language are
    /// guaranteed to panic on resuming after `Complete`, this is not guaranteed
    /// for all implementations of the `Generator` trait.
    fn resume(&mut self) -> State<Self::Yield, Self::Return>;
}

#[unstable(feature = "generator_trait", issue = "43122")]
impl<'a, T> Generator for &'a mut T
    where T: Generator + ?Sized
{
    type Yield = T::Yield;
    type Return = T::Return;
    fn resume(&mut self) -> State<Self::Yield, Self::Return> {
        (**self).resume()
    }
}
<|endoftext|>


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

//! A priority queue implemented with a binary heap

use core::old_iter::BaseIter;
use core::util::{replace, swap};

#[abi = "rust-intrinsic"]
extern "rust-intrinsic" {
    fn move_val_init<T>(dst: &mut T, src: T);
    fn init<T>() -> T;
    #[cfg(not(stage0))]
    fn uninit<T>() -> T;
}

pub struct PriorityQueue<T> {
    priv data: ~[T],
}

impl<T:Ord> BaseIter<T> for PriorityQueue<T> {
    /// Visit all values in the underlying vector.
    ///
    /// The values are **not** visited in order.
    #[cfg(stage0)]
    fn each(&self, f: &fn(&T) -> bool) { self.data.each(f) }
    /// Visit all values in the underlying vector.
    ///
    /// The values are **not** visited in order.
    #[cfg(not(stage0))]
    fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.each(f) }

    fn size_hint(&self) -> Option<uint> { self.data.size_hint() }
}

impl<T:Ord> Container for PriorityQueue<T> {
    /// Returns the length of the queue
    fn len(&const self) -> uint { vec::uniq_len(&const self.data) }

    /// Returns true if a queue contains no elements
    fn is_empty(&const self) -> bool { self.len() == 0 }
}

impl<T:Ord> Mutable for PriorityQueue<T> {
    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }
}

pub impl <T:Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    fn top<'a>(&'a self) -> &'a T { &self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    fn maybe_top<'a>(&'a self) -> Option<&'a T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the number of elements the queue can hold without reallocating
    fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let mut item = self.data.pop();
        if !self.is_empty() {
            swap(&mut item, &mut self.data[0]);
            self.siftdown(0);
        }
        item
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        let new_len = self.len() - 1;
        self.siftup(0, new_len);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, mut item: T) -> T {
        if !self.is_empty() && self.data[0] > item {
            swap(&mut item, &mut self.data[0]);
            self.siftdown(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, mut item: T) -> T {
        swap(&mut item, &mut self.data[0]);
        self.siftdown(0);
        item
    }

    /// Consume the PriorityQueue and return the underlying vector
    fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v }

    /// Consume the PriorityQueue and return a vector in sorted
    /// (ascending) order
    fn to_sorted_vec(self) -> ~[T] {
        let mut q = self;
        let mut end = q.len();
        while end > 1 {
            end -= 1;
            vec::swap(q.data, 0, end);
            q.siftdown_range(0, end)
        }
        q.to_vec()
    }

    /// Create an empty PriorityQueue
    fn new() -> PriorityQueue<T> { PriorityQueue{data: ~[],} }

    /// Create a PriorityQueue from a vector (heapify)
    fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
        let mut q = PriorityQueue{data: xs,};
        let mut n = q.len() / 2;
        while n > 0 {
            n -= 1;
            q.siftdown(n)
        }
        q
    }

    // The implementations of siftup and siftdown use unsafe blocks in
    // order to move an element out of the vector (leaving behind a
    // junk element), shift along the others and move it back into the
    // vector over the junk element.  This reduces the constant factor
    // compared to using swaps, which involves twice as many moves.

    #[cfg(not(stage0))]
    priv fn siftup(&mut self, start: uint, mut pos: uint) {
        unsafe {
            let new = *ptr::to_unsafe_ptr(&self.data[pos]);

            while pos > start {
                let parent = (pos - 1) >> 1;
                if new > self.data[parent] {
                    let x = replace(&mut self.data[parent], uninit());
                    move_val_init(&mut self.data[pos], x);
                    pos = parent;
                    loop
                }
                break
            }
            move_val_init(&mut self.data[pos], new);
        }
    }

    #[cfg(stage0)]
    priv fn siftup(&mut self, start: uint, mut pos: uint) {
        unsafe {
            let new = *ptr::to_unsafe_ptr(&self.data[pos]);

            while pos > start {
                let parent = (pos - 1) >> 1;
                if new > self.data[parent] {
                    let x = replace(&mut self.data[parent], init());
                    move_val_init(&mut self.data[pos], x);
                    pos = parent;
                    loop
                }
                break
            }
            move_val_init(&mut self.data[pos], new);
        }
    }

    #[cfg(not(stage0))]
    priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
        unsafe {
            let start = pos;
            let new = *ptr::to_unsafe_ptr(&self.data[pos]);

            let mut child = 2 * pos + 1;
            while child < end {
                let right = child + 1;
                if right < end && !(self.data[child] > self.data[right]) {
                    child = right;
                }
                let x = replace(&mut self.data[child], uninit());
                move_val_init(&mut self.data[pos], x);
                pos = child;
                child = 2 * pos + 1;
            }

            move_val_init(&mut self.data[pos], new);
            self.siftup(start, pos);
        }
    }

    #[cfg(stage0)]
    priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
        unsafe {
            let start = pos;
            let new = *ptr::to_unsafe_ptr(&self.data[pos]);

            let mut child = 2 * pos + 1;
            while child < end {
                let right = child + 1;
                if right < end && !(self.data[child] > self.data[right]) {
                    child = right;
                }
                let x = replace(&mut self.data[child], init());
                move_val_init(&mut self.data[pos], x);
                pos = child;
                child = 2 * pos + 1;
            }

            move_val_init(&mut self.data[pos], new);
            self.siftup(start, pos);
        }
    }

    priv fn siftdown(&mut self, pos: uint) {
        let len = self.len();
        self.siftdown_range(pos, len);
    }
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;
    use priority_queue::PriorityQueue::{from_vec, new};

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while !heap.is_empty() {
            assert!(heap.top() == sorted.last());
            assert!(heap.pop() == sorted.pop());
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert!(heap.len() == 3);
        assert!(*heap.top() == 9);
        heap.push(11);
        assert!(heap.len() == 4);
        assert!(*heap.top() == 11);
        heap.push(5);
        assert!(heap.len() == 5);
        assert!(*heap.top() == 11);
        heap.push(27);
        assert!(heap.len() == 6);
        assert!(*heap.top() == 27);
        heap.push(3);
        assert!(heap.len() == 7);
        assert!(*heap.top() == 27);
        heap.push(103);
        assert!(heap.len() == 8);
        assert!(*heap.top() == 103);
    }

    #[test]
    fn test_push_unique() {
        let mut heap = from_vec(~[~2, ~4, ~9]);
        assert!(heap.len() == 3);
        assert!(*heap.top() == ~9);
        heap.push(~11);
        assert!(heap.len() == 4);
        assert!(*heap.top() == ~11);
        heap.push(~5);
        assert!(heap.len() == 5);
        assert!(*heap.top() == ~11);
        heap.push(~27);
        assert!(heap.len() == 6);
        assert!(*heap.top() == ~27);
        heap.push(~3);
        assert!(heap.len() == 7);
        assert!(*heap.top() == ~27);
        heap.push(~103);
        assert!(heap.len() == 8);
        assert!(*heap.top() == ~103);
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert!(heap.len() == 5);
        assert!(heap.push_pop(6) == 6);
        assert!(heap.len() == 5);
        assert!(heap.push_pop(0) == 5);
        assert!(heap.len() == 5);
        assert!(heap.push_pop(4) == 5);
        assert!(heap.len() == 5);
        assert!(heap.push_pop(1) == 4);
        assert!(heap.len() == 5);
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert!(heap.len() == 5);
        assert!(heap.replace(6) == 5);
        assert!(heap.len() == 5);
        assert!(heap.replace(0) == 6);
        assert!(heap.len() == 5);
        assert!(heap.replace(4) == 5);
        assert!(heap.len() == 5);
        assert!(heap.replace(1) == 4);
        assert!(heap.len() == 5);
    }

    fn check_to_vec(data: ~[int]) {
        let heap = from_vec(copy data);
        assert!(merge_sort((copy heap).to_vec(), le) == merge_sort(data, le));
        assert!(heap.to_sorted_vec() == merge_sort(data, le));
    }

    #[test]
    fn test_to_vec() {
        check_to_vec(~[]);
        check_to_vec(~[5]);
        check_to_vec(~[3, 2]);
        check_to_vec(~[2, 3]);
        check_to_vec(~[5, 1, 2]);
        check_to_vec(~[1, 100, 2, 3]);
        check_to_vec(~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
        check_to_vec(~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
        check_to_vec(~[9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        check_to_vec(~[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
        check_to_vec(~[5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_pop() { let mut heap = new::<int>(); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = new::<int>();
        assert!(heap.maybe_pop().is_none());
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_top() { let empty = new::<int>(); empty.top(); }

    #[test]
    fn test_empty_maybe_top() {
        let empty = new::<int>();
        assert!(empty.maybe_top().is_none());
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_replace() { let mut heap = new(); heap.replace(5); }
}
<commit_msg>auto merge of #6461 : thestinger/rust/fix_priority_queue, r=pcwalton<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A priority queue implemented with a binary heap

use core::old_iter::BaseIter;
use core::util::{replace, swap};
use core::unstable::intrinsics::{init, move_val_init};

pub struct PriorityQueue<T> {
    priv data: ~[T],
}

impl<T:Ord> BaseIter<T> for PriorityQueue<T> {
    /// Visit all values in the underlying vector.
    ///
    /// The values are **not** visited in order.
    #[cfg(stage0)]
    fn each(&self, f: &fn(&T) -> bool) { self.data.each(f) }
    /// Visit all values in the underlying vector.
    ///
    /// The values are **not** visited in order.
    #[cfg(not(stage0))]
    fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.each(f) }

    fn size_hint(&self) -> Option<uint> { self.data.size_hint() }
}

impl<T:Ord> Container for PriorityQueue<T> {
    /// Returns the length of the queue
    fn len(&const self) -> uint { vec::uniq_len(&const self.data) }

    /// Returns true if a queue contains no elements
    fn is_empty(&const self) -> bool { self.len() == 0 }
}

impl<T:Ord> Mutable for PriorityQueue<T> {
    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }
}

pub impl <T:Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    fn top<'a>(&'a self) -> &'a T { &self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    fn maybe_top<'a>(&'a self) -> Option<&'a T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the number of elements the queue can hold without reallocating
    fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let mut item = self.data.pop();
        if !self.is_empty() {
            swap(&mut item, &mut self.data[0]);
            self.siftdown(0);
        }
        item
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        let new_len = self.len() - 1;
        self.siftup(0, new_len);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, mut item: T) -> T {
        if !self.is_empty() && self.data[0] > item {
            swap(&mut item, &mut self.data[0]);
            self.siftdown(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, mut item: T) -> T {
        swap(&mut item, &mut self.data[0]);
        self.siftdown(0);
        item
    }

    /// Consume the PriorityQueue and return the underlying vector
    fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v }

    /// Consume the PriorityQueue and return a vector in sorted
    /// (ascending) order
    fn to_sorted_vec(self) -> ~[T] {
        let mut q = self;
        let mut end = q.len();
        while end > 1 {
            end -= 1;
            vec::swap(q.data, 0, end);
            q.siftdown_range(0, end)
        }
        q.to_vec()
    }

    /// Create an empty PriorityQueue
    fn new() -> PriorityQueue<T> { PriorityQueue{data: ~[],} }

    /// Create a PriorityQueue from a vector (heapify)
    fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
        let mut q = PriorityQueue{data: xs,};
        let mut n = q.len() / 2;
        while n > 0 {
            n -= 1;
            q.siftdown(n)
        }
        q
    }

    // The implementations of siftup and siftdown use unsafe blocks in
    // order to move an element out of the vector (leaving behind a
    // zeroed element), shift along the others and move it back into the
    // vector over the junk element.  This reduces the constant factor
    // compared to using swaps, which involves twice as many moves.

    priv fn siftup(&mut self, start: uint, mut pos: uint) {
        unsafe {
            let new = replace(&mut self.data[pos], init());

            while pos > start {
                let parent = (pos - 1) >> 1;
                if new > self.data[parent] {
                    let x = replace(&mut self.data[parent], init());
                    move_val_init(&mut self.data[pos], x);
                    pos = parent;
                    loop
                }
                break
            }
            move_val_init(&mut self.data[pos], new);
        }
    }

    priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
        unsafe {
            let start = pos;
            let new = replace(&mut self.data[pos], init());

            let mut child = 2 * pos + 1;
            while child < end {
                let right = child + 1;
                if right < end && !(self.data[child] > self.data[right]) {
                    child = right;
                }
                let x = replace(&mut self.data[child], init());
                move_val_init(&mut self.data[pos], x);
                pos = child;
                child = 2 * pos + 1;
            }

            move_val_init(&mut self.data[pos], new);
            self.siftup(start, pos);
        }
    }

    priv fn siftdown(&mut self, pos: uint) {
        let len = self.len();
        self.siftdown_range(pos, len);
    }
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;
    use priority_queue::PriorityQueue::{from_vec, new};

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while !heap.is_empty() {
            assert!(heap.top() == sorted.last());
            assert!(heap.pop() == sorted.pop());
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert!(heap.len() == 3);
        assert!(*heap.top() == 9);
        heap.push(11);
        assert!(heap.len() == 4);
        assert!(*heap.top() == 11);
        heap.push(5);
        assert!(heap.len() == 5);
        assert!(*heap.top() == 11);
        heap.push(27);
        assert!(heap.len() == 6);
        assert!(*heap.top() == 27);
        heap.push(3);
        assert!(heap.len() == 7);
        assert!(*heap.top() == 27);
        heap.push(103);
        assert!(heap.len() == 8);
        assert!(*heap.top() == 103);
    }

    #[test]
    fn test_push_unique() {
        let mut heap = from_vec(~[~2, ~4, ~9]);
        assert!(heap.len() == 3);
        assert!(*heap.top() == ~9);
        heap.push(~11);
        assert!(heap.len() == 4);
        assert!(*heap.top() == ~11);
        heap.push(~5);
        assert!(heap.len() == 5);
        assert!(*heap.top() == ~11);
        heap.push(~27);
        assert!(heap.len() == 6);
        assert!(*heap.top() == ~27);
        heap.push(~3);
        assert!(heap.len() == 7);
        assert!(*heap.top() == ~27);
        heap.push(~103);
        assert!(heap.len() == 8);
        assert!(*heap.top() == ~103);
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert!(heap.len() == 5);
        assert!(heap.push_pop(6) == 6);
        assert!(heap.len() == 5);
        assert!(heap.push_pop(0) == 5);
        assert!(heap.len() == 5);
        assert!(heap.push_pop(4) == 5);
        assert!(heap.len() == 5);
        assert!(heap.push_pop(1) == 4);
        assert!(heap.len() == 5);
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert!(heap.len() == 5);
        assert!(heap.replace(6) == 5);
        assert!(heap.len() == 5);
        assert!(heap.replace(0) == 6);
        assert!(heap.len() == 5);
        assert!(heap.replace(4) == 5);
        assert!(heap.len() == 5);
        assert!(heap.replace(1) == 4);
        assert!(heap.len() == 5);
    }

    fn check_to_vec(data: ~[int]) {
        let heap = from_vec(copy data);
        assert!(merge_sort((copy heap).to_vec(), le) == merge_sort(data, le));
        assert!(heap.to_sorted_vec() == merge_sort(data, le));
    }

    #[test]
    fn test_to_vec() {
        check_to_vec(~[]);
        check_to_vec(~[5]);
        check_to_vec(~[3, 2]);
        check_to_vec(~[2, 3]);
        check_to_vec(~[5, 1, 2]);
        check_to_vec(~[1, 100, 2, 3]);
        check_to_vec(~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
        check_to_vec(~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
        check_to_vec(~[9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        check_to_vec(~[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
        check_to_vec(~[5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_pop() { let mut heap = new::<int>(); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = new::<int>();
        assert!(heap.maybe_pop().is_none());
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_top() { let empty = new::<int>(); empty.top(); }

    #[test]
    fn test_empty_maybe_top() {
        let empty = new::<int>();
        assert!(empty.maybe_top().is_none());
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_replace() { let mut heap = new(); heap.replace(5); }
}
<|endoftext|>


<commit_before>
/// A priority queue implemented with a binary heap
use core::cmp::Ord;

pub struct PriorityQueue <T: Copy Ord>{
    priv data: ~[T],
}

impl <T: Copy Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    pure fn top(&self) -> &self/T { &self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    pure fn maybe_top(&self) -> Option<&self/T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the length of the queue
    pure fn len(&self) -> uint { self.data.len() }

    /// Returns true if a queue contains no elements
    pure fn is_empty(&self) -> bool { self.data.is_empty() }

    /// Returns true if a queue contains some elements
    pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() }

    /// Returns the number of elements the queue can hold without reallocating
    pure fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let mut item = self.data.pop();
        if self.is_not_empty() { item <-> self.data[0]; self.siftup(0); }
        item
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        self.siftdown(0, self.len() - 1);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, item: T) -> T {
        let mut item = item;
        if self.is_not_empty() && self.data[0] > item {
            item <-> self.data[0];
            self.siftup(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, item: T) -> T {
        let mut item = item;
        item <-> self.data[0];
        self.siftup(0);
        item
    }

    /// Consume the PriorityQueue and return the underlying vector
    pure fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v }

    /// Consume the PriorityQueue and return a vector in sorted (ascending) order
    pure fn to_sorted_vec(self) -> ~[T] {
        let mut q = self;
        let mut end = q.len();
        while end > 1 {
            end -= 1;
            q.data[end] <-> q.data[0];
            unsafe { q.siftup_range(0, end) } // purity-checking workaround
        }
        q.to_vec()
    }

    static pub pure fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
        let mut q = PriorityQueue{data: xs,};
        let mut n = q.len() / 2;
        while n > 0 {
            n -= 1;
            unsafe { q.siftup(n) }; // purity-checking workaround
        }
        q
    }

    priv fn siftdown(&mut self, startpos: uint, pos: uint) {
        let mut pos = pos;
        let newitem = self.data[pos];

        while pos > startpos {
            let parentpos = (pos - 1) >> 1;
            let parent = self.data[parentpos];
            if newitem > parent {
                self.data[pos] = parent;
                pos = parentpos;
                loop
            }
            break
        }
        self.data[pos] = newitem;
    }

    priv fn siftup_range(&mut self, pos: uint, endpos: uint) {
        let mut pos = pos;
        let startpos = pos;
        let newitem = self.data[pos];

        let mut childpos = 2 * pos + 1;
        while childpos < endpos {
            let rightpos = childpos + 1;
            if rightpos < endpos &&
                   !(self.data[childpos] > self.data[rightpos]) {
                childpos = rightpos;
            }
            self.data[pos] = self.data[childpos];
            pos = childpos;
            childpos = 2 * pos + 1;
        }
        self.data[pos] = newitem;
        self.siftdown(startpos, pos);
    }

    priv fn siftup(&mut self, pos: uint) {
        self.siftup_range(pos, self.len());
    }
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;
    use PriorityQueue::from_vec;

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while heap.is_not_empty() {
            assert *heap.top() == sorted.last();
            assert heap.pop() == sorted.pop();
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert heap.len() == 3;
        assert *heap.top() == 9;
        heap.push(11);
        assert heap.len() == 4;
        assert *heap.top() == 11;
        heap.push(5);
        assert heap.len() == 5;
        assert *heap.top() == 11;
        heap.push(27);
        assert heap.len() == 6;
        assert *heap.top() == 27;
        heap.push(3);
        assert heap.len() == 7;
        assert *heap.top() == 27;
        heap.push(103);
        assert heap.len() == 8;
        assert *heap.top() == 103;
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.push_pop(6) == 6;
        assert heap.len() == 5;
        assert heap.push_pop(0) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(4) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.replace(6) == 5;
        assert heap.len() == 5;
        assert heap.replace(0) == 6;
        assert heap.len() == 5;
        assert heap.replace(4) == 5;
        assert heap.len() == 5;
        assert heap.replace(1) == 4;
        assert heap.len() == 5;
    }

    fn check_to_vec(data: ~[int]) {
        let heap = from_vec(data);
        assert merge_sort(heap.to_vec(), le) == merge_sort(data, le);
        assert heap.to_sorted_vec() == merge_sort(data, le);
    }

    #[test]
    fn test_to_vec() {
        check_to_vec(~[]);
        check_to_vec(~[5]);
        check_to_vec(~[3, 2]);
        check_to_vec(~[2, 3]);
        check_to_vec(~[5, 1, 2]);
        check_to_vec(~[1, 100, 2, 3]);
        check_to_vec(~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
        check_to_vec(~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
        check_to_vec(~[9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        check_to_vec(~[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
        check_to_vec(~[5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
    }

    #[test]
    #[should_fail]
    fn test_empty_pop() { let mut heap = from_vec::<int>(~[]); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = from_vec::<int>(~[]);
        assert heap.maybe_pop().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_top() { let empty = from_vec::<int>(~[]); empty.top(); }

    #[test]
    fn test_empty_maybe_top() {
        let empty = from_vec::<int>(~[]);
        assert empty.maybe_top().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_replace() {
        let mut heap = from_vec::<int>(~[]);
        heap.replace(5);
    }
}
<commit_msg>priority_queue: fix siftup/siftdown naming<commit_after>
/// A priority queue implemented with a binary heap
use core::cmp::Ord;

pub struct PriorityQueue <T: Copy Ord>{
    priv data: ~[T],
}

impl <T: Copy Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    pure fn top(&self) -> &self/T { &self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    pure fn maybe_top(&self) -> Option<&self/T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the length of the queue
    pure fn len(&self) -> uint { self.data.len() }

    /// Returns true if a queue contains no elements
    pure fn is_empty(&self) -> bool { self.data.is_empty() }

    /// Returns true if a queue contains some elements
    pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() }

    /// Returns the number of elements the queue can hold without reallocating
    pure fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let mut item = self.data.pop();
        if self.is_not_empty() { item <-> self.data[0]; self.siftdown(0); }
        item
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        self.siftup(0, self.len() - 1);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, item: T) -> T {
        let mut item = item;
        if self.is_not_empty() && self.data[0] > item {
            item <-> self.data[0];
            self.siftdown(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, item: T) -> T {
        let mut item = item;
        item <-> self.data[0];
        self.siftdown(0);
        item
    }

    /// Consume the PriorityQueue and return the underlying vector
    pure fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v }

    /// Consume the PriorityQueue and return a vector in sorted (ascending) order
    pure fn to_sorted_vec(self) -> ~[T] {
        let mut q = self;
        let mut end = q.len();
        while end > 1 {
            end -= 1;
            q.data[end] <-> q.data[0];
            unsafe { q.siftdown_range(0, end) } // purity-checking workaround
        }
        q.to_vec()
    }

    static pub pure fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
        let mut q = PriorityQueue{data: xs,};
        let mut n = q.len() / 2;
        while n > 0 {
            n -= 1;
            unsafe { q.siftdown(n) }; // purity-checking workaround
        }
        q
    }

    priv fn siftup(&mut self, startpos: uint, pos: uint) {
        let mut pos = pos;
        let newitem = self.data[pos];

        while pos > startpos {
            let parentpos = (pos - 1) >> 1;
            let parent = self.data[parentpos];
            if newitem > parent {
                self.data[pos] = parent;
                pos = parentpos;
                loop
            }
            break
        }
        self.data[pos] = newitem;
    }

    priv fn siftdown_range(&mut self, pos: uint, endpos: uint) {
        let mut pos = pos;
        let startpos = pos;
        let newitem = self.data[pos];

        let mut childpos = 2 * pos + 1;
        while childpos < endpos {
            let rightpos = childpos + 1;
            if rightpos < endpos &&
                   !(self.data[childpos] > self.data[rightpos]) {
                childpos = rightpos;
            }
            self.data[pos] = self.data[childpos];
            pos = childpos;
            childpos = 2 * pos + 1;
        }
        self.data[pos] = newitem;
        self.siftup(startpos, pos);
    }

    priv fn siftdown(&mut self, pos: uint) {
        self.siftdown_range(pos, self.len());
    }
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;
    use PriorityQueue::from_vec;

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while heap.is_not_empty() {
            assert *heap.top() == sorted.last();
            assert heap.pop() == sorted.pop();
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert heap.len() == 3;
        assert *heap.top() == 9;
        heap.push(11);
        assert heap.len() == 4;
        assert *heap.top() == 11;
        heap.push(5);
        assert heap.len() == 5;
        assert *heap.top() == 11;
        heap.push(27);
        assert heap.len() == 6;
        assert *heap.top() == 27;
        heap.push(3);
        assert heap.len() == 7;
        assert *heap.top() == 27;
        heap.push(103);
        assert heap.len() == 8;
        assert *heap.top() == 103;
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.push_pop(6) == 6;
        assert heap.len() == 5;
        assert heap.push_pop(0) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(4) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.replace(6) == 5;
        assert heap.len() == 5;
        assert heap.replace(0) == 6;
        assert heap.len() == 5;
        assert heap.replace(4) == 5;
        assert heap.len() == 5;
        assert heap.replace(1) == 4;
        assert heap.len() == 5;
    }

    fn check_to_vec(data: ~[int]) {
        let heap = from_vec(data);
        assert merge_sort(heap.to_vec(), le) == merge_sort(data, le);
        assert heap.to_sorted_vec() == merge_sort(data, le);
    }

    #[test]
    fn test_to_vec() {
        check_to_vec(~[]);
        check_to_vec(~[5]);
        check_to_vec(~[3, 2]);
        check_to_vec(~[2, 3]);
        check_to_vec(~[5, 1, 2]);
        check_to_vec(~[1, 100, 2, 3]);
        check_to_vec(~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
        check_to_vec(~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
        check_to_vec(~[9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        check_to_vec(~[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
        check_to_vec(~[5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
    }

    #[test]
    #[should_fail]
    fn test_empty_pop() { let mut heap = from_vec::<int>(~[]); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = from_vec::<int>(~[]);
        assert heap.maybe_pop().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_top() { let empty = from_vec::<int>(~[]); empty.top(); }

    #[test]
    fn test_empty_maybe_top() {
        let empty = from_vec::<int>(~[]);
        assert empty.maybe_top().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_replace() {
        let mut heap = from_vec::<int>(~[]);
        heap.replace(5);
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement focused for layout<commit_after><|endoftext|>


<commit_before><commit_msg>Split PacketHandler to multiple traits and functions, Remove PacketSide.<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/. */

//! Supports writing a trace file created during each layout scope
//! that can be viewed by an external tool to make layout debugging easier.

#![macro_use]
#![allow(unsafe_code)] // thread_local!() defines an unsafe function on Android

use flow_ref::FlowRef;
use flow;
use rustc_serialize::json;

use std::borrow::ToOwned;
use std::cell::RefCell;
use std::io::Write;
use std::fs::File;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};

thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None));

static mut DEBUG_ID_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;

pub struct Scope;

#[macro_export]
macro_rules! layout_debug_scope(
    ($($arg:tt)*) => (
        if cfg!(not(ndebug)) {
            layout_debug::Scope::new(format!($($arg)*))
        } else {
            layout_debug::Scope
        }
    )
);

#[derive(RustcEncodable)]
struct ScopeData {
    name: String,
    pre: String,
    post: String,
    children: Vec<Box<ScopeData>>,
}

impl ScopeData {
    fn new(name: String, pre: String) -> ScopeData {
        ScopeData {
            name: name,
            pre: pre,
            post: String::new(),
            children: vec!(),
        }
    }
}

struct State {
    flow_root: FlowRef,
    scope_stack: Vec<Box<ScopeData>>,
}

/// A layout debugging scope. The entire state of the flow tree
/// will be output at the beginning and end of this scope.
impl Scope {
    pub fn new(name: String) -> Scope {
        STATE_KEY.with(|ref r| {
            match &mut *r.borrow_mut() {
                &mut Some(ref mut state) => {
                    let flow_trace = json::encode(&flow::base(&*state.flow_root)).unwrap();
                    let data = box ScopeData::new(name.clone(), flow_trace);
                    state.scope_stack.push(data);
                }
                &mut None => {}
            }
        });
        Scope
    }
}

#[cfg(not(ndebug))]
impl Drop for Scope {
    fn drop(&mut self) {
        STATE_KEY.with(|ref r| {
            match &mut *r.borrow_mut() {
                &mut Some(ref mut state) => {
                    let mut current_scope = state.scope_stack.pop().unwrap();
                    current_scope.post = json::encode(&flow::base(&*state.flow_root)).unwrap();
                    let previous_scope = state.scope_stack.last_mut().unwrap();
                    previous_scope.children.push(current_scope);
                }
                &mut None => {}
            }
        });
    }
}

/// Generate a unique ID. This is used for items such as Fragment
/// which are often reallocated but represent essentially the
/// same data.
pub fn generate_unique_debug_id() -> u16 {
    unsafe { DEBUG_ID_COUNTER.fetch_add(1, Ordering::SeqCst) as u16 }
}

/// Begin a layout debug trace. If this has not been called,
/// creating debug scopes has no effect.
pub fn begin_trace(flow_root: FlowRef) {
    assert!(STATE_KEY.with(|ref r| r.borrow().is_none()));

    STATE_KEY.with(|ref r| {
        let flow_trace = json::encode(&flow::base(&*flow_root)).unwrap();
        let state = State {
            scope_stack: vec![box ScopeData::new("root".to_owned(), flow_trace)],
            flow_root: flow_root.clone(),
        };
        *r.borrow_mut() = Some(state);
    });
}

/// End the debug layout trace. This will write the layout
/// trace to disk in the current directory. The output
/// file can then be viewed with an external tool.
pub fn end_trace() {
    let mut task_state = STATE_KEY.with(|ref r| r.borrow_mut().take().unwrap());
    assert!(task_state.scope_stack.len() == 1);
    let mut root_scope = task_state.scope_stack.pop().unwrap();
    root_scope.post = json::encode(&flow::base(&*task_state.flow_root)).unwrap();

    let result = json::encode(&root_scope).unwrap();
    let mut file = File::create("layout_trace.json").unwrap();
    file.write_all(result.as_bytes()).unwrap();
}
<commit_msg>Make DEBUG_ID_COUNTER a plain static.<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/. */

//! Supports writing a trace file created during each layout scope
//! that can be viewed by an external tool to make layout debugging easier.

#![macro_use]

use flow_ref::FlowRef;
use flow;
use rustc_serialize::json;

use std::borrow::ToOwned;
use std::cell::RefCell;
use std::io::Write;
use std::fs::File;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};

thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None));

static DEBUG_ID_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;

pub struct Scope;

#[macro_export]
macro_rules! layout_debug_scope(
    ($($arg:tt)*) => (
        if cfg!(not(ndebug)) {
            layout_debug::Scope::new(format!($($arg)*))
        } else {
            layout_debug::Scope
        }
    )
);

#[derive(RustcEncodable)]
struct ScopeData {
    name: String,
    pre: String,
    post: String,
    children: Vec<Box<ScopeData>>,
}

impl ScopeData {
    fn new(name: String, pre: String) -> ScopeData {
        ScopeData {
            name: name,
            pre: pre,
            post: String::new(),
            children: vec!(),
        }
    }
}

struct State {
    flow_root: FlowRef,
    scope_stack: Vec<Box<ScopeData>>,
}

/// A layout debugging scope. The entire state of the flow tree
/// will be output at the beginning and end of this scope.
impl Scope {
    pub fn new(name: String) -> Scope {
        STATE_KEY.with(|ref r| {
            match &mut *r.borrow_mut() {
                &mut Some(ref mut state) => {
                    let flow_trace = json::encode(&flow::base(&*state.flow_root)).unwrap();
                    let data = box ScopeData::new(name.clone(), flow_trace);
                    state.scope_stack.push(data);
                }
                &mut None => {}
            }
        });
        Scope
    }
}

#[cfg(not(ndebug))]
impl Drop for Scope {
    fn drop(&mut self) {
        STATE_KEY.with(|ref r| {
            match &mut *r.borrow_mut() {
                &mut Some(ref mut state) => {
                    let mut current_scope = state.scope_stack.pop().unwrap();
                    current_scope.post = json::encode(&flow::base(&*state.flow_root)).unwrap();
                    let previous_scope = state.scope_stack.last_mut().unwrap();
                    previous_scope.children.push(current_scope);
                }
                &mut None => {}
            }
        });
    }
}

/// Generate a unique ID. This is used for items such as Fragment
/// which are often reallocated but represent essentially the
/// same data.
pub fn generate_unique_debug_id() -> u16 {
    DEBUG_ID_COUNTER.fetch_add(1, Ordering::SeqCst) as u16
}

/// Begin a layout debug trace. If this has not been called,
/// creating debug scopes has no effect.
pub fn begin_trace(flow_root: FlowRef) {
    assert!(STATE_KEY.with(|ref r| r.borrow().is_none()));

    STATE_KEY.with(|ref r| {
        let flow_trace = json::encode(&flow::base(&*flow_root)).unwrap();
        let state = State {
            scope_stack: vec![box ScopeData::new("root".to_owned(), flow_trace)],
            flow_root: flow_root.clone(),
        };
        *r.borrow_mut() = Some(state);
    });
}

/// End the debug layout trace. This will write the layout
/// trace to disk in the current directory. The output
/// file can then be viewed with an external tool.
pub fn end_trace() {
    let mut task_state = STATE_KEY.with(|ref r| r.borrow_mut().take().unwrap());
    assert!(task_state.scope_stack.len() == 1);
    let mut root_scope = task_state.scope_stack.pop().unwrap();
    root_scope.post = json::encode(&flow::base(&*task_state.flow_root)).unwrap();

    let result = json::encode(&root_scope).unwrap();
    let mut file = File::create("layout_trace.json").unwrap();
    file.write_all(result.as_bytes()).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Create phone_number_match.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Add const_variable.rs<commit_after>use crate::mir::interpret::ConstValue;
use syntax::symbol::InternedString;
use syntax_pos::Span;
use crate::ty::{self, InferConst};

use std::cmp;
use std::marker::PhantomData;
use rustc_data_structures::snapshot_vec as sv;
use rustc_data_structures::unify as ut;

pub struct ConstVariableTable<'tcx> {
    values: sv::SnapshotVec<Delegate<'tcx>>,

    relations: ut::UnificationTable<ut::InPlace<ty::ConstVid<'tcx>>>,
}

/// Reasons to create a const inference variable
#[derive(Copy, Clone, Debug)]
pub enum ConstVariableOrigin {
    MiscVariable(Span),
    ConstInference(Span),
    ConstParameterDefinition(Span, InternedString),
    SubstitutionPlaceholder(Span),
}

struct ConstVariableData {
    origin: ConstVariableOrigin,
}

#[derive(Copy, Clone, Debug)]
pub enum ConstVariableValue<'tcx> {
    Known { value: &'tcx ty::LazyConst<'tcx> },
    Unknown { universe: ty::UniverseIndex },
}

impl<'tcx> ConstVariableValue<'tcx> {
    /// If this value is known, returns the const it is known to be.
    /// Otherwise, `None`.
    pub fn known(&self) -> Option<&'tcx ty::LazyConst<'tcx>> {
        match *self {
            ConstVariableValue::Unknown { .. } => None,
            ConstVariableValue::Known { value } => Some(value),
        }
    }

    pub fn is_unknown(&self) -> bool {
        match *self {
            ConstVariableValue::Unknown { .. } => true,
            ConstVariableValue::Known { .. } => false,
        }
    }
}

pub struct Snapshot<'tcx> {
    snapshot: sv::Snapshot,
    relation_snapshot: ut::Snapshot<ut::InPlace<ty::ConstVid<'tcx>>>,
}

struct Instantiate<'tcx> {
    _vid: ty::ConstVid<'tcx>,
}

struct Delegate<'tcx> {
    pub phantom: PhantomData<&'tcx ()>,
}

impl<'tcx> ConstVariableTable<'tcx> {
    pub fn new() -> ConstVariableTable<'tcx> {
        ConstVariableTable {
            values: sv::SnapshotVec::new(),
            relations: ut::UnificationTable::new(),
        }
    }

    /// Returns the origin that was given when `vid` was created.
    ///
    /// Note that this function does not return care whether
    /// `vid` has been unified with something else or not.
    pub fn var_origin(&self, vid: ty::ConstVid<'tcx>) -> &ConstVariableOrigin {
        &self.values[vid.index as usize].origin
    }

    pub fn unify_var_var(
        &mut self,
        a_id: ty::ConstVid<'tcx>,
        b_id: ty::ConstVid<'tcx>,
    ) -> Result<(), (&'tcx ty::LazyConst<'tcx>, &'tcx ty::LazyConst<'tcx>)> {
        self.relations.unify_var_var(a_id, b_id)
    }

    pub fn unify_var_value(
        &mut self,
        a_id: ty::ConstVid<'tcx>,
        b: ConstVariableValue<'tcx>,
    ) -> Result<(), (&'tcx ty::LazyConst<'tcx>, &'tcx ty::LazyConst<'tcx>)> {
        self.relations.unify_var_value(a_id, b)
    }

    /// Creates a new const variable.
    ///
    /// - `origin`: indicates *why* the const variable was created.
    ///   The code in this module doesn't care, but it can be useful
    ///   for improving error messages.
    pub fn new_var(
        &mut self,
        universe: ty::UniverseIndex,
        origin: ConstVariableOrigin,
    ) -> ty::ConstVid<'tcx> {
        let vid = self.relations.new_key(ConstVariableValue::Unknown{ universe });

        let index = self.values.push(ConstVariableData {
            origin,
        });
        assert_eq!(vid.index, index as u32);

        debug!("new_var(index={:?}, origin={:?}", vid, origin);

        vid
    }

    /// Retrieves the type to which `vid` has been instantiated, if
    /// any.
    pub fn probe(
        &mut self,
        vid: ty::ConstVid<'tcx>
    ) -> ConstVariableValue<'tcx> {
        self.relations.probe_value(vid)
    }

    /// If `t` is a type-inference variable, and it has been
    /// instantiated, then return the with which it was
    /// instantiated. Otherwise, returns `t`.
    pub fn replace_if_possible(
        &mut self,
        c: &'tcx ty::LazyConst<'tcx>
    ) -> &'tcx ty::LazyConst<'tcx> {
        if let ty::LazyConst::Evaluated(ty::Const {
            val: ConstValue::Infer(InferConst::Var(vid)),
            ..
        }) = c {
            match self.probe(*vid).known() {
                Some(c) => c,
                None => c,
            }
        } else {
            c
        }
    }

    /// Creates a snapshot of the type variable state.  This snapshot
    /// must later be committed (`commit()`) or rolled back
    /// (`rollback_to()`).  Nested snapshots are permitted, but must
    /// be processed in a stack-like fashion.
    pub fn snapshot(&mut self) -> Snapshot<'tcx> {
        Snapshot {
            snapshot: self.values.start_snapshot(),
            relation_snapshot: self.relations.snapshot(),
        }
    }

    /// Undoes all changes since the snapshot was created. Any
    /// snapshots created since that point must already have been
    /// committed or rolled back.
    pub fn rollback_to(&mut self, s: Snapshot<'tcx>) {
        debug!("rollback_to{:?}", {
            for action in self.values.actions_since_snapshot(&s.snapshot) {
                if let sv::UndoLog::NewElem(index) = *action {
                    debug!("inference variable _#{}t popped", index)
                }
            }
        });

        let Snapshot { snapshot, relation_snapshot } = s;
        self.values.rollback_to(snapshot);
        self.relations.rollback_to(relation_snapshot);
    }

    /// Commits all changes since the snapshot was created, making
    /// them permanent (unless this snapshot was created within
    /// another snapshot). Any snapshots created since that point
    /// must already have been committed or rolled back.
    pub fn commit(&mut self, s: Snapshot<'tcx>) {
        let Snapshot { snapshot, relation_snapshot } = s;
        self.values.commit(snapshot);
        self.relations.commit(relation_snapshot);
    }
}

impl<'tcx> ut::UnifyKey for ty::ConstVid<'tcx> {
    type Value = ConstVariableValue<'tcx>;
    fn index(&self) -> u32 { self.index }
    fn from_index(i: u32) -> Self { ty::ConstVid { index: i, phantom: PhantomData } }
    fn tag() -> &'static str { "ConstVid" }
}

impl<'tcx> ut::UnifyValue for ConstVariableValue<'tcx> {
    type Error = (&'tcx ty::LazyConst<'tcx>, &'tcx ty::LazyConst<'tcx>);

    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
        match (value1, value2) {
            (
                &ConstVariableValue::Known { value: value1 },
                &ConstVariableValue::Known { value: value2 }
            ) => {
                match <&'tcx ty::LazyConst<'tcx>>::unify_values(&value1, &value2) {
                    Ok(value) => Ok(ConstVariableValue::Known { value }),
                    Err(err) => Err(err),
                }
            }

            // If one side is known, prefer that one.
            (&ConstVariableValue::Known { .. }, &ConstVariableValue::Unknown { .. }) => Ok(*value1),
            (&ConstVariableValue::Unknown { .. }, &ConstVariableValue::Known { .. }) => Ok(*value2),

            // If both sides are *unknown*, it hardly matters, does it?
            (&ConstVariableValue::Unknown { universe: universe1 },
             &ConstVariableValue::Unknown { universe: universe2 }) =>  {
                // If we unify two unbound variables, ?T and ?U, then whatever
                // value they wind up taking (which must be the same value) must
                // be nameable by both universes. Therefore, the resulting
                // universe is the minimum of the two universes, because that is
                // the one which contains the fewest names in scope.
                let universe = cmp::min(universe1, universe2);
                Ok(ConstVariableValue::Unknown { universe })
            }
        }
    }
}

impl<'tcx> ut::EqUnifyValue for &'tcx ty::LazyConst<'tcx> {}

impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
    type Value = ConstVariableData;
    type Undo = Instantiate<'tcx>;

    fn reverse(_values: &mut Vec<ConstVariableData>, _action: Instantiate<'tcx>) {
        // We don't actually have to *do* anything to reverse an
        // instantiation; the value for a variable is stored in the
        // `relations` and hence its rollback code will handle
        // it.
    }
}
<|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/. */

use dom::bindings::codegen::BindingDeclarations::HTMLTableSectionElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTableSectionElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTableSectionElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLTableSectionElement {
    pub htmlelement: HTMLElement,
}

impl HTMLTableSectionElementDerived for EventTarget {
    fn is_htmltablesectionelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLTableSectionElementTypeId))
    }
}

impl HTMLTableSectionElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTableSectionElement {
        HTMLTableSectionElement {
            htmlelement: HTMLElement::new_inherited(HTMLTableSectionElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTableSectionElement> {
        let element = HTMLTableSectionElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLTableSectionElementBinding::Wrap)
    }
}

pub trait HTMLTableSectionElementMethods {
    fn DeleteRow(&mut self, _index: i32) -> ErrorResult;
    fn Align(&self) -> DOMString;
    fn SetAlign(&mut self, _align: DOMString) -> ErrorResult;
    fn Ch(&self) -> DOMString;
    fn SetCh(&mut self, _ch: DOMString) -> ErrorResult;
    fn ChOff(&self) -> DOMString;
    fn SetChOff(&mut self, _ch_off: DOMString) -> ErrorResult;
    fn VAlign(&self) -> DOMString;
    fn SetVAlign(&mut self, _v_align: DOMString) -> ErrorResult;
}

impl<'a> HTMLTableSectionElementMethods for JSRef<'a, HTMLTableSectionElement> {
    fn DeleteRow(&mut self, _index: i32) -> ErrorResult {
        Ok(())
    }

    fn Align(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAlign(&mut self, _align: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Ch(&self) -> DOMString {
        "".to_owned()
    }

    fn SetCh(&mut self, _ch: DOMString) -> ErrorResult {
        Ok(())
    }

    fn ChOff(&self) -> DOMString {
        "".to_owned()
    }

    fn SetChOff(&mut self, _ch_off: DOMString) -> ErrorResult {
        Ok(())
    }

    fn VAlign(&self) -> DOMString {
        "".to_owned()
    }

    fn SetVAlign(&mut self, _v_align: DOMString) -> ErrorResult {
        Ok(())
    }
}
<commit_msg>Remove needless '&mut self' from HTMLTableSectionElementMethods.<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/. */

use dom::bindings::codegen::BindingDeclarations::HTMLTableSectionElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTableSectionElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTableSectionElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLTableSectionElement {
    pub htmlelement: HTMLElement,
}

impl HTMLTableSectionElementDerived for EventTarget {
    fn is_htmltablesectionelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLTableSectionElementTypeId))
    }
}

impl HTMLTableSectionElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTableSectionElement {
        HTMLTableSectionElement {
            htmlelement: HTMLElement::new_inherited(HTMLTableSectionElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTableSectionElement> {
        let element = HTMLTableSectionElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLTableSectionElementBinding::Wrap)
    }
}

pub trait HTMLTableSectionElementMethods {
    fn DeleteRow(&self, _index: i32) -> ErrorResult;
    fn Align(&self) -> DOMString;
    fn SetAlign(&self, _align: DOMString) -> ErrorResult;
    fn Ch(&self) -> DOMString;
    fn SetCh(&self, _ch: DOMString) -> ErrorResult;
    fn ChOff(&self) -> DOMString;
    fn SetChOff(&self, _ch_off: DOMString) -> ErrorResult;
    fn VAlign(&self) -> DOMString;
    fn SetVAlign(&self, _v_align: DOMString) -> ErrorResult;
}

impl<'a> HTMLTableSectionElementMethods for JSRef<'a, HTMLTableSectionElement> {
    fn DeleteRow(&self, _index: i32) -> ErrorResult {
        Ok(())
    }

    fn Align(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAlign(&self, _align: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Ch(&self) -> DOMString {
        "".to_owned()
    }

    fn SetCh(&self, _ch: DOMString) -> ErrorResult {
        Ok(())
    }

    fn ChOff(&self) -> DOMString {
        "".to_owned()
    }

    fn SetChOff(&self, _ch_off: DOMString) -> ErrorResult {
        Ok(())
    }

    fn VAlign(&self) -> DOMString {
        "".to_owned()
    }

    fn SetVAlign(&self, _v_align: DOMString) -> ErrorResult {
        Ok(())
    }
}
<|endoftext|>


<commit_before><commit_msg>use vec![v; n] instead of iter::repeat in TreeRouter::find<commit_after><|endoftext|>


<commit_before><commit_msg>added traits example<commit_after>trait Polygon {
    // Static method signature; `Self` refers to the implementor type
    fn new(width: i32, height: i32) -> Self;

    fn area(&self) -> f32;
}

struct Rectangle { width: i32, height: i32 }

impl Polygon for Rectangle {
    fn new(w: i32, h: i32) -> Rectangle {
        Rectangle { width: w, height: h }
    }

    fn area(&self) -> f32 {
        return (self.width * self.height) as f32;
    }
}

struct Triangle { width: i32, height: i32 }

impl Polygon for Triangle {
    fn new(w: i32, h: i32) -> Triangle {
        Triangle { width: w, height: h }
    }

    fn area(&self) -> f32 {
        return self.width as f32 * self.height as f32 / 2.0;
    }
}

fn main() {
    let r: Rectangle = Polygon::new(2, 3);
    println!("{}", r.area());

    let t: Triangle = Triangle::new(2, 3);
    println!("{}", t.area());
}
<|endoftext|>


<commit_before>extern crate clap;
#[macro_use] extern crate log;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate libimagstore;
extern crate libimagrt;
extern crate libimagtag;
extern crate libimagutil;

use std::process::exit;

use libimagrt::runtime::Runtime;
use libimagtag::tagable::Tagable;

mod ui;
mod util;

use ui::build_ui;
use util::build_entry_path;

use libimagutil::trace::trace_error;

fn main() {
    let name = "imag-store";
    let version = &version!()[..];
    let about = "Direct interface to the store. Use with great care!";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));
    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.err().unwrap());
            exit(1);
        }
    };

    rt.init_logger();

    debug!("Hello. Logging was just enabled");
    debug!("I already set up the Runtime object and build the commandline interface parser.");
    debug!("Lets get rollin' ...");

    let id = rt.cli().value_of("id").unwrap(); // enforced by clap
    rt.cli()
        .subcommand_name()
        .map_or_else(
            || {
                let add = rt.cli().value_of("add");
                let rem = rt.cli().value_of("remove");
                let set = rt.cli().value_of("set");

                alter(&rt, id, add, rem, set);
            },
            |name| {
                debug!("Call: {}", name);
                match name {
                    "list" => list(id, &rt),
                    _ => {
                        warn!("Unknown command");
                        // More error handling
                    },
                };
            });
}

fn alter(rt: &Runtime, id: &str, add: Option<&str>, rem: Option<&str>, set: Option<&str>) {
    let path = build_entry_path(rt, id);
    debug!("path = {:?}", path);
    rt.store()
        // "id" must be present, enforced via clap spec
        .retrieve(path)
        .map(|mut e| {
            add.map(|tags| {
                let tags = tags.split(",");
                for tag in tags {
                    info!("Adding tag '{}'", tag);
                    e.add_tag(String::from(tag)).map_err(|e| trace_error(&e));
                }
            });

            rem.map(|tags| {
                let tags = tags.split(",");
                for tag in tags {
                    info!("Removing tag '{}'", tag);
                    e.remove_tag(String::from(tag)).map_err(|e| trace_error(&e));
                }
            });

            set.map(|tags| {
                info!("Setting tags '{}'", tags);
                let tags = tags.split(",").map(String::from).collect();
                e.set_tags(tags);
            });
        })
        .map_err(|e| {
            info!("No entry.");
            debug!("{}", e);
        });
}

fn list(id: &str, rt: &Runtime) {
    let path = build_entry_path(rt, id);
    debug!("path = {:?}", path);

    let entry = rt.store().retrieve(path.clone());
    if entry.is_err() {
        debug!("Could not retrieve '{:?}' => {:?}", id, path);
        warn!("Could not retrieve entry '{}'", id);
        trace_error(&entry.err().unwrap());
        exit(1);
    }
    let entry = entry.unwrap();

    let scmd = rt.cli().subcommand_matches("list").unwrap(); // safe, we checked in main()

    let json_out = scmd.is_present("json");
    let line_out = scmd.is_present("linewise");
    let sepp_out = scmd.is_present("sep");
    let mut comm_out = scmd.is_present("commasep");

    if !vec![json_out, line_out, comm_out, sepp_out].iter().any(|v| *v) {
        // None of the flags passed, go to default
        comm_out = true;
    }

    let tags = entry.get_tags();
    if tags.is_err() {
        trace_error(&tags.err().unwrap());
        exit(1);
    }
    let tags = tags.unwrap();

    if json_out {
        unimplemented!()
    }

    if line_out {
        for tag in &tags {
            println!("{}", tag);
        }
    }

    if sepp_out {
        let sepp = scmd.value_of("sep").unwrap(); // we checked before
        println!("{}", tags.join(sepp));
    }

    if comm_out {
        println!("{}", tags.join(", "));
    }
}

<commit_msg>Remove warnings: Unused result -> use trace_error()<commit_after>extern crate clap;
#[macro_use] extern crate log;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate libimagstore;
extern crate libimagrt;
extern crate libimagtag;
extern crate libimagutil;

use std::process::exit;

use libimagrt::runtime::Runtime;
use libimagtag::tagable::Tagable;

mod ui;
mod util;

use ui::build_ui;
use util::build_entry_path;

use libimagutil::trace::trace_error;

fn main() {
    let name = "imag-store";
    let version = &version!()[..];
    let about = "Direct interface to the store. Use with great care!";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));
    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.err().unwrap());
            exit(1);
        }
    };

    rt.init_logger();

    debug!("Hello. Logging was just enabled");
    debug!("I already set up the Runtime object and build the commandline interface parser.");
    debug!("Lets get rollin' ...");

    let id = rt.cli().value_of("id").unwrap(); // enforced by clap
    rt.cli()
        .subcommand_name()
        .map_or_else(
            || {
                let add = rt.cli().value_of("add");
                let rem = rt.cli().value_of("remove");
                let set = rt.cli().value_of("set");

                alter(&rt, id, add, rem, set);
            },
            |name| {
                debug!("Call: {}", name);
                match name {
                    "list" => list(id, &rt),
                    _ => {
                        warn!("Unknown command");
                        // More error handling
                    },
                };
            });
}

fn alter(rt: &Runtime, id: &str, add: Option<&str>, rem: Option<&str>, set: Option<&str>) {
    let path = build_entry_path(rt, id);
    debug!("path = {:?}", path);
    rt.store()
        // "id" must be present, enforced via clap spec
        .retrieve(path)
        .map(|mut e| {
            add.map(|tags| {
                let tags = tags.split(",");
                for tag in tags {
                    info!("Adding tag '{}'", tag);
                    if let Err(e) = e.add_tag(String::from(tag)) {
                        trace_error(&e);
                    }
                }
            });

            rem.map(|tags| {
                let tags = tags.split(",");
                for tag in tags {
                    info!("Removing tag '{}'", tag);
                    if let Err(e) = e.remove_tag(String::from(tag)) {
                        trace_error(&e);
                    }
                }
            });

            set.map(|tags| {
                info!("Setting tags '{}'", tags);
                let tags = tags.split(",").map(String::from).collect();
                if let Err(e) = e.set_tags(tags) {
                    trace_error(&e);
                }
            });
        })
        .map_err(|e| {
            info!("No entry.");
            trace_error(&e);
        })
        .ok();
}

fn list(id: &str, rt: &Runtime) {
    let path = build_entry_path(rt, id);
    debug!("path = {:?}", path);

    let entry = rt.store().retrieve(path.clone());
    if entry.is_err() {
        debug!("Could not retrieve '{:?}' => {:?}", id, path);
        warn!("Could not retrieve entry '{}'", id);
        trace_error(&entry.err().unwrap());
        exit(1);
    }
    let entry = entry.unwrap();

    let scmd = rt.cli().subcommand_matches("list").unwrap(); // safe, we checked in main()

    let json_out = scmd.is_present("json");
    let line_out = scmd.is_present("linewise");
    let sepp_out = scmd.is_present("sep");
    let mut comm_out = scmd.is_present("commasep");

    if !vec![json_out, line_out, comm_out, sepp_out].iter().any(|v| *v) {
        // None of the flags passed, go to default
        comm_out = true;
    }

    let tags = entry.get_tags();
    if tags.is_err() {
        trace_error(&tags.err().unwrap());
        exit(1);
    }
    let tags = tags.unwrap();

    if json_out {
        unimplemented!()
    }

    if line_out {
        for tag in &tags {
            println!("{}", tag);
        }
    }

    if sepp_out {
        let sepp = scmd.value_of("sep").unwrap(); // we checked before
        println!("{}", tags.join(sepp));
    }

    if comm_out {
        println!("{}", tags.join(", "));
    }
}

<|endoftext|>


<commit_before><commit_msg>Simple vector example<commit_after>fn main() {
  let your_favorite_numbers = @[1,2,3];
  let my_favorite_numbers = @[4,5,6];

  let our_favorite_numbers = your_favorite_numbers + my_favorite_numbers;

  println(fmt!("The third favorite number is %d.", our_favorite_numbers[2]));
}
<|endoftext|>