<commit_before>// Copyright 2012-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 double-ended queue implemented as a circular buffer

static initial_capacity: uint = 32u; // 2^5

pub struct Deque<T> {
    priv nelts: uint,
    priv lo: uint,
    priv hi: uint,
    priv elts: ~[Option<T>]
}

impl<T> Container for Deque<T> {
    /// Return the number of elements in the deque
    fn len(&const self) -> uint { self.nelts }

    /// Return true if the deque contains no elements
    fn is_empty(&const self) -> bool { self.len() == 0 }
}

impl<T> Mutable for Deque<T> {
    /// Clear the deque, removing all values.
    fn clear(&mut self) {
        for self.elts.each_mut |x| { *x = None }
        self.nelts = 0;
        self.lo = 0;
        self.hi = 0;
    }
}

pub impl<T> Deque<T> {
    /// Create an empty Deque
    fn new() -> Deque<T> {
        Deque{nelts: 0, lo: 0, hi: 0,
              elts: vec::from_fn(initial_capacity, |_| None)}
    }

    /// Return a reference to the first element in the deque
    ///
    /// Fails if the deque is empty
    fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) }

    /// Return a reference to the last element in the deque
    ///
    /// Fails if the deque is empty
    fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) }

    /// Retrieve an element in the deque by index
    ///
    /// Fails if there is no element with the given index
    fn get<'a>(&'a self, i: int) -> &'a T {
        let idx = (self.lo + (i as uint)) % self.elts.len();
        get(self.elts, idx)
    }

    /// Iterate over the elements in the deque
    fn each(&self, f: &fn(&T) -> bool) {
        self.eachi(|_i, e| f(e))
    }

    /// Iterate over the elements in the deque by index
    fn eachi(&self, f: &fn(uint, &T) -> bool) {
        for uint::range(0, self.nelts) |i| {
            if !f(i, self.get(i as int)) { return; }
        }
    }

    /// Remove and return the first element in the deque
    ///
    /// Fails if the deque is empty
    fn pop_front(&mut self) -> T {
        let result = self.elts[self.lo].swap_unwrap();
        self.lo = (self.lo + 1u) % self.elts.len();
        self.nelts -= 1u;
        result
    }

    /// Remove and return the last element in the deque
    ///
    /// Fails if the deque is empty
    fn pop_back(&mut self) -> T {
        if self.hi == 0u {
            self.hi = self.elts.len() - 1u;
        } else { self.hi -= 1u; }
        let result = self.elts[self.hi].swap_unwrap();
        self.elts[self.hi] = None;
        self.nelts -= 1u;
        result
    }

    /// Prepend an element to the deque
    fn add_front(&mut self, t: T) {
        let oldlo = self.lo;
        if self.lo == 0u {
            self.lo = self.elts.len() - 1u;
        } else { self.lo -= 1u; }
        if self.lo == self.hi {
            self.elts = grow(self.nelts, oldlo, self.elts);
            self.lo = self.elts.len() - 1u;
            self.hi = self.nelts;
        }
        self.elts[self.lo] = Some(t);
        self.nelts += 1u;
    }

    /// Append an element to the deque
    fn add_back(&mut self, t: T) {
        if self.lo == self.hi && self.nelts != 0u {
            self.elts = grow(self.nelts, self.lo, self.elts);
            self.lo = 0u;
            self.hi = self.nelts;
        }
        self.elts[self.hi] = Some(t);
        self.hi = (self.hi + 1u) % self.elts.len();
        self.nelts += 1u;
    }
}

/// Grow is only called on full elts, so nelts is also len(elts), unlike
/// elsewhere.
fn grow<T>(nelts: uint, lo: uint, elts: &mut [Option<T>]) -> ~[Option<T>] {
    assert!(nelts == elts.len());
    let mut rv = ~[];

    do rv.grow_fn(nelts + 1) |i| {
        let mut element = None;
        element <-> elts[(lo + i) % nelts];
        element
    }

    rv
}

fn get<'r, T>(elts: &'r [Option<T>], i: uint) -> &'r T {
    match elts[i] { Some(ref t) => t, _ => fail!() }
}

#[cfg(test)]
mod tests {
    use super::*;
    use core::cmp::Eq;
    use core::kinds::{Durable, Copy};

    #[test]
    fn test_simple() {
        let mut d = Deque::new();
        assert!(d.len() == 0u);
        d.add_front(17);
        d.add_front(42);
        d.add_back(137);
        assert!(d.len() == 3u);
        d.add_back(137);
        assert!(d.len() == 4u);
        debug!(d.peek_front());
        assert!(*d.peek_front() == 42);
        debug!(d.peek_back());
        assert!(*d.peek_back() == 137);
        let mut i: int = d.pop_front();
        debug!(i);
        assert!(i == 42);
        i = d.pop_back();
        debug!(i);
        assert!(i == 137);
        i = d.pop_back();
        debug!(i);
        assert!(i == 137);
        i = d.pop_back();
        debug!(i);
        assert!(i == 17);
        assert!(d.len() == 0u);
        d.add_back(3);
        assert!(d.len() == 1u);
        d.add_front(2);
        assert!(d.len() == 2u);
        d.add_back(4);
        assert!(d.len() == 3u);
        d.add_front(1);
        assert!(d.len() == 4u);
        debug!(d.get(0));
        debug!(d.get(1));
        debug!(d.get(2));
        debug!(d.get(3));
        assert!(*d.get(0) == 1);
        assert!(*d.get(1) == 2);
        assert!(*d.get(2) == 3);
        assert!(*d.get(3) == 4);
    }

    #[test]
    fn test_boxes() {
        let a: @int = @5;
        let b: @int = @72;
        let c: @int = @64;
        let d: @int = @175;

        let mut deq = Deque::new();
        assert!(deq.len() == 0);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert!(deq.len() == 3);
        deq.add_back(d);
        assert!(deq.len() == 4);
        assert!(*deq.peek_front() == b);
        assert!(*deq.peek_back() == d);
        assert!(deq.pop_front() == b);
        assert!(deq.pop_back() == d);
        assert!(deq.pop_back() == c);
        assert!(deq.pop_back() == a);
        assert!(deq.len() == 0);
        deq.add_back(c);
        assert!(deq.len() == 1);
        deq.add_front(b);
        assert!(deq.len() == 2);
        deq.add_back(d);
        assert!(deq.len() == 3);
        deq.add_front(a);
        assert!(deq.len() == 4);
        assert!(*deq.get(0) == a);
        assert!(*deq.get(1) == b);
        assert!(*deq.get(2) == c);
        assert!(*deq.get(3) == d);
    }

    #[cfg(test)]
    fn test_parameterized<T:Copy + Eq + Durable>(a: T, b: T, c: T, d: T) {
        let mut deq = Deque::new();
        assert!(deq.len() == 0);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert!(deq.len() == 3);
        deq.add_back(d);
        assert!(deq.len() == 4);
        assert!(*deq.peek_front() == b);
        assert!(*deq.peek_back() == d);
        assert!(deq.pop_front() == b);
        assert!(deq.pop_back() == d);
        assert!(deq.pop_back() == c);
        assert!(deq.pop_back() == a);
        assert!(deq.len() == 0);
        deq.add_back(c);
        assert!(deq.len() == 1);
        deq.add_front(b);
        assert!(deq.len() == 2);
        deq.add_back(d);
        assert!(deq.len() == 3);
        deq.add_front(a);
        assert!(deq.len() == 4);
        assert!(*deq.get(0) == a);
        assert!(*deq.get(1) == b);
        assert!(*deq.get(2) == c);
        assert!(*deq.get(3) == d);
    }

    #[deriving(Eq)]
    enum Taggy { One(int), Two(int, int), Three(int, int, int), }

    #[deriving(Eq)]
    enum Taggypar<T> {
        Onepar(int), Twopar(int, int), Threepar(int, int, int),
    }

    #[deriving(Eq)]
    struct RecCy {
        x: int,
        y: int,
        t: Taggy
    }

    #[test]
    fn test_param_int() {
        test_parameterized::<int>(5, 72, 64, 175);
    }

    #[test]
    fn test_param_at_int() {
        test_parameterized::<@int>(@5, @72, @64, @175);
    }

    #[test]
    fn test_param_taggy() {
        test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3),
                                    Two(17, 42));
    }

    #[test]
    fn test_param_taggypar() {
        test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
                                            Twopar::<int>(1, 2),
                                            Threepar::<int>(1, 2, 3),
                                            Twopar::<int>(17, 42));
    }

    #[test]
    fn test_param_reccy() {
        let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
        let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
        let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
        let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
        test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
    }

    #[test]
    fn test_eachi() {
        let mut deq = Deque::new();
        deq.add_back(1);
        deq.add_back(2);
        deq.add_back(3);

        for deq.eachi |i, e| {
            assert_eq!(*e, i + 1);
        }

        deq.pop_front();

        for deq.eachi |i, e| {
            assert_eq!(*e, i + 2);
        }

    }
}
<commit_msg>std: Replace Durable with 'static<commit_after>// Copyright 2012-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 double-ended queue implemented as a circular buffer

static initial_capacity: uint = 32u; // 2^5

pub struct Deque<T> {
    priv nelts: uint,
    priv lo: uint,
    priv hi: uint,
    priv elts: ~[Option<T>]
}

impl<T> Container for Deque<T> {
    /// Return the number of elements in the deque
    fn len(&const self) -> uint { self.nelts }

    /// Return true if the deque contains no elements
    fn is_empty(&const self) -> bool { self.len() == 0 }
}

impl<T> Mutable for Deque<T> {
    /// Clear the deque, removing all values.
    fn clear(&mut self) {
        for self.elts.each_mut |x| { *x = None }
        self.nelts = 0;
        self.lo = 0;
        self.hi = 0;
    }
}

pub impl<T> Deque<T> {
    /// Create an empty Deque
    fn new() -> Deque<T> {
        Deque{nelts: 0, lo: 0, hi: 0,
              elts: vec::from_fn(initial_capacity, |_| None)}
    }

