<commit_before>use std::collections::HashSet;
use std::io::Read;
use std::ops::Add;
use std::ops::Sub;

use nom::bytes::complete::tag;
use nom::character::complete::newline;
use nom::combinator::map;
use nom::multi::many1;
use nom::multi::separated_list1;
use nom::sequence::delimited;
use nom::sequence::preceded;
use nom::sequence::terminated;
use nom::sequence::tuple;
use nom::IResult;

use crate::common::read_input;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
struct Point3(pub [i32; 3]);

impl Point3 {
    pub fn manhattan(&self) -> i32 {
        self.0.into_iter().map(i32::abs).sum()
    }
}

impl Sub for Point3 {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        Point3([
            self.0[0] - rhs.0[0],
            self.0[1] - rhs.0[1],
            self.0[2] - rhs.0[2],
        ])
    }
}

impl Add for Point3 {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        Point3([
            self.0[0] + rhs.0[0],
            self.0[1] + rhs.0[1],
            self.0[2] + rhs.0[2],
        ])
    }
}

struct Rotations<'a> {
    points: &'a [Point3],
    axes: [usize; 3],
    rotation_index: usize,
}

impl<'a> Rotations<'a> {
    const ROTATIONS: [[i32; 3]; 8] = [
        [1, 1, 1],
        [1, 1, -1],
        [1, -1, 1],
        [1, -1, -1],
        [-1, 1, 1],
        [-1, 1, -1],
        [-1, -1, 1],
        [-1, -1, -1],
    ];

    pub fn new(points: &'a [Point3]) -> Self {
        Self {
            points,
            axes: [0, 1, 2],
            rotation_index: 0,
        }
    }
}

impl Iterator for Rotations<'_> {
    type Item = Vec<Point3>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.rotation_index >= Self::ROTATIONS.len() {
            if !next_permutation(&mut self.axes) {
                return None;
            }

            self.rotation_index = 0;
        }

        let axes = &self.axes;
        let rot = &Self::ROTATIONS[self.rotation_index];

        let result = self
            .points
            .iter()
            .map(|Point3(coords)| {
                Point3([
                    coords[axes[0]] * rot[0],
                    coords[axes[1]] * rot[1],
                    coords[axes[2]] * rot[2],
                ])
            })
            .collect();

        self.rotation_index += 1;

        Some(result)
    }
}

fn parse_point(input: &[u8]) -> IResult<&[u8], Point3> {
    use nom::character::complete::char;
    use nom::character::complete::i32;

    map(
        tuple((i32, preceded(char(','), i32), preceded(char(','), i32))),
        |(x, y, z)| Point3([x, y, z]),
    )(input)
}

fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Vec<Point3>>> {
    use nom::character::complete::i32;
    let parse_header = delimited(tag("--- scanner "), i32, tag(" ---\n"));

    let parse_scanner = preceded(parse_header, many1(terminated(parse_point, newline)));
    separated_list1(newline, parse_scanner)(input)
}

fn try_overlap(
    correct: &[(Point3, HashSet<Point3>)],
    candidate: &[Point3],
) -> Option<(Point3, Vec<Point3>)> {
    let mut relative = HashSet::new();
    for rot in Rotations::new(candidate) {
        for &start in &rot {
            relative.clear();

            relative.extend(rot.iter().map(|&other| other - start));

            if let Some((base, _)) = correct.iter().find(|(_, correct_relative)| {
                correct_relative.intersection(&relative).count() >= 12
            }) {
                // Found a solution, build the correct output
                let translated = relative.drain().map(|point| point + *base).collect();

                return Some((start - *base, translated));
            }
        }
    }

    None
}

fn parts_common(input: &mut dyn Read) -> (HashSet<Point3>, Vec<Point3>) {
    let mut scanners = read_input(input, parse_input);

    let mut points: HashSet<_> = scanners[0].iter().copied().collect();

    let mut todo = vec![std::mem::take(&mut scanners[0])];
    let mut scanners_found = vec![Point3::default()];

    while let Some(matched) = todo.pop() {
        if scanners.iter().all(Vec::is_empty) {
            break;
        }

        let relative: Vec<(Point3, HashSet<Point3>)> = matched
            .iter()
            .map(|&base| (base, matched.iter().map(|&other| (other - base)).collect()))
            .collect();

        for candidate in &mut scanners {
            if candidate.is_empty() {
                continue;
            }

            if let Some((scanner, result)) = try_overlap(&relative, candidate) {
                scanners_found.push(scanner);
                points.extend(result.iter().copied());
                todo.push(result);
                candidate.clear();
            }
        }
    }

    (points, scanners_found)
}

pub fn part1(input: &mut dyn Read) -> String {
    let (points, _) = parts_common(input);
    points.len().to_string()
}

pub fn part2(input: &mut dyn Read) -> String {
    let (_, scanners) = parts_common(input);

    scanners
        .iter()
        .flat_map(|&first| {
            scanners
                .iter()
                .map(move |&second| (first - second).manhattan())
        })
        .max()
        .unwrap()
        .to_string()
}

pub fn next_permutation<T: Ord>(list: &mut [T]) -> bool {
    // Based on: https://en.cppreference.com/w/cpp/algorithm/next_permutation
    if list.len() <= 1 {
        return false;
    }

    if let Some((i, val1)) = list
        .windows(2)
        .enumerate()
        .rev()
        .find_map(|(i, window)| (window[0] < window[1]).then(|| (i, &window[0])))
    {
        let it2 = list
            .iter()
            .enumerate()
            .skip(i + 1)
            .rev()
            .find_map(|(idx, val2)| (val1 < val2).then(|| idx))
            .expect("Unreachable, ascending pair exists");

        list.swap(i, it2);
        list[(i + 1)..].reverse();
        true
    } else {
        list.reverse();
        false
    }
}

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

    use crate::test_implementation;

    const SAMPLE: &[u8] = include_bytes!("samples/19.txt");

    #[test]
    fn test_next_permutation() {
        let mut list = [1, 2, 3];

        assert!(next_permutation(&mut list));
        assert_eq!(list, [1, 3, 2]);

        assert!(next_permutation(&mut list));
        assert_eq!(list, [2, 1, 3]);

        assert!(next_permutation(&mut list));
        assert_eq!(list, [2, 3, 1]);

        assert!(next_permutation(&mut list));
        assert_eq!(list, [3, 1, 2]);

        assert!(next_permutation(&mut list));
        assert_eq!(list, [3, 2, 1]);

        // Note the negation!
        assert!(!next_permutation(&mut list));
        assert_eq!(list, [1, 2, 3]);

        // 24 is a bit too much to write out, but we can check the number
        let mut list2 = [1, 2, 3, 4];
        for _ in 1..24 {
            assert!(next_permutation(&mut list2));
        }

        // Should be back to the start
        assert!(!next_permutation(&mut list2));
        assert_eq!(list2, [1, 2, 3, 4]);
    }

    #[test]
    fn sample_part1() {
        test_implementation(part1, SAMPLE, 79);
    }

    #[test]
    fn sample_part2() {
        test_implementation(part2, SAMPLE, 3621);
    }
}
<commit_msg>Use pre-matching strategy<commit_after>use std::collections::HashMap;
use std::collections::HashSet;
use std::io::Read;
use std::ops::Add;
use std::ops::Deref;
use std::ops::Sub;

use nom::bytes::complete::tag;
use nom::character::complete::newline;
use nom::combinator::map;
use nom::multi::many1;
use nom::multi::separated_list1;
use nom::sequence::delimited;
use nom::sequence::preceded;
use nom::sequence::terminated;
use nom::sequence::tuple;
use nom::IResult;

use crate::common::read_input;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
struct Point3(pub [i32; 3]);

impl Point3 {
    pub fn manhattan(&self) -> i32 {
        self.0.into_iter().map(i32::abs).sum()
    }

    pub fn euler_square(&self) -> i32 {
        self.0.into_iter().map(|c| c * c).sum()
    }
}

impl Sub for Point3 {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        Point3([
            self.0[0] - rhs.0[0],
            self.0[1] - rhs.0[1],
            self.0[2] - rhs.0[2],
        ])
    }
}

impl Add for Point3 {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        Point3([
            self.0[0] + rhs.0[0],
            self.0[1] + rhs.0[1],
            self.0[2] + rhs.0[2],
        ])
    }
}

struct Scanner {
    visible: Vec<Point3>,
    distances: HashMap<i32, (Point3, Point3)>,
}

impl Scanner {
    pub fn new(visible: Vec<Point3>) -> Self {
        let distances = visible
            .iter()
            .enumerate()
            .flat_map(|(skip, &a)| {
                visible[(skip + 1)..]
                    .iter()
                    .map(move |&b| ((a - b).euler_square(), (a, b)))
            })
            .collect();

        Self { visible, distances }
    }

    pub fn can_overlap(&self, other: &Self) -> bool {
        other
            .distances
            .keys()
            .filter(|&k| self.distances.contains_key(k))
            .count()
            >= 11
    }
}

impl Deref for Scanner {
    type Target = [Point3];

    fn deref(&self) -> &Self::Target {
        &self.visible
    }
}

struct Rotations<'a> {
    points: &'a [Point3],
    axes: [usize; 3],
    rotation_index: usize,
}

impl<'a> Rotations<'a> {
    const ROTATIONS: [[i32; 3]; 8] = [
        [1, 1, 1],
        [1, 1, -1],
        [1, -1, 1],
        [1, -1, -1],
        [-1, 1, 1],
        [-1, 1, -1],
        [-1, -1, 1],
        [-1, -1, -1],
    ];

    pub fn new(points: &'a [Point3]) -> Self {
        Self {
            points,
            axes: [0, 1, 2],
            rotation_index: 0,
        }
    }
}

