<commit_before>use std::mem;
use std::fmt;
use std::ptr;
use std::iter;

use rand::{thread_rng, Rng};

// 32
const DEFAULT_LEVEL: usize = 6;

type Link<T> = Option<Box<T>>;

#[allow(raw_pointer_derive)]
#[derive(Debug)]
struct Rawlink<T> {
    p: *mut T,
}

impl<T> Copy for Rawlink<T> {}
unsafe impl<T:Send> Send for Rawlink<T> {}
unsafe impl<T:Sync> Sync for Rawlink<T> {}

fn random_level() -> usize {
    let mut rng = thread_rng();
    let mut level = 0;
    loop {
        if rng.gen_weighted_bool(2) {
            level += 1;
            continue;
        }
        break;
    }

    level
}

#[derive(Debug)]
pub struct SkipNode<Key,E> {
    key: Key,
    it: E,
    next: Link<SkipNode<Key,E>>,
    prev: Rawlink<SkipNode<Key,E>>,
    // level 0 to DEFAULT_LEVEL
    forward: Vec<Rawlink<SkipNode<Key,E>>>,
}

impl<Key: PartialOrd, E> SkipNode<Key,E> {
    // level: 0 ~ DEFAULT_LEVEL
    fn new(key: Key, it: E, level: usize) -> SkipNode<Key,E> {
        SkipNode {
            key: key,
            it: it,
            next: None,
            prev: Rawlink::none(),
            forward: iter::repeat(Rawlink::none()).take(level).collect(),
        }
    }

    #[inline]
    fn level(&self) -> usize {
        self.level
    }

    fn to_ptr(&mut self) -> Rawlink<SkipNode<Key,E>> {
        Rawlink::some(self)
    }

    fn insert(&mut self, key: Key, it: E, level: usize) {
    }
}

pub struct SkipList<Key,E> {
    head: Link<SkipNode<Key,E>>,
    forward: Vec<Rawlink<SkipNode<Key,E>>>,
    level: usize,
    size: usize,
}

impl<Key: PartialOrd + fmt::Debug, E: fmt::Debug> SkipList<Key,E> {
    /// create new empty SkipList
    pub fn new() -> SkipList<Key, E> {
        SkipList {
            head: None,
            forward: iter::repeat(Rawlink::none()).take(DEFAULT_LEVEL).collect(),
            level: DEFAULT_LEVEL,
            size: 0,
        }
    }

    pub fn level(&self) -> usize {
        self.forward.iter().take_while(|p| p.is_some()).count()
    }

    pub fn find(&self, key: &Key) -> Option<&E> {
        None
        // let mut x = self.head.as_ref().map_or_else(Rawlink::none, |n| {
        //         Rawlink::some(&mut **n)
        //     });
        //     // insert normally
        //     let mut update: Vec<Rawlink<SkipNode<Key,E>>> = self.forward[..self.level()].to_vec();
        //         x = update[new_level-1];
        //         for i in (0..new_level).rev() {
        //             while x.resolve().map_or(false, |n| n.forward[i].is_some()) &&
        //                 x.resolve().map_or(false, |n| n.forward[i].resolve().unwrap().key < key) {
        //                     let nx = x.resolve().map_or_else(Rawlink::none, |n| n.forward[i] );
        //                     x = nx;
        //                 }
        //             update[i] = x.resolve_mut().map_or_else(Rawlink::none, |n| {
        //                 Rawlink::some(&mut *n)
        //             });
        //         }
        //     }

        //     let mut y = x.resolve_mut().map_or_else(Rawlink::none, |n| {
        //         Rawlink::some(&mut *n)
        //     });
        //     // When head node level is lower than current
        //     if y.is_none() {
        //         println!("update => {:?}", update);
        //         y = self.head.as_mut().map_or_else(Rawlink::none, |n| {
        //             Rawlink::some(&mut **n)
        //         });
        //     }
        //     while y.resolve().map_or(false, |n| n.next.is_some()) &&
        //         y.resolve().map_or(false, |n| n.next.as_ref().unwrap().key < key) {
        //             let ny = y.resolve_mut().map_or_else(Rawlink::none, |n| {
        //                 n.next.as_mut().map_or_else(Rawlink::none, |n| Rawlink::some(&mut **n))
        //             });
        //             y = ny
        //         }
    }

    fn adjust_head(&mut self, new_level: usize) {
        let diff = new_level - self.level;
        if diff > 0 {
            self.forward.append(&mut iter::repeat(Rawlink::none()).take(diff).collect())
        }
    }

    // Due to head node must be of same level as List,
    // inserting with decreasing order will lead to almost same bad performance as a linked list
    pub fn insert(&mut self, key: Key, it: E) {
        let mut new_level = random_level();
        if new_level > self.level { // new node will be deepest
            self.adjust_head(new_level);
            self.level = new_level;
        }
        self.size += 1;

        if self.head.is_none() {
            new_level = self.level;
            self.head = Some(Box::new(SkipNode::new(key, it, new_level)));
            let p = Rawlink::from(&mut self.head);
            for i in 0..new_level {
                self.forward[i] = p;
            }
        } else if self.head.as_ref().map_or(false, |n| n.key > key) {
            new_level = self.level;
            // insert at head
            let mut new_node = Some(Box::new(SkipNode::new(key, it, new_level)));
            let new_link = new_node.as_mut().map_or_else(Rawlink::none, |n| {
                Rawlink::some(&mut **n)
            });

            for i in 0..new_level {
                new_node.as_mut().map(|n| {
                    n.forward[i] = self.forward[i]
                });
            }

            for i in 0..new_level {
                self.forward[i] = new_link
            }

            new_node.as_mut().map(|n| n.next = self.head.take());
            self.head = new_node;
        } else {
            let mut x = self.head.as_mut().map_or_else(Rawlink::none, |n| {
                Rawlink::some(&mut **n)
            });
            // insert normally
            let mut update: Vec<Rawlink<SkipNode<Key,E>>> = self.forward[..new_level].to_vec();
            if new_level > 0 {  // need to insert skip pointers
                x = update[new_level-1];
                for i in (0..new_level).rev() {
                    while x.resolve().map_or(false, |n| n.forward[i].is_some()) &&
                        x.resolve().map_or(false, |n| n.forward[i].resolve().unwrap().key < key) {
                            let nx = x.resolve().map_or_else(Rawlink::none, |n| n.forward[i] );
                            x = nx;
                        }
                    update[i] = x.resolve_mut().map_or_else(Rawlink::none, |n| {
                        Rawlink::some(&mut *n)
                    });
                }
            }

            let mut y = x.resolve_mut().map_or_else(Rawlink::none, |n| {
                Rawlink::some(&mut *n)
            });
            // When head node level is lower than current
            if y.is_none() {
                println!("update => {:?}", update);
                y = self.head.as_mut().map_or_else(Rawlink::none, |n| {
                    Rawlink::some(&mut **n)
                });
            }
            while y.resolve().map_or(false, |n| n.next.is_some()) &&
                y.resolve().map_or(false, |n| n.next.as_ref().unwrap().key < key) {
                    let ny = y.resolve_mut().map_or_else(Rawlink::none, |n| {
                        n.next.as_mut().map_or_else(Rawlink::none, |n| Rawlink::some(&mut **n))
                    });
                    y = ny
                }
            assert!(y.is_some());
            // create node and insert
            let mut new_node = Some(Box::new(SkipNode::new(key, it, self.level)));
            let new_link = new_node.as_mut().map_or_else(Rawlink::none, |n| {
                Rawlink::some(&mut **n)
            });

            for i in 0..new_level {
                new_node.as_mut().map(|n| {
                    n.forward[i] = update[i].resolve_mut().map_or_else(Rawlink::none, |nx| {
                        nx.forward[i]
                    });
                });
                // if update is empty, then update head node's link
                update[i].resolve_mut().map_or_else(|| {
                    self.forward[i] = new_link;
                },
                    |prev| {
                    prev.forward[i] = new_link;
                });
            }

            // move in
            y.resolve_mut().map(|n| {
                new_node.as_mut().map(|new| {
                    new.next = n.next.take();
                });
                n.next = new_node;
            });
        }
    }

    pub fn remove(&mut self, key: &Key) {
        unimplemented!()
    }

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

impl<Key: PartialOrd + fmt::Display + fmt::Debug, E: fmt::Debug> fmt::Display for SkipList<Key,E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.head.is_none() {
            write!(f, "<empty skip list>")
        } else {
            write!(f, "\nlv0 ");
            let mut x = self.head.as_ref();
            while x.is_some() {
                write!(f, "{} --> ", x.as_ref().map_or_else(String::new, |n| format!("{}", n.key)));
                x = x.as_ref().map_or(None, |n| n.next.as_ref());
            }
            writeln!(f, "");
            for i in 0..self.level {
                write!(f, "lv{} ", i+1);
                let mut x = self.forward[i];
                while x.is_some() {
                    write!(f, "{} ..> ",
                           x.resolve().map_or_else(String::new, |n| format!("{}", n.key)));
                    if x.resolve().map_or(false, |n| n.level() <= i) {
                        break;
                    }
                    x = x.resolve().map_or_else(Rawlink::none, |n| n.forward[i]);
                }
                writeln!(f, "");
            }
            Ok(())
        }
    }
}

/// Rawlink is a type like Option<T> but for holding a raw mutable pointer.
impl<T> Rawlink<T> {
    /// Like `Option::None` for Rawlink.
    fn none() -> Rawlink<T> {
        Rawlink{p: ptr::null_mut()}
    }

    /// Like `Option::Some` for Rawlink
    fn some(n: &mut T) -> Rawlink<T> {
        Rawlink{p: n}
    }

    fn is_some(&self) -> bool {
        !self.is_none()
    }

    fn is_none(&self) -> bool {
        self.p.is_null()
    }

    fn take(&mut self) -> Rawlink<T> {
        mem::replace(self, Rawlink::none())
    }

    /// Convert the `Rawlink` into an immutable Option value.
    fn resolve<'a>(&self) -> Option<&'a T> {
        if self.p.is_null() {
            None
        } else {
            Some(unsafe { &*self.p })
        }
    }

    /// Convert the `Rawlink` into a mutable Option value.
    fn resolve_mut<'a>(&mut self) -> Option<&'a mut T> {
        if self.p.is_null() {
            None
        } else {
            Some(unsafe { &mut *self.p })
        }
    }
}

impl<'a, Key, E> From<&'a mut Link<SkipNode<Key, E>>> for Rawlink<SkipNode<Key, E>> {
    fn from(node: &'a mut Link<SkipNode<Key, E>>) -> Self {
        match node.as_mut() {
            None => Rawlink::none(),
            Some(ptr) => Rawlink::some(&mut **ptr),
        }
    }
}