    /// Return a reference to the first element in the deque
    ///
    /// Fails if the deque is empty
    fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) }

    /// Return a reference to the last element in the deque
    ///
    /// Fails if the deque is empty
    fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) }

    /// Retrieve an element in the deque by index
    ///
    /// Fails if there is no element with the given index
    fn get<'a>(&'a self, i: int) -> &'a T {
        let idx = (self.lo + (i as uint)) % self.elts.len();
        get(self.elts, idx)
    }

    /// Iterate over the elements in the deque
    fn each(&self, f: &fn(&T) -> bool) {
        self.eachi(|_i, e| f(e))
    }

    /// Iterate over the elements in the deque by index
    fn eachi(&self, f: &fn(uint, &T) -> bool) {
        for uint::range(0, self.nelts) |i| {
            if !f(i, self.get(i as int)) { return; }
        }
    }

    /// Remove and return the first element in the deque
    ///
    /// Fails if the deque is empty
    fn pop_front(&mut self) -> T {
        let result = self.elts[self.lo].swap_unwrap();
        self.lo = (self.lo + 1u) % self.elts.len();
        self.nelts -= 1u;
        result
    }

    /// Remove and return the last element in the deque
    ///
    /// Fails if the deque is empty
    fn pop_back(&mut self) -> T {
        if self.hi == 0u {
            self.hi = self.elts.len() - 1u;
        } else { self.hi -= 1u; }
        let result = self.elts[self.hi].swap_unwrap();
        self.elts[self.hi] = None;
        self.nelts -= 1u;
        result
    }

    /// Prepend an element to the deque
    fn add_front(&mut self, t: T) {
        let oldlo = self.lo;
        if self.lo == 0u {
            self.lo = self.elts.len() - 1u;
        } else { self.lo -= 1u; }
        if self.lo == self.hi {
            self.elts = grow(self.nelts, oldlo, self.elts);
            self.lo = self.elts.len() - 1u;
            self.hi = self.nelts;
        }
        self.elts[self.lo] = Some(t);
        self.nelts += 1u;
    }

    /// Append an element to the deque
    fn add_back(&mut self, t: T) {
        if self.lo == self.hi && self.nelts != 0u {
            self.elts = grow(self.nelts, self.lo, self.elts);
            self.lo = 0u;
            self.hi = self.nelts;
        }
        self.elts[self.hi] = Some(t);
        self.hi = (self.hi + 1u) % self.elts.len();
        self.nelts += 1u;
    }
}

/// Grow is only called on full elts, so nelts is also len(elts), unlike
/// elsewhere.
fn grow<T>(nelts: uint, lo: uint, elts: &mut [Option<T>]) -> ~[Option<T>] {
    assert!(nelts == elts.len());
    let mut rv = ~[];

    do rv.grow_fn(nelts + 1) |i| {
        let mut element = None;
        element <-> elts[(lo + i) % nelts];
        element
    }

    rv
}

fn get<'r, T>(elts: &'r [Option<T>], i: uint) -> &'r T {
    match elts[i] { Some(ref t) => t, _ => fail!() }
}

#[cfg(test)]
mod tests {
    use super::*;
    use core::cmp::Eq;
    use core::kinds::Copy;

    #[test]
    fn test_simple() {
        let mut d = Deque::new();
        assert!(d.len() == 0u);
        d.add_front(17);
        d.add_front(42);
        d.add_back(137);
        assert!(d.len() == 3u);
        d.add_back(137);
        assert!(d.len() == 4u);
        debug!(d.peek_front());
        assert!(*d.peek_front() == 42);
        debug!(d.peek_back());
        assert!(*d.peek_back() == 137);
        let mut i: int = d.pop_front();
        debug!(i);
        assert!(i == 42);
        i = d.pop_back();
        debug!(i);
        assert!(i == 137);
        i = d.pop_back();
        debug!(i);
        assert!(i == 137);
        i = d.pop_back();
        debug!(i);
        assert!(i == 17);
        assert!(d.len() == 0u);
        d.add_back(3);
        assert!(d.len() == 1u);
        d.add_front(2);
        assert!(d.len() == 2u);
        d.add_back(4);
        assert!(d.len() == 3u);
        d.add_front(1);
        assert!(d.len() == 4u);
        debug!(d.get(0));
        debug!(d.get(1));
        debug!(d.get(2));
        debug!(d.get(3));
        assert!(*d.get(0) == 1);
        assert!(*d.get(1) == 2);
        assert!(*d.get(2) == 3);
        assert!(*d.get(3) == 4);
    }

    #[test]
    fn test_boxes() {
        let a: @int = @5;
        let b: @int = @72;
        let c: @int = @64;
        let d: @int = @175;

        let mut deq = Deque::new();
        assert!(deq.len() == 0);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert!(deq.len() == 3);
        deq.add_back(d);
        assert!(deq.len() == 4);
        assert!(*deq.peek_front() == b);
        assert!(*deq.peek_back() == d);
        assert!(deq.pop_front() == b);
        assert!(deq.pop_back() == d);
        assert!(deq.pop_back() == c);
        assert!(deq.pop_back() == a);
        assert!(deq.len() == 0);
        deq.add_back(c);
        assert!(deq.len() == 1);
        deq.add_front(b);
        assert!(deq.len() == 2);
        deq.add_back(d);
        assert!(deq.len() == 3);
        deq.add_front(a);
        assert!(deq.len() == 4);
        assert!(*deq.get(0) == a);
        assert!(*deq.get(1) == b);
        assert!(*deq.get(2) == c);
        assert!(*deq.get(3) == d);
    }

    #[cfg(test)]
    fn test_parameterized<T:Copy + Eq>(a: T, b: T, c: T, d: T) {
        let mut deq = Deque::new();
        assert!(deq.len() == 0);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert!(deq.len() == 3);
        deq.add_back(d);
        assert!(deq.len() == 4);
        assert!(*deq.peek_front() == b);
        assert!(*deq.peek_back() == d);
        assert!(deq.pop_front() == b);
        assert!(deq.pop_back() == d);
        assert!(deq.pop_back() == c);
        assert!(deq.pop_back() == a);
        assert!(deq.len() == 0);
        deq.add_back(c);
        assert!(deq.len() == 1);
        deq.add_front(b);
        assert!(deq.len() == 2);
        deq.add_back(d);
        assert!(deq.len() == 3);
        deq.add_front(a);
        assert!(deq.len() == 4);
        assert!(*deq.get(0) == a);
        assert!(*deq.get(1) == b);
        assert!(*deq.get(2) == c);
        assert!(*deq.get(3) == d);
    }

    #[deriving(Eq)]
    enum Taggy { One(int), Two(int, int), Three(int, int, int), }

    #[deriving(Eq)]
    enum Taggypar<T> {
        Onepar(int), Twopar(int, int), Threepar(int, int, int),
    }

    #[deriving(Eq)]
    struct RecCy {
        x: int,
        y: int,
        t: Taggy
    }

    #[test]
    fn test_param_int() {
        test_parameterized::<int>(5, 72, 64, 175);
    }

    #[test]
    fn test_param_at_int() {
        test_parameterized::<@int>(@5, @72, @64, @175);
    }

    #[test]
    fn test_param_taggy() {
        test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3),
                                    Two(17, 42));
    }

    #[test]
    fn test_param_taggypar() {
        test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
                                            Twopar::<int>(1, 2),
                                            Threepar::<int>(1, 2, 3),
                                            Twopar::<int>(17, 42));
    }

    #[test]
    fn test_param_reccy() {
        let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
        let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
        let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
        let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
        test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
    }

    #[test]
    fn test_eachi() {
        let mut deq = Deque::new();
        deq.add_back(1);
        deq.add_back(2);
        deq.add_back(3);

        for deq.eachi |i, e| {
            assert_eq!(*e, i + 1);
        }

        deq.pop_front();

        for deq.eachi |i, e| {
            assert_eq!(*e, i + 2);
        }

    }
}
<|endoftext|>


<commit_before>//! A naive implementation of left-leaning red-black trees
//! that are isomorphic to 2-3 trees. This implementation
//! borrows heavily from https://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf
//! and https://github.com/rcatolino/rbtree-rust.

// I have spent a lot of hours trying all possible ways to
// implement this data structure. Most of the attemps
// led to confusing compilation errors. The heart of the
// issue is how to represent the Option<Box<Node>>.

// I tried using the newtype pattern
// https://doc.rust-lang.org/book/structs.html#tuple-structs.
// I (and others) had difficulty writing the
// destructuring lets correctly. See
// https://www.reddit.com/r/rust/comments/2cmjfn/how_to_do_typedefsnewtypes

// I tried creating a struct with a single field
// but had trouble accessing the field correctly
// ("let", "let ref", "let mut", "let ref mut").
// In addition the dummy field obfuscated the implementation.

// I tried using a type alias but then it's not
// possible to implement Display and Debug.

// Eventually I settled on using no abstraction for
// Option<Box<Node>>. The implementation became
// much easier to write.

// Also the implementation became much easier after I
// saw from rcatolino that some methods should be defined
// on a trait that wraps Box<Node> and other method
// should be defined on a trait that wraps Option<Box<Node>>.

use std::cmp::Ordering;
use std::fmt;
use std::mem;

#[derive(PartialEq, Eq, Copy, Clone)]
enum Color {
    Red,
    Black,
}

// This instance of the newtype pattern
// https://doc.rust-lang.org/book/structs.html#tuple-structs
// is used only for fmt::Display and fmt::Debug.
struct Link<'a>(&'a Option<Box<Node>>);

pub struct LLRBTree {
    root: Option<Box<Node>>,
}

struct Node {
    key: i32,
    val: i32,
    color: Color,
    left: Option<Box<Node>>,
    right: Option<Box<Node>>,
}

impl LLRBTree {

    pub fn new() -> Self {
        LLRBTree { root: None }
    }

    pub fn get(&self, key: i32) -> Option<i32> {
        self.root.get(key)
    }

    pub fn insert(&mut self, key: i32, value: i32) -> Option<i32> {
        let prev = self.root.insert(key, value);
        self.root.mutate().color = Color::Black;
        prev
    }

}

impl fmt::Display for LLRBTree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{}", Link(&self.root))
     }
}

impl fmt::Debug for LLRBTree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{:?}", Link(&self.root))
     }
}

impl Node {

    fn new(key: i32, val: i32) -> Self {
        Node {
            key: key,
            val: val,
            color: Color::Red,
            left: None,
            right: None,
        }
    }

}

trait BoxNode {
    fn left_rotate(&mut self);
    fn right_rotate(&mut self);
    fn flip_colors(&mut self);
}

impl BoxNode for Box<Node> {

    fn left_rotate(&mut self) {
        debug_assert!(self.right.is_red());
        let mut child = self.right.take().unwrap();
        mem::swap(self, &mut child);
        mem::swap(&mut child.right, &mut self.left);
        self.color = child.color;
        child.color = Color::Red;
        self.left = Some(child);
    }

    fn right_rotate(&mut self) {
        debug_assert!(self.left.is_red());
        let mut child = self.left.take().unwrap();
        mem::swap(self, &mut child);
        mem::swap(&mut child.left, &mut self.right);
        self.color = child.color;
        child.color = Color::Red;
        self.right = Some(child);
    }