impl Iterator for Rotations<'_> {
    type Item = Vec<Point3>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.rotation_index >= Self::ROTATIONS.len() {
            if !next_permutation(&mut self.axes) {
                return None;
            }

            self.rotation_index = 0;
        }

        let axes = &self.axes;
        let rot = &Self::ROTATIONS[self.rotation_index];

        let result = self
            .points
            .iter()
            .map(|Point3(coords)| {
                Point3([
                    coords[axes[0]] * rot[0],
                    coords[axes[1]] * rot[1],
                    coords[axes[2]] * rot[2],
                ])
            })
            .collect();

        self.rotation_index += 1;

        Some(result)
    }
}

fn parse_point(input: &[u8]) -> IResult<&[u8], Point3> {
    use nom::character::complete::char;
    use nom::character::complete::i32;

    map(
        tuple((i32, preceded(char(','), i32), preceded(char(','), i32))),
        |(x, y, z)| Point3([x, y, z]),
    )(input)
}

fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Scanner>> {
    use nom::character::complete::i32;
    let parse_header = delimited(tag("--- scanner "), i32, tag(" ---\n"));

    let parse_scanner = map(
        preceded(parse_header, many1(terminated(parse_point, newline))),
        Scanner::new,
    );
    separated_list1(newline, parse_scanner)(input)
}

fn try_overlap(matched: &Scanner, candidate: &Scanner) -> Option<(Point3, Scanner)> {
    if !matched.can_overlap(candidate) {
        return None;
    }

    let correct: Vec<(Point3, HashSet<Point3>)> = matched
        .iter()
        .map(|&base| (base, matched.iter().map(|&other| (other - base)).collect()))
        .collect();

    let mut relative = HashSet::new();
    for rot in Rotations::new(&candidate.visible) {
        for &start in &rot {
            relative.clear();

            relative.extend(rot.iter().map(|&other| other - start));

            if let Some((base, _)) = correct.iter().find(|(_, correct_relative)| {
                correct_relative.intersection(&relative).count() >= 12
            }) {
                // Found a solution, build the correct output
                let translated = relative.drain().map(|point| point + *base).collect();

                return Some((start - *base, Scanner::new(translated)));
            }
        }
    }

    None
}

fn parts_common(input: &mut dyn Read) -> (HashSet<Point3>, Vec<Point3>) {
    let mut scanners = read_input(input, parse_input);

    let mut points: HashSet<_> = scanners[0].iter().copied().collect();

    let mut todo = vec![scanners.remove(0)];
    let mut scanners_found = vec![Point3::default()];

    while let Some(matched) = todo.pop() {
        if scanners.is_empty() {
            break;
        }

        let mut i = 0;

        while i < scanners.len() {
            if let Some((scanner, result)) = try_overlap(&matched, &scanners[i]) {
                scanners.remove(i);
                scanners_found.push(scanner);
                points.extend(result.iter().copied());
                todo.push(result);
            } else {
                i += 1;
            }
        }
    }

    (points, scanners_found)
}

pub fn part1(input: &mut dyn Read) -> String {
    let (points, _) = parts_common(input);
    points.len().to_string()
}

pub fn part2(input: &mut dyn Read) -> String {
    let (_, scanners) = parts_common(input);

    scanners
        .iter()
        .flat_map(|&first| {
            scanners
                .iter()
                .map(move |&second| (first - second).manhattan())
        })
        .max()
        .unwrap()
        .to_string()
}

pub fn next_permutation<T: Ord>(list: &mut [T]) -> bool {
    // Based on: https://en.cppreference.com/w/cpp/algorithm/next_permutation
    if list.len() <= 1 {
        return false;
    }

    if let Some((i, val1)) = list
        .windows(2)
        .enumerate()
        .rev()
        .find_map(|(i, window)| (window[0] < window[1]).then(|| (i, &window[0])))
    {
        let it2 = list
            .iter()
            .enumerate()
            .skip(i + 1)
            .rev()
            .find_map(|(idx, val2)| (val1 < val2).then(|| idx))
            .expect("Unreachable, ascending pair exists");

        list.swap(i, it2);
        list[(i + 1)..].reverse();
        true
    } else {
        list.reverse();
        false
    }
}

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

    use crate::test_implementation;

    const SAMPLE: &[u8] = include_bytes!("samples/19.txt");

    #[test]
    fn test_next_permutation() {
        let mut list = [1, 2, 3];

        assert!(next_permutation(&mut list));
        assert_eq!(list, [1, 3, 2]);

        assert!(next_permutation(&mut list));
        assert_eq!(list, [2, 1, 3]);

        assert!(next_permutation(&mut list));
        assert_eq!(list, [2, 3, 1]);

        assert!(next_permutation(&mut list));
        assert_eq!(list, [3, 1, 2]);

        assert!(next_permutation(&mut list));
        assert_eq!(list, [3, 2, 1]);

        // Note the negation!
        assert!(!next_permutation(&mut list));
        assert_eq!(list, [1, 2, 3]);

        // 24 is a bit too much to write out, but we can check the number
        let mut list2 = [1, 2, 3, 4];
        for _ in 1..24 {
            assert!(next_permutation(&mut list2));
        }

        // Should be back to the start
        assert!(!next_permutation(&mut list2));
        assert_eq!(list2, [1, 2, 3, 4]);
    }

    #[test]
    fn sample_part1() {
        test_implementation(part1, SAMPLE, 79);
    }

    #[test]
    fn sample_part2() {
        test_implementation(part2, SAMPLE, 3621);
    }
}
<|endoftext|>


<commit_before>use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Weak};

use super::{Message, ActorRef, Actor, ActorSystem};

/// This is a very basic `Actor` which can deal with `String` messages by printing them,
/// any other type of `Data` will have the `Printer` do nothing.
pub struct Printer {
    name: Arc<String>,
    message_queue: Arc<Mutex<VecDeque<Message>>>,
    actor_system: Arc<ActorSystem>,
    known_actors: Arc<Mutex<Vec<ActorRef>>>,
    myself: Arc<Mutex<Option<Weak<Mutex<Actor>>>>>,
}

unsafe impl Send for Printer {}

impl Actor for Printer {
    fn new(name: String, actor_system: Arc<ActorSystem>, known_actors: Vec<ActorRef>) -> ActorRef {
        let actor_ref = Arc::new(Mutex::new(Printer {
            name: Arc::new(name),
            message_queue: Arc::new(Mutex::new(VecDeque::new())),
            actor_system: actor_system,
            known_actors: Arc::new(Mutex::new(known_actors)),
            myself: Arc::new(Mutex::new(None)),
        }));
        //Actor::init(actor_ref.clone());
        actor_ref
    }

    fn init(me: ActorRef) {
        // There are 2 temp values to satisfy the borrow checker.
        let x = me.lock().unwrap().myself();
        let mut y = x.lock().unwrap();
        *y = Some(Arc::downgrade(&me));
    }

    //fn actor_ref(&self) -> ActorRef {
    //    let x = self.myself();
    //    let y = x.lock().unwrap(); // Get the Option<Weak> out of the Mutex.
    //    let z = y.unwrap().clone(); // Get the Weak out of the Option.
    //    z.upgrade().unwrap()
    //}

    fn myself(&self) -> Arc<Mutex<Option<Weak<Mutex<Actor>>>>> {
        self.myself.clone()
    }

    fn handle_message(&self) {
        let message = self.message_queue.lock().unwrap().pop_front().unwrap();

        println!("({}) treats a message", self.name);
        match message {
            Message::Data(ref data) => {
                match data.downcast_ref::<String>() {
                    Some(s) => println!("Received data: ({})", s),
                    None => println!("Message is dropped"),
                }
            },
            Message::Command => println!("Receiced a command"),
        }
    }

    fn actor_system(&self) -> Arc<ActorSystem> { self.actor_system.clone() }
    fn receive(&self, message: Message) { self.message_queue.lock().unwrap().push_back(message); }
    fn send_to_first(&self, message: Message) {
        let actor_ref = self.known_actors.lock().unwrap()[0].clone();
        self.send_message(actor_ref, message);
    }
}

/// This is a very basic `Actor` which can deal with `u32` messages by counting up to them,
/// any other type of `Data` will have the `Counter` do nothing.
pub struct Counter {
    name: Arc<String>,
    message_queue: Arc<Mutex<VecDeque<Message>>>,
    actor_system: Arc<ActorSystem>,
    known_actors: Arc<Mutex<Vec<ActorRef>>>,
    myself: Arc<Mutex<Option<Weak<Mutex<Actor>>>>>,
}

impl Actor for Counter {
    fn new(name: String, actor_system: Arc<ActorSystem>, known_actors: Vec<ActorRef>) -> ActorRef {
        let actor_ref = Arc::new(Mutex::new(Counter {
            name: Arc::new(name),
            message_queue: Arc::new(Mutex::new(VecDeque::new())),
            actor_system: actor_system,
            known_actors: Arc::new(Mutex::new(known_actors)),
            myself: Arc::new(Mutex::new(None)),
        }));
        //Actor::init(actor_ref.clone());
        actor_ref
    }

    fn init(me: ActorRef) {
        // There are 2 temp values to satisfy the borrow checker.
        let x = me.lock().unwrap().myself();
        let mut y = x.lock().unwrap();
        *y = Some(Arc::downgrade(&me));
    }

    //fn actor_ref(&self) -> ActorRef {
    //    let x = self.myself();
    //    let y = x.lock().unwrap(); // Get the Option<Weak> out of the Mutex.
    //    let z = y.unwrap(); // Get the Weak out of the Option.
    //    z.upgrade().unwrap()
    //}

    fn myself(&self) -> Arc<Mutex<Option<Weak<Mutex<Actor>>>>> {
        self.myself.clone()
    }

    fn handle_message(&self) {
        let message = self.message_queue.lock().unwrap().pop_front().unwrap();

        println!("({}) treats a message", self.name);
        match message {
            Message::Data(ref data) => {
                match data.downcast_ref::<u32>() {
                    Some(n) => {
                        println!("Received data: ({})", n);
                        for i in 0..*n {
                            println!("{}", i);
                        }
                    },
                    None => println!("Message is dropped"),
                }
            },
            Message::Command => println!("Receiced a command"),
        }
    }