impl<T> Clone for Rawlink<T> {
    #[inline]
    fn clone(&self) -> Rawlink<T> {
        Rawlink{p: self.p}
    }
}

#[test]
fn test_skip_list() {
    let mut list: SkipList<i8, ()> = SkipList::new();

    let mut rng = thread_rng();

    //let vals = vec![ -18130, 16865, -1813, 1686, -181, 168, -18, 16];
    for i in 0 .. 20 {
        let val = rng.gen();
        // let val = vals[i];
        println!("DEBUG {} insert => {}", i+1, val);
        list.insert(val, ());
    }

    println!("list => {}", list);
    println!("level => {}", list.level());
}
<commit_msg>skip_list: implement find() contains_key()<commit_after>use std::mem;
use std::fmt;
use std::ptr;
use std::iter;

use rand::{thread_rng, Rng};

// 32
const DEFAULT_LEVEL: usize = 3;

type Link<T> = Option<Box<T>>;

#[allow(raw_pointer_derive)]
#[derive(Debug)]
struct Rawlink<T> {
    p: *mut T,
}

impl<T> Copy for Rawlink<T> {}
unsafe impl<T:Send> Send for Rawlink<T> {}
unsafe impl<T:Sync> Sync for Rawlink<T> {}

fn random_level() -> usize {
    let mut rng = thread_rng();
    let mut level = 0;
    loop {
        if rng.gen_weighted_bool(2) {
            level += 1;
            continue;
        }
        break;
    }

    level
}

#[derive(Debug)]
pub struct SkipNode<Key,E> {
    key: Key,
    it: E,
    next: Link<SkipNode<Key,E>>,
    prev: Rawlink<SkipNode<Key,E>>,
    // level 0 to DEFAULT_LEVEL
    forward: Vec<Rawlink<SkipNode<Key,E>>>,
}

impl<Key: PartialOrd, E> SkipNode<Key,E> {
    // level: 0 ~ DEFAULT_LEVEL
    fn new(key: Key, it: E, level: usize) -> SkipNode<Key,E> {
        SkipNode {
            key: key,
            it: it,
            next: None,
            prev: Rawlink::none(),
            forward: iter::repeat(Rawlink::none()).take(level).collect(),
        }
    }

    #[inline]
    fn level(&self) -> usize {
        self.forward.len()
    }

    fn to_ptr(&mut self) -> Rawlink<SkipNode<Key,E>> {
        Rawlink::some(self)
    }

    fn insert(&mut self, key: Key, it: E, level: usize) {
    }
}

pub struct SkipList<Key,E> {
    head: Link<SkipNode<Key,E>>,
    forward: Vec<Rawlink<SkipNode<Key,E>>>,
    level: usize,
    size: usize,
}

impl<Key: PartialOrd + fmt::Debug, E: fmt::Debug> SkipList<Key,E> {
    /// create new empty SkipList
    pub fn new() -> SkipList<Key, E> {
        SkipList {
            head: None,
            forward: iter::repeat(Rawlink::none()).take(DEFAULT_LEVEL).collect(),
            level: DEFAULT_LEVEL,
            size: 0,
        }
    }

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

    pub fn contains_key(&self, key: &Key) -> bool {
        self.find(key).is_some()
    }

    pub fn find(&self, key: &Key) -> Option<&E> {

        let level = self.level();
        let mut x = self.forward[level-1];
        for i in (0..level).rev() {
            while x.resolve().map_or(false, |n| n.forward[i].is_some()) &&
                x.resolve().map_or(false, |n| n.forward[i].resolve().unwrap().key < *key) {
                    let nx = x.resolve().map_or_else(Rawlink::none, |n| n.forward[i] );
                    x = nx;
                }
        }

        while x.resolve().map_or(false, |n| n.next.is_some()) &&
            x.resolve().map_or(false, |n| n.next.as_ref().unwrap().key < *key) {
                let nx = x.resolve_mut().map_or_else(Rawlink::none, |n| {
                    n.next.as_mut().map_or_else(Rawlink::none, |n| Rawlink::some(&mut **n))
                });
                x = nx
            }

        x.resolve().map_or(None, |n| {
            if n.key == *key {
                Some(&n.it)
            } else {
                None
            }
        })
    }

    fn adjust_head(&mut self, new_level: usize) {
        let diff = new_level - self.level;
        if diff > 0 {
            self.forward.append(&mut iter::repeat(Rawlink::none()).take(diff).collect())
        }
    }

    // Due to head node must be of same level as List,
    // inserting with decreasing order will lead to almost same bad performance as a linked list
    pub fn insert(&mut self, key: Key, it: E) {
        let mut new_level = random_level();
        if new_level > self.level { // new node will be deepest
            self.adjust_head(new_level);
            self.level = new_level;
        }
        self.size += 1;

        if self.head.is_none() {
            new_level = self.level;
            self.head = Some(Box::new(SkipNode::new(key, it, new_level)));
            let p = Rawlink::from(&mut self.head);
            for i in 0..new_level {
                self.forward[i] = p;
            }
        } else if self.head.as_ref().map_or(false, |n| n.key > key) {
            new_level = self.level;
            // insert at head
            let mut new_node = Some(Box::new(SkipNode::new(key, it, new_level)));
            let new_link = new_node.as_mut().map_or_else(Rawlink::none, |n| {
                Rawlink::some(&mut **n)
            });

            for i in 0..new_level {
                new_node.as_mut().map(|n| {
                    n.forward[i] = self.forward[i]
                });
            }

            for i in 0..new_level {
                self.forward[i] = new_link
            }

            new_node.as_mut().map(|n| n.next = self.head.take());
            self.head = new_node;
        } else {
            let mut x = self.head.as_mut().map_or_else(Rawlink::none, |n| {
                Rawlink::some(&mut **n)
            });
            // insert normally
            let mut update: Vec<Rawlink<SkipNode<Key,E>>> = self.forward[..new_level].to_vec();
            if new_level > 0 {  // need to insert skip pointers
                x = update[new_level-1];
                for i in (0..new_level).rev() {
                    while x.resolve().map_or(false, |n| n.forward[i].is_some()) &&
                        x.resolve().map_or(false, |n| n.forward[i].resolve().unwrap().key < key) {
                            let nx = x.resolve().map_or_else(Rawlink::none, |n| n.forward[i] );
                            x = nx;
                        }
                    update[i] = x.resolve_mut().map_or_else(Rawlink::none, |n| {
                        Rawlink::some(&mut *n)
                    });
                }
            }

            let mut y = x.resolve_mut().map_or_else(Rawlink::none, |n| {
                Rawlink::some(&mut *n)
            });
            // When head node level is lower than current
            if y.is_none() {
                println!("update => {:?}", update);
                y = self.head.as_mut().map_or_else(Rawlink::none, |n| {
                    Rawlink::some(&mut **n)
                });
            }
            while y.resolve().map_or(false, |n| n.next.is_some()) &&
                y.resolve().map_or(false, |n| n.next.as_ref().unwrap().key < key) {
                    let ny = y.resolve_mut().map_or_else(Rawlink::none, |n| {
                        n.next.as_mut().map_or_else(Rawlink::none, |n| Rawlink::some(&mut **n))
                    });
                    y = ny
                }
            assert!(y.is_some());
            // create node and insert
            let mut new_node = Some(Box::new(SkipNode::new(key, it, self.level)));
            let new_link = new_node.as_mut().map_or_else(Rawlink::none, |n| {
                Rawlink::some(&mut **n)
            });

            for i in 0..new_level {
                new_node.as_mut().map(|n| {
                    n.forward[i] = update[i].resolve_mut().map_or_else(Rawlink::none, |nx| {
                        nx.forward[i]
                    });
                });
                // if update is empty, then update head node's link
                update[i].resolve_mut().map_or_else(|| {
                    self.forward[i] = new_link;
                },
                    |prev| {
                    prev.forward[i] = new_link;
                });
            }

            // move in
            y.resolve_mut().map(|n| {
                new_node.as_mut().map(|new| {
                    new.next = n.next.take();
                });
                n.next = new_node;
            });
        }
    }

    pub fn remove(&mut self, key: &Key) {
        unimplemented!()
    }

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

impl<Key: PartialOrd + fmt::Display + fmt::Debug, E: fmt::Debug> fmt::Display for SkipList<Key,E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.head.is_none() {
            write!(f, "<empty skip list>")
        } else {
            write!(f, "\nlv0 ");
            let mut x = self.head.as_ref();
            while x.is_some() {
                write!(f, "{} --> ", x.as_ref().map_or_else(String::new, |n| format!("{}", n.key)));
                x = x.as_ref().map_or(None, |n| n.next.as_ref());
            }
            writeln!(f, "");
            for i in 0..self.level {
                write!(f, "lv{} ", i+1);
                let mut x = self.forward[i];
                while x.is_some() {
                    write!(f, "{} ..> ",
                           x.resolve().map_or_else(String::new, |n| format!("{}", n.key)));
                    if x.resolve().map_or(false, |n| n.level() <= i) {
                        break;
                    }
                    x = x.resolve().map_or_else(Rawlink::none, |n| n.forward[i]);
                }
                writeln!(f, "");
            }
            Ok(())
        }
    }
}

/// Rawlink is a type like Option<T> but for holding a raw mutable pointer.
impl<T> Rawlink<T> {
    /// Like `Option::None` for Rawlink.
    fn none() -> Rawlink<T> {
        Rawlink{p: ptr::null_mut()}
    }

    /// Like `Option::Some` for Rawlink
    fn some(n: &mut T) -> Rawlink<T> {
        Rawlink{p: n}
    }

    fn is_some(&self) -> bool {
        !self.is_none()
    }

    fn is_none(&self) -> bool {
        self.p.is_null()
    }

    fn take(&mut self) -> Rawlink<T> {
        mem::replace(self, Rawlink::none())
    }

    /// Convert the `Rawlink` into an immutable Option value.
    fn resolve<'a>(&self) -> Option<&'a T> {
        if self.p.is_null() {
            None
        } else {
            Some(unsafe { &*self.p })
        }
    }

    /// Convert the `Rawlink` into a mutable Option value.
    fn resolve_mut<'a>(&mut self) -> Option<&'a mut T> {
        if self.p.is_null() {
            None
        } else {
            Some(unsafe { &mut *self.p })
        }
    }
}