    fn flip_colors(&mut self) {
        debug_assert!(self.color == Color::Black);
        debug_assert!(self.left.is_red());
        debug_assert!(self.right.is_red());
        self.color = Color::Red;
        self.left.mutate().color = Color::Black;
        self.right.mutate().color = Color::Black;
    }
}

trait OptionBoxNode {
    fn get(&self, key: i32) -> Option<i32>;
    fn is_red(&self) -> bool;
    fn insert(&mut self, key: i32, val: i32) -> Option<i32>;
    fn reference(&mut self) -> & Box<Node>;
    fn mutate(&mut self) -> &mut Box<Node>;
}

impl OptionBoxNode for Option<Box<Node>> {

    fn get(&self, key: i32) -> Option<i32> {
        match *self {
            None => None,
            Some(ref node) => match key.cmp(&node.key) {
                Ordering::Equal => Some(node.val),
                Ordering::Less => node.left.get(key),
                Ordering::Greater => node.right.get(key)
            }
        }
    }

    fn is_red(&self) -> bool {
        match *self {
            None => false,
            Some(ref node) => (node.color == Color::Red)
        }
    }

    fn insert(&mut self, key: i32, value: i32) -> Option<i32> {
        let prev = match *self {
            None => {
                *self = new_leaf(key, value);
                None
            },
            Some(ref mut node) => {
                match key.cmp(&node.key) {
                    Ordering::Equal => {
                        let prev = node.val;
                        node.val = value;
                        Some(prev)
                    },
                    Ordering::Less => node.left.insert(key, value),
                    Ordering::Greater => node.right.insert(key, value),
                }
            }
        };
        let node = self.mutate();
        if !node.left.is_red() && node.right.is_red() {
            node.left_rotate();
        }
        if node.left.is_red() && node.left.reference().left.is_red() {
            node.right_rotate();
        }
        if node.left.is_red() && node.right.is_red() {
             node.flip_colors();
        }
        prev
    }

    fn reference(&mut self) -> & Box<Node> {
        self.as_ref().unwrap()
    }

    fn mutate(&mut self) -> &mut Box<Node> {
        self.as_mut().unwrap()
    }

}

impl<'a> fmt::Display for Link<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Link(ref link) = *self;
        match *link {
            &None => write!(f, "nil"),
            &Some(ref node) => write!(f, "({} {} {})",
                node.key, Link(&node.left), Link(&node.right))
        }
    }
}

impl<'a> fmt::Debug for Link<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Link(ref link) = *self;
        match *link {
            &None => write!(f, "nil"),
            &Some(ref node) => write!(f, "({},{},{} {:?} {:?})",
                node.key, node.val, node.color,
                Link(&node.left), Link(&node.right))
        }
    }
}

impl fmt::Display for Color {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Color::Red => write!(f, "red"),
            Color::Black => write!(f, "black")
        }
    }
}

fn new_leaf(key: i32, val: i32) -> Option<Box<Node>> {
    Some(Box::new(Node::new(key, val)))
}

#[test]
fn basic_construction() {
    let mut tree = LLRBTree::new();
    assert_eq!(tree.get(0), None);
    assert_eq!(tree.insert(0, 1), None);
    assert_eq!(tree.insert(0, 2), Some(1));
    assert_eq!(tree.get(0), Some(2));
}

#[test]
fn insert_sequence() {
    let mut tree = LLRBTree::new();
    for i in 0..10 {
        assert_eq!(tree.insert(i, i), None);
    }
    for i in 0..10 {
        assert_eq!(tree.get(i), Some(i));
    }
}
<commit_msg>Apply rustfmt tool.<commit_after>//! A naive implementation of left-leaning red-black trees
//! that are isomorphic to 2-3 trees. This implementation
//! borrows heavily from https://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf
//! and https://github.com/rcatolino/rbtree-rust.

// I have spent a lot of hours trying all possible ways to
// implement this data structure. Most of the attemps
// led to confusing compilation errors. The heart of the
// issue is how to represent the Option<Box<Node>>.

// I tried using the newtype pattern
// https://doc.rust-lang.org/book/structs.html#tuple-structs.
// I (and others) had difficulty writing the
// destructuring lets correctly. See
// https://www.reddit.com/r/rust/comments/2cmjfn/how_to_do_typedefsnewtypes

// I tried creating a struct with a single field
// but had trouble accessing the field correctly
// ("let", "let ref", "let mut", "let ref mut").
// In addition the dummy field obfuscated the implementation.

// I tried using a type alias but then it's not
// possible to implement Display and Debug.

// Eventually I settled on using no abstraction for
// Option<Box<Node>>. The implementation became
// much easier to write.

// Also the implementation became much easier after I
// saw from rcatolino that some methods should be defined
// on a trait that wraps Box<Node> and other method
// should be defined on a trait that wraps Option<Box<Node>>.

use std::cmp::Ordering;
use std::fmt;
use std::mem;

#[derive(PartialEq, Eq, Copy, Clone)]
enum Color {
    Red,
    Black,
}

// This instance of the newtype pattern
// https://doc.rust-lang.org/book/structs.html#tuple-structs
// is used only for fmt::Display and fmt::Debug.
struct Link<'a>(&'a Option<Box<Node>>);

pub struct LLRBTree {
    root: Option<Box<Node>>,
}

struct Node {
    key: i32,
    val: i32,
    color: Color,
    left: Option<Box<Node>>,
    right: Option<Box<Node>>,
}

impl LLRBTree {
    pub fn new() -> Self {
        LLRBTree { root: None }
    }

    pub fn get(&self, key: i32) -> Option<i32> {
        self.root.get(key)
    }

    pub fn insert(&mut self, key: i32, value: i32) -> Option<i32> {
        let prev = self.root.insert(key, value);
        self.root.mutate().color = Color::Black;
        prev
    }
}

impl fmt::Display for LLRBTree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", Link(&self.root))
    }
}

impl fmt::Debug for LLRBTree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", Link(&self.root))
    }
}

impl Node {
    fn new(key: i32, val: i32) -> Self {
        Node {
            key: key,
            val: val,
            color: Color::Red,
            left: None,
            right: None,
        }
    }
}

trait BoxNode {
    fn left_rotate(&mut self);
    fn right_rotate(&mut self);
    fn flip_colors(&mut self);
}

impl BoxNode for Box<Node> {
    fn left_rotate(&mut self) {
        debug_assert!(self.right.is_red());
        let mut child = self.right.take().unwrap();
        mem::swap(self, &mut child);
        mem::swap(&mut child.right, &mut self.left);
        self.color = child.color;
        child.color = Color::Red;
        self.left = Some(child);
    }

    fn right_rotate(&mut self) {
        debug_assert!(self.left.is_red());
        let mut child = self.left.take().unwrap();
        mem::swap(self, &mut child);
        mem::swap(&mut child.left, &mut self.right);
        self.color = child.color;
        child.color = Color::Red;
        self.right = Some(child);
    }

    fn flip_colors(&mut self) {
        debug_assert!(self.color == Color::Black);
        debug_assert!(self.left.is_red());
        debug_assert!(self.right.is_red());
        self.color = Color::Red;
        self.left.mutate().color = Color::Black;
        self.right.mutate().color = Color::Black;
    }
}

trait OptionBoxNode {
    fn get(&self, key: i32) -> Option<i32>;
    fn is_red(&self) -> bool;
    fn insert(&mut self, key: i32, val: i32) -> Option<i32>;
    fn reference(&mut self) -> &Box<Node>;
    fn mutate(&mut self) -> &mut Box<Node>;
}

impl OptionBoxNode for Option<Box<Node>> {
    fn get(&self, key: i32) -> Option<i32> {
        match *self {
            None => None,
            Some(ref node) => {
                match key.cmp(&node.key) {
                    Ordering::Equal => Some(node.val),
                    Ordering::Less => node.left.get(key),
                    Ordering::Greater => node.right.get(key),
                }
            }
        }
    }

    fn is_red(&self) -> bool {
        match *self {
            None => false,
            Some(ref node) => (node.color == Color::Red),
        }
    }

    fn insert(&mut self, key: i32, value: i32) -> Option<i32> {
        let prev = match *self {
            None => {
                *self = new_leaf(key, value);
                None
            }
            Some(ref mut node) => {
                match key.cmp(&node.key) {
                    Ordering::Equal => {
                        let prev = node.val;
                        node.val = value;
                        Some(prev)
                    }
                    Ordering::Less => node.left.insert(key, value),
                    Ordering::Greater => node.right.insert(key, value),
                }
            }
        };
        let node = self.mutate();
        if !node.left.is_red() && node.right.is_red() {
            node.left_rotate();
        }
        if node.left.is_red() && node.left.reference().left.is_red() {
            node.right_rotate();
        }
        if node.left.is_red() && node.right.is_red() {
            node.flip_colors();
        }
        prev
    }

    fn reference(&mut self) -> &Box<Node> {
        self.as_ref().unwrap()
    }

    fn mutate(&mut self) -> &mut Box<Node> {
        self.as_mut().unwrap()
    }
}

impl<'a> fmt::Display for Link<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Link(ref link) = *self;
        match *link {
            &None => write!(f, "nil"),
            &Some(ref node) => {
                write!(f,
                       "({} {} {})",
                       node.key,
                       Link(&node.left),
                       Link(&node.right))
            }
        }
    }
}

impl<'a> fmt::Debug for Link<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Link(ref link) = *self;
        match *link {
            &None => write!(f, "nil"),
            &Some(ref node) => {
                write!(f,
                       "({},{},{} {:?} {:?})",
                       node.key,
                       node.val,
                       node.color,
                       Link(&node.left),
                       Link(&node.right))
            }
        }
    }
}

impl fmt::Display for Color {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Color::Red => write!(f, "red"),
            Color::Black => write!(f, "black"),
        }
    }
}

fn new_leaf(key: i32, val: i32) -> Option<Box<Node>> {
    Some(Box::new(Node::new(key, val)))
}

#[test]
fn basic_construction() {
    let mut tree = LLRBTree::new();
    assert_eq!(tree.get(0), None);
    assert_eq!(tree.insert(0, 1), None);
    assert_eq!(tree.insert(0, 2), Some(1));
    assert_eq!(tree.get(0), Some(2));
}

#[test]
fn insert_sequence() {
    let mut tree = LLRBTree::new();
    for i in 0..10 {
        assert_eq!(tree.insert(i, i), None);
    }
    for i in 0..10 {
        assert_eq!(tree.get(i), Some(i));
    }
}
<|endoftext|>


<commit_before>//! Matrix user identifiers.

use std::{convert::TryFrom, fmt, num::NonZeroU8};

use crate::ServerName;