    fn actor_system(&self) -> Arc<ActorSystem> { self.actor_system.clone() }
    fn receive(&self, message: Message) { self.message_queue.lock().unwrap().push_back(message); }
    fn send_to_first(&self, message: Message) {
        let actor_ref = self.known_actors.lock().unwrap()[0].clone();
        self.send_message(actor_ref, message);
    }
}
<commit_msg>WIP - The myself is filed now<commit_after>use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Weak};

use super::{Message, ActorRef, Actor, ActorSystem};

/// This is a very basic `Actor` which can deal with `String` messages by printing them,
/// any other type of `Data` will have the `Printer` do nothing.
pub struct Printer {
    name: Arc<String>,
    message_queue: Arc<Mutex<VecDeque<Message>>>,
    actor_system: Arc<ActorSystem>,
    known_actors: Arc<Mutex<Vec<ActorRef>>>,
    myself: Arc<Mutex<Option<Weak<Mutex<Actor>>>>>,
}

impl Actor for Printer {
    fn new(name: String, actor_system: Arc<ActorSystem>, known_actors: Vec<ActorRef>) -> ActorRef {
        let actor_ref = Arc::new(Mutex::new(Printer {
            name: Arc::new(name),
            message_queue: Arc::new(Mutex::new(VecDeque::new())),
            actor_system: actor_system,
            known_actors: Arc::new(Mutex::new(known_actors)),
            myself: Arc::new(Mutex::new(None)),
        }));
        Printer::init(actor_ref.clone());
        actor_ref
    }

    fn init(me: ActorRef) {
        // There are 2 temp values to satisfy the borrow checker.
        let x = me.lock().unwrap().myself();
        let mut y = x.lock().unwrap();
        *y = Some(Arc::downgrade(&me));
    }

    //fn actor_ref(&self) -> ActorRef {
    //    let x = self.myself();
    //    let y = x.lock().unwrap(); // Get the Option<Weak> out of the Mutex.
    //    let z = y.unwrap().clone(); // Get the Weak out of the Option.
    //    z.upgrade().unwrap()
    //}

    fn myself(&self) -> Arc<Mutex<Option<Weak<Mutex<Actor>>>>> {
        self.myself.clone()
    }

    fn handle_message(&self) {
        let message = self.message_queue.lock().unwrap().pop_front().unwrap();

        println!("({}) treats a message", self.name);
        match message {
            Message::Data(ref data) => {
                match data.downcast_ref::<String>() {
                    Some(s) => println!("Received data: ({})", s),
                    None => println!("Message is dropped"),
                }
            },
            Message::Command => println!("Receiced a command"),
        }
    }

    fn actor_system(&self) -> Arc<ActorSystem> { self.actor_system.clone() }
    fn receive(&self, message: Message) { self.message_queue.lock().unwrap().push_back(message); }
    fn send_to_first(&self, message: Message) {
        let actor_ref = self.known_actors.lock().unwrap()[0].clone();
        self.send_message(actor_ref, message);
    }
}

/// This is a very basic `Actor` which can deal with `u32` messages by counting up to them,
/// any other type of `Data` will have the `Counter` do nothing.
pub struct Counter {
    name: Arc<String>,
    message_queue: Arc<Mutex<VecDeque<Message>>>,
    actor_system: Arc<ActorSystem>,
    known_actors: Arc<Mutex<Vec<ActorRef>>>,
    myself: Arc<Mutex<Option<Weak<Mutex<Actor>>>>>,
}

impl Actor for Counter {
    fn new(name: String, actor_system: Arc<ActorSystem>, known_actors: Vec<ActorRef>) -> ActorRef {
        let actor_ref = Arc::new(Mutex::new(Counter {
            name: Arc::new(name),
            message_queue: Arc::new(Mutex::new(VecDeque::new())),
            actor_system: actor_system,
            known_actors: Arc::new(Mutex::new(known_actors)),
            myself: Arc::new(Mutex::new(None)),
        }));
        Counter::init(actor_ref.clone());
        actor_ref
    }

    fn init(me: ActorRef) {
        // There are 2 temp values to satisfy the borrow checker.
        let x = me.lock().unwrap().myself();
        let mut y = x.lock().unwrap();
        *y = Some(Arc::downgrade(&me));
    }

    //fn actor_ref(&self) -> ActorRef {
    //    let x = self.myself();
    //    let y = x.lock().unwrap(); // Get the Option<Weak> out of the Mutex.
    //    let z = y.unwrap(); // Get the Weak out of the Option.
    //    z.upgrade().unwrap()
    //}

    fn myself(&self) -> Arc<Mutex<Option<Weak<Mutex<Actor>>>>> {
        self.myself.clone()
    }

    fn handle_message(&self) {
        let message = self.message_queue.lock().unwrap().pop_front().unwrap();

        println!("({}) treats a message", self.name);
        match message {
            Message::Data(ref data) => {
                match data.downcast_ref::<u32>() {
                    Some(n) => {
                        println!("Received data: ({})", n);
                        for i in 0..*n {
                            println!("{}", i);
                        }
                    },
                    None => println!("Message is dropped"),
                }
            },
            Message::Command => println!("Receiced a command"),
        }
    }

    fn actor_system(&self) -> Arc<ActorSystem> { self.actor_system.clone() }
    fn receive(&self, message: Message) { self.message_queue.lock().unwrap().push_back(message); }
    fn send_to_first(&self, message: Message) {
        let actor_ref = self.known_actors.lock().unwrap()[0].clone();
        self.send_message(actor_ref, message);
    }
}
<|endoftext|>


<commit_before>use std::mem;

use edit_types::{BufferEvent, EventDomain};

pub(crate) struct Recorder {
    is_recording: bool,
    recording: Recording,
}

impl Recorder {
    pub(crate) fn new() -> Recorder {
        Recorder {
            is_recording: false,
            recording: Recording {
                events: Vec::new()
            },
        }
    }

    pub(crate) fn is_recording(&self) -> bool {
        self.is_recording
    }

    pub(crate) fn toggle_recording(&mut self) {
        if !self.is_recording && !self.recording.events.is_empty() {
            self.clear_recording();
        } else if self.is_recording {
            let mut saw_undo = false;
            let mut saw_redo = false;

            // Walk the recording backwards and remove any undo / redo events
            let filtered: Vec<EventDomain> = self.recording.events.clone().into_iter()
                .rev()
                .filter(|event| {
                    if let EventDomain::Buffer(event) = event {
                        match event {
                            BufferEvent::Undo => {
                                saw_undo = !saw_redo;
                                saw_redo = false;
                                return false;
                            }
                            BufferEvent::Redo => {
                                saw_redo = !saw_undo;
                                saw_undo = false;
                                return false;
                            }
                            _ => {
                                let ret = !saw_undo;
                                saw_undo = false;
                                saw_redo = false;
                                return ret;
                            }
                        }
                    }

                    true
                })
                .collect();

            mem::replace(&mut self.recording.events, filtered);
        }

        self.is_recording = !self.is_recording;
    }

    pub(crate) fn record(&mut self, cmd: EventDomain) {
        if !self.is_recording {
            // We're not supposed to be recording? Can we log somehow?
            return;
        }

        self.recording.events.push(cmd.clone());
    }

    pub(crate) fn play<F>(&self, action: F)
        where F: FnMut(&EventDomain) -> () {
        self.recording.events.iter().for_each(action)
    }

    fn clear_recording(&mut self) {
        self.recording.events.clear();
    }
}

struct Recording {
    events: Vec<EventDomain>
}

#[cfg(test)]
mod tests {
    use recorder::Recorder;
    use edit_types::BufferEvent;

    #[test]
    fn undo_filtering_tests() {
        let mut recorder = Recorder::new();

        // Tests for filtering undo / redo from the recording buffer
        // A = Action
        // U = Undo
        // R = Redo

        // Undo removes last item, redo only affects undo
        // A U A R => A
        recorder.toggle_recording();
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Redo.into());
        recorder.toggle_recording();
        assert_eq!(recorder.recording.events, vec![BufferEvent::Transpose.into()]);

        recorder.clear_recording();

        // Swapping order shouldn't change the outcome
        // A R A U => A
        recorder.toggle_recording();
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Redo.into());
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.toggle_recording();
        assert_eq!(recorder.recording.events, vec![BufferEvent::Transpose.into()]);

        recorder.clear_recording();

        // Redo cancels out an undo
        // A U R A => A A
        recorder.toggle_recording();
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.record(BufferEvent::Redo.into());
        recorder.record(BufferEvent::Transpose.into());
        recorder.toggle_recording();
        assert_eq!(recorder.recording.events, vec![BufferEvent::Transpose.into(), BufferEvent::Transpose.into()]);

        recorder.clear_recording();

        // Undo should cancel a redo, preventing it from canceling another undo
        // A U R U => _
        recorder.toggle_recording();
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.record(BufferEvent::Redo.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.toggle_recording();
        assert_eq!(recorder.recording.events, vec![]);
    }
}<commit_msg>Fix tests for undo<commit_after>use std::mem;

use edit_types::{BufferEvent, EventDomain};

pub(crate) struct Recorder {
    is_recording: bool,
    recording: Recording,
}

impl Recorder {
    pub(crate) fn new() -> Recorder {
        Recorder {
            is_recording: false,
            recording: Recording {
                events: Vec::new()
            },
        }
    }

    pub(crate) fn is_recording(&self) -> bool {
        self.is_recording
    }

    pub(crate) fn toggle_recording(&mut self) {
        if !self.is_recording && !self.recording.events.is_empty() {
            self.recording.clear();
        } else if self.is_recording {
            self.recording.filter_undos();
        }

        self.is_recording = !self.is_recording;
    }

    pub(crate) fn record(&mut self, cmd: EventDomain) {
        if !self.is_recording {
            // We're not supposed to be recording? Can we log somehow?
            return;
        }

        self.recording.events.push(cmd);
    }

    pub(crate) fn play<F>(&self, action: F)
        where F: FnMut(&EventDomain) -> () {
        self.recording.play(action);
    }

    pub(crate) fn clear(&mut self) {
        self.recording.clear();
    }
}