impl<'a, Key, E> From<&'a mut Link<SkipNode<Key, E>>> for Rawlink<SkipNode<Key, E>> {
    fn from(node: &'a mut Link<SkipNode<Key, E>>) -> Self {
        match node.as_mut() {
            None => Rawlink::none(),
            Some(ptr) => Rawlink::some(&mut **ptr),
        }
    }
}

impl<T> Clone for Rawlink<T> {
    #[inline]
    fn clone(&self) -> Rawlink<T> {
        Rawlink{p: self.p}
    }
}

#[test]
fn test_skip_list() {
    let mut list: SkipList<i32, ()> = SkipList::new();

    let mut rng = thread_rng();

    //let vals = vec![ -18130, 16865, -1813, 1686, -181, 168, -18, 16];
    for i in 0 .. 10 {
        let val = rng.gen_range(0, 2000);
        // let val = vals[i];
        println!("DEBUG {} insert => {}", i+1, val);
        list.insert(val, ());
    }

    println!("list => {}", list);
    println!("level => {}", list.level());

    list.insert(20, ());
    println!("has(20) => {}", list.contains_key(&20));
}
<|endoftext|>


<commit_before>//! This crate contains server-only components of Playform.

#![allow(let_and_return)]
#![allow(match_ref_pats)]
#![allow(mutex_atomic)]
#![allow(type_complexity)]
#![allow(items_after_statements)]
#![allow(collapsible_if)]
#![allow(match_same_arms)]
#![allow(new_without_default)]
#![allow(similar_names)]
#![allow(doc_markdown)]

#![deny(missing_docs)]
#![deny(warnings)]

#![feature(box_syntax)]
#![feature(plugin)]
#![feature(test)]
#![feature(unboxed_closures)]

#![plugin(clippy)]

extern crate bincode;
extern crate cgmath;
extern crate common;
#[macro_use]
extern crate log;
extern crate nanomsg;
extern crate num;
extern crate rand;
extern crate rustc_serialize;
extern crate stopwatch;
extern crate terrain;
extern crate test;
extern crate thread_scoped;
extern crate time;
extern crate voxel_data;

mod client_recv_thread;
mod in_progress_terrain;
mod init_mobs;
mod lod;
mod mob;
mod octree;
mod physics;
mod player;
mod run;
mod server;
mod sun;
mod terrain_loader;
mod update_gaia;
mod update_world;

pub use run::run;
<commit_msg>don't ignore the similar_names lint<commit_after>//! This crate contains server-only components of Playform.

#![allow(let_and_return)]
#![allow(match_ref_pats)]
#![allow(mutex_atomic)]
#![allow(type_complexity)]
#![allow(items_after_statements)]
#![allow(collapsible_if)]
#![allow(match_same_arms)]
#![allow(new_without_default)]
#![allow(doc_markdown)]

#![deny(missing_docs)]
#![deny(warnings)]

#![feature(box_syntax)]
#![feature(plugin)]
#![feature(test)]
#![feature(unboxed_closures)]

#![plugin(clippy)]

extern crate bincode;
extern crate cgmath;
extern crate common;
#[macro_use]
extern crate log;
extern crate nanomsg;
extern crate num;
extern crate rand;
extern crate rustc_serialize;
extern crate stopwatch;
extern crate terrain;
extern crate test;
extern crate thread_scoped;
extern crate time;
extern crate voxel_data;

mod client_recv_thread;
mod in_progress_terrain;
mod init_mobs;
mod lod;
mod mob;
mod octree;
mod physics;
mod player;
mod run;
mod server;
mod sun;
mod terrain_loader;
mod update_gaia;
mod update_world;

pub use run::run;
<|endoftext|>