/// A Matrix user ID.
///
/// A `UserId` is generated randomly or converted from a string slice, and can be converted back
/// into a string as needed.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::UserId;
/// assert_eq!(
///     UserId::try_from("@carl:example.com").unwrap().as_ref(),
///     "@carl:example.com"
/// );
/// ```
#[derive(Clone)]
pub struct UserId {
    full_id: Box<str>,
    colon_idx: NonZeroU8,

    /// Whether this user id is a historical one.
    ///
    /// A historical user id is one that is not legal per the regular user id rules, but was
    /// accepted by previous versions of the spec and thus has to be supported because users with
    /// these kinds of ids still exist.
    is_historical: bool,
}

impl fmt::Debug for UserId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(&self.full_id)
    }
}

impl UserId {
    /// Attempts to generate a `UserId` for the given origin server with a localpart consisting of
    /// 12 random ASCII characters.
    #[cfg(feature = "rand")]
    #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
    pub fn new(server_name: &ServerName) -> Self {
        use crate::generate_localpart;

        let full_id = format!("@{}:{}", generate_localpart(12).to_lowercase(), server_name).into();

        Self { full_id, colon_idx: NonZeroU8::new(13).unwrap(), is_historical: false }
    }

    /// Attempts to complete a user ID, by adding the colon + server name and `@` prefix, if not
    /// present already.
    ///
    /// This is a convenience function for the login API, where a user can supply either their full
    /// user ID or just the localpart. It only supports a valid user ID or a valid user ID
    /// localpart, not the localpart plus the `@` prefix, or the localpart plus server name without
    /// the `@` prefix.
    pub fn parse_with_server_name(
        id: impl AsRef<str> + Into<Box<str>>,
        server_name: &ServerName,
    ) -> Result<Self, crate::Error> {
        let id_str = id.as_ref();

        if id_str.starts_with('@') {
            try_from(id.into())
        } else {
            let is_fully_conforming = localpart_is_fully_conforming(id_str)?;

            Ok(Self {
                full_id: format!("@{}:{}", id_str, server_name).into(),
                colon_idx: NonZeroU8::new(id_str.len() as u8 + 1).unwrap(),
                is_historical: !is_fully_conforming,
            })
        }
    }
}

impl UserId {
    /// Returns the user's localpart.
    pub fn localpart(&self) -> &str {
        &self.full_id[1..self.colon_idx.get() as usize]
    }

    /// Returns the server name of the user ID.
    pub fn server_name(&self) -> &ServerName {
        <&ServerName>::try_from(&self.full_id[self.colon_idx.get() as usize + 1..]).unwrap()
    }

    /// Whether this user ID is a historical one, i.e. one that doesn't conform to the latest
    /// specification of the user ID grammar but is still accepted because it was previously
    /// allowed.
    pub fn is_historical(&self) -> bool {
        self.is_historical
    }
}

/// Attempts to create a new Matrix user ID from a string representation.
///
/// The string must include the leading @ sigil, the localpart, a literal colon, and a server name.
fn try_from<S>(user_id: S) -> Result<UserId, crate::Error>
where
    S: AsRef<str> + Into<Box<str>>,
{
    let (colon_idx, is_historical) =
        ruma_identifiers_validation::user_id::validate(user_id.as_ref())?;
    Ok(UserId { full_id: user_id.into(), colon_idx, is_historical: !is_historical })
}

common_impls!(UserId, try_from, "a Matrix user ID");

pub use ruma_identifiers_validation::user_id::localpart_is_fully_conforming;

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use super::UserId;
    use crate::{Error, ServerName};

    #[test]
    fn valid_user_id_from_str() {
        let user_id = UserId::try_from("@carl:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn parse_valid_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("@carl:example.com", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn parse_valid_user_id_parts() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id =
            UserId::parse_with_server_name("carl", server_name).expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn valid_historical_user_id() {
        let user_id = UserId::try_from("@a%b[irc]:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn parse_valid_historical_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("@a%b[irc]:example.com", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn parse_valid_historical_user_id_parts() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("a%b[irc]", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn uppercase_user_id() {
        let user_id = UserId::try_from("@CARL:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@CARL:example.com");
        assert!(user_id.is_historical());
    }

    #[cfg(feature = "rand")]
    #[test]
    fn generate_random_valid_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::new(server_name);
        assert_eq!(user_id.localpart().len(), 12);
        assert_eq!(user_id.server_name(), "example.com");

        let id_str = user_id.as_str();

        assert!(id_str.starts_with('@'));
        assert_eq!(id_str.len(), 25);
    }

    #[cfg(feature = "serde")]
    #[test]
    fn serialize_valid_user_id() {
        assert_eq!(
            serde_json::to_string(
                &UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
            )
            .expect("Failed to convert UserId to JSON."),
            r#""@carl:example.com""#
        );
    }

    #[cfg(feature = "serde")]
    #[test]
    fn deserialize_valid_user_id() {
        assert_eq!(
            serde_json::from_str::<UserId>(r#""@carl:example.com""#)
                .expect("Failed to convert JSON to UserId"),
            UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
        );
    }

    #[test]
    fn valid_user_id_with_explicit_standard_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:443").expect("Failed to create UserId.").as_ref(),
            "@carl:example.com:443"
        );
    }

    #[test]
    fn valid_user_id_with_non_standard_port() {
        let user_id = UserId::try_from("@carl:example.com:5000").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com:5000");
        assert!(!user_id.is_historical());
    }

    #[test]
    #[cfg(not(feature = "compat"))]
    fn invalid_characters_in_user_id_localpart() {
        assert_eq!(UserId::try_from("@te\nst:example.com").unwrap_err(), Error::InvalidCharacters);
    }

    #[test]
    fn missing_user_id_sigil() {
        assert_eq!(UserId::try_from("carl:example.com").unwrap_err(), Error::MissingLeadingSigil);
    }

    #[test]
    fn missing_user_id_delimiter() {
        assert_eq!(UserId::try_from("@carl").unwrap_err(), Error::MissingDelimiter);
    }

    #[test]
    fn invalid_user_id_host() {
        assert_eq!(UserId::try_from("@carl:/").unwrap_err(), Error::InvalidServerName);
    }

    #[test]
    fn invalid_user_id_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:notaport").unwrap_err(),
            Error::InvalidServerName
        );
    }
}
<commit_msg>identifiers: Merge impl blocks<commit_after>//! Matrix user identifiers.

use std::{convert::TryFrom, fmt, num::NonZeroU8};

use crate::ServerName;

/// A Matrix user ID.
///
/// A `UserId` is generated randomly or converted from a string slice, and can be converted back
/// into a string as needed.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::UserId;
/// assert_eq!(
///     UserId::try_from("@carl:example.com").unwrap().as_ref(),
///     "@carl:example.com"
/// );
/// ```
#[derive(Clone)]
pub struct UserId {
    full_id: Box<str>,
    colon_idx: NonZeroU8,

    /// Whether this user id is a historical one.
    ///
    /// A historical user id is one that is not legal per the regular user id rules, but was
    /// accepted by previous versions of the spec and thus has to be supported because users with
    /// these kinds of ids still exist.
    is_historical: bool,
}

impl fmt::Debug for UserId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(&self.full_id)
    }
}

impl UserId {
    /// Attempts to generate a `UserId` for the given origin server with a localpart consisting of
    /// 12 random ASCII characters.
    #[cfg(feature = "rand")]
    #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
    pub fn new(server_name: &ServerName) -> Self {
        use crate::generate_localpart;

        let full_id = format!("@{}:{}", generate_localpart(12).to_lowercase(), server_name).into();

        Self { full_id, colon_idx: NonZeroU8::new(13).unwrap(), is_historical: false }
    }

    /// Attempts to complete a user ID, by adding the colon + server name and `@` prefix, if not
    /// present already.
    ///
    /// This is a convenience function for the login API, where a user can supply either their full
    /// user ID or just the localpart. It only supports a valid user ID or a valid user ID
    /// localpart, not the localpart plus the `@` prefix, or the localpart plus server name without
    /// the `@` prefix.
    pub fn parse_with_server_name(
        id: impl AsRef<str> + Into<Box<str>>,
        server_name: &ServerName,
    ) -> Result<Self, crate::Error> {
        let id_str = id.as_ref();

        if id_str.starts_with('@') {
            try_from(id.into())
        } else {
            let is_fully_conforming = localpart_is_fully_conforming(id_str)?;

            Ok(Self {
                full_id: format!("@{}:{}", id_str, server_name).into(),
                colon_idx: NonZeroU8::new(id_str.len() as u8 + 1).unwrap(),
                is_historical: !is_fully_conforming,
            })
        }
    }

    /// Returns the user's localpart.
    pub fn localpart(&self) -> &str {
        &self.full_id[1..self.colon_idx.get() as usize]
    }

    /// Returns the server name of the user ID.
    pub fn server_name(&self) -> &ServerName {
        <&ServerName>::try_from(&self.full_id[self.colon_idx.get() as usize + 1..]).unwrap()
    }

    /// Whether this user ID is a historical one, i.e. one that doesn't conform to the latest
    /// specification of the user ID grammar but is still accepted because it was previously
    /// allowed.
    pub fn is_historical(&self) -> bool {
        self.is_historical
    }
}

/// Attempts to create a new Matrix user ID from a string representation.
///
/// The string must include the leading @ sigil, the localpart, a literal colon, and a server name.
fn try_from<S>(user_id: S) -> Result<UserId, crate::Error>
where
    S: AsRef<str> + Into<Box<str>>,
{
    let (colon_idx, is_historical) =
        ruma_identifiers_validation::user_id::validate(user_id.as_ref())?;
    Ok(UserId { full_id: user_id.into(), colon_idx, is_historical: !is_historical })
}

common_impls!(UserId, try_from, "a Matrix user ID");