struct Recording {
    events: Vec<EventDomain>
}

impl Recording {
    pub(crate) fn clear(&mut self) {
        self.events.clear();
    }

    pub(crate) fn play<F>(&self, action: F)
        where F: FnMut(&EventDomain) -> () {
        self.events.iter().for_each(action)
    }

    pub(crate) fn filter_undos(&mut self) {
        let mut saw_undo = false;
        let mut saw_redo = false;

        // Walk the recording backwards and remove any undo / redo events
        let filtered: Vec<EventDomain> = self.events.clone().into_iter()
            .rev()
            .filter(|event| {
                if let EventDomain::Buffer(event) = event {
                    return match event {
                        BufferEvent::Undo => {
                            saw_undo = !saw_redo;
                            saw_redo = false;
                            false
                        }
                        BufferEvent::Redo => {
                            saw_redo = !saw_undo;
                            saw_undo = false;
                            false
                        }
                        _ => {
                            let ret = !saw_undo;
                            saw_undo = false;
                            saw_redo = false;
                            ret
                        }
                    };
                }

                true
            })
            .collect::<Vec<EventDomain>>()
            .into_iter() // Why does rev().filter().rev().collect() cancel out the first rev()????
            .rev()
            .collect();

        mem::replace(&mut self.events, filtered);
    }
}

#[cfg(test)]
mod tests {
    use recorder::Recorder;
    use edit_types::BufferEvent;

    #[test]
    fn undo_filtering_tests() {
        let mut recorder = Recorder::new();

        // Tests for filtering undo / redo from the recording buffer
        // A = Event
        // B = Event
        // U = Undo
        // R = Redo

        // Undo removes last item, redo only affects undo
        // A U B R => B
        recorder.toggle_recording();
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.record(BufferEvent::DuplicateLine.into());
        recorder.record(BufferEvent::Redo.into());
        recorder.toggle_recording();
        assert_eq!(recorder.recording.events, vec![BufferEvent::DuplicateLine.into()]);

        recorder.clear();

        // Swapping order of undo and redo should give us a different leftover item
        // A R B U => A
        recorder.toggle_recording();
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Redo.into());
        recorder.record(BufferEvent::DuplicateLine.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.toggle_recording();
        assert_eq!(recorder.recording.events, vec![BufferEvent::Transpose.into()]);

        recorder.clear();

        // Redo cancels out an undo
        // A U R B => A B
        recorder.toggle_recording();
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.record(BufferEvent::Redo.into());
        recorder.record(BufferEvent::DuplicateLine.into());
        recorder.toggle_recording();
        assert_eq!(recorder.recording.events, vec![BufferEvent::Transpose.into(), BufferEvent::DuplicateLine.into()]);

        recorder.clear();

        // Undo should cancel a redo, preventing it from canceling another undo
        // A U R U => _
        recorder.toggle_recording();
        recorder.record(BufferEvent::Transpose.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.record(BufferEvent::Redo.into());
        recorder.record(BufferEvent::Undo.into());
        recorder.toggle_recording();
        assert_eq!(recorder.recording.events, vec![]);
    }
}<|endoftext|>


<commit_before>#[inline]
fn is_prime(n: u64) -> bool {
    if n <= 1 {
        return false;
    }

    if n <= 3 {
        return true;
    }

    if n % 2 == 0 || n % 3 == 0 {
        return false;
    }

    let mut i = 5;
    while i * i <= n {
        if n % i == 0 || n % (i + 2) == 0 {
            return false;
        }

        i += 6;
    }

    true
}

pub fn factors(number: u64) -> Vec<u64> {
    let mut p = 2;
    let mut v = number;
    let mut result = Vec::new();

    while p <= v {
        if !is_prime(p) || v % p != 0 {
            p += 1;
            continue;
        }

        v /= p;

        result.push(p);
    }

    result
}
<commit_msg>I found a simple one<commit_after>pub fn factors(number: u64) -> Vec<u64> {
    let mut i = 2;
    let mut cur = number;
    let mut result = Vec::new();

    while cur > 1 {
        if cur % i == 0 {
            result.push(i);

            cur /= i;
        } else {
            i += 1;
        }
    }

    result
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::io;
use std::net::Shutdown;
use std::rc::Rc;
use mio::Token;
use mio::net::TcpStream;
use mio::{Event, PollOpt, Ready};

use super::close_listener::CloseListener;
use super::ipv4_packet_buffer::IPv4PacketBuffer;
use super::selector::Selector;

const TAG: &'static str = "Client";

pub struct Client {
    id: u32,
    stream: TcpStream,
    client_to_network: IPv4PacketBuffer,
    closed: bool,
    close_listener: Box<CloseListener<Client>>,
    token: Token,
}

impl Client {
    pub fn new<C>(id: u32, selector: &mut Selector, stream: TcpStream, close_listener: C) -> io::Result<Rc<RefCell<Self>>>
            where C: CloseListener<Client> + 'static {
        let rc = Rc::new(RefCell::new(Self {
            id: id,
            stream: stream,
            client_to_network: IPv4PacketBuffer::new(),
            closed: false,
            close_listener: Box::new(close_listener),
            token: Token(0), // default value, will be set afterwards
        }));
        let rc_clone = rc.clone();
        let handler = move |selector: &mut Selector, ready| {
            let mut self_ref = rc_clone.borrow_mut();
            self_ref.on_ready(selector, ready);
        };
        {
            let mut self_ref = rc.borrow_mut();
            // on start, we are interested only in writing (we must first send the client id)
            let token = selector.register(&self_ref.stream, handler, Ready::writable(), PollOpt::level())?;
            self_ref.token = token;
        }
        Ok(rc)
    }

    pub fn get_id(&self) -> u32 {
        return self.id;
    }

    fn close(&mut self, selector: &mut Selector) {
        self.closed = true;
        selector.deregister(&self.stream, self.token);
        // shutdown only (there is no close), the socket will be closed on drop
        self.stream.shutdown(Shutdown::Both);
        // TODO router.clear();
        self.close_listener.on_closed(self);
    }

    fn process_send(&mut self, selector: &mut Selector) {

    }

    fn process_receive(&mut self, selector: &mut Selector) {
        match self.read() {
            Ok(_) => {}
            Err(_) => {
                error!(target: TAG, "Cannot read");
                self.close(selector);
            }
        }
    }

    fn update_interests(&mut self, selector: &mut Selector) {

    }

    fn read(&mut self) -> io::Result<()> {
        self.client_to_network.read_from(&mut self.stream)
    }

    fn on_ready(&mut self, selector: &mut Selector, event: Event) {
        assert!(!self.closed);
        let ready = event.readiness();
        if ready.is_writable() {
            self.process_send(selector);
        }
        if !self.closed && ready.is_readable() {
            self.process_receive(selector);
        }
        if !self.closed {
            self.update_interests(selector);
        }
    }
}
<commit_msg>Implement Client.push_to_network()<commit_after>use std::cell::RefCell;
use std::io;
use std::net::Shutdown;
use std::rc::Rc;
use mio::Token;
use mio::net::TcpStream;
use mio::{Event, PollOpt, Ready};

use super::close_listener::CloseListener;
use super::ipv4_packet_buffer::IPv4PacketBuffer;
use super::selector::Selector;

const TAG: &'static str = "Client";

pub struct Client {
    id: u32,
    stream: TcpStream,
    client_to_network: IPv4PacketBuffer,
    closed: bool,
    close_listener: Box<CloseListener<Client>>,
    token: Token,
}

impl Client {
    pub fn new<C>(id: u32, selector: &mut Selector, stream: TcpStream, close_listener: C) -> io::Result<Rc<RefCell<Self>>>
            where C: CloseListener<Client> + 'static {
        let rc = Rc::new(RefCell::new(Self {
            id: id,
            stream: stream,
            client_to_network: IPv4PacketBuffer::new(),
            closed: false,
            close_listener: Box::new(close_listener),
            token: Token(0), // default value, will be set afterwards
        }));
        let rc_clone = rc.clone();
        let handler = move |selector: &mut Selector, ready| {
            let mut self_ref = rc_clone.borrow_mut();
            self_ref.on_ready(selector, ready);
        };
        {
            let mut self_ref = rc.borrow_mut();
            // on start, we are interested only in writing (we must first send the client id)
            let token = selector.register(&self_ref.stream, handler, Ready::writable(), PollOpt::level())?;
            self_ref.token = token;
        }
        Ok(rc)
    }

    pub fn get_id(&self) -> u32 {
        return self.id;
    }

    fn close(&mut self, selector: &mut Selector) {
        self.closed = true;
        selector.deregister(&self.stream, self.token);
        // shutdown only (there is no close), the socket will be closed on drop
        self.stream.shutdown(Shutdown::Both);
        // TODO router.clear();
        self.close_listener.on_closed(self);
    }

    fn process_send(&mut self, selector: &mut Selector) {

    }

    fn process_receive(&mut self, selector: &mut Selector) {
        match self.read() {
            Ok(_) => self.push_to_network(),
            Err(_) => {
                error!(target: TAG, "Cannot read");
                self.close(selector);
            }
        }
    }

    fn update_interests(&mut self, selector: &mut Selector) {

    }

    fn read(&mut self) -> io::Result<()> {
        self.client_to_network.read_from(&mut self.stream)
    }

    fn write(&mut self) -> io::Result<()> {
        // TODO
        Ok(())
    }

    fn push_to_network(&mut self) {
        while self.push_one_packet_to_network() {
            self.client_to_network.next();
        }
    }

    fn push_one_packet_to_network(&mut self) -> bool {
        match self.client_to_network.as_ipv4_packet() {
            Some(ref packet) => {
                // router.send_to_network(packet);
                true
            },
            None => false
        }
    }

    fn on_ready(&mut self, selector: &mut Selector, event: Event) {
        assert!(!self.closed);
        let ready = event.readiness();
        if ready.is_writable() {
            self.process_send(selector);
        }
        if !self.closed && ready.is_readable() {
            self.process_receive(selector);
        }
        if !self.closed {
            self.update_interests(selector);
        }
    }
}
<|endoftext|>