<commit_before>// vim: tw=80
/// Generate Expectation and Expectations types with specific signatures
///
/// # Arguments
///
/// * `expectation`:    Name of the generated Expectation type
/// * `module`:         Name of the private module to create
/// * `o`:              Output type.  Must be static
/// * `methty`:         Comma-delimited sequence of arguments types for the
///                     method being mocked.
/// * `matchcall`:      Comma-delimited sequence of expressions that produce
///                     values of type `matchty` from values of type `methty`.
/// * `args`:           comma-delimited sequence of argument names for each
///                     argument.  Ideally this wouldn't need to be specified,
///                     but it is due to Rust's macro hygiene rules.
/// * `predargs`:       Comma-delimited sequence of identifiers of the same
///                     length as `args`, but distinct.
/// * `matchty`:        comma-delimited sequence of types for each match
///                     argument.  Must all be `'static`.
///
/// # Examples
///
/// ```
/// // Mock a method like foo(&self, x: u32, y: &i16) -> u32
/// expectation!{(u32, &i16), u32, i, [&i.0, i.1], [i0, i1], [u32, i16]}
#[macro_export]
macro_rules! expectation {(
        $expectation:ident,
        $module:ident,
        $o:ty,
        [ $( $methty:ty ),* ],
        [ $( $matchcall:expr ),* ],
        [ $( $args:ident ),* ],
        [ $( $predargs:ident ),* ],
        [ $( $matchty:ty ),* ]) =>
    {
        mod $module {
        use ::predicates_tree::CaseTreeExt;
        use ::std::ops::DerefMut;
        use super::*;

        enum Rfunc {
            Default,
            // Indicates that a `return_once` expectation has already returned
            Expired,
            Mut(Box<dyn FnMut($( $methty, )*) -> $o + Send>),
            // Should be Box<dyn FnOnce> once that feature is stabilized
            // https://github.com/rust-lang/rust/issues/28796
            Once(Box<dyn FnMut($( $methty, )*) -> $o + Send>),
        }

        impl  Rfunc {
            fn call_mut(&mut self, $( $args: $methty, )* ) -> $o {
                match self {
                    Rfunc::Default => {
                        unimplemented!()
                        //Self::return_default()
                    },
                    Rfunc::Expired => {
                        panic!("Called a method twice that was expected only once")
                    },
                    Rfunc::Mut(f) => {
                        f( $( $args, )* )
                    },
                    Rfunc::Once(_) => {
                        let fo = ::std::mem::replace(self, Rfunc::Expired);
                        if let Rfunc::Once(mut f) = fo {
                            f( $( $args, )* )
                        } else {
                            unreachable!()
                        }
                    },
                }
            }
        }

        impl std::default::Default for Rfunc {
            fn default() -> Self {
                Rfunc::Default
            }
        }

        enum Matcher {
            Func(Box<Fn($( &$matchty, )* ) -> bool>),
            Pred( $( Box<::mockall::Predicate<$matchty>>, )* )
        }

        impl Matcher {
            fn eval(&self, $( $args: &$matchty, )*) -> bool {
                match self {
                    Matcher::Func(f) => f($( $args, )*),
                    Matcher::Pred($( $predargs, )*) =>
                        [$( $predargs.eval($args), )*]
                        .into_iter()
                        .all(|x| *x),
                }
            }

            fn verify(&self, $( $args: &$matchty, )* ) {
                match self {
                    Matcher::Func(f) => assert!(f($( $args, )*),
                        "Expectation didn't match arguments"),
                    Matcher::Pred($( $predargs, )*) => {
                        $(if let Some(c) = $predargs.find_case(false, $args) {
                            panic!("Expectation didn't match arguments:\n{}",
                                   c.tree());
                        })*
                    }
                }
            }
        }

        impl Default for Matcher {
            #[allow(unused_variables)]
            fn default() -> Self {
                Matcher::Func(Box::new(|$( $args, )*| true))
            }
        }

        #[derive(Default)]
        struct Common {
            matcher: ::std::sync::Mutex<Matcher>,
            seq_handle: Option<::mockall::SeqHandle>,
            times: ::mockall::Times
        }

        impl Common {
            fn call(&self, $( $args: &$matchty, )* ) {
                self.matcher.lock().unwrap().verify($( $args, )*);
                self.times.call();
                self.verify_sequence();
                if self.times.is_satisfied() {
                    self.satisfy_sequence()
                }
            }

            fn in_sequence(&mut self, seq: &mut ::mockall::Sequence)
                -> &mut Self
            {
                assert!(self.times.is_exact(),
                    "Only Expectations with an exact call count have sequences");
                self.seq_handle = Some(seq.next());
                self
            }

            /// Forbid this expectation from ever being called
            fn never(&mut self) {
                self.times.never();
            }

            fn satisfy_sequence(&self) {
                if let Some(handle) = &self.seq_handle {
                    handle.satisfy()
                }
            }

            /// Require this expectation to be called exactly `n` times.
            fn times(&mut self, n: usize) {
                self.times.n(n);
            }

            /// Allow this expectation to be called any number of times
            fn times_any(&mut self) {
                self.times.any();
            }

            /// Allow this expectation to be called any number of times within a given
            /// range
            fn times_range(&mut self, range: ::std::ops::Range<usize>) {
                self.times.range(range);
            }

            fn verify_sequence(&self) {
                if let Some(handle) = &self.seq_handle {
                    handle.verify()
                }
            }

            #[allow(non_camel_case_types)]  // Repurpose $predargs for generics
            fn with<$( $predargs: ::mockall::Predicate<$matchty> + 'static,)*>
                (&mut self, $( $args: $predargs,)*)
            {
                let mut guard = self.matcher.lock().unwrap();
                let m = Matcher::Pred($( Box::new($args), )*);
                ::std::mem::replace(guard.deref_mut(), m);
            }

            fn withf<F>(&mut self, f: F)
                where F: Fn($( &$matchty, )* ) -> bool + Send + 'static
            {
                let mut guard = self.matcher.lock().unwrap();
                let m = Matcher::Func(Box::new(f));
                ::std::mem::replace(guard.deref_mut(), m);
            }
        }

        #[derive(Default)]
        pub struct Expectation {
            common: Common,
            rfunc: ::std::sync::Mutex<Rfunc>,
        }

        impl Expectation {
            pub fn call(&self, $( $args: $methty, )* ) -> $o {
                self.common.call($( $matchcall, )*);
                self.rfunc.lock().unwrap().call_mut($( $args, )*)
            }

            pub fn in_sequence(&mut self, seq: &mut ::mockall::Sequence)
                -> &mut Self
            {
                self.common.in_sequence(seq);
                self
            }

            /// Forbid this expectation from ever being called
            pub fn never(&mut self) -> &mut Self {
                self.common.never();
                self
            }

            /// Supply an `FnOnce` closure that will provide the return value
            /// for this Expectation.  This is useful for return types that
            /// aren't `Clone`.  It will be an error to call this Expectation
            /// multiple times.
            pub fn return_once<F>(&mut self, f: F) -> &mut Self
                where F: FnOnce($( $methty, )*) -> $o + Send + 'static
            {
                let mut fopt = Some(f);
                let fmut = move |$( $args: $methty, )*| {
                    if let Some(f) = fopt.take() {
                        f($( $args, )*)
                    } else {
                        panic!("Called a method twice that was expected only once")
                    }
                };
                {
                    let mut guard = self.rfunc.lock().unwrap();
                    ::std::mem::replace(guard.deref_mut(),
                                        Rfunc::Once(Box::new(fmut)));
                }
                self
            }

            /// Single-threaded version of [`return_once`](#method.return_once).
            /// This is useful for return types that are neither `Send` nor
            /// `Clone`.
            ///
            /// It is a runtime error to call the mock method from a different
            /// thread than the one that originally called this method.  It is
            /// also a runtime error to call the method more than once.
            pub fn return_once_st<F>(&mut self, f: F) -> &mut Self
                where F: FnOnce($( $methty, )*) -> $o + 'static
            {
                let mut fragile = Some(::fragile::Fragile::new(f));
                let fmut = Box::new(move |$( $args: $methty, )*| {
                    match fragile.take() {
                        Some(frag) => (frag.into_inner())($( $args, )*),
                        None => panic!(
                            "Called a method twice that was expected only once")
                    }
                });
                {
                    let mut guard = self.rfunc.lock().unwrap();
                    ::std::mem::replace(guard.deref_mut(), Rfunc::Once(fmut));
                }
                self
            }

            pub fn returning<F>(&mut self, f: F) -> &mut Self
                where F: FnMut($( $methty, )*) -> $o + Send + 'static
            {
                {
                    let mut guard = self.rfunc.lock().unwrap();
                    ::std::mem::replace(guard.deref_mut(), Rfunc::Mut(Box::new(f)));
                }
                self
            }

            /// Single-threaded version of [`returning`](#method.returning).
            /// Can be used when the argument or return type isn't `Send`.
            ///
            /// It is a runtime error to call the mock method from a different
            /// thread than the one that originally called this method.
            pub fn returning_st<F>(&mut self, f: F) -> &mut Self
                where F: FnMut($( $methty, )*) -> $o + 'static
            {
                let mut fragile = ::fragile::Fragile::new(f);
                let fmut = move |$( $args: $methty, )*| {
                    (fragile.get_mut())($( $args, )*)
                };
                {
                    let mut guard = self.rfunc.lock().unwrap();
                    ::std::mem::replace(guard.deref_mut(),
                                        Rfunc::Mut(Box::new(fmut)));
                }
                self
            }

            /// Require this expectation to be called exactly `n` times.
            pub fn times(&mut self, n: usize) -> &mut Self {
                self.common.times(n);
                self
            }

            /// Allow this expectation to be called any number of times
            ///
            /// This behavior is the default, but the method is provided in case the
            /// default behavior changes.
            pub fn times_any(&mut self) -> &mut Self {
                self.common.times_any();
                self
            }

            /// Allow this expectation to be called any number of times within a
            /// given range
            pub fn times_range(&mut self, range: ::std::ops::Range<usize>)
                -> &mut Self
            {
                self.common.times_range(range);
                self
            }

            #[allow(non_camel_case_types)]  // Repurpose $predargs for generics
            pub fn with<$( $predargs: ::mockall::Predicate<$matchty> + 'static,)*>
                (&mut self, $( $args: $predargs,)*) -> &mut Self
            {
                self.common.with($( $args, )*);
                self
            }

            pub fn withf<F>(&mut self, f: F) -> &mut Self
                where F: Fn($( &$matchty, )* ) -> bool + Send + 'static
            {
                self.common.withf(f);
                self
            }
        }

        }
        use $module::Expectation as $expectation;
    }
}
<commit_msg>Use $crate in macros.<commit_after>// vim: tw=80
/// Generate Expectation and Expectations types with specific signatures
///
/// # Arguments
///
/// * `expectation`:    Name of the generated Expectation type
/// * `module`:         Name of the private module to create
/// * `o`:              Output type.  Must be static
/// * `methty`:         Comma-delimited sequence of arguments types for the
///                     method being mocked.
/// * `matchcall`:      Comma-delimited sequence of expressions that produce
///                     values of type `matchty` from values of type `methty`.
/// * `args`:           comma-delimited sequence of argument names for each
///                     argument.  Ideally this wouldn't need to be specified,
///                     but it is due to Rust's macro hygiene rules.
/// * `predargs`:       Comma-delimited sequence of identifiers of the same
///                     length as `args`, but distinct.
/// * `matchty`:        comma-delimited sequence of types for each match
///                     argument.  Must all be `'static`.
///
/// # Examples
///
/// ```
/// // Mock a method like foo(&self, x: u32, y: &i16) -> u32
/// expectation!{(u32, &i16), u32, i, [&i.0, i.1], [i0, i1], [u32, i16]}
#[macro_export]
macro_rules! expectation {(
        $expectation:ident,
        $module:ident,
        $o:ty,
        [ $( $methty:ty ),* ],
        [ $( $matchcall:expr ),* ],
        [ $( $args:ident ),* ],
        [ $( $predargs:ident ),* ],
        [ $( $matchty:ty ),* ]) =>
    {
        mod $module {
        use ::predicates_tree::CaseTreeExt;
        use ::std::ops::DerefMut;
        use super::*;

        enum Rfunc {
            Default,
            // Indicates that a `return_once` expectation has already returned
            Expired,
            Mut(Box<dyn FnMut($( $methty, )*) -> $o + Send>),
            // Should be Box<dyn FnOnce> once that feature is stabilized
            // https://github.com/rust-lang/rust/issues/28796
            Once(Box<dyn FnMut($( $methty, )*) -> $o + Send>),
        }

        impl  Rfunc {
            fn call_mut(&mut self, $( $args: $methty, )* ) -> $o {
                match self {
                    Rfunc::Default => {
                        unimplemented!()
                        //Self::return_default()
                    },
                    Rfunc::Expired => {
                        panic!("Called a method twice that was expected only once")
                    },
                    Rfunc::Mut(f) => {
                        f( $( $args, )* )
                    },
                    Rfunc::Once(_) => {
                        let fo = ::std::mem::replace(self, Rfunc::Expired);
                        if let Rfunc::Once(mut f) = fo {
                            f( $( $args, )* )
                        } else {
                            unreachable!()
                        }
                    },
                }
            }
        }

        impl std::default::Default for Rfunc {
            fn default() -> Self {
                Rfunc::Default
            }
        }

        enum Matcher {
            Func(Box<Fn($( &$matchty, )* ) -> bool>),
            Pred( $( Box<$crate::Predicate<$matchty>>, )* )
        }

        impl Matcher {
            fn eval(&self, $( $args: &$matchty, )*) -> bool {
                match self {
                    Matcher::Func(f) => f($( $args, )*),
                    Matcher::Pred($( $predargs, )*) =>
                        [$( $predargs.eval($args), )*]
                        .into_iter()
                        .all(|x| *x),
                }
            }

            fn verify(&self, $( $args: &$matchty, )* ) {
                match self {
                    Matcher::Func(f) => assert!(f($( $args, )*),
                        "Expectation didn't match arguments"),
                    Matcher::Pred($( $predargs, )*) => {
                        $(if let Some(c) = $predargs.find_case(false, $args) {
                            panic!("Expectation didn't match arguments:\n{}",
                                   c.tree());
                        })*
                    }
                }
            }
        }

        impl Default for Matcher {
            #[allow(unused_variables)]
            fn default() -> Self {
                Matcher::Func(Box::new(|$( $args, )*| true))
            }
        }

        #[derive(Default)]
        struct Common {
            matcher: ::std::sync::Mutex<Matcher>,
            seq_handle: Option<$crate::SeqHandle>,
            times: $crate::Times
        }

        impl Common {
            fn call(&self, $( $args: &$matchty, )* ) {
                self.matcher.lock().unwrap().verify($( $args, )*);
                self.times.call();
                self.verify_sequence();
                if self.times.is_satisfied() {
                    self.satisfy_sequence()
                }
            }

            fn in_sequence(&mut self, seq: &mut $crate::Sequence)
                -> &mut Self
            {
                assert!(self.times.is_exact(),
                    "Only Expectations with an exact call count have sequences");
                self.seq_handle = Some(seq.next());
                self
            }

            /// Forbid this expectation from ever being called
            fn never(&mut self) {
                self.times.never();
            }

            fn satisfy_sequence(&self) {
                if let Some(handle) = &self.seq_handle {
                    handle.satisfy()
                }
            }

            /// Require this expectation to be called exactly `n` times.
            fn times(&mut self, n: usize) {
                self.times.n(n);
            }

            /// Allow this expectation to be called any number of times
            fn times_any(&mut self) {
                self.times.any();
            }

            /// Allow this expectation to be called any number of times within a given
            /// range
            fn times_range(&mut self, range: ::std::ops::Range<usize>) {
                self.times.range(range);
            }

            fn verify_sequence(&self) {
                if let Some(handle) = &self.seq_handle {
                    handle.verify()
                }
            }

            #[allow(non_camel_case_types)]  // Repurpose $predargs for generics
            fn with<$( $predargs: $crate::Predicate<$matchty> + 'static,)*>
                (&mut self, $( $args: $predargs,)*)
            {
                let mut guard = self.matcher.lock().unwrap();
                let m = Matcher::Pred($( Box::new($args), )*);
                ::std::mem::replace(guard.deref_mut(), m);
            }

            fn withf<F>(&mut self, f: F)
                where F: Fn($( &$matchty, )* ) -> bool + Send + 'static
            {
                let mut guard = self.matcher.lock().unwrap();
                let m = Matcher::Func(Box::new(f));
                ::std::mem::replace(guard.deref_mut(), m);
            }
        }

        #[derive(Default)]
        pub struct Expectation {
            common: Common,
            rfunc: ::std::sync::Mutex<Rfunc>,
        }

        impl Expectation {
            pub fn call(&self, $( $args: $methty, )* ) -> $o {
                self.common.call($( $matchcall, )*);
                self.rfunc.lock().unwrap().call_mut($( $args, )*)
            }

            pub fn in_sequence(&mut self, seq: &mut $crate::Sequence)
                -> &mut Self
            {
                self.common.in_sequence(seq);
                self
            }

            /// Forbid this expectation from ever being called
            pub fn never(&mut self) -> &mut Self {
                self.common.never();
                self
            }

            /// Supply an `FnOnce` closure that will provide the return value
            /// for this Expectation.  This is useful for return types that
            /// aren't `Clone`.  It will be an error to call this Expectation
            /// multiple times.
            pub fn return_once<F>(&mut self, f: F) -> &mut Self
                where F: FnOnce($( $methty, )*) -> $o + Send + 'static
            {
                let mut fopt = Some(f);
                let fmut = move |$( $args: $methty, )*| {
                    if let Some(f) = fopt.take() {
                        f($( $args, )*)
                    } else {
                        panic!("Called a method twice that was expected only once")
                    }
                };
                {
                    let mut guard = self.rfunc.lock().unwrap();
                    ::std::mem::replace(guard.deref_mut(),
                                        Rfunc::Once(Box::new(fmut)));
                }
                self
            }

            /// Single-threaded version of [`return_once`](#method.return_once).
            /// This is useful for return types that are neither `Send` nor
            /// `Clone`.
            ///
            /// It is a runtime error to call the mock method from a different
            /// thread than the one that originally called this method.  It is
            /// also a runtime error to call the method more than once.
            pub fn return_once_st<F>(&mut self, f: F) -> &mut Self
                where F: FnOnce($( $methty, )*) -> $o + 'static
            {
                let mut fragile = Some(::fragile::Fragile::new(f));
                let fmut = Box::new(move |$( $args: $methty, )*| {
                    match fragile.take() {
                        Some(frag) => (frag.into_inner())($( $args, )*),
                        None => panic!(
                            "Called a method twice that was expected only once")
                    }
                });
                {
                    let mut guard = self.rfunc.lock().unwrap();
                    ::std::mem::replace(guard.deref_mut(), Rfunc::Once(fmut));
                }
                self
            }

            pub fn returning<F>(&mut self, f: F) -> &mut Self
                where F: FnMut($( $methty, )*) -> $o + Send + 'static
            {
                {
                    let mut guard = self.rfunc.lock().unwrap();
                    ::std::mem::replace(guard.deref_mut(), Rfunc::Mut(Box::new(f)));
                }
                self
            }

            /// Single-threaded version of [`returning`](#method.returning).
            /// Can be used when the argument or return type isn't `Send`.
            ///
            /// It is a runtime error to call the mock method from a different
            /// thread than the one that originally called this method.
            pub fn returning_st<F>(&mut self, f: F) -> &mut Self
                where F: FnMut($( $methty, )*) -> $o + 'static
            {
                let mut fragile = ::fragile::Fragile::new(f);
                let fmut = move |$( $args: $methty, )*| {
                    (fragile.get_mut())($( $args, )*)
                };
                {
                    let mut guard = self.rfunc.lock().unwrap();
                    ::std::mem::replace(guard.deref_mut(),
                                        Rfunc::Mut(Box::new(fmut)));
                }
                self
            }

            /// Require this expectation to be called exactly `n` times.
            pub fn times(&mut self, n: usize) -> &mut Self {
                self.common.times(n);
                self
            }

            /// Allow this expectation to be called any number of times
            ///
            /// This behavior is the default, but the method is provided in case the
            /// default behavior changes.
            pub fn times_any(&mut self) -> &mut Self {
                self.common.times_any();
                self
            }

            /// Allow this expectation to be called any number of times within a
            /// given range
            pub fn times_range(&mut self, range: ::std::ops::Range<usize>)
                -> &mut Self
            {
                self.common.times_range(range);
                self
            }

            #[allow(non_camel_case_types)]  // Repurpose $predargs for generics
            pub fn with<$( $predargs: $crate::Predicate<$matchty> + 'static,)*>
                (&mut self, $( $args: $predargs,)*) -> &mut Self
            {
                self.common.with($( $args, )*);
                self
            }

            pub fn withf<F>(&mut self, f: F) -> &mut Self
                where F: Fn($( &$matchty, )* ) -> bool + Send + 'static
            {
                self.common.withf(f);
                self
            }
        }

        }
        use $module::Expectation as $expectation;
    }
}
<|endoftext|>


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

//! The bulk of the HTML parser integration is in `script::parse::html`.
//! This module is mostly about its interaction with DOM memory management.

use document_loader::LoadType;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::ServoHTMLParserBinding;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::document::Document;
use dom::node::Node;
use dom::text::Text;
use dom::window::Window;
use encoding::all::UTF_8;
use encoding::types::{DecoderTrap, Encoding};
use html5ever::tokenizer;
use html5ever::tree_builder;
use html5ever::tree_builder::{NodeOrText, TreeBuilder, TreeBuilderOpts};
use hyper::header::ContentType;
use hyper::mime::{Mime, SubLevel, TopLevel};
use js::jsapi::JSTracer;
use msg::constellation_msg::{PipelineId, SubpageId};
use net_traits::{AsyncResponseListener, Metadata};
use network_listener::PreInvoke;
use parse::Parser;
use script_task::{ScriptChan, ScriptTask};
use std::cell::Cell;
use std::default::Default;
use url::Url;

#[must_root]
#[derive(JSTraceable, HeapSizeOf)]
pub struct Sink {
    pub base_url: Option<Url>,
    pub document: JS<Document>,
}

impl Sink {
    #[allow(unrooted_must_root)] // method is only run at parse time
    pub fn get_or_create(&self, child: NodeOrText<JS<Node>>) -> Root<Node> {
        match child {
            NodeOrText::AppendNode(n) => Root::from_ref(&*n),
            NodeOrText::AppendText(t) => {
                let text = Text::new(t.into(), &self.document);
                Root::upcast(text)
            }
        }
    }
}

/// FragmentContext is used only to pass this group of related values
/// into functions.
#[derive(Copy, Clone)]
pub struct FragmentContext<'a> {
    pub context_elem: &'a Node,
    pub form_elem: Option<&'a Node>,
}

pub type Tokenizer = tokenizer::Tokenizer<TreeBuilder<JS<Node>, Sink>>;

/// The context required for asynchronously fetching a document and parsing it progressively.
pub struct ParserContext {
    /// The parser that initiated the request.
    parser: Option<Trusted<ServoHTMLParser>>,
    /// Is this document a synthesized document for a single image?
    is_image_document: bool,
    /// The pipeline associated with this document.
    id: PipelineId,
    /// The subpage associated with this document.
    subpage: Option<SubpageId>,
    /// The target event loop for the response notifications.
    script_chan: Box


<commit_before>
//! This temporary module generates types that wrap around the old API (winit v5 and below) and
//! expose the new API (winit v6 and above).
//!
//! This is temporary so that existing backends can smoothly transition. After all implementations
//! have finished transitionning, this module should disappear.

macro_rules! gen_api_transition {
    () => {
        pub struct EventsLoop {
            windows: ::std::sync::Mutex<Vec<::std::sync::Arc<Window>>>,
            interrupted: ::std::sync::atomic::AtomicBool,
        }

        impl EventsLoop {
            pub fn new() -> EventsLoop {
                EventsLoop {
                    windows: ::std::sync::Mutex::new(vec![]),
                    interrupted: ::std::sync::atomic::AtomicBool::new(false),
                }
            }

            pub fn interrupt(&self) {
                self.interrupted.store(true, ::std::sync::atomic::Ordering::Relaxed);
            }

            pub fn poll_events<F>(&self, mut callback: F)
                where F: FnMut(::Event)
            {
                let mut windows = self.windows.lock().unwrap();
                for window in windows.iter() {
                    for event in window.poll_events() {
                        callback(::Event::WindowEvent {
                            window_id: &**window as *const Window as usize,
                            event: event,
                        })
                    }
                }
            }

            pub fn run_forever<F>(&self, mut callback: F)
                where F: FnMut(::Event)
            {
                self.interrupted.store(false, ::std::sync::atomic::Ordering::Relaxed);

                // Yeah that's a very bad implementation.
                loop {
                    self.poll_events(|e| callback(e));
                    ::std::thread::sleep_ms(5);
                    if self.interrupted.load(::std::sync::atomic::Ordering::Relaxed) {
                        break;
                    }
                }
            }
        }

        pub struct Window2 {
            window: ::std::sync::Arc<Window>,
        }

        impl ::std::ops::Deref for Window2 {
            type Target = Window;
            #[inline]
            fn deref(&self) -> &Window {
                &*self.window
            }
        }

        impl Window2 {
            pub fn new(events_loop: ::std::sync::Arc<EventsLoop>, window: &::WindowAttributes,
                       pl_attribs: &PlatformSpecificWindowBuilderAttributes)
                       -> Result<Window2, CreationError>
            {
                let win = ::std::sync::Arc::new(try!(Window::new(window, pl_attribs)));
                events_loop.windows.lock().unwrap().push(win.clone());
                Ok(Window2 {
                    window: win,
                })
            }

            #[inline]
            pub fn id(&self) -> usize {
                &*self.window as *const Window as usize
            }
        }
    };
}
<commit_msg>Remove the window from the events loop on destruction<commit_after>
//! This temporary module generates types that wrap around the old API (winit v5 and below) and
//! expose the new API (winit v6 and above).
//!
//! This is temporary so that existing backends can smoothly transition. After all implementations
//! have finished transitionning, this module should disappear.

macro_rules! gen_api_transition {
    () => {
        pub struct EventsLoop {
            windows: ::std::sync::Mutex<Vec<::std::sync::Arc<Window>>>,
            interrupted: ::std::sync::atomic::AtomicBool,
        }

        impl EventsLoop {
            pub fn new() -> EventsLoop {
                EventsLoop {
                    windows: ::std::sync::Mutex::new(vec![]),
                    interrupted: ::std::sync::atomic::AtomicBool::new(false),
                }
            }

            pub fn interrupt(&self) {
                self.interrupted.store(true, ::std::sync::atomic::Ordering::Relaxed);
            }

            pub fn poll_events<F>(&self, mut callback: F)
                where F: FnMut(::Event)
            {
                let mut windows = self.windows.lock().unwrap();
                for window in windows.iter() {
                    for event in window.poll_events() {
                        callback(::Event::WindowEvent {
                            window_id: &**window as *const Window as usize,
                            event: event,
                        })
                    }
                }
            }

            pub fn run_forever<F>(&self, mut callback: F)
                where F: FnMut(::Event)
            {
                self.interrupted.store(false, ::std::sync::atomic::Ordering::Relaxed);

                // Yeah that's a very bad implementation.
                loop {
                    self.poll_events(|e| callback(e));
                    ::std::thread::sleep_ms(5);
                    if self.interrupted.load(::std::sync::atomic::Ordering::Relaxed) {
                        break;
                    }
                }
            }
        }

        pub struct Window2 {
            window: ::std::sync::Arc<Window>,
            events_loop: ::std::sync::Weak<EventsLoop>,
        }

        impl ::std::ops::Deref for Window2 {
            type Target = Window;
            #[inline]
            fn deref(&self) -> &Window {
                &*self.window
            }
        }

        impl Window2 {
            pub fn new(events_loop: ::std::sync::Arc<EventsLoop>, window: &::WindowAttributes,
                       pl_attribs: &PlatformSpecificWindowBuilderAttributes)
                       -> Result<Window2, CreationError>
            {
                let win = ::std::sync::Arc::new(try!(Window::new(window, pl_attribs)));
                events_loop.windows.lock().unwrap().push(win.clone());
                Ok(Window2 {
                    window: win,
                    events_loop: ::std::sync::Arc::downgrade(&events_loop),
                })
            }

            #[inline]
            pub fn id(&self) -> usize {
                &*self.window as *const Window as usize
            }
        }

        impl Drop for Window2 {
            fn drop(&mut self) {
                if let Some(ev) = self.events_loop.upgrade() {
                    let mut windows = ev.windows.lock().unwrap();
                    windows.retain(|w| &**w as *const Window != &*self.window as *const _);
                }
            }
        }
    };
}
<|endoftext|>


<commit_before>use std::fmt::{self, Display, Formatter};
use std::default::Default;
use rlua::{self, Table, Lua, UserData, AnyUserData, UserDataMethods, ToLua,
           Value};
use super::object::{self, Object, Objectable};
use super::property::Property;
use super::class::{self, Class};
use rustwlc::xkb::Keysym;
use rustwlc::types::KeyMod;

#[derive(Clone, Debug)]
pub struct ButtonState {
    button: Option<i32>,
    modifiers: KeyMod
}

#[derive(Clone, Debug)]
pub struct Button<'lua>(Table<'lua>);

impl <'lua> Button<'lua> {
    pub fn button(&self) -> rlua::Result<Value<'lua>> {
        let button = self.0.get::<_, ButtonState>("data")?;
        Ok(button.button
            .map(|num| Value::Number(num as f64))
            .unwrap_or(Value::Nil))
    }

    pub fn set_button(&self, new_val: Option<i32>) -> rlua::Result<()> {
        let mut button = self.0.get::<_, ButtonState>("data")?;
        button.button = new_val;
        Ok(())
    }
}

impl <'lua> ToLua<'lua> for Button<'lua> {
    fn to_lua(self, lua: &'lua Lua) -> rlua::Result<Value<'lua>> {
        self.0.to_lua(lua)
    }
}

impl <'lua> Objectable<'lua, Button<'lua>, ButtonState> for Button<'lua> {
    fn _wrap(table: Table<'lua>) -> Button {
        Button(table)
    }

    fn get_table(self) -> Table<'lua> {
        self.0
    }
}

impl Display for ButtonState {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Button: {:p}", self)
    }
}