pub use ruma_identifiers_validation::user_id::localpart_is_fully_conforming;

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use super::UserId;
    use crate::{Error, ServerName};

    #[test]
    fn valid_user_id_from_str() {
        let user_id = UserId::try_from("@carl:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn parse_valid_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("@carl:example.com", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn parse_valid_user_id_parts() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id =
            UserId::parse_with_server_name("carl", server_name).expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn valid_historical_user_id() {
        let user_id = UserId::try_from("@a%b[irc]:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn parse_valid_historical_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("@a%b[irc]:example.com", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn parse_valid_historical_user_id_parts() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("a%b[irc]", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn uppercase_user_id() {
        let user_id = UserId::try_from("@CARL:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@CARL:example.com");
        assert!(user_id.is_historical());
    }

    #[cfg(feature = "rand")]
    #[test]
    fn generate_random_valid_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::new(server_name);
        assert_eq!(user_id.localpart().len(), 12);
        assert_eq!(user_id.server_name(), "example.com");

        let id_str = user_id.as_str();

        assert!(id_str.starts_with('@'));
        assert_eq!(id_str.len(), 25);
    }

    #[cfg(feature = "serde")]
    #[test]
    fn serialize_valid_user_id() {
        assert_eq!(
            serde_json::to_string(
                &UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
            )
            .expect("Failed to convert UserId to JSON."),
            r#""@carl:example.com""#
        );
    }

    #[cfg(feature = "serde")]
    #[test]
    fn deserialize_valid_user_id() {
        assert_eq!(
            serde_json::from_str::<UserId>(r#""@carl:example.com""#)
                .expect("Failed to convert JSON to UserId"),
            UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
        );
    }

    #[test]
    fn valid_user_id_with_explicit_standard_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:443").expect("Failed to create UserId.").as_ref(),
            "@carl:example.com:443"
        );
    }

    #[test]
    fn valid_user_id_with_non_standard_port() {
        let user_id = UserId::try_from("@carl:example.com:5000").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com:5000");
        assert!(!user_id.is_historical());
    }

    #[test]
    #[cfg(not(feature = "compat"))]
    fn invalid_characters_in_user_id_localpart() {
        assert_eq!(UserId::try_from("@te\nst:example.com").unwrap_err(), Error::InvalidCharacters);
    }

    #[test]
    fn missing_user_id_sigil() {
        assert_eq!(UserId::try_from("carl:example.com").unwrap_err(), Error::MissingLeadingSigil);
    }

    #[test]
    fn missing_user_id_delimiter() {
        assert_eq!(UserId::try_from("@carl").unwrap_err(), Error::MissingDelimiter);
    }

    #[test]
    fn invalid_user_id_host() {
        assert_eq!(UserId::try_from("@carl:/").unwrap_err(), Error::InvalidServerName);
    }

    #[test]
    fn invalid_user_id_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:notaport").unwrap_err(),
            Error::InvalidServerName
        );
    }
}
<|endoftext|>


<commit_before>extern crate num;

use self::num::traits::{Num};
use self::num::traits::{One};
use common::{mid};
use std::fmt::{Debug};
use std::io::stdout;
use std::io::Write;

pub struct PointSegmentTree<N, P>{
    root: Node<N, P>,
    lower_bound: N,
    upper_bound: N,
    default: P,
    combine: Box<F<P>>
}

#[derive(PartialEq, Eq, Debug)]
struct Node<N, P> {
    start: N,
    end: N,
    value: P,
    left: Option<Box<Node<N, P>>>,
    right: Option<Box<Node<N, P>>>,
}

pub type F<P> = Fn(&P, &P) -> P;

impl<N: Debug+Num+Clone+Ord, P: Debug+Clone> PointSegmentTree<N, P> {
    pub fn new(lower_bound: N, upper_bound: N, default_value: P,
               combine: Box<F<P>>) -> Self
    {
        if lower_bound > upper_bound {
            panic!("Invalid bounds (lower_bound must not be greater than upper_bound)");
        }
        let node = Node::new(lower_bound.clone(),
                             upper_bound.clone(),
                             &default_value);

        PointSegmentTree {
            default:  default_value,
            lower_bound: lower_bound,
            upper_bound: upper_bound,
            combine: combine,
            root: node
        }
    }

    pub fn insert(&mut self, point_n: N, point_data: P) {
        if point_n < self.lower_bound || point_n > self.upper_bound {
           panic!("Attempted insert out of tree bounds");
        }
        self.root.insert(point_n, point_data, &self.default,
                         &*self.combine);
    }

    pub fn query(&self, start_q: N, end_q: N) -> Option<P> {
        if end_q < start_q || start_q < self.lower_bound || end_q > self.upper_bound {
            None
        } else {
            Some(self.root.query(start_q, end_q, &*self.combine, self.default.clone()))
        }
    }

    pub fn bounds(&self) -> (N, N) {
        (self.lower_bound.clone(), self.upper_bound.clone())
    }

}

impl<N: Num+Clone+Ord+Debug, P: Debug+Clone> Node<N, P> {
    fn new(start: N, end: N, default_value: &P) -> Self {
        Node {
            start: start,
            end: end,
            value: default_value.clone(),
            left: None,
            right: None,
        }
    }

    fn new_son(start: N, end: N, default_value: &P) -> Option<Box<Self>> {
        Some(Box::new(Node::new(start, end, default_value)))
    }

    fn query(&self, start_q: N, end_q: N, combine: &F<P>, acc: P) -> P {
        if self.start == start_q && self.end == end_q {
            stdout().flush();
            return combine(&self.value, &acc);
        }
        let mid = mid(self.start.clone(), self.end.clone());

        if end_q <= mid {
            match self.left {
                None => acc,
                Some(ref n) => n.query(start_q, end_q, combine, acc)
            }
        } else if start_q > mid {
            match self.right {
                None => acc,
                Some(ref n) => n.query(start_q, end_q, combine, acc)
            }
        } else {
            // split
            let acc_l = match self.left {
                None => acc,
                Some(ref n) => n.query(start_q, mid.clone(), combine, acc)
            };
            let acc_r = match self.right {
                None => acc_l,
                Some(ref n) => n.query(mid + One::one(), end_q, combine, acc_l)
            };
            acc_r
        }
    }

    fn insert(&mut self, point_n: N, point_data: P,
              default: &P, combine: &F<P>) {
        let mid = mid(self.start.clone(), self.end.clone());
        self.value = combine(&self.value, &point_data);
        if self.start == self.end {
            // leaf
            return;
        }
        if point_n <= mid {
            if self.left.is_none() {
                self.left = Node::new_son(self.start.clone(), mid, default);
            }
            self.left.as_mut().map(|n| n.insert(point_n, point_data, default, combine));
        } else {
            if self.right.is_none() {
                self.right = Node::new_son(mid + One::one(), self.end.clone(), default);
            }
            self.right.as_mut().map(|n| n.insert(point_n, point_data, default, combine));
        }
    }
}
<commit_msg>Remove debug code<commit_after>extern crate num;

use self::num::traits::{Num};
use self::num::traits::{One};
use common::{mid};

pub struct PointSegmentTree<N, P>{
    root: Node<N, P>,
    lower_bound: N,
    upper_bound: N,
    default: P,
    combine: Box<F<P>>
}

#[derive(PartialEq, Eq, Debug)]
struct Node<N, P> {
    start: N,
    end: N,
    value: P,
    left: Option<Box<Node<N, P>>>,
    right: Option<Box<Node<N, P>>>,
}

pub type F<P> = Fn(&P, &P) -> P;

impl<N: Num+Clone+Ord, P: Clone> PointSegmentTree<N, P> {
    pub fn new(lower_bound: N, upper_bound: N, default_value: P,
               combine: Box<F<P>>) -> Self
    {
        if lower_bound > upper_bound {
            panic!("Invalid bounds (lower_bound must not be greater than upper_bound)");
        }
        let node = Node::new(lower_bound.clone(),
                             upper_bound.clone(),
                             &default_value);

        PointSegmentTree {
            default:  default_value,
            lower_bound: lower_bound,
            upper_bound: upper_bound,
            combine: combine,
            root: node
        }
    }

    pub fn insert(&mut self, point_n: N, point_data: P) {
        if point_n < self.lower_bound || point_n > self.upper_bound {
           panic!("Attempted insert out of tree bounds");
        }
        self.root.insert(point_n, point_data, &self.default,
                         &*self.combine);
    }

    pub fn query(&self, start_q: N, end_q: N) -> Option<P> {
        if end_q < start_q || start_q < self.lower_bound || end_q > self.upper_bound {
            None
        } else {
            Some(self.root.query(start_q, end_q, &*self.combine, self.default.clone()))
        }
    }

    pub fn bounds(&self) -> (N, N) {
        (self.lower_bound.clone(), self.upper_bound.clone())
    }

}

impl<N: Num+Clone+Ord, P: Clone> Node<N, P> {
    fn new(start: N, end: N, default_value: &P) -> Self {
        Node {
            start: start,
            end: end,
            value: default_value.clone(),
            left: None,
            right: None,
        }
    }

    fn new_son(start: N, end: N, default_value: &P) -> Option<Box<Self>> {
        Some(Box::new(Node::new(start, end, default_value)))
    }

    fn query(&self, start_q: N, end_q: N, combine: &F<P>, acc: P) -> P {
        if self.start == start_q && self.end == end_q {
            return combine(&self.value, &acc);
        }
        let mid = mid(self.start.clone(), self.end.clone());

        if end_q <= mid {
            match self.left {
                None => acc,
                Some(ref n) => n.query(start_q, end_q, combine, acc)
            }
        } else if start_q > mid {
            match self.right {
                None => acc,
                Some(ref n) => n.query(start_q, end_q, combine, acc)
            }
        } else {
            // split
            let acc_l = match self.left {
                None => acc,
                Some(ref n) => n.query(start_q, mid.clone(), combine, acc)
            };
            let acc_r = match self.right {
                None => acc_l,
                Some(ref n) => n.query(mid + One::one(), end_q, combine, acc_l)
            };
            acc_r
        }
    }

    fn insert(&mut self, point_n: N, point_data: P,
              default: &P, combine: &F<P>) {
        let mid = mid(self.start.clone(), self.end.clone());
        self.value = combine(&self.value, &point_data);
        if self.start == self.end {
            // leaf
            return;
        }
        if point_n <= mid {
            if self.left.is_none() {
                self.left = Node::new_son(self.start.clone(), mid, default);
            }
            self.left.as_mut().map(|n| n.insert(point_n, point_data, default, combine));
        } else {
            if self.right.is_none() {
                self.right = Node::new_son(mid + One::one(), self.end.clone(), default);
            }
            self.right.as_mut().map(|n| n.insert(point_n, point_data, default, combine));
        }
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::io::process::Process;
use std::io::fs;
use sync::Future;

use context::{Context, Call};
use into_path::IntoPath;
use into_future::IntoFuture;

#[deriving(Clone)]
pub struct SharedBuilder {
    ctx: Context,
    exe: Path,
    flags: ~[~str],
}

impl SharedBuilder {
    pub fn new<T: IntoPath>(ctx: Context, exe: T) -> SharedBuilder {
        SharedBuilder {
            ctx: ctx,
            exe: exe.into_path(),
            flags: ~[],
        }
    }

    pub fn compile<T: IntoFuture<Path>>(&self, src: T) -> Gcc {
        let src = src.into_future().unwrap();
        let dst = src.with_extension("o");

        Gcc::new(self.ctx.clone(), self.exe.clone(), dst)
            .add_src(src)
            .add_flag(~"-c")
            .add_flag(~"-fPIC")
    }

    pub fn link_lib<'a, T: IntoPath>(&self, dst: T) -> Gcc {
        let mut dst = dst.into_path();

        // change the filename to be "lib${filename}.dylib".
        let filename = format!("lib{}.dylib", dst.filename_str().unwrap());
        dst.set_filename(filename);

        Gcc::new(self.ctx.clone(), self.exe.clone(), dst)
            .add_flag(~"-fPIC")
            .add_flag(~"-dynamiclib")
    }

    pub fn link_exe<'a, T: IntoPath>(&self, dst: T) -> Gcc {
        Gcc::new(self.ctx.clone(), self.exe.clone(), dst.into_path())
    }
}