<commit_before>use std::sync::Arc;
use error::Error;

use super::{Request, Response, IronResult};

/// `Handler`s are responsible for handling requests by creating Responses from Requests.
///
/// By default, bare functions and variants of Chain implement `Handler`.
///
/// `Handler`s are allowed to return errors, and if they do, their `catch` method is called and the
/// error is propagated to `AfterMiddleware`.
pub trait Handler: Send + Sync {
    /// Produce a `Response` from a Request, with the possibility of error.
    ///
    /// If this returns an Err, `catch` is called with the error.
    fn call(&self, &mut Request) -> IronResult<Response>;

    /// If `Handler`'s call method produces an Err, then this method is called
    /// to produce a `Response` and possibly handle the error.
    ///
    /// If the passed-in error is not handled, it should be returned as the second
    /// item in the returned tuple. If it is handled, then `Ok(())` can be returned
    /// instead to indicate that all is good with the Response.
    fn catch(&self, &mut Request, Box<Error>) -> (Response, IronResult<()>);
}

/// `BeforeMiddleware` are fired before a `Handler` is called inside of a Chain.
///
/// `BeforeMiddleware` are responsible for doing request pre-processing that requires
/// the ability to change control-flow, such as authorization middleware, or for editing
/// the request by modifying the headers.
///
/// `BeforeMiddleware` only have access to the Request, if you need to modify or read a Response,
/// you will need `AfterMiddleware`.
pub trait BeforeMiddleware: Send + Sync {
    /// Do whatever work this middleware should do with a `Request` object.
    ///
    /// An error here is propagated by the containing Chain to, first, this Middleware's
    /// `catch` method, then every subsequent `BeforeMiddleware`'s `catch` methods until one returns
    /// Ok(()) or the Chain's `Handler` is reached, at which point the `Handler`'s `catch` method is
    /// called to produce an error Response.
    fn before(&self, &mut Request) -> IronResult<()>;

    /// Try to `catch` an error thrown by this Middleware or a previous `BeforeMiddleware`.
    ///
    /// Should only return Ok(()) if the error has been completely handled and a Chain
    /// can proceed as normal.
    fn catch(&self, _: &mut Request, err: Box<Error>) -> IronResult<()> {
        Err(err)
    }
}

/// `AfterMiddleware` are fired after a `Handler` is called inside of a Chain.
///
/// `AfterMiddleware` receive both a `Request` and a `Response` and are responsible for doing
/// any response-post-processing.
///
/// `AfterMiddleware` should *not* usually overwrite the contents of a Response. In
/// the common case, a complete response is generated by the Chain's `Handler` and
/// `AfterMiddleware` simply do post-processing of that Response, such as
/// adding headers or logging.
pub trait AfterMiddleware: Send + Sync {
    /// Do whatever work this middleware needs to do with both a `Request` and `Response` objects.
    ///
    /// An error here is propagated by the containing Chain down to this and any later
    /// `AfterMiddleware`'s `catch` methods, which can attempt to handle the error or modify
    /// the `Response` to indicate to a client that something went wrong.
    fn after(&self, &mut Request, &mut Response) -> IronResult<()>;

    /// Try to catch an error thrown by previous `AfterMiddleware`, the `Handler`, or a previous
    /// `BeforeMiddleware`.
    ///
    /// The response was generated by the `catch` function of `Handler`s and is abnormal or
    /// errored in some way.
    fn catch(&self, _: &mut Request, _: &mut Response, err: Box<Error>) -> IronResult<()> {
        Err(err)
    }
}

/// AroundMiddleware are used to wrap and replace the `Handler` in a Chain.
///
/// AroundMiddleware must themselves be `Handler`s, and can integrate an existing
/// `Handler` through the around method, which is called once on insertion
/// into a Chain.
pub trait AroundMiddleware: Handler {
    /// Incorporate another `Handler` into this AroundMiddleware.
    ///
    /// Usually this means wrapping the handler and editing the `Request` on the
    /// way in and the `Response` on the way out.
    fn around(&mut self, handler: Box<Handler + Send + Sync>);
}

pub trait Chain: Handler {
    fn new<H: Handler>(H) -> Self;

    fn link<B, A>(&mut self, (B, A)) where A: AfterMiddleware, B: BeforeMiddleware;

    fn link_before<B>(&mut self, B) where B: BeforeMiddleware;

    fn link_after<A>(&mut self, A) where A: AfterMiddleware;

    fn around<A>(&mut self, A) where A: AroundMiddleware;
}

pub struct ChainBuilder {
    befores: Vec<Box<BeforeMiddleware + Send + Sync>>,
    afters: Vec<Box<AfterMiddleware + Send + Sync>>,
    handler: Box<Handler + Send + Sync>
}

impl Chain for ChainBuilder {
    fn new<H: Handler>(handler: H) -> ChainBuilder {
        ChainBuilder {
            befores: vec![],
            afters: vec![],
            handler: box handler as Box<Handler + Send + Sync>
        }
    }

    fn link<B, A>(&mut self, link: (B, A))
    where A: AfterMiddleware, B: BeforeMiddleware {
        let (before, after) = link;
        self.befores.push(box before as Box<BeforeMiddleware + Send + Sync>);
        self.afters.push(box after as Box<AfterMiddleware + Send + Sync>);
    }

    fn link_before<B>(&mut self, before: B) where B: BeforeMiddleware {
        self.befores.push(box before as Box<BeforeMiddleware + Send + Sync>);
    }

    fn link_after<A>(&mut self, after: A) where A: AfterMiddleware {
        self.afters.push(box after as Box<AfterMiddleware + Send + Sync>);
    }

    fn around<A>(&mut self, mut around: A) where A: AroundMiddleware {
        use std::mem;

        let old = mem::replace(&mut self.handler, box Nop as Box<Handler + Send + Sync>);
        around.around(old);
        self.handler = box around as Box<Handler + Send + Sync>;
    }
}

impl Handler for ChainBuilder {
    fn call(&self, req: &mut Request) -> IronResult<Response> {
        let before_result = helpers::run_befores(req, self.befores.as_slice(), None);

        let (res, err) = match before_result {
            Ok(()) => match self.handler.call(req) {
                Ok(res) => (res, None),
                Err(e) => helpers::run_handler_catch(req, e, &self.handler)
            },
            Err(e) => helpers::run_handler_catch(req, e, &self.handler)
        };

        helpers::run_afters(req, res, err, self.afters.as_slice())
    }

    fn catch(&self, req: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        let before_result = helpers::run_befores(req, self.befores.as_slice(), Some(err));

        let (res, err) = match before_result {
            Ok(()) => match self.handler.call(req) {
                Ok(res) => (res, None),
                Err(e) => helpers::run_handler_catch(req, e, &self.handler)
            },
            Err(e) => helpers::run_handler_catch(req, e, &self.handler)
        };

        match helpers::run_afters(req, res, err, self.afters.as_slice()) {
            Ok(res) => (res, Ok(())),
            // FIXME: Make 500
            Err(err) => (Response::new(), Err(err))
        }
    }
}

impl Handler for fn(&mut Request) -> IronResult<Response> {
    fn call(&self, req: &mut Request) -> IronResult<Response> {
        self.call(req)
    }

    fn catch(&self, _: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        // FIXME: Make Response a 500
        (Response::new(), Err(err))
    }
}

pub struct Nop;

impl Handler for Nop {
    fn call(&self, _: &mut Request) -> IronResult<Response> {
        Ok(Response::new())
    }

    fn catch(&self, _: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        // FIXME: Make Response a 500
        (Response::new(), Err(err))
    }
}

impl Handler for Box<Handler + Send + Sync> {
    fn call(&self, req: &mut Request) -> IronResult<Response> {
        self.call(req)
    }

    fn catch(&self, req: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        self.catch(req, err)
    }
}

impl Handler for Arc<Box<Handler + Send + Sync>> {
    fn call(&self, req: &mut Request) -> IronResult<Response> {
        self.call(req)
    }

    fn catch(&self, req: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        self.catch(req, err)
    }
}

mod helpers {
    use super::super::{Request, Response, IronResult};
    use super::{AfterMiddleware, BeforeMiddleware, Handler};
    use error::Error;

    pub fn run_befores(req: &mut Request, befores: &[Box<BeforeMiddleware>], err: Option<Box<Error>>) -> IronResult<()> {
        match err {
            Some(mut e) => {
                for (i, before) in befores.iter().enumerate() {
                    match before.catch(req, e) {
                        Ok(_) => return run_befores(req, befores, None),
                        Err(new) => e = new
                    }
                }
                Err(e)
            },

            None => {
                for (i, before) in befores.iter().enumerate() {
                    match before.before(req) {
                        Ok(_) => (),
                        Err(err) => return run_befores(req, befores.slice_from(i), Some(err))
                    }
                }
                Ok(())
            }
        }
    }

    pub fn run_afters(req: &mut Request, mut res: Response, err: Option<Box<Error>>,
                  afters: &[Box<AfterMiddleware>]) -> IronResult<Response> {
        match err {
            Some(mut e) => {
                for (i, after) in afters.iter().enumerate() {
                    match after.catch(req, &mut res, e) {
                        Ok(_) => return run_afters(req, res, None, afters),
                        Err(new) => e = new
                    }
                }
                Err(e)
            },

            None => {
                for (i, after) in afters.iter().enumerate() {
                    match after.after(req, &mut res) {
                        Ok(_) => (),
                        Err(err) => return run_afters(req, res, Some(err), afters.slice_from(i))
                    }
                }
                Ok(res)
            }
        }
    }

    pub fn run_handler_catch(req: &mut Request, err: Box<Error>,
                         handler: &Box<Handler>) -> (Response, Option<Box<Error>>) {
        match handler.catch(req, err) {
            (res, Ok(())) => (res, None),
            (res, Err(e)) => (res, Some(e))
        }
    }
}

<commit_msg>(doc) Documented Chain and ChainBuilder.<commit_after>use std::sync::Arc;
use error::Error;