impl Default for ButtonState {
    fn default() -> Self {
        ButtonState {
            button: None,
            modifiers: KeyMod::empty()
        }
    }
}

impl UserData for ButtonState {}

/// Makes a new button stored in a table beside its signals
pub fn allocator(lua: &Lua) -> rlua::Result<Object> {
    let meta = lua.create_table();
    let class = class::button_class(lua)?;
    Ok(Button::new(lua, class)?
       .add_to_meta(meta)?
       .build())
}

pub fn new<'lua>(lua: &'lua Lua, _table: Table<'lua>)
                 -> rlua::Result<Object<'lua>> {
    allocator(lua)
}

pub fn init(lua: &Lua) -> rlua::Result<Class> {
    Class::new(lua, Some(allocator), None, None)?
        .method("__call".into(), lua.create_function(new))?
        .property(Property::new("button".into(),
                                Some(lua.create_function(set_button)),
                                Some(lua.create_function(get_button)),
                                Some(lua.create_function(set_button))))?
        .property(Property::new("modifiers".into(),
                                Some(lua.create_function(set_modifiers)),
                                Some(lua.create_function(get_modifiers)),
                                Some(lua.create_function(set_modifiers))))?
        .save_class("__button_class")?
        .build()
}

fn set_button<'lua>(lua: &'lua Lua, (table, num): (Table, i32))
                    -> rlua::Result<Value<'lua>> {
    let button = Button::cast(table.into())?;
    button.set_button(Some(num))?;
    Ok(Value::Nil)
}