pub struct Gcc {
    priv ctx: Context,
    priv exe: Path,
    priv dst: Path,
    priv srcs: ~[Path],
    priv includes: ~[Path],
    priv libs: ~[Path],
    priv flags: ~[~str],
}

impl Gcc {
    pub fn new(ctx: Context, exe: Path, mut dst: Path) -> Gcc {
        // Make sure we write the output in the build/ directory.
        if !dst.is_ancestor_of(&ctx.root) {
            dst = ctx.root.join(dst);
        }

        Gcc {
            ctx: ctx,
            exe: exe,
            dst: dst,
            srcs: ~[],
            includes: ~[],
            libs: ~[],
            flags: ~[],
        }
    }

    pub fn add_src<T: IntoFuture<Path>>(mut self, src: T) -> Gcc {
        self.srcs.push(src.into_future().unwrap());
        self
    }

    pub fn add_srcs<T: IntoFuture<Path>>(mut self, srcs: ~[T]) -> Gcc {
        let mut iter = srcs.move_iter().map(|src| src.into_future().unwrap());
        self.srcs.extend(&mut iter);
        self
    }

    pub fn add_include<T: IntoFuture<Path>>(mut self, include: T) -> Gcc {
        self.includes.push(include.into_future().unwrap());
        self
    }

    pub fn add_lib<T: IntoFuture<Path>>(mut self, lib: T) -> Gcc {
        let lib = lib.into_future().unwrap();
        self.libs.push(lib);
        self
    }

    pub fn add_flag<S: Str>(mut self, flag: S) -> Gcc {
        self.flags.push(flag.as_slice().to_owned());
        self
    }

    pub fn run(self) -> Path {
        self.into_future().unwrap()
    }
}

impl IntoFuture<Path> for Gcc {
    fn into_future(self) -> Future<Path> {
        let Gcc { ctx, exe, dst, srcs, includes, libs, flags } = self;

        assert!(!srcs.is_empty());

        let mut prep = ctx.prep("Call");

        let mut call = Call::new(exe.clone()).unwrap();

        call.push_str(~"-o");
        call.push_output_path(dst.clone());

        for include in includes.move_iter() {
            call.push_str(~"-I");
            call.push_input_path(include).unwrap();
        }

        let mut new_libs: ~[~str] = ~[];
        let mut new_libpaths: ~[Path] = ~[];

        for lib in libs.move_iter() {
            prep.declare_input_path(lib.clone()).unwrap();

            new_libpaths.push(lib.dir_path());

            let name = lib.filename_str().unwrap();

            let prefix = "lib";
            let suffix = ".dylib";

            assert!(name.starts_with(prefix) && name.ends_with(suffix));

            new_libs.push(name.slice(prefix.len(), suffix.len()).to_owned());
        }

        for libpath in new_libpaths.move_iter() {
            call.push_str(~"-L");
            call.push_str(libpath.as_str().unwrap().to_owned());
        }

        for lib in new_libs.move_iter() {
            call.push_str(~"-l");
            call.push_str(lib);
        }

        for flag in flags.move_iter() {
            call.push_str(flag);
        }

        for src in srcs.iter() {
            call.push_input_path(src.clone()).ok().expect("src");
        }

        prep.declare_call(&call);

        prep.exec(proc(_exec) {
            let (prog, args) = call.cmd();

            print!("{}:", exe.display());

            for src in srcs.iter() {
                print!(" {}", src.display());
            }

            // Make sure the parent directories exist.
            fs::mkdir_recursive(&dst.dir_path(), io::UserDir).unwrap();

            println!(" -> {}", dst.display());
            println!("{} {}", prog, args);

            let mut process = Process::new(prog, args).unwrap();
            let status = process.wait();

            if !status.success() {
                fail!("command failed");
            }

            dst
        })
    }
}
<commit_msg>flesh out the gcc flags<commit_after>use std::io;
use std::io::process::Process;
use std::io::fs;
use sync::Future;

use context::{Context, Call};
use into_path::IntoPath;
use into_future::IntoFuture;

#[deriving(Clone)]
pub struct SharedBuilder {
    ctx: Context,
    exe: Path,
    flags: ~[~str],
}

impl SharedBuilder {
    pub fn new<T: IntoPath>(ctx: Context, exe: T) -> SharedBuilder {
        SharedBuilder {
            ctx: ctx,
            exe: exe.into_path(),
            flags: ~[],
        }
    }

    pub fn compile<T: IntoFuture<Path>>(&self, src: T) -> Gcc {
        let src = src.into_future().unwrap();
        let dst = src.with_extension("o");

        Gcc::new(self.ctx.clone(), self.exe.clone(), dst)
            .add_src(src)
            .add_flag(~"-c")
            .add_flag(~"-fPIC")
    }

    pub fn link_lib<'a, T: IntoPath>(&self, dst: T) -> Gcc {
        let mut dst = dst.into_path();

        // change the filename to be "lib${filename}.dylib".
        let filename = format!("lib{}.dylib", dst.filename_str().unwrap());
        dst.set_filename(filename);

        Gcc::new(self.ctx.clone(), self.exe.clone(), dst)
            .add_flag(~"-fPIC")
            .add_flag(~"-dynamiclib")
    }

    pub fn link_exe<'a, T: IntoPath>(&self, dst: T) -> Gcc {
        Gcc::new(self.ctx.clone(), self.exe.clone(), dst.into_path())
    }
}

pub struct Gcc {
    priv ctx: Context,
    priv exe: Path,
    priv dst: Path,
    priv srcs: ~[Path],
    priv includes: ~[Path],
    priv libs: ~[Path],
    priv external_libs: ~[~str],
    priv libpaths: ~[Path],
    priv macros: ~[~str],
    priv warnings: ~[~str],
    priv debug: bool,
    priv profile: bool,
    priv optimize: bool,
    priv flags: ~[~str],
}

impl Gcc {
    pub fn new(ctx: Context, exe: Path, mut dst: Path) -> Gcc {
        // Make sure we write the output in the build/ directory.
        if !dst.is_ancestor_of(&ctx.root) {
            dst = ctx.root.join(dst);
        }

        Gcc {
            ctx: ctx,
            exe: exe,
            dst: dst,
            srcs: ~[],
            includes: ~[],
            libs: ~[],
            external_libs: ~[],
            libpaths: ~[],
            macros: ~[],
            warnings: ~[],
            debug: false,
            profile: false,
            optimize: false,
            flags: ~[],
        }
    }

    pub fn add_src<T: IntoFuture<Path>>(mut self, src: T) -> Gcc {
        self.srcs.push(src.into_future().unwrap());
        self
    }

    pub fn add_include<T: IntoFuture<Path>>(mut self, include: T) -> Gcc {
        self.includes.push(include.into_future().unwrap());
        self
    }

    pub fn add_lib<T: IntoFuture<Path>>(mut self, lib: T) -> Gcc {
        self.libs.push(lib.into_future().unwrap());
        self
    }

    pub fn add_external_lib<T: Str>(mut self, lib: T) -> Gcc {
        self.external_libs.push(lib.into_owned());
        self
    }

    pub fn add_libpath<T: IntoPath>(mut self, libpath: T) -> Gcc {
        self.libpaths.push(libpath.into_path());
        self
    }

    pub fn add_macro<T: Str>(mut self, macro: T) -> Gcc {
        self.macros.push(macro.into_owned());
        self
    }

    pub fn add_warning<T: Str>(mut self, warning: T) -> Gcc {
        self.warnings.push(warning.into_owned());
        self
    }

    pub fn set_debug(mut self, debug: bool) -> Gcc {
        self.debug = debug;
        self
    }

    pub fn set_optimize(mut self, optimize: bool) -> Gcc {
        self.optimize = optimize;
        self
    }

    pub fn set_profile(mut self, profile: bool) -> Gcc {
        self.profile = profile;
        self
    }

    pub fn add_flag<S: Str>(mut self, flag: S) -> Gcc {
        self.flags.push(flag.into_owned());
        self
    }

    pub fn run(self) -> Path {
        self.into_future().unwrap()
    }
}

impl IntoFuture<Path> for Gcc {
    fn into_future(self) -> Future<Path> {
        let Gcc {
            ctx,
            exe,
            dst,
            srcs,
            includes,
            libs,
            mut external_libs,
            mut libpaths,
            macros,
            warnings,
            debug,
            profile,
            optimize,
            flags
        } = self;

        assert!(!srcs.is_empty());

        let mut prep = ctx.prep("Call");

        let mut call = Call::new(exe.clone()).unwrap();

        call.push_str(~"-o");
        call.push_output_path(dst.clone());

        for include in includes.move_iter() {
            call.push_str(~"-I");
            call.push_input_path(include).unwrap();
        }

        // We need to extract the relative lib info from a lib path
        for lib in libs.move_iter() {
            prep.declare_input_path(lib.clone()).unwrap();

            libpaths.push(lib.dir_path());

            let name = lib.filename_str().unwrap();

            let prefix = "lib";
            let suffix = ".dylib";

            assert!(name.starts_with(prefix) && name.ends_with(suffix));

            external_libs.push(name.slice(prefix.len(), suffix.len()).to_owned());
        }

        for libpath in libpaths.move_iter() {
            call.push_str(~"-L");
            call.push_str(libpath.as_str().unwrap().to_owned());
        }

        for lib in external_libs.move_iter() {
            call.push_str(~"-l");
            call.push_str(lib);
        }

        if debug { call.push_str(~"-g"); }
        if optimize { call.push_str(~"-O2"); }
        if profile { call.push_str(~"-pg"); }

        for macro in macros.move_iter() {
            call.push_str(~"-D");
            call.push_str(macro);
        }

        for warning in warnings.move_iter() {
            call.push_str(~"-W");
            call.push_str(warning);
        }

        for flag in flags.move_iter() {
            call.push_str(flag);
        }

        for src in srcs.iter() {
            call.push_input_path(src.clone()).ok().expect("src");
        }

        prep.declare_call(&call);

        prep.exec(proc(_exec) {
            let (prog, args) = call.cmd();

            print!("{}:", exe.display());

            for src in srcs.iter() {
                print!(" {}", src.display());
            }

            // Make sure the parent directories exist.
            fs::mkdir_recursive(&dst.dir_path(), io::UserDir).unwrap();

            println!(" -> {}", dst.display());
            println!("{} {}", prog, args);

            let mut process = Process::new(prog, args).unwrap();
            let status = process.wait();

            if !status.success() {
                fail!("command failed");
            }

            dst
        })
    }
}
<|endoftext|>