use super::{Request, Response, IronResult};

/// `Handler`s are responsible for handling requests by creating Responses from Requests.
///
/// By default, bare functions and variants of Chain implement `Handler`.
///
/// `Handler`s are allowed to return errors, and if they do, their `catch` method is called and the
/// error is propagated to `AfterMiddleware`.
pub trait Handler: Send + Sync {
    /// Produce a `Response` from a Request, with the possibility of error.
    ///
    /// If this returns an Err, `catch` is called with the error.
    fn call(&self, &mut Request) -> IronResult<Response>;

    /// If `Handler`'s call method produces an Err, then this method is called
    /// to produce a `Response` and possibly handle the error.
    ///
    /// If the passed-in error is not handled, it should be returned as the second
    /// item in the returned tuple. If it is handled, then `Ok(())` can be returned
    /// instead to indicate that all is good with the Response.
    fn catch(&self, &mut Request, Box<Error>) -> (Response, IronResult<()>);
}

/// `BeforeMiddleware` are fired before a `Handler` is called inside of a Chain.
///
/// `BeforeMiddleware` are responsible for doing request pre-processing that requires
/// the ability to change control-flow, such as authorization middleware, or for editing
/// the request by modifying the headers.
///
/// `BeforeMiddleware` only have access to the Request, if you need to modify or read a Response,
/// you will need `AfterMiddleware`.
pub trait BeforeMiddleware: Send + Sync {
    /// Do whatever work this middleware should do with a `Request` object.
    ///
    /// An error here is propagated by the containing Chain to, first, this Middleware's
    /// `catch` method, then every subsequent `BeforeMiddleware`'s `catch` methods until one returns
    /// Ok(()) or the Chain's `Handler` is reached, at which point the `Handler`'s `catch` method is
    /// called to produce an error Response.
    fn before(&self, &mut Request) -> IronResult<()>;

    /// Try to `catch` an error thrown by this Middleware or a previous `BeforeMiddleware`.
    ///
    /// Should only return Ok(()) if the error has been completely handled and a Chain
    /// can proceed as normal.
    fn catch(&self, _: &mut Request, err: Box<Error>) -> IronResult<()> {
        Err(err)
    }
}

/// `AfterMiddleware` are fired after a `Handler` is called inside of a Chain.
///
/// `AfterMiddleware` receive both a `Request` and a `Response` and are responsible for doing
/// any response-post-processing.
///
/// `AfterMiddleware` should *not* usually overwrite the contents of a Response. In
/// the common case, a complete response is generated by the Chain's `Handler` and
/// `AfterMiddleware` simply do post-processing of that Response, such as
/// adding headers or logging.
pub trait AfterMiddleware: Send + Sync {
    /// Do whatever work this middleware needs to do with both a `Request` and `Response` objects.
    ///
    /// An error here is propagated by the containing Chain down to this and any later
    /// `AfterMiddleware`'s `catch` methods, which can attempt to handle the error or modify
    /// the `Response` to indicate to a client that something went wrong.
    fn after(&self, &mut Request, &mut Response) -> IronResult<()>;

    /// Try to catch an error thrown by previous `AfterMiddleware`, the `Handler`, or a previous
    /// `BeforeMiddleware`.
    ///
    /// The response was generated by the `catch` function of `Handler`s and is abnormal or
    /// errored in some way.
    fn catch(&self, _: &mut Request, _: &mut Response, err: Box<Error>) -> IronResult<()> {
        Err(err)
    }
}

/// AroundMiddleware are used to wrap and replace the `Handler` in a Chain.
///
/// AroundMiddleware must themselves be `Handler`s, and can integrate an existing
/// `Handler` through the around method, which is called once on insertion
/// into a Chain.
pub trait AroundMiddleware: Handler {
    /// Incorporate another `Handler` into this AroundMiddleware.
    ///
    /// Usually this means wrapping the handler and editing the `Request` on the
    /// way in and the `Response` on the way out.
    fn around(&mut self, handler: Box<Handler + Send + Sync>);
}

/// Chain's hold `BeforeMiddleware`, a `Handler`, and `AfterMiddleware` and are responsible
/// for correctly dispatching a `Request` through them.
///
/// Chain's are handlers, and most of their work is done in the call method of their
/// `Handler` implementation.
pub trait Chain: Handler {
    /// Create a new Chain from a `Handler`.
    fn new<H: Handler>(H) -> Self;

    /// Link both a before and after middleware to the chain at once.
    ///
    /// Middleware that have a Before and After piece should have a constructor
    /// which returns both as a tuple, so it can be passed directly to link.
    fn link<B, A>(&mut self, (B, A)) where A: AfterMiddleware, B: BeforeMiddleware;

    /// Link a `BeforeMiddleware` to the Chain.
    fn link_before<B>(&mut self, B) where B: BeforeMiddleware;

    /// Link a `AfterMiddleware` to the Chain.
    fn link_after<A>(&mut self, A) where A: AfterMiddleware;

    /// Wrap the Chain's `Handler` using an AroundMiddleware.
    fn around<A>(&mut self, A) where A: AroundMiddleware;
}

/// The default Chain used in Iron.
///
/// For almost all intents and purposes, this is synonymous with the
/// Chain trait and is the canonical implementation. However, Chain
/// is left as a trait for future interoperability with other
/// frameworks.
pub struct ChainBuilder {
    befores: Vec<Box<BeforeMiddleware + Send + Sync>>,
    afters: Vec<Box<AfterMiddleware + Send + Sync>>,
    handler: Box<Handler + Send + Sync>
}

impl ChainBuilder {
    /// Construct a new ChainBuilder from a `Handler`.
    pub fn new<H: Handler>(handler: H) -> ChainBuilder {
        ChainBuilder {
            befores: vec![],
            afters: vec![],
            handler: box handler as Box<Handler + Send + Sync>
        }
    }
}

impl Chain for ChainBuilder {
    fn new<H: Handler>(handler: H) -> ChainBuilder {
        ChainBuilder {
            befores: vec![],
            afters: vec![],
            handler: box handler as Box<Handler + Send + Sync>
        }
    }

    fn link<B, A>(&mut self, link: (B, A))
    where A: AfterMiddleware, B: BeforeMiddleware {
        let (before, after) = link;
        self.befores.push(box before as Box<BeforeMiddleware + Send + Sync>);
        self.afters.push(box after as Box<AfterMiddleware + Send + Sync>);
    }

    fn link_before<B>(&mut self, before: B) where B: BeforeMiddleware {
        self.befores.push(box before as Box<BeforeMiddleware + Send + Sync>);
    }

    fn link_after<A>(&mut self, after: A) where A: AfterMiddleware {
        self.afters.push(box after as Box<AfterMiddleware + Send + Sync>);
    }

    fn around<A>(&mut self, mut around: A) where A: AroundMiddleware {
        use std::mem;

        let old = mem::replace(&mut self.handler, box Nop as Box<Handler + Send + Sync>);
        around.around(old);
        self.handler = box around as Box<Handler + Send + Sync>;
    }
}

impl Handler for ChainBuilder {
    fn call(&self, req: &mut Request) -> IronResult<Response> {
        let before_result = helpers::run_befores(req, self.befores.as_slice(), None);

        let (res, err) = match before_result {
            Ok(()) => match self.handler.call(req) {
                Ok(res) => (res, None),
                Err(e) => helpers::run_handler_catch(req, e, &self.handler)
            },
            Err(e) => helpers::run_handler_catch(req, e, &self.handler)
        };

        helpers::run_afters(req, res, err, self.afters.as_slice())
    }

    fn catch(&self, req: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        let before_result = helpers::run_befores(req, self.befores.as_slice(), Some(err));

        let (res, err) = match before_result {
            Ok(()) => match self.handler.call(req) {
                Ok(res) => (res, None),
                Err(e) => helpers::run_handler_catch(req, e, &self.handler)
            },
            Err(e) => helpers::run_handler_catch(req, e, &self.handler)
        };

        match helpers::run_afters(req, res, err, self.afters.as_slice()) {
            Ok(res) => (res, Ok(())),
            // FIXME: Make 500
            Err(err) => (Response::new(), Err(err))
        }
    }
}

impl Handler for fn(&mut Request) -> IronResult<Response> {
    fn call(&self, req: &mut Request) -> IronResult<Response> {
        self.call(req)
    }

    fn catch(&self, _: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        // FIXME: Make Response a 500
        (Response::new(), Err(err))
    }
}

pub struct Nop;

impl Handler for Nop {
    fn call(&self, _: &mut Request) -> IronResult<Response> {
        Ok(Response::new())
    }

    fn catch(&self, _: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        // FIXME: Make Response a 500
        (Response::new(), Err(err))
    }
}

impl Handler for Box<Handler + Send + Sync> {
    fn call(&self, req: &mut Request) -> IronResult<Response> {
        self.call(req)
    }

    fn catch(&self, req: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        self.catch(req, err)
    }
}

impl Handler for Arc<Box<Handler + Send + Sync>> {
    fn call(&self, req: &mut Request) -> IronResult<Response> {
        self.call(req)
    }

    fn catch(&self, req: &mut Request, err: Box<Error>) -> (Response, IronResult<()>) {
        self.catch(req, err)
    }
}

mod helpers {
    use super::super::{Request, Response, IronResult};
    use super::{AfterMiddleware, BeforeMiddleware, Handler};
    use error::Error;

    pub fn run_befores(req: &mut Request, befores: &[Box<BeforeMiddleware>], err: Option<Box<Error>>) -> IronResult<()> {
        match err {
            Some(mut e) => {
                for (i, before) in befores.iter().enumerate() {
                    match before.catch(req, e) {
                        Ok(_) => return run_befores(req, befores, None),
                        Err(new) => e = new
                    }
                }
                Err(e)
            },

            None => {
                for (i, before) in befores.iter().enumerate() {
                    match before.before(req) {
                        Ok(_) => (),
                        Err(err) => return run_befores(req, befores.slice_from(i), Some(err))
                    }
                }
                Ok(())
            }
        }
    }