fn get_button<'lua>(lua: &'lua Lua, table: Table<'lua>)
                    -> rlua::Result<Value<'lua>> {
    Button::cast(table.into())?.button()
}

fn set_modifiers<'lua>(lua: &'lua Lua, button: Table)
                       -> rlua::Result<Value<'lua>> {
    unimplemented!()
}

fn get_modifiers<'lua>(lua: &'lua Lua, button: Table)
                    -> rlua::Result<Value<'lua>> {
    unimplemented!()
}

mod test {
    use rlua::Lua;
    use super::super::button;

    #[test]
    fn button_object_test() {
        let lua = Lua::new();
        button::init(&lua).unwrap();
        lua.globals().set("button0", button::allocator(&lua).unwrap());
        lua.globals().set("button1", button::allocator(&lua).unwrap());
        lua.eval(r#"
 assert(button0.button == nil)
 assert(button1.button == nil)
 button0.connect_signal("test", function(button) button.button = 3 end)
 button0.emit_signal("test")
 assert(button1.button == nil)
 assert(button0.button == 3)
 "#,
        None).unwrap()
    }

    #[test]
    fn button_class_test() {
        let lua = Lua::new();
        let button_class = button::init(&lua).unwrap();
        lua.globals().set("button", button_class).unwrap();
        lua.eval(r#"
a_button = button()
assert(a_button.button == nil)
a_button.connect_signal("test", function(button) button.num = 2 end)
a_button.emit_signal("test")
assert(a_button.num == 2)
"#, None).unwrap()
    }

    #[test]
    fn button_property_test() {
        let lua = Lua::new();
        button::init(&lua).unwrap();
        let button_class = button::init(&lua).unwrap();
        assert_eq!(button_class.properties().unwrap().len().unwrap(), 2);
        lua.globals().set("button", button_class).unwrap();
        lua.eval(r#"
a_button = button()
assert(a_button.button == nil)
a_button.button = 5
assert(a_button.button == 5)
"#, None).unwrap()
    }

    #[test]
    fn button_remove_signal_test() {
        let lua = Lua::new();
        let button_class = button::init(&lua).unwrap();
        lua.globals().set("button", button_class).unwrap();
        lua.eval(r#"
button0 = button()
assert(button0.button == nil)
button0.connect_signal("test", function(button) button.button = 3 end)
button0.emit_signal("test")
assert(button0.button == 3)
button0.button = 0
button0.disconnect_signal("test")
button0.emit_signal("test")
assert(button0.button == 0)
"#, None).unwrap()
    }
}

<commit_msg>Added test for emit signal multiple args<commit_after>use std::fmt::{self, Display, Formatter};
use std::default::Default;
use rlua::{self, Table, Lua, UserData, AnyUserData, UserDataMethods, ToLua,
           Value};
use super::object::{self, Object, Objectable};
use super::property::Property;
use super::class::{self, Class};
use rustwlc::xkb::Keysym;
use rustwlc::types::KeyMod;

#[derive(Clone, Debug)]
pub struct ButtonState {
    button: Option<i32>,
    modifiers: KeyMod
}

#[derive(Clone, Debug)]
pub struct Button<'lua>(Table<'lua>);

impl <'lua> Button<'lua> {
    pub fn button(&self) -> rlua::Result<Value<'lua>> {
        let button = self.0.get::<_, ButtonState>("data")?;
        Ok(button.button
            .map(|num| Value::Number(num as f64))
            .unwrap_or(Value::Nil))
    }

    pub fn set_button(&self, new_val: Option<i32>) -> rlua::Result<()> {
        let mut button = self.0.get::<_, ButtonState>("data")?;
        button.button = new_val;
        Ok(())
    }
}

impl <'lua> ToLua<'lua> for Button<'lua> {
    fn to_lua(self, lua: &'lua Lua) -> rlua::Result<Value<'lua>> {
        self.0.to_lua(lua)
    }
}

impl <'lua> Objectable<'lua, Button<'lua>, ButtonState> for Button<'lua> {
    fn _wrap(table: Table<'lua>) -> Button {
        Button(table)
    }

    fn get_table(self) -> Table<'lua> {
        self.0
    }
}

impl Display for ButtonState {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Button: {:p}", self)
    }
}

impl Default for ButtonState {
    fn default() -> Self {
        ButtonState {
            button: None,
            modifiers: KeyMod::empty()
        }
    }
}

impl UserData for ButtonState {}

/// Makes a new button stored in a table beside its signals
pub fn allocator(lua: &Lua) -> rlua::Result<Object> {
    let meta = lua.create_table();
    let class = class::button_class(lua)?;
    Ok(Button::new(lua, class)?
       .add_to_meta(meta)?
       .build())
}

pub fn new<'lua>(lua: &'lua Lua, _table: Table<'lua>)
                 -> rlua::Result<Object<'lua>> {
    allocator(lua)
}

pub fn init(lua: &Lua) -> rlua::Result<Class> {
    Class::new(lua, Some(allocator), None, None)?
        .method("__call".into(), lua.create_function(new))?
        .property(Property::new("button".into(),
                                Some(lua.create_function(set_button)),
                                Some(lua.create_function(get_button)),
                                Some(lua.create_function(set_button))))?
        .property(Property::new("modifiers".into(),
                                Some(lua.create_function(set_modifiers)),
                                Some(lua.create_function(get_modifiers)),
                                Some(lua.create_function(set_modifiers))))?
        .save_class("__button_class")?
        .build()
}

fn set_button<'lua>(lua: &'lua Lua, (table, num): (Table, i32))
                    -> rlua::Result<Value<'lua>> {
    let button = Button::cast(table.into())?;
    button.set_button(Some(num))?;
    Ok(Value::Nil)
}

fn get_button<'lua>(lua: &'lua Lua, table: Table<'lua>)
                    -> rlua::Result<Value<'lua>> {
    Button::cast(table.into())?.button()
}

fn set_modifiers<'lua>(lua: &'lua Lua, button: Table)
                       -> rlua::Result<Value<'lua>> {
    unimplemented!()
}

fn get_modifiers<'lua>(lua: &'lua Lua, button: Table)
                    -> rlua::Result<Value<'lua>> {
    unimplemented!()
}

mod test {
    use rlua::Lua;
    use super::super::button;

    #[test]
    fn button_object_test() {
        let lua = Lua::new();
        button::init(&lua).unwrap();
        lua.globals().set("button0", button::allocator(&lua).unwrap());
        lua.globals().set("button1", button::allocator(&lua).unwrap());
        lua.eval(r#"
 assert(button0.button == nil)
 assert(button1.button == nil)
 button0.connect_signal("test", function(button) button.button = 3 end)
 button0.emit_signal("test")
 assert(button1.button == nil)
 assert(button0.button == 3)
 "#,
        None).unwrap()
    }