<commit_before>pub mod info;
pub mod user;
pub mod list;

/// `S`ring/`I`nteger
/// a temporary type for strings that are integers
/// if a field with an integer as string is used, just use `.into()`

/// `S`ring/`I`nteger
/// a temporary type for strings that are integers
/// if a field with an integer as string is used, just use `.into()`
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
pub enum SI {
	I(i64),
	S(String),
}

#[derive(Debug, Clone, Deserialize)]
pub enum Kat {
	Anime,
	Manga,
}

#[derive(Debug, Clone, Deserialize)]
pub enum Medium {
	#[serde(rename = "animerseries")]
	AnimeSeries,
	#[serde(rename = "movie")]
	Movie,
	#[serde(rename = "ova")]
	OVA,
	#[serde(rename = "hentai")]
	Hentai,
	#[serde(rename = "mangaseries")]
	Manga,
	#[serde(rename = "oneshot")]
	OneShot,
	#[serde(rename = "doujin")]
	Doujin,
	#[serde(rename = "hmanga")]
	HManga,
}

#[derive(Debug, Clone, Deserialize)]
pub enum State {
	#[serde(rename = "0")]
	PreAiring,
	#[serde(rename = "1")]
	Finished,
	#[serde(rename = "2")]
	Airing,
	#[serde(rename = "3")]
	Cancelled,
	#[serde(rename = "4")]
	NoSub,
}

#[derive(Debug, Clone, Deserialize)]
pub enum Season {
	#[serde(rename = "0")]
	Unknown,
	#[serde(rename = "1")]
	Winter,
	#[serde(rename = "2")]
	Spring,
	#[serde(rename = "3")]
	Summer,
	#[serde(rename = "4")]
	Autumn,
}
<commit_msg>fix typo<commit_after>pub mod info;
pub mod user;
pub mod list;

/// `S`ring/`I`nteger
/// a temporary type for strings that are integers
/// if a field with an integer as string is used, just use `.into()`

/// `S`ring/`I`nteger
/// a temporary type for strings that are integers
/// if a field with an integer as string is used, just use `.into()`
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
pub enum SI {
	I(i64),
	S(String),
}

#[derive(Debug, Clone, Deserialize)]
pub enum Kat {
	Anime,
	Manga,
}

#[derive(Debug, Clone, Deserialize)]
pub enum Medium {
	#[serde(rename = "animeseries")]
	AnimeSeries,
	#[serde(rename = "movie")]
	Movie,
	#[serde(rename = "ova")]
	OVA,
	#[serde(rename = "hentai")]
	Hentai,
	#[serde(rename = "mangaseries")]
	Manga,
	#[serde(rename = "oneshot")]
	OneShot,
	#[serde(rename = "doujin")]
	Doujin,
	#[serde(rename = "hmanga")]
	HManga,
}

#[derive(Debug, Clone, Deserialize)]
pub enum State {
	#[serde(rename = "0")]
	PreAiring,
	#[serde(rename = "1")]
	Finished,
	#[serde(rename = "2")]
	Airing,
	#[serde(rename = "3")]
	Cancelled,
	#[serde(rename = "4")]
	NoSub,
}

#[derive(Debug, Clone, Deserialize)]
pub enum Season {
	#[serde(rename = "0")]
	Unknown,
	#[serde(rename = "1")]
	Winter,
	#[serde(rename = "2")]
	Spring,
	#[serde(rename = "3")]
	Summer,
	#[serde(rename = "4")]
	Autumn,
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use url::{self, form_urlencoded};

use {Github, Stream, Future, SortDirection};
use std::fmt;

use hyper::client::Connect;
use super::{Search, SearchResult};
use users::User;

#[derive(Debug, PartialEq)]
pub enum ReposSort {
    /// Sort by the number of stars
    Stars,
    ///Sort by the number of forks
    Forks,
    /// Sort by when the repo was last updated
    Updated
}

impl fmt::Display for ReposSort {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ReposSort::Stars => "stars",
            ReposSort::Forks => "forks",
            ReposSort::Updated => "updated",
        }.fmt(f)
    }
}

/// Provides access to search operations for repositories
/// https://developer.github.com/v3/search/#search-repositories
pub struct SearchRepos<C>
    where C: Clone + Connect
{
    search: Search<C>
}

impl<C: Clone + Connect> SearchRepos<C> {
    #[doc(hidden)]
    pub fn new(search: Search<C>) -> Self {
        Self {
            search
        }
    }

    fn search_uri<Q>(&self, q: Q, options: &SearchReposOptions) -> String
    where
        Q: Into<String>
    {
        let mut uri = vec!["/search/repositories".to_string()];
        let query_options = options.serialize().unwrap_or(String::new());
        let query = form_urlencoded::Serializer::new(query_options)
            .append_pair("q", &q.into())
            .finish();

        uri.push(query);
        uri.join("?")
    }

    pub fn iter<Q>(&self, q: Q, options: &SearchReposOptions) -> Stream<ReposItem>
    where
        Q: Into<String>
    {
        self.search.iter::<ReposItem> (&self.search_uri(q, options))
    }

    pub fn list<Q>(&self, q: Q, options: &SearchReposOptions) -> Future<SearchResult<ReposItem>>
    where
        Q: Into<String>
    {
        self.search.search::<ReposItem>(&self.search_uri(q, options))
    }
}

#[derive(Default)]
pub struct SearchReposOptions {
    params: HashMap<&'static str, String>,
}

impl SearchReposOptions {
    pub fn builder() -> SearchReposOptionsBuilder {
        SearchReposOptionsBuilder::new()
    }

    pub fn serialize(&self) -> Option<String> {
        if self.params.is_empty() {
            None
        }else {
            let encoded: String = form_urlencoded::Serializer::new(String::new())
                .extend_pairs(&self.params)
                .finish();
            Some(encoded)
        }
    }
}

pub struct SearchReposOptionsBuilder(SearchReposOptions);

impl SearchReposOptionsBuilder {
    pub fn new() -> SearchReposOptionsBuilder {
        SearchReposOptionsBuilder(SearchReposOptions { ..Default::default() })
    }

    pub fn per_page(&mut self, n: usize) -> &mut Self {
        self.0.params.insert("per_page", n.to_string());
        self
    }

    pub fn sort(&mut self, sort: ReposSort) -> &mut Self {
        self.0.params.insert("sort", sort.to_string());
        self
    }

    pub fn order(&mut self, direction: SortDirection) -> &mut Self {
        self.0.params.insert("order", direction.to_string());
        self
    }

    pub fn build(&self) -> SearchReposOptions {
        SearchReposOptions { params: self.0.params.clone() }
    }
}

#[derive(Debug, Deserialize)]
pub struct ReposItem {
    pub id: u32,
    pub name: String,
    pub full_name: String,
    pub owner: User,
    pub private: bool,
    pub html_url: String,
    pub description: String,
    pub fork: bool,
    pub url: String,
    pub created_at: String,
    pub updated_at: String,
    pub pushed_at: String,
    pub homepage: String,
    pub size: u32,
    pub stargazers_count: u32,
    pub watchers_count: u32,
    pub language: String,
    pub forks_count: u32,
    pub open_issues_count: u32,
    pub master_branch: String,
    pub default_branch: String,
    pub score: f64
}

<commit_msg>Fixed model<commit_after>use std::collections::HashMap;
use url::{self, form_urlencoded};

use {Github, Stream, Future, SortDirection};
use std::fmt;

use hyper::client::Connect;
use super::{Search, SearchResult};
use users::User;

#[derive(Debug, PartialEq)]
pub enum ReposSort {
    /// Sort by the number of stars
    Stars,
    ///Sort by the number of forks
    Forks,
    /// Sort by when the repo was last updated
    Updated
}

impl fmt::Display for ReposSort {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ReposSort::Stars => "stars",
            ReposSort::Forks => "forks",
            ReposSort::Updated => "updated",
        }.fmt(f)
    }
}

/// Provides access to search operations for repositories
/// https://developer.github.com/v3/search/#search-repositories
pub struct SearchRepos<C>
    where C: Clone + Connect
{
    search: Search<C>
}

impl<C: Clone + Connect> SearchRepos<C> {
    #[doc(hidden)]
    pub fn new(search: Search<C>) -> Self {
        Self {
            search
        }
    }

    fn search_uri<Q>(&self, q: Q, options: &SearchReposOptions) -> String
    where
        Q: Into<String>
    {
        let mut uri = vec!["/search/repositories".to_string()];
        let query_options = options.serialize().unwrap_or(String::new());
        let query = form_urlencoded::Serializer::new(query_options)
            .append_pair("q", &q.into())
            .finish();

        uri.push(query);
        uri.join("?")
    }

    pub fn iter<Q>(&self, q: Q, options: &SearchReposOptions) -> Stream<ReposItem>
    where
        Q: Into<String>
    {
        self.search.iter::<ReposItem> (&self.search_uri(q, options))
    }

    pub fn list<Q>(&self, q: Q, options: &SearchReposOptions) -> Future<SearchResult<ReposItem>>
    where
        Q: Into<String>
    {
        self.search.search::<ReposItem>(&self.search_uri(q, options))
    }
}

#[derive(Default)]
pub struct SearchReposOptions {
    params: HashMap<&'static str, String>,
}

impl SearchReposOptions {
    pub fn builder() -> SearchReposOptionsBuilder {
        SearchReposOptionsBuilder::new()
    }

    pub fn serialize(&self) -> Option<String> {
        if self.params.is_empty() {
            None
        }else {
            let encoded: String = form_urlencoded::Serializer::new(String::new())
                .extend_pairs(&self.params)
                .finish();
            Some(encoded)
        }
    }
}

pub struct SearchReposOptionsBuilder(SearchReposOptions);

impl SearchReposOptionsBuilder {
    pub fn new() -> SearchReposOptionsBuilder {
        SearchReposOptionsBuilder(SearchReposOptions { ..Default::default() })
    }

    pub fn per_page(&mut self, n: usize) -> &mut Self {
        self.0.params.insert("per_page", n.to_string());
        self
    }