    pub fn run_afters(req: &mut Request, mut res: Response, err: Option<Box<Error>>,
                  afters: &[Box<AfterMiddleware>]) -> IronResult<Response> {
        match err {
            Some(mut e) => {
                for (i, after) in afters.iter().enumerate() {
                    match after.catch(req, &mut res, e) {
                        Ok(_) => return run_afters(req, res, None, afters),
                        Err(new) => e = new
                    }
                }
                Err(e)
            },

            None => {
                for (i, after) in afters.iter().enumerate() {
                    match after.after(req, &mut res) {
                        Ok(_) => (),
                        Err(err) => return run_afters(req, res, Some(err), afters.slice_from(i))
                    }
                }
                Ok(res)
            }
        }
    }

    pub fn run_handler_catch(req: &mut Request, err: Box<Error>,
                         handler: &Box<Handler>) -> (Response, Option<Box<Error>>) {
        match handler.catch(req, err) {
            (res, Ok(())) => (res, None),
            (res, Err(e)) => (res, Some(e))
        }
    }
}

<|endoftext|>


<commit_before>use std::str::FromStr;
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::result::Result;
use std::sync::RwLock;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap};
use iron::modifier::Modifier;
use plugin::Plugin as PluginFor;
use iron::headers::ContentType;
use walker::Walker;

use handlebars::Handlebars;
use serialize::json::{ToJson, Json};

#[derive(Clone)]
pub struct Template {
    name: String,
    value: Json
}

impl Template {
    pub fn new<T: ToJson>(name: &str, value: T) -> Template {
        Template {
            name: name.to_string(),
            value: value.to_json()
        }
    }
}

pub struct HandlebarsEngine {
    pub prefix: String,
    pub suffix: String,
    pub registry: RwLock<Box<Handlebars>>
}

impl typemap::Key for HandlebarsEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<HandlebarsEngine>(self);
    }
}

impl PluginFor<Response> for HandlebarsEngine {
    type Error = ();

    fn eval(resp: &mut Response) -> Result<Template, ()> {
        match resp.extensions.get::<HandlebarsEngine>(){
            Some(t) => Ok(t.clone()),
            None => Err(())
        }
    }
}

impl HandlebarsEngine {
    pub fn reload(&self) {
        let mut prefix_slash = self.prefix.clone();
        let suffix: &str = self.suffix.as_ref();
        let mut hbs = self.registry.write().unwrap();

        let normalized_prefix = if self.prefix.ends_with("/") {
            prefix_slash
        } else {
            prefix_slash.push('/');
            prefix_slash
        };
        let prefix_path = Path::new(&normalized_prefix);
        let walker = Walker::new(prefix_path);
        if !walker.is_ok() {
            panic!(format!("Failed to list directory: {}", normalized_prefix));
        }

        hbs.clear_templates();
        for p in walker.ok().unwrap().filter_map(Result::ok) {
            let path = p.path();
            let disp = path.to_str().unwrap();
            if disp.ends_with(suffix) {
                if let Ok(mut file) = File::open(&path) {
                    let mut buf = String::new();
                    if let Ok(_) = file.read_to_string(&mut buf) {
                        if let Err(e) = hbs.register_template_string(
                            &disp[normalized_prefix.len() .. disp.len()-suffix.len()], buf){
                            println!("Failed to parse template {}", e);
                        }
                    } else {
                        println!("Failed to read file {}, skipped", disp);
                    }
                } else {
                    println!("Failed to open file {}, skipped.", disp);
                }
            }
        }
    }

    pub fn new(prefix: &str, suffix: &str) -> HandlebarsEngine {
        let eng = HandlebarsEngine {
            prefix: prefix.to_string(),
            suffix: suffix.to_string(),
            registry: RwLock::new(Box::new(Handlebars::new()))
        };
        eng.reload();
        eng
    }
}

impl AfterMiddleware for HandlebarsEngine {
    fn after(&self, _: &mut Request, r: Response) -> IronResult<Response> {
        let mut resp = r;
        // internally we still extensions.get to avoid clone
        let page = match resp.extensions.get::<HandlebarsEngine>() {
            Some(ref h) => {
                let name = &h.name;
                let value = &h.value;
                let hbs = self.registry.read().unwrap();
                let rendered = hbs.render(name.as_ref(), value);
                match rendered {
                    Ok(r) => Some(r),
                    Err(_) => None
                }
            },
            None => {
                None
            }
        };

        if page.is_some() {
            if !resp.headers.has::<ContentType>() {
                resp.headers.set(ContentType(FromStr::from_str("text/html;charset=utf-8").unwrap()));
            }
            resp.set_mut(page.unwrap());
        }

        Ok(resp)
    }
}

#[cfg(test)]
mod test {
    use serialize::json::ToJson;
    use std::collections::BTreeMap;
    use iron::prelude::*;
    use middleware::*;
    use handlebars::{Handlebars, RenderError, RenderContext, Helper, Context};

    fn hello_world() -> IronResult<Response> {
        let resp = Response::new();

        let mut data = BTreeMap::new();
        data.insert("title".to_string(), "Handlebars on Iron".to_json());

        Ok(resp.set(Template::new("index", data)))
    }

    #[test]
    fn test_resp_set() {
        let mut resp = hello_world().ok().expect("response expected");

        // use response plugin to retrieve a cloned template for testing
        match resp.get::<HandlebarsEngine>() {
            Ok(h) => {
                assert_eq!(h.name, "index".to_string());
                assert_eq!(h.value.as_object().unwrap()
                           .get(&"title".to_string()).unwrap()
                           .as_string().unwrap(),
                           "Handlebars on Iron");
            },
            _ => panic!("template expected")
        }
    }

    #[test]
    fn test_register_helper() {
        let hbs = HandlebarsEngine::new("./examples/templates", ".hbs");
        let mut reg = hbs.registry.write().unwrap();
        reg.register_helper("ignore", Box::new(|_: &Context, _: &Helper, _: &Handlebars, _: &mut RenderContext| -> Result<String, RenderError> {
            Ok("".to_string())
        }));
    }
}
<commit_msg>(feat) Implemented HandlebarsEngine::from() for support construct HandlebarsEngine with custom Handlebars structure.<commit_after>use std::str::FromStr;
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::result::Result;
use std::sync::RwLock;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap};
use iron::modifier::Modifier;
use plugin::Plugin as PluginFor;
use iron::headers::ContentType;
use walker::Walker;

use handlebars::Handlebars;
use serialize::json::{ToJson, Json};

#[derive(Clone)]
pub struct Template {
    name: String,
    value: Json
}

impl Template {
    pub fn new<T: ToJson>(name: &str, value: T) -> Template {
        Template {
            name: name.to_string(),
            value: value.to_json()
        }
    }
}

pub struct HandlebarsEngine {
    pub prefix: String,
    pub suffix: String,
    pub registry: RwLock<Box<Handlebars>>
}

impl typemap::Key for HandlebarsEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<HandlebarsEngine>(self);
    }
}

impl PluginFor<Response> for HandlebarsEngine {
    type Error = ();

    fn eval(resp: &mut Response) -> Result<Template, ()> {
        match resp.extensions.get::<HandlebarsEngine>(){
            Some(t) => Ok(t.clone()),
            None => Err(())
        }
    }
}

impl HandlebarsEngine {
    pub fn reload(&self) {
        let mut prefix_slash = self.prefix.clone();
        let suffix: &str = self.suffix.as_ref();
        let mut hbs = self.registry.write().unwrap();

        let normalized_prefix = if self.prefix.ends_with("/") {
            prefix_slash
        } else {
            prefix_slash.push('/');
            prefix_slash
        };
        let prefix_path = Path::new(&normalized_prefix);
        let walker = Walker::new(prefix_path);
        if !walker.is_ok() {
            panic!(format!("Failed to list directory: {}", normalized_prefix));
        }

        hbs.clear_templates();
        for p in walker.ok().unwrap().filter_map(Result::ok) {
            let path = p.path();
            let disp = path.to_str().unwrap();
            if disp.ends_with(suffix) {
                if let Ok(mut file) = File::open(&path) {
                    let mut buf = String::new();
                    if let Ok(_) = file.read_to_string(&mut buf) {
                        if let Err(e) = hbs.register_template_string(
                            &disp[normalized_prefix.len() .. disp.len()-suffix.len()], buf){
                            println!("Failed to parse template {}", e);
                        }
                    } else {
                        println!("Failed to read file {}, skipped", disp);
                    }
                } else {
                    println!("Failed to open file {}, skipped.", disp);
                }
            }
        }
    }

    pub fn from(prefix: &str, suffix: &str, custom: Handlebars) -> HandlebarsEngine {
        let eng = HandlebarsEngine {
            prefix: prefix.to_string(),
            suffix: suffix.to_string(),
            registry: RwLock::new(Box::new(custom))
        };
        eng.reload();
        eng
    }

    pub fn new(prefix: &str, suffix: &str) -> HandlebarsEngine {
        HandlebarsEngine::from(prefix,suffix, Handlebars::new())
    }
}

impl AfterMiddleware for HandlebarsEngine {
    fn after(&self, _: &mut Request, r: Response) -> IronResult<Response> {
        let mut resp = r;
        // internally we still extensions.get to avoid clone
        let page = match resp.extensions.get::<HandlebarsEngine>() {
            Some(ref h) => {
                let name = &h.name;
                let value = &h.value;
                let hbs = self.registry.read().unwrap();
                let rendered = hbs.render(name.as_ref(), value);
                match rendered {
                    Ok(r) => Some(r),
                    Err(_) => None
                }
            },
            None => {
                None
            }
        };

        if page.is_some() {
            if !resp.headers.has::<ContentType>() {
                resp.headers.set(ContentType(FromStr::from_str("text/html;charset=utf-8").unwrap()));
            }
            resp.set_mut(page.unwrap());
        }

        Ok(resp)
    }
}

#[cfg(test)]
mod test {
    use serialize::json::ToJson;
    use std::collections::BTreeMap;
    use iron::prelude::*;
    use middleware::*;
    use handlebars::{Handlebars, RenderError, RenderContext, Helper, Context};