    #[test]
    fn button_class_test() {
        let lua = Lua::new();
        let button_class = button::init(&lua).unwrap();
        lua.globals().set("button", button_class).unwrap();
        lua.eval(r#"
a_button = button()
assert(a_button.button == nil)
a_button.connect_signal("test", function(button) button.num = 2 end)
a_button.emit_signal("test")
assert(a_button.num == 2)
"#, None).unwrap()
    }

    #[test]
    fn button_property_test() {
        let lua = Lua::new();
        button::init(&lua).unwrap();
        let button_class = button::init(&lua).unwrap();
        assert_eq!(button_class.properties().unwrap().len().unwrap(), 2);
        lua.globals().set("button", button_class).unwrap();
        lua.eval(r#"
a_button = button()
assert(a_button.button == nil)
a_button.button = 5
assert(a_button.button == 5)
"#, None).unwrap()
    }

    #[test]
    fn button_remove_signal_test() {
        let lua = Lua::new();
        let button_class = button::init(&lua).unwrap();
        lua.globals().set("button", button_class).unwrap();
        lua.eval(r#"
button0 = button()
assert(button0.button == nil)
button0.connect_signal("test", function(button) button.button = 3 end)
button0.emit_signal("test")
assert(button0.button == 3)
button0.button = 0
button0.disconnect_signal("test")
button0.emit_signal("test")
assert(button0.button == 0)
"#, None).unwrap()
    }

    #[test]
    fn button_emit_signal_multiple_args() {
        let lua = Lua::new();
        button::init(&lua).unwrap();
        lua.globals().set("a_button", button::allocator(&lua).unwrap());
        lua.eval(r#"
 assert(a_button.button == nil)
 a_button.connect_signal("test", function(button, num) button.button = num end)
 a_button.emit_signal("test", 5)
 assert(a_button.button == 5)
 a_button.emit_signal("test", -1)
 assert(a_button.button == -1)
 a_button.emit_signal("test", nil)
 assert(a_button.button == nil)
 "#, None).unwrap()
    }
}

<|endoftext|>


<commit_before>extern crate crossbeam;
extern crate multiqueue;
extern crate time;

use multiqueue::{MultiReader, MultiWriter, multiqueue};
use std::sync::mpsc::TryRecvError;

use crossbeam::scope;

use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread::spawn;

const EACH_READER: usize = 100;
const MAX_READERS: usize = 60;
const WRITERS: usize = 20;

#[inline(never)]
fn recv(reader: MultiReader<u64>, how_many_r: Arc<AtomicUsize>) -> u64 {
    let mut cur = 0;
    for _ in 0..2 {
        for _ in 0..EACH_READER {
            match reader.try_recv() {
                Ok(_) => cur += 1,
                Err(TryRecvError::Disconnected) => return cur,
                _ => (),
            }
        }
        if how_many_r.load(Ordering::SeqCst) < MAX_READERS {
            let new_reader = reader.add_reader();
            how_many_r.fetch_add(1, Ordering::SeqCst);
            let newr = how_many_r.clone();
            spawn(move || { recv(new_reader, newr)});
        }
    }
    let current = how_many_r.load(Ordering::SeqCst);
    if current <= 10 {
        let new_reader = reader.add_reader();
        spawn(move || { recv(new_reader, how_many_r) });
    }
    return cur;
}

fn send(writer: MultiWriter<u64>, num_push: usize) {
    for i in 0..num_push as u64 {
        loop {
            let topush = i;
            if let Ok(_) =  writer.try_send(topush) {
                break;
            }
        }
    }
}

fn main() {
    let num_do = 10000000;
    let mytest = Arc::new(AtomicUsize::new(1));
    let (writer, reader) = multiqueue(200);
    scope(|scope| {
        for _ in 0..WRITERS {
            let cwriter = writer.clone();
            scope.spawn(move || {
                send(cwriter, num_do);
            });
        }
        writer.unsubscribe();
        recv(reader, mytest);
    });
}
<commit_msg>Added loop limits on readers/writers for stress test<commit_after>extern crate crossbeam;
extern crate multiqueue;
extern crate time;

use multiqueue::{MultiReader, MultiWriter, multiqueue};
use std::sync::mpsc::TryRecvError;

use crossbeam::scope;

use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread::spawn;

const EACH_READER: usize = 100;
const MAX_READERS: usize = 60;
const WRITERS: usize = 20;

#[inline(never)]
fn recv(reader: MultiReader<u64>, how_many_r: Arc<AtomicUsize>) -> u64 {
    let mut cur = 0;
    for _ in 0..2 {
        'outer: for _ in 0..EACH_READER {
            for _ in 0..100000 {
            match reader.try_recv() {
                Ok(_) => {
                    cur += 1;
                    continue 'outer;
                },
                Err(TryRecvError::Disconnected) => return cur,
                _ => (),
               }
           }
           panic!("Couldn't read from queue");
        }
        if how_many_r.load(Ordering::SeqCst) < MAX_READERS {
            let new_reader = reader.add_reader();
            how_many_r.fetch_add(1, Ordering::SeqCst);
            let newr = how_many_r.clone();
            spawn(move || { recv(new_reader, newr)});
        }
    }
    let current = how_many_r.load(Ordering::SeqCst);
    if current <= 10 {
        let new_reader = reader.add_reader();
        spawn(move || { recv(new_reader, how_many_r) });
    }
    return cur;
}

fn send(writer: MultiWriter<u64>, num_push: usize) {
    'outer: for i in 0..num_push as u64 {
        for _ in 0..100000 {
            let topush = i;
            if let Ok(_) =  writer.try_send(topush) {
                continue 'outer;
            }
        }
        panic!("Couldn't write to queue");
    }
}

fn main() {
    let num_do = 10000000;
    let mytest = Arc::new(AtomicUsize::new(1));
    let (writer, reader) = multiqueue(200);
    scope(|scope| {
        for _ in 0..WRITERS {
            let cwriter = writer.clone();
            scope.spawn(move || {
                send(cwriter, num_do);
            });
        }
        writer.unsubscribe();
        recv(reader, mytest);
    });
}
<|endoftext|>


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

use std::str::FromStr;

use bindgen::ir::Enum;

/// The type of identifier to be renamed.
#[derive(Debug, Clone, Copy)]
pub enum IdentifierType<'a> {
    StructMember,
    EnumVariant(&'a Enum),
    FunctionArg,
    Enum,
}

impl<'a> IdentifierType<'a> {
    fn to_str(&'a self) -> &'static str {
        match *self {
            IdentifierType::StructMember => "m",
            IdentifierType::EnumVariant(..) => "",
            IdentifierType::FunctionArg => "a",
            IdentifierType::Enum => "",
        }
    }
}

/// A rule to apply to an identifier when generating bindings.
#[derive(Debug, Clone, Copy)]
pub enum RenameRule {
    /// Do not apply any renaming. The default.
    None,
    /// Converts the identifier to PascalCase and adds a prefix based on where the identifier is used.
    GeckoCase,
    /// Converts the identifier to lower case.
    LowerCase,
    /// Converts the identifier to upper case.
    UpperCase,
    /// Converts the identifier to PascalCase.
    PascalCase,
    /// Converts the identifier to camelCase.
    CamelCase,
    /// Converts the identifier to snake_case.
    SnakeCase,
    /// Converts the identifier to SCREAMING_SNAKE_CASE.
    ScreamingSnakeCase,
    /// Converts the identifier to SCREAMING_SNAKE_CASE and prefixes enum variants
    /// with the enum name.
    QualifiedScreamingSnakeCase,
}

impl RenameRule {
    /// Applies the rename rule to a string that is formatted in PascalCase.
    pub fn apply_to_pascal_case(&self, text: &str, context: IdentifierType) -> String {
        if text.len() == 0 {
            return String::new();
        }

        match *self {
            RenameRule::None => String::from(text),
            RenameRule::GeckoCase => context.to_str().to_owned() + text,
            RenameRule::LowerCase => text.to_lowercase(),
            RenameRule::UpperCase => text.to_uppercase(),
            RenameRule::PascalCase => text.to_owned(),
            RenameRule::CamelCase => {
                text[..1].to_lowercase() + &text[1..]
            }
            RenameRule::SnakeCase => {
                let mut result = String::new();
                for (i, c) in text.char_indices() {
                    if c.is_uppercase() && i != 0 {
                        result.push_str("_");
                    }
                    for x in c.to_lowercase() {
                        result.push(x);
                    }
                }
                result
            }
            RenameRule::ScreamingSnakeCase => {
                // Same as SnakeCase code above, but uses to_uppercase
                let mut result = String::new();
                for (i, c) in text.char_indices() {
                    if c.is_uppercase() && i != 0 {
                        result.push_str("_");
                    }
                    for x in c.to_uppercase() {
                        result.push(x);
                    }
                }
                result
            }
            RenameRule::QualifiedScreamingSnakeCase => {
                let mut result = String::new();

                if let IdentifierType::EnumVariant(e) = context {
                    if let &RenameRule::QualifiedScreamingSnakeCase = self {
                        result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_pascal_case(
                            &e.name, IdentifierType::Enum));
                        result.push_str("_");
                    }
                }

                result.push_str(&RenameRule::SnakeCase.apply_to_pascal_case(
                    &text, context));
                result
            }
        }
    }

    /// Applies the rename rule to a string that is formatted in snake_case.
    pub fn apply_to_snake_case(&self, mut text: &str, context: IdentifierType) -> String {
        if text.len() == 0 {
            return String::new();
        }

        match *self {
            RenameRule::None => String::from(text),
            RenameRule::GeckoCase => {
                if &text[..1] == "_" {
                    text = &text[1..];
                }

                context.to_str().to_owned() +
                    &RenameRule::PascalCase.apply_to_snake_case(text, context)
            }
            RenameRule::LowerCase => text.to_lowercase(),
            RenameRule::UpperCase => text.to_uppercase(),
            RenameRule::PascalCase => {
                let mut result = String::new();
                let mut is_uppercase = true;
                for c in text.chars() {
                    if c == '_' {
                        is_uppercase = true;
                        continue;
                    }

                    if is_uppercase {
                        for x in c.to_uppercase() {
                            result.push(x);
                        }
                        is_uppercase = false;
                    } else {
                        result.push(c);
                    }
                }
                result
            }
            RenameRule::CamelCase => {
                // Same as PascalCase code above, but is_uppercase = false to start
                let mut result = String::new();
                let mut is_uppercase = false;
                for c in text.chars() {
                    if c == '_' {
                        is_uppercase = true;
                        continue;
                    }

                    if is_uppercase {
                        for x in c.to_uppercase() {
                            result.push(x);
                        }
                        is_uppercase = false;
                    } else {
                        result.push(c);
                    }
                }
                result
            }
            RenameRule::SnakeCase => text.to_owned(),
            RenameRule::ScreamingSnakeCase => text.to_owned().to_uppercase(),
            RenameRule::QualifiedScreamingSnakeCase => {
                let mut result = String::new();

                if let IdentifierType::EnumVariant(e) = context {
                    if let &RenameRule::QualifiedScreamingSnakeCase = self {
                        result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_snake_case(
                            &e.name, IdentifierType::Enum));
                        result.push_str("_");
                    }
                }

                result.push_str(&RenameRule::SnakeCase.apply_to_snake_case(
                    &text, context));
                result
            }
        }
    }
}

impl Default for RenameRule {
    fn default() -> RenameRule {
        RenameRule::None
    }
}

impl FromStr for RenameRule {
    type Err = String;