    pub fn sort(&mut self, sort: ReposSort) -> &mut Self {
        self.0.params.insert("sort", sort.to_string());
        self
    }

    pub fn order(&mut self, direction: SortDirection) -> &mut Self {
        self.0.params.insert("order", direction.to_string());
        self
    }

    pub fn build(&self) -> SearchReposOptions {
        SearchReposOptions { params: self.0.params.clone() }
    }
}

#[derive(Debug, Deserialize)]
pub struct ReposItem {
    pub id: u32,
    pub name: String,
    pub full_name: String,
    pub owner: User,
    pub private: bool,
    pub html_url: String,
    pub description: String,
    pub fork: bool,
    pub url: String,
    pub forks_url: String,
    pub keys_url: String,
    pub collaborators_url: String,
    pub teams_url: String,
    pub hooks_url: String,
    pub issue_events_url: String,
    pub events_url: String,
    pub assignees_url: String,
    pub branches_url: String,
    pub tags_url: String,
    pub blobs_url: String,
    pub git_tags_url: String,
    pub git_refs_url: String,
    pub trees_url: String,
    pub statuses_url: String,
    pub languages_url: String,
    pub stargazers_url: String,
    pub contributors_url: String,
    pub subscribers_url: String,
    pub subscription_url: String,
    pub commits_url: String,
    pub git_commits_url: String,
    pub comments_url: String,
    pub issue_comment_url: String,
    pub contents_url: String,
    pub compare_url: String,
    pub merges_url: String,
    pub archive_url: String,
    pub downloads_url: String,
    pub issues_url: String,
    pub pulls_url: String,
    pub milestones_url: String,
    pub notifications_url: String,
    pub labels_url: String,
    pub releases_url: String,
    pub deployments_url: String,
    pub created_at: String,
    pub updated_at: String,
    pub pushed_at: String,
    pub git_url: String,
    pub ssh_url: String,
    pub clone_url: String,
    pub svn_url: String,
    pub homepage: String,
    pub size: u32,
    pub stargazers_count: u32,
    pub watchers_count: u32,
    pub language: String,
    pub has_issues: bool,
    pub has_projects: bool,
    pub has_downloads: bool,
    pub has_wiki: bool,
    pub has_pages: bool,
    pub forks_count: u32,
    pub mirror_url: Option<String>,
    pub archived: bool,
    pub open_issues_count: u32,
    pub license: License,
    pub forks: u32,
    pub open_issues: u32,
    pub watchers: u32,
    pub default_branch: String,
    pub score: f64
}

#[derive(Debug, Deserialize)]
pub struct License {
    key: String,
    name: String,
    spdx_id: String,
    url: String
}

<|endoftext|>


<commit_before>use super::forthnum::ForthNum;

/// Provides space for memory to be allocated by Forth words like VARIABLE
/// and ALLOC
#[derive(Default)]
pub struct Memory {
    values: Vec<ForthNum>,
}

impl Memory {
    pub fn get<T: From<ForthNum>>(&self, addr: i32) -> T {
        if let Some(value) = self.values.get(addr as usize) {
            (*value).into()
        } else {
            panic!("Invalid memory address");
        }
    }
    pub fn set<T: Into<ForthNum>>(&mut self, addr: i32, value: T) {
        if addr as usize > self.values.len() - 1 {
            panic!("Invalid memory address");
        }
        self.values[addr as usize] = value.into();
    }
    pub fn new<T: Into<ForthNum>>(&mut self, value: T) -> i32 {
        self.values.push(value.into());
        self.here()
    }
    pub fn here(&self) -> i32 {
        self.values.len() as i32 - 1
    }
}
<commit_msg>Add newlines between functions<commit_after>use super::forthnum::ForthNum;

/// Provides space for memory to be allocated by Forth words like VARIABLE
/// and ALLOC
#[derive(Default)]
pub struct Memory {
    values: Vec<ForthNum>,
}

impl Memory {
    pub fn get<T: From<ForthNum>>(&self, addr: i32) -> T {
        if let Some(value) = self.values.get(addr as usize) {
            (*value).into()
        } else {
            panic!("Invalid memory address");
        }
    }

    pub fn set<T: Into<ForthNum>>(&mut self, addr: i32, value: T) {
        if addr as usize > self.values.len() - 1 {
            panic!("Invalid memory address");
        }
        self.values[addr as usize] = value.into();
    }

    pub fn new<T: Into<ForthNum>>(&mut self, value: T) -> i32 {
        self.values.push(value.into());
        self.here()
    }

    pub fn here(&self) -> i32 {
        self.values.len() as i32 - 1
    }
}
<|endoftext|>


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

use std::io;
use std::mem;
use std::net::{TcpListener, TcpStream, UdpSocket};
use std::os::unix::io::FromRawFd;
use libc::{self, c_int};
#[cfg(not(any(target_os = "solaris", target_os = "emscripten")))]
use libc::{ioctl, FIOCLEX};

mod impls;

pub mod c {
    pub use libc::*;

    pub fn sockaddr_in_u32(sa: &sockaddr_in) -> u32 {
        ::ntoh((*sa).sin_addr.s_addr)
    }
}

pub struct Socket {
    fd: c_int,
}

impl Socket {
    #[cfg(not(any(target_os = "solaris", target_os = "emscripten")))]
    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
        unsafe {
            let fd = try!(::cvt(libc::socket(family, ty, 0)));
            ioctl(fd, FIOCLEX);
            Ok(Socket { fd: fd })
        }
    }

    // ioctl(FIOCLEX) is not supported by Solaris/Illumos or emscripten,
    // use fcntl(FD_CLOEXEC) instead
    #[cfg(any(target_os = "solaris", target_os = "emscripten"))]
    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
        unsafe {
            let fd = try!(::cvt(libc::socket(family, ty, 0)));
            libc::fcntl(fd, libc::FD_CLOEXEC);
            Ok(Socket { fd: fd })
        }
    }

    pub fn raw(&self) -> c_int { self.fd }

    fn into_fd(self) -> c_int {
        let fd = self.fd;
        mem::forget(self);
        fd
    }

    pub fn into_tcp_listener(self) -> TcpListener {
        unsafe { TcpListener::from_raw_fd(self.into_fd()) }
    }

    pub fn into_tcp_stream(self) -> TcpStream {
        unsafe { TcpStream::from_raw_fd(self.into_fd()) }
    }

    pub fn into_udp_socket(self) -> UdpSocket {
        unsafe { UdpSocket::from_raw_fd(self.into_fd()) }
    }
}

impl ::FromInner for Socket {
    type Inner = c_int;
    fn from_inner(fd: c_int) -> Socket {
        Socket { fd: fd }
    }
}

impl Drop for Socket {
    fn drop(&mut self) {
        unsafe {
            let _ = libc::close(self.fd);
        }
    }
}
<commit_msg>Use SOCK_CLOEXEC on linux to avoid race with fork<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::io;
use std::mem;
use std::net::{TcpListener, TcpStream, UdpSocket};
use std::os::unix::io::FromRawFd;
use libc::{self, c_int};
#[cfg(not(any(target_os = "solaris", target_os = "emscripten")))]
use libc::{ioctl, FIOCLEX};

mod impls;

pub mod c {
    pub use libc::*;

    pub fn sockaddr_in_u32(sa: &sockaddr_in) -> u32 {
        ::ntoh((*sa).sin_addr.s_addr)
    }
}

pub struct Socket {
    fd: c_int,
}

impl Socket {
    #[cfg(not(any(target_os = "solaris", target_os = "emscripten")))]
    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
        unsafe {
            // Linux >2.6.26 overloads the type argument to accept SOCK_CLOEXEC,
            // avoiding a race with another thread running fork/exec between
            // socket() and ioctl()
            #[cfg(any(target_os = "linux", target_os = "android"))]
            match ::cvt(libc::socket(family, ty | libc::SOCK_CLOEXEC, 0)) {
                Ok(fd) => return Ok(Socket { fd: fd }),
                // Older versions of Linux return EINVAL; fall back to ioctl
                Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
                Err(e) => return Err(e),
            }

            let fd = try!(::cvt(libc::socket(family, ty, 0)));
            ioctl(fd, FIOCLEX);
            Ok(Socket { fd: fd })
        }
    }

    // ioctl(FIOCLEX) is not supported by Solaris/Illumos or emscripten,
    // use fcntl(FD_CLOEXEC) instead
    #[cfg(any(target_os = "solaris", target_os = "emscripten"))]
    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
        unsafe {
            let fd = try!(::cvt(libc::socket(family, ty, 0)));
            libc::fcntl(fd, libc::FD_CLOEXEC);
            Ok(Socket { fd: fd })
        }
    }

    pub fn raw(&self) -> c_int { self.fd }

    fn into_fd(self) -> c_int {
        let fd = self.fd;
        mem::forget(self);
        fd
    }

    pub fn into_tcp_listener(self) -> TcpListener {
        unsafe { TcpListener::from_raw_fd(self.into_fd()) }
    }

    pub fn into_tcp_stream(self) -> TcpStream {
        unsafe { TcpStream::from_raw_fd(self.into_fd()) }
    }

    pub fn into_udp_socket(self) -> UdpSocket {
        unsafe { UdpSocket::from_raw_fd(self.into_fd()) }
    }
}

impl ::FromInner for Socket {
    type Inner = c_int;
    fn from_inner(fd: c_int) -> Socket {
        Socket { fd: fd }
    }
}

impl Drop for Socket {
    fn drop(&mut self) {
        unsafe {
            let _ = libc::close(self.fd);
        }
    }
}
<|endoftext|>


<commit_before>use super::*;

pub struct MemberMock {

}

impl development::MemberInternal for MemberMock {
	type Id = MockId;

    fn size(&self) -> (u16, u16);
    fn on_resize(&mut self, Option<callbacks::Resize>);

    fn set_visibility(&mut self, visibility: types::Visibility);
    fn visibility(&self) -> types::Visibility;

    fn id(&self) -> ids::Id;
    unsafe fn native_id(&self) -> Self::Id;
}

fn test_sanity() {

}<commit_msg>Tests fix<commit_after>use super::*;

pub struct MemberMock {

}

impl development::MemberInner for MemberMock {
	type Id = MockId;

    fn size(&self) -> (u16, u16);
    fn on_resize(&mut self, Option<callbacks::Resize>);

    fn set_visibility(&mut self, visibility: types::Visibility);
    fn visibility(&self) -> types::Visibility;

    fn id(&self) -> ids::Id;
    unsafe fn native_id(&self) -> Self::Id;
}

fn test_sanity() {

}<|endoftext|>