    fn hello_world() -> IronResult<Response> {
        let resp = Response::new();

        let mut data = BTreeMap::new();
        data.insert("title".to_string(), "Handlebars on Iron".to_json());

        Ok(resp.set(Template::new("index", data)))
    }

    #[test]
    fn test_resp_set() {
        let mut resp = hello_world().ok().expect("response expected");

        // use response plugin to retrieve a cloned template for testing
        match resp.get::<HandlebarsEngine>() {
            Ok(h) => {
                assert_eq!(h.name, "index".to_string());
                assert_eq!(h.value.as_object().unwrap()
                           .get(&"title".to_string()).unwrap()
                           .as_string().unwrap(),
                           "Handlebars on Iron");
            },
            _ => panic!("template expected")
        }
    }

    #[test]
    fn test_register_helper() {
        let hbs = HandlebarsEngine::new("./examples/templates", ".hbs");
        let mut reg = hbs.registry.write().unwrap();
        reg.register_helper("ignore", Box::new(|_: &Context, _: &Helper, _: &Handlebars, _: &mut RenderContext| -> Result<String, RenderError> {
            Ok("".to_string())
        }));
    }
}
<|endoftext|>


<commit_before>//! Intermediate representation for the physical layout of some type.

use super::derive::{CanTriviallyDeriveCopy, CanTriviallyDeriveDebug,
                    CanTriviallyDeriveDefault, CanTriviallyDeriveHash,
                    CanTriviallyDerivePartialEqOrPartialOrd};
use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind};
use clang;
use std::{cmp, mem};

/// A type that represents the struct layout of a type.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Layout {
    /// The size (in bytes) of this layout.
    pub size: usize,
    /// The alignment (in bytes) of this layout.
    pub align: usize,
    /// Whether this layout's members are packed or not.
    pub packed: bool,
}

#[test]
fn test_layout_for_size() {
    let ptr_size = mem::size_of::<*mut ()>();
    assert_eq!(Layout::for_size(ptr_size), Layout::new(ptr_size, ptr_size));
    assert_eq!(
        Layout::for_size(3 * ptr_size),
        Layout::new(3 * ptr_size, ptr_size)
    );
}

impl Layout {
    /// Construct a new `Layout` with the given `size` and `align`. It is not
    /// packed.
    pub fn new(size: usize, align: usize) -> Self {
        Layout {
            size: size,
            align: align,
            packed: false,
        }
    }

    /// Creates a non-packed layout for a given size, trying to use the maximum
    /// alignment possible.
    pub fn for_size(size: usize) -> Self {
        let mut next_align = 2;
        while size % next_align == 0 &&
            next_align <= mem::size_of::<*mut ()>()
        {
            next_align *= 2;
        }
        Layout {
            size: size,
            align: next_align / 2,
            packed: false,
        }
    }

    /// Is this a zero-sized layout?
    pub fn is_zero(&self) -> bool {
        self.size == 0 && self.align == 0
    }

    /// Construct a zero-sized layout.
    pub fn zero() -> Self {
        Self::new(0, 0)
    }

    /// Get this layout as an opaque type.
    pub fn opaque(&self) -> Opaque {
        Opaque(*self)
    }
}

/// When we are treating a type as opaque, it is just a blob with a `Layout`.
#[derive(Clone, Debug, PartialEq)]
pub struct Opaque(pub Layout);

impl Opaque {
    /// Construct a new opaque type from the given clang type.
    pub fn from_clang_ty(ty: &clang::Type) -> Type {
        let layout = Layout::new(ty.size(), ty.align());
        let ty_kind = TypeKind::Opaque;
        Type::new(None, Some(layout), ty_kind, false)
    }

    /// Return the known rust type we should use to create a correctly-aligned
    /// field with this layout.
    pub fn known_rust_type_for_array(&self) -> Option<&'static str> {
        Some(match self.0.align {
            8 => "u64",
            4 => "u32",
            2 => "u16",
            1 => "u8",
            _ => return None,
        })
    }

    /// Return the array size that an opaque type for this layout should have if
    /// we know the correct type for it, or `None` otherwise.
    pub fn array_size(&self) -> Option<usize> {
        if self.known_rust_type_for_array().is_some() {
            Some(self.0.size / cmp::max(self.0.align, 1))
        } else {
            None
        }
    }
}

impl CanTriviallyDeriveDebug for Opaque {
    fn can_trivially_derive_debug(&self) -> bool {
        self.array_size().map_or(false, |size| {
            size <= RUST_DERIVE_IN_ARRAY_LIMIT
        })
    }
}

impl CanTriviallyDeriveDefault for Opaque {
    fn can_trivially_derive_default(&self) -> bool {
        self.array_size().map_or(false, |size| {
            size <= RUST_DERIVE_IN_ARRAY_LIMIT
        })
    }
}

impl CanTriviallyDeriveCopy for Opaque {
    fn can_trivially_derive_copy(&self) -> bool {
        self.array_size().map_or(false, |size| {
            size <= RUST_DERIVE_IN_ARRAY_LIMIT
        })
    }
}

impl CanTriviallyDeriveHash for Opaque {
    fn can_trivially_derive_hash(&self) -> bool {
        self.array_size().map_or(false, |size| {
            size <= RUST_DERIVE_IN_ARRAY_LIMIT
        })
    }
}

impl CanTriviallyDerivePartialEqOrPartialOrd for Opaque {
    fn can_trivially_derive_partialeq_or_partialord(&self) -> bool {
        self.array_size().map_or(false, |size| {
            size <= RUST_DERIVE_IN_ARRAY_LIMIT
        })
    }
}
<commit_msg>Factor array size vs Rust derive limit checking into a common method<commit_after>//! Intermediate representation for the physical layout of some type.

use super::derive::{CanTriviallyDeriveCopy, CanTriviallyDeriveDebug,
                    CanTriviallyDeriveDefault, CanTriviallyDeriveHash,
                    CanTriviallyDerivePartialEqOrPartialOrd};
use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind};
use clang;
use std::{cmp, mem};

/// A type that represents the struct layout of a type.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Layout {
    /// The size (in bytes) of this layout.
    pub size: usize,
    /// The alignment (in bytes) of this layout.
    pub align: usize,
    /// Whether this layout's members are packed or not.
    pub packed: bool,
}

#[test]
fn test_layout_for_size() {
    let ptr_size = mem::size_of::<*mut ()>();
    assert_eq!(Layout::for_size(ptr_size), Layout::new(ptr_size, ptr_size));
    assert_eq!(
        Layout::for_size(3 * ptr_size),
        Layout::new(3 * ptr_size, ptr_size)
    );
}

impl Layout {
    /// Construct a new `Layout` with the given `size` and `align`. It is not
    /// packed.
    pub fn new(size: usize, align: usize) -> Self {
        Layout {
            size: size,
            align: align,
            packed: false,
        }
    }

    /// Creates a non-packed layout for a given size, trying to use the maximum
    /// alignment possible.
    pub fn for_size(size: usize) -> Self {
        let mut next_align = 2;
        while size % next_align == 0 &&
            next_align <= mem::size_of::<*mut ()>()
        {
            next_align *= 2;
        }
        Layout {
            size: size,
            align: next_align / 2,
            packed: false,
        }
    }

    /// Is this a zero-sized layout?
    pub fn is_zero(&self) -> bool {
        self.size == 0 && self.align == 0
    }

    /// Construct a zero-sized layout.
    pub fn zero() -> Self {
        Self::new(0, 0)
    }

    /// Get this layout as an opaque type.
    pub fn opaque(&self) -> Opaque {
        Opaque(*self)
    }
}

/// When we are treating a type as opaque, it is just a blob with a `Layout`.
#[derive(Clone, Debug, PartialEq)]
pub struct Opaque(pub Layout);

impl Opaque {
    /// Construct a new opaque type from the given clang type.
    pub fn from_clang_ty(ty: &clang::Type) -> Type {
        let layout = Layout::new(ty.size(), ty.align());
        let ty_kind = TypeKind::Opaque;
        Type::new(None, Some(layout), ty_kind, false)
    }

    /// Return the known rust type we should use to create a correctly-aligned
    /// field with this layout.
    pub fn known_rust_type_for_array(&self) -> Option<&'static str> {
        Some(match self.0.align {
            8 => "u64",
            4 => "u32",
            2 => "u16",
            1 => "u8",
            _ => return None,
        })
    }

    /// Return the array size that an opaque type for this layout should have if
    /// we know the correct type for it, or `None` otherwise.
    pub fn array_size(&self) -> Option<usize> {
        if self.known_rust_type_for_array().is_some() {
            Some(self.0.size / cmp::max(self.0.align, 1))
        } else {
            None
        }
    }

    /// Return `true` if this opaque layout's array size will fit within the
    /// maximum number of array elements that Rust allows deriving traits
    /// with. Return `false` otherwise.
    pub fn array_size_within_derive_limit(&self) -> bool {
        self.array_size().map_or(false, |size| {
            size <= RUST_DERIVE_IN_ARRAY_LIMIT
        })
    }
}

impl CanTriviallyDeriveDebug for Opaque {
    fn can_trivially_derive_debug(&self) -> bool {
        self.array_size_within_derive_limit()
    }
}

impl CanTriviallyDeriveDefault for Opaque {
    fn can_trivially_derive_default(&self) -> bool {
        self.array_size_within_derive_limit()
    }
}

impl CanTriviallyDeriveCopy for Opaque {
    fn can_trivially_derive_copy(&self) -> bool {
        self.array_size_within_derive_limit()
    }
}

impl CanTriviallyDeriveHash for Opaque {
    fn can_trivially_derive_hash(&self) -> bool {
        self.array_size_within_derive_limit()
    }
}

impl CanTriviallyDerivePartialEqOrPartialOrd for Opaque {
    fn can_trivially_derive_partialeq_or_partialord(&self) -> bool {
        self.array_size_within_derive_limit()
    }
}
<|endoftext|>