    fn from_str(s: &str) -> Result<RenameRule, Self::Err> {
        match s {
            "none" => Ok(RenameRule::None),
            "None" => Ok(RenameRule::None),

            "mGeckoCase" => Ok(RenameRule::GeckoCase),
            "GeckoCase" => Ok(RenameRule::GeckoCase),
            "gecko_case" => Ok(RenameRule::GeckoCase),

            "lowercase" => Ok(RenameRule::LowerCase),
            "LowerCase" => Ok(RenameRule::LowerCase),
            "lower_case" => Ok(RenameRule::LowerCase),

            "UPPERCASE" => Ok(RenameRule::UpperCase),
            "UpperCase" => Ok(RenameRule::UpperCase),
            "upper_case" => Ok(RenameRule::UpperCase),

            "PascalCase" => Ok(RenameRule::PascalCase),
            "pascal_case" => Ok(RenameRule::PascalCase),

            "camelCase" => Ok(RenameRule::CamelCase),
            "CamelCase" => Ok(RenameRule::CamelCase),
            "camel_case" => Ok(RenameRule::CamelCase),

            "snake_case" => Ok(RenameRule::SnakeCase),
            "SnakeCase" => Ok(RenameRule::SnakeCase),

            "SCREAMING_SNAKE_CASE" => Ok(RenameRule::ScreamingSnakeCase),
            "ScreamingSnakeCase" => Ok(RenameRule::ScreamingSnakeCase),
            "screaming_snake_case" => Ok(RenameRule::ScreamingSnakeCase),

            "QUALIFIED_SCREAMING_SNAKE_CASE" => Ok(RenameRule::QualifiedScreamingSnakeCase),
            "QualifiedScreamingSnakeCase" => Ok(RenameRule::QualifiedScreamingSnakeCase),
            "qualified_screaming_snake_case" => Ok(RenameRule::QualifiedScreamingSnakeCase),

            _ => Err(format!("unrecognized RenameRule: '{}'", s)),
        }
    }
}

deserialize_enum_str!(RenameRule);
<commit_msg>Fix incorrectly implemented QualifiedScreamingSnakeCase<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::str::FromStr;

use bindgen::ir::Enum;

/// The type of identifier to be renamed.
#[derive(Debug, Clone, Copy)]
pub enum IdentifierType<'a> {
    StructMember,
    EnumVariant(&'a Enum),
    FunctionArg,
    Enum,
}

impl<'a> IdentifierType<'a> {
    fn to_str(&'a self) -> &'static str {
        match *self {
            IdentifierType::StructMember => "m",
            IdentifierType::EnumVariant(..) => "",
            IdentifierType::FunctionArg => "a",
            IdentifierType::Enum => "",
        }
    }
}

/// A rule to apply to an identifier when generating bindings.
#[derive(Debug, Clone, Copy)]
pub enum RenameRule {
    /// Do not apply any renaming. The default.
    None,
    /// Converts the identifier to PascalCase and adds a prefix based on where the identifier is used.
    GeckoCase,
    /// Converts the identifier to lower case.
    LowerCase,
    /// Converts the identifier to upper case.
    UpperCase,
    /// Converts the identifier to PascalCase.
    PascalCase,
    /// Converts the identifier to camelCase.
    CamelCase,
    /// Converts the identifier to snake_case.
    SnakeCase,
    /// Converts the identifier to SCREAMING_SNAKE_CASE.
    ScreamingSnakeCase,
    /// Converts the identifier to SCREAMING_SNAKE_CASE and prefixes enum variants
    /// with the enum name.
    QualifiedScreamingSnakeCase,
}

impl RenameRule {
    /// Applies the rename rule to a string that is formatted in PascalCase.
    pub fn apply_to_pascal_case(&self, text: &str, context: IdentifierType) -> String {
        if text.len() == 0 {
            return String::new();
        }

        match *self {
            RenameRule::None => String::from(text),
            RenameRule::GeckoCase => context.to_str().to_owned() + text,
            RenameRule::LowerCase => text.to_lowercase(),
            RenameRule::UpperCase => text.to_uppercase(),
            RenameRule::PascalCase => text.to_owned(),
            RenameRule::CamelCase => {
                text[..1].to_lowercase() + &text[1..]
            }
            RenameRule::SnakeCase => {
                let mut result = String::new();
                for (i, c) in text.char_indices() {
                    if c.is_uppercase() && i != 0 {
                        result.push_str("_");
                    }
                    for x in c.to_lowercase() {
                        result.push(x);
                    }
                }
                result
            }
            RenameRule::ScreamingSnakeCase => {
                // Same as SnakeCase code above, but uses to_uppercase
                let mut result = String::new();
                for (i, c) in text.char_indices() {
                    if c.is_uppercase() && i != 0 {
                        result.push_str("_");
                    }
                    for x in c.to_uppercase() {
                        result.push(x);
                    }
                }
                result
            }
            RenameRule::QualifiedScreamingSnakeCase => {
                let mut result = String::new();

                if let IdentifierType::EnumVariant(e) = context {
                    if let &RenameRule::QualifiedScreamingSnakeCase = self {
                        result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_pascal_case(
                            &e.name, IdentifierType::Enum));
                        result.push_str("_");
                    }
                }

                result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_pascal_case(
                    &text, context));
                result
            }
        }
    }

    /// Applies the rename rule to a string that is formatted in snake_case.
    pub fn apply_to_snake_case(&self, mut text: &str, context: IdentifierType) -> String {
        if text.len() == 0 {
            return String::new();
        }

        match *self {
            RenameRule::None => String::from(text),
            RenameRule::GeckoCase => {
                if &text[..1] == "_" {
                    text = &text[1..];
                }

                context.to_str().to_owned() +
                    &RenameRule::PascalCase.apply_to_snake_case(text, context)
            }
            RenameRule::LowerCase => text.to_lowercase(),
            RenameRule::UpperCase => text.to_uppercase(),
            RenameRule::PascalCase => {
                let mut result = String::new();
                let mut is_uppercase = true;
                for c in text.chars() {
                    if c == '_' {
                        is_uppercase = true;
                        continue;
                    }

                    if is_uppercase {
                        for x in c.to_uppercase() {
                            result.push(x);
                        }
                        is_uppercase = false;
                    } else {
                        result.push(c);
                    }
                }
                result
            }
            RenameRule::CamelCase => {
                // Same as PascalCase code above, but is_uppercase = false to start
                let mut result = String::new();
                let mut is_uppercase = false;
                for c in text.chars() {
                    if c == '_' {
                        is_uppercase = true;
                        continue;
                    }

                    if is_uppercase {
                        for x in c.to_uppercase() {
                            result.push(x);
                        }
                        is_uppercase = false;
                    } else {
                        result.push(c);
                    }
                }
                result
            }
            RenameRule::SnakeCase => text.to_owned(),
            RenameRule::ScreamingSnakeCase => text.to_owned().to_uppercase(),
            RenameRule::QualifiedScreamingSnakeCase => {
                let mut result = String::new();

                if let IdentifierType::EnumVariant(e) = context {
                    if let &RenameRule::QualifiedScreamingSnakeCase = self {
                        result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_snake_case(
                            &e.name, IdentifierType::Enum));
                        result.push_str("_");
                    }
                }

                result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_snake_case(
                    &text, context));
                result
            }
        }
    }
}

impl Default for RenameRule {
    fn default() -> RenameRule {
        RenameRule::None
    }
}

impl FromStr for RenameRule {
    type Err = String;

    fn from_str(s: &str) -> Result<RenameRule, Self::Err> {
        match s {
            "none" => Ok(RenameRule::None),
            "None" => Ok(RenameRule::None),

            "mGeckoCase" => Ok(RenameRule::GeckoCase),
            "GeckoCase" => Ok(RenameRule::GeckoCase),
            "gecko_case" => Ok(RenameRule::GeckoCase),

            "lowercase" => Ok(RenameRule::LowerCase),
            "LowerCase" => Ok(RenameRule::LowerCase),
            "lower_case" => Ok(RenameRule::LowerCase),

            "UPPERCASE" => Ok(RenameRule::UpperCase),
            "UpperCase" => Ok(RenameRule::UpperCase),
            "upper_case" => Ok(RenameRule::UpperCase),

            "PascalCase" => Ok(RenameRule::PascalCase),
            "pascal_case" => Ok(RenameRule::PascalCase),

            "camelCase" => Ok(RenameRule::CamelCase),
            "CamelCase" => Ok(RenameRule::CamelCase),
            "camel_case" => Ok(RenameRule::CamelCase),

            "snake_case" => Ok(RenameRule::SnakeCase),
            "SnakeCase" => Ok(RenameRule::SnakeCase),

            "SCREAMING_SNAKE_CASE" => Ok(RenameRule::ScreamingSnakeCase),
            "ScreamingSnakeCase" => Ok(RenameRule::ScreamingSnakeCase),
            "screaming_snake_case" => Ok(RenameRule::ScreamingSnakeCase),

            "QUALIFIED_SCREAMING_SNAKE_CASE" => Ok(RenameRule::QualifiedScreamingSnakeCase),
            "QualifiedScreamingSnakeCase" => Ok(RenameRule::QualifiedScreamingSnakeCase),
            "qualified_screaming_snake_case" => Ok(RenameRule::QualifiedScreamingSnakeCase),

            _ => Err(format!("unrecognized RenameRule: '{}'", s)),
        }
    }
}

deserialize_enum_str!(RenameRule);
<|endoftext|>