<commit_before>#![allow(dead_code)]
#![allow(clippy::new_ret_no_self)]

use crate::stack::{Node, Stack};
use crate::xlib_window_system::XlibWindowSystem;
use std::cmp::min;
use std::fmt;
use x11::xlib::Window;
use serde::{Deserialize, Serialize};

#[derive(Clone, Copy)]
pub struct Rect {
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32,
}

impl fmt::Debug for Rect {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "{{ x: {}, y: {}, width: {}, height: {} }}",
               self.x,
               self.y,
               self.width,
               self.height)
    }
}

#[derive(Clone)]
pub enum LayoutMsg {
    Increase,
    Decrease,
    IncreaseMaster,
    DecreaseMaster,
    SplitHorizontal,
    SplitVertical,
    NextLayout,
    PrevLayout,
    FirstLayout,
    LastLayout,
    NthLayout(usize),
    Custom(String),
}

impl fmt::Debug for LayoutMsg {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LayoutMsg::Increase => write!(f, "Increase"),
            LayoutMsg::Decrease => write!(f, "Decrease"),
            LayoutMsg::IncreaseMaster => write!(f, "IncreasMaster"),
            LayoutMsg::DecreaseMaster => write!(f, "DecreaseMaster"),
            LayoutMsg::SplitHorizontal => write!(f, "SplitHorizontal"),
            LayoutMsg::SplitVertical => write!(f, "SplitVertical"),
            LayoutMsg::NextLayout => write!(f, "NextLayout"),
            LayoutMsg::PrevLayout => write!(f, "PrevLayout"),
            LayoutMsg::FirstLayout => write!(f, "FirstLayout"),
            LayoutMsg::NthLayout(n) => write!(f, "NthLayout: {}", n),
            LayoutMsg::LastLayout => write!(f, "LastLayout"),
            LayoutMsg::Custom(ref val) => write!(f, "Custom({})", val.clone()),
        }
    }
}

#[typetag::serde(tag = "type")]
pub trait Layout {
    fn name(&self) -> String;
    fn send_msg(&mut self, msg: LayoutMsg);

    fn apply(&self, area: Rect, _: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        self.simple_apply(area, &stack.nodes)
    }

    fn simple_apply(&self, _: Rect, _: &[Node]) -> Vec<Rect> {
        Vec::new()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Choose {
    layouts: Vec<Box<dyn Layout>>,
    current: usize,
}

impl Choose {
    pub fn new(layouts: Vec<Box<dyn Layout>>) -> Box<dyn Layout> {
        // TODO: add proper error handling
        if layouts.is_empty() {
            panic!("Choose layout needs at least one layout");
        }

        Box::new(Choose {
            layouts,
            current: 0,
        })
    }
}

#[typetag::serde]
impl Layout for Choose {
    fn name(&self) -> String {
        self.layouts[self.current].name()
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        let len = self.layouts.len();

        match msg {
            LayoutMsg::NextLayout => {
                self.current = (self.current + 1) % len;
            }
            LayoutMsg::PrevLayout => {
                self.current = (self.current + len - 1) % len;
            }
            LayoutMsg::FirstLayout => {
                self.current = 0;
            }
            LayoutMsg::LastLayout => {
                self.current = len - 1;
            }
            LayoutMsg::NthLayout(n) => {
                if n < self.layouts.len() {
                    self.current = n
                }
            }
            x => {
                self.layouts[self.current].send_msg(x);
            }
        }
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        self.layouts[self.current].apply(area, ws, stack)
    }
}

#[derive(Serialize, Deserialize)]
pub struct Tall {
    num_masters: usize,
    ratio: f32,
    ratio_increment: f32,
}

impl Tall {
    pub fn new(num_masters: usize, ratio: f32, ratio_increment: f32) -> Box<dyn Layout> {
        Box::new(Tall {
            num_masters,
            ratio,
            ratio_increment,
        })
    }
}

#[typetag::serde]
impl Layout for Tall {
    fn name(&self) -> String {
        "Tall".to_string()
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        match msg {
            LayoutMsg::Increase => {
                if self.ratio + self.ratio_increment < 1.0 {
                    self.ratio += self.ratio_increment;
                }
            }
            LayoutMsg::Decrease => {
                if self.ratio - self.ratio_increment > self.ratio_increment {
                    self.ratio -= self.ratio_increment;
                }
            }
            LayoutMsg::IncreaseMaster => self.num_masters += 1,
            LayoutMsg::DecreaseMaster => {
                if self.num_masters > 1 {
                    self.num_masters -= 1;
                }
            }
            _ => {}
        }
    }

    fn simple_apply(&self, area: Rect, windows: &[Node]) -> Vec<Rect> {
        let nwindows = windows.len();

        (0..nwindows)
            .map(|i| {
                if i < self.num_masters {
                    let yoff = area.height / min(self.num_masters, nwindows) as u32;

                    Rect {
                        x: area.x,
                        y: area.y + (yoff * i as u32),
                        width: (area.width as f32 *
                                (1.0 -
                                 (nwindows > self.num_masters) as u32 as f32 *
                                 (1.0 - self.ratio)))
                            .floor() as u32,
                        height: yoff,
                    }
                } else {
                    let yoff = area.height / (nwindows - self.num_masters) as u32;

                    Rect {
                        x: area.x + (area.width as f32 * self.ratio).floor() as u32,
                        y: area.y + (yoff * (i - self.num_masters) as u32),
                        width: (area.width as f32 * (1.0 - self.ratio)).floor() as u32,
                        height: yoff,
                    }
                }
            })
            .collect()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Strut {
    layout: Box<dyn Layout>,
}

impl Strut {
    pub fn new(layout: Box<dyn Layout>) -> Box<dyn Layout> {
        Box::new(Strut {
            layout
        })
    }
}

#[typetag::serde]
impl Layout for Strut {
    fn name(&self) -> String {
        self.layout.name()
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        self.layout.send_msg(msg);
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        let mut new_area = Rect {
            x: 0,
            y: 0,
            width: 0,
            height: 0,
        };
        let strut = ws.get_strut(area);

        new_area.x = area.x + strut.0;
        new_area.width = area.width - (strut.0 + strut.1);
        new_area.y = area.y + strut.2;
        new_area.height = area.height - (strut.2 + strut.3);

        self.layout.apply(new_area, ws, stack)
    }
}

#[derive(Serialize, Deserialize)]
pub struct Full {
    focus: Option<Window>
}

impl Full {
    pub fn new() -> Box<dyn Layout> {
        Box::new(Full{
            focus: None
        })
    }
}

#[typetag::serde]
impl Layout for Full {
    fn name(&self) -> String {
        "Full".to_string()
    }

    fn send_msg(&mut self, _msg: LayoutMsg) {}

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        stack.nodes.iter()
            .enumerate()
            .map(|(i,node)| {
                if Some(i) != stack.focus {
                    match node {
                        Node::Window(w) => ws.lower_window(*w),
                        Node::Container(c) => c.stack.all_windows().iter().for_each(|&w| ws.lower_window(w)),
                    }
                }

                Rect {
                    x: area.x,
                    y: area.y,
                    width: area.width,
                    height: area.height,
                }
            }).collect()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Gap {
    screen_gap: u32,
    window_gap: u32,
    layout: Box<dyn Layout>,
}

impl Gap {
    pub fn new(screen_gap: u32, window_gap: u32, layout: Box<dyn Layout>) -> Box<dyn Layout> {
        Box::new(Gap {
            screen_gap,
            window_gap,
            layout,
        })
    }
}

#[typetag::serde]
impl Layout for Gap {
    fn name(&self) -> String {
        self.layout.name()
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        self.layout.send_msg(msg);
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        let area = Rect {
            x: area.x + self.screen_gap,
            y: area.y + self.screen_gap,
            width: area.width - (2 * self.screen_gap),
            height: area.height - (2 * self.screen_gap),
        };

        let mut rects = self.layout.apply(area, ws, stack);

        for rect in rects.iter_mut() {
            rect.x += self.window_gap;
            rect.y += self.window_gap;
            rect.width -= 2 * self.window_gap;
            rect.height -= 2 * self.window_gap;
        }

        rects
    }
}

#[derive(Serialize, Deserialize)]
pub enum MirrorStyle {
    Horizontal,
    Vertical,
}

#[derive(Serialize, Deserialize)]
pub struct Mirror {
    style: MirrorStyle,
    layout: Box<dyn Layout>,
}

impl Mirror {
    pub fn new(style: MirrorStyle, layout: Box<dyn Layout>) -> Box<dyn Layout> {
        Box::new(Mirror {
            style,
            layout
        })
    }
}

#[typetag::serde]
impl Layout for Mirror {
    fn name(&self) -> String {
        format!("Mirror({})", self.layout.name())
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        self.layout.send_msg(msg);
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        let mut rects = self.layout.apply(area, ws, stack);

        match self.style {
            MirrorStyle::Horizontal => {
                rects.iter_mut().for_each(|r| r.y = area.y + area.height - min(r.y + r.height - area.y, area.height))
            }
            MirrorStyle::Vertical => {
                rects.iter_mut().for_each(|r| r.x = area.width - min(r.x + r.width, area.width))
            }
        }

        rects
    }
}

#[derive(Serialize, Deserialize)]
pub struct Rotate {
    layout: Box<dyn Layout>,
}

impl Rotate {
    pub fn new(layout: Box<dyn Layout>) -> Box<dyn Layout> {
        Box::new(Rotate {
            layout
        })
    }

    fn rotate_rect(rect: Rect) -> Rect {
        Rect {
            x: rect.y,
            y: rect.x,
            width: rect.height,
            height: rect.width,
        }
    }
}

#[typetag::serde]
impl Layout for Rotate {
    fn name(&self) -> String {
        format!("Rotate({})", self.layout.name())
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        self.layout.send_msg(msg);
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        self.layout
            .apply(Self::rotate_rect(area), ws, stack)
            .iter()
            .map(|&r| {
                Self::rotate_rect(r)
            })
            .collect()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Horizontal;

impl Horizontal {
    pub fn new() -> Box<dyn Layout> {
        Box::new(Horizontal {})
    }
}

#[typetag::serde]
impl Layout for Horizontal {
    fn name(&self) -> String {
        "Horizontal".to_string()
    }

    fn send_msg(&mut self, _msg: LayoutMsg) {}

    fn simple_apply(&self, area: Rect, windows: &[Node]) -> Vec<Rect> {
        let nwindows = windows.len();

        (0..nwindows)
            .map(|i| {
                   let yoff = area.height / nwindows as u32;

                    Rect {
                        x: area.x,
                        y: area.y + (yoff * i as u32),
                        width: area.width,
                        height: yoff,
                    }
            })
            .collect()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Vertical;

impl Vertical {
    pub fn new() -> Box<dyn Layout> {
        Box::new(Vertical {})
    }
}

#[typetag::serde]
impl Layout for Vertical {
    fn name(&self) -> String {
        "Vertical".to_string()
    }

    fn send_msg(&mut self, _msg: LayoutMsg) {}

    fn simple_apply(&self, area: Rect, windows: &[Node]) -> Vec<Rect> {
        let nwindows = windows.len();

        (0..nwindows)
            .map(|i| {
                   let xoff = area.width / nwindows as u32;

                    Rect {
                        x: area.x + (xoff * i as u32),
                        y: area.y,
                        width: xoff,
                        height: area.height,
                    }
            })
            .collect()
    }
}
<commit_msg>Remove obsolete splitting layout messages<commit_after>#![allow(dead_code)]
#![allow(clippy::new_ret_no_self)]

use crate::stack::{Node, Stack};
use crate::xlib_window_system::XlibWindowSystem;
use std::cmp::min;
use std::fmt;
use x11::xlib::Window;
use serde::{Deserialize, Serialize};

#[derive(Clone, Copy)]
pub struct Rect {
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32,
}

impl fmt::Debug for Rect {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "{{ x: {}, y: {}, width: {}, height: {} }}",
               self.x,
               self.y,
               self.width,
               self.height)
    }
}

#[derive(Clone)]
pub enum LayoutMsg {
    Increase,
    Decrease,
    IncreaseMaster,
    DecreaseMaster,
    NextLayout,
    PrevLayout,
    FirstLayout,
    LastLayout,
    NthLayout(usize),
    Custom(String),
}

impl fmt::Debug for LayoutMsg {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LayoutMsg::Increase => write!(f, "Increase"),
            LayoutMsg::Decrease => write!(f, "Decrease"),
            LayoutMsg::IncreaseMaster => write!(f, "IncreasMaster"),
            LayoutMsg::DecreaseMaster => write!(f, "DecreaseMaster"),
            LayoutMsg::NextLayout => write!(f, "NextLayout"),
            LayoutMsg::PrevLayout => write!(f, "PrevLayout"),
            LayoutMsg::FirstLayout => write!(f, "FirstLayout"),
            LayoutMsg::NthLayout(n) => write!(f, "NthLayout: {}", n),
            LayoutMsg::LastLayout => write!(f, "LastLayout"),
            LayoutMsg::Custom(ref val) => write!(f, "Custom({})", val.clone()),
        }
    }
}

#[typetag::serde(tag = "type")]
pub trait Layout {
    fn name(&self) -> String;
    fn send_msg(&mut self, msg: LayoutMsg);

    fn apply(&self, area: Rect, _: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        self.simple_apply(area, &stack.nodes)
    }

    fn simple_apply(&self, _: Rect, _: &[Node]) -> Vec<Rect> {
        Vec::new()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Choose {
    layouts: Vec<Box<dyn Layout>>,
    current: usize,
}

impl Choose {
    pub fn new(layouts: Vec<Box<dyn Layout>>) -> Box<dyn Layout> {
        // TODO: add proper error handling
        if layouts.is_empty() {
            panic!("Choose layout needs at least one layout");
        }

        Box::new(Choose {
            layouts,
            current: 0,
        })
    }
}

#[typetag::serde]
impl Layout for Choose {
    fn name(&self) -> String {
        self.layouts[self.current].name()
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        let len = self.layouts.len();

        match msg {
            LayoutMsg::NextLayout => {
                self.current = (self.current + 1) % len;
            }
            LayoutMsg::PrevLayout => {
                self.current = (self.current + len - 1) % len;
            }
            LayoutMsg::FirstLayout => {
                self.current = 0;
            }
            LayoutMsg::LastLayout => {
                self.current = len - 1;
            }
            LayoutMsg::NthLayout(n) => {
                if n < self.layouts.len() {
                    self.current = n
                }
            }
            x => {
                self.layouts[self.current].send_msg(x);
            }
        }
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        self.layouts[self.current].apply(area, ws, stack)
    }
}

#[derive(Serialize, Deserialize)]
pub struct Tall {
    num_masters: usize,
    ratio: f32,
    ratio_increment: f32,
}

impl Tall {
    pub fn new(num_masters: usize, ratio: f32, ratio_increment: f32) -> Box<dyn Layout> {
        Box::new(Tall {
            num_masters,
            ratio,
            ratio_increment,
        })
    }
}

#[typetag::serde]
impl Layout for Tall {
    fn name(&self) -> String {
        "Tall".to_string()
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        match msg {
            LayoutMsg::Increase => {
                if self.ratio + self.ratio_increment < 1.0 {
                    self.ratio += self.ratio_increment;
                }
            }
            LayoutMsg::Decrease => {
                if self.ratio - self.ratio_increment > self.ratio_increment {
                    self.ratio -= self.ratio_increment;
                }
            }
            LayoutMsg::IncreaseMaster => self.num_masters += 1,
            LayoutMsg::DecreaseMaster => {
                if self.num_masters > 1 {
                    self.num_masters -= 1;
                }
            }
            _ => {}
        }
    }

    fn simple_apply(&self, area: Rect, windows: &[Node]) -> Vec<Rect> {
        let nwindows = windows.len();

        (0..nwindows)
            .map(|i| {
                if i < self.num_masters {
                    let yoff = area.height / min(self.num_masters, nwindows) as u32;

                    Rect {
                        x: area.x,
                        y: area.y + (yoff * i as u32),
                        width: (area.width as f32 *
                                (1.0 -
                                 (nwindows > self.num_masters) as u32 as f32 *
                                 (1.0 - self.ratio)))
                            .floor() as u32,
                        height: yoff,
                    }
                } else {
                    let yoff = area.height / (nwindows - self.num_masters) as u32;

                    Rect {
                        x: area.x + (area.width as f32 * self.ratio).floor() as u32,
                        y: area.y + (yoff * (i - self.num_masters) as u32),
                        width: (area.width as f32 * (1.0 - self.ratio)).floor() as u32,
                        height: yoff,
                    }
                }
            })
            .collect()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Strut {
    layout: Box<dyn Layout>,
}

impl Strut {
    pub fn new(layout: Box<dyn Layout>) -> Box<dyn Layout> {
        Box::new(Strut {
            layout
        })
    }
}

#[typetag::serde]
impl Layout for Strut {
    fn name(&self) -> String {
        self.layout.name()
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        self.layout.send_msg(msg);
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        let mut new_area = Rect {
            x: 0,
            y: 0,
            width: 0,
            height: 0,
        };
        let strut = ws.get_strut(area);

        new_area.x = area.x + strut.0;
        new_area.width = area.width - (strut.0 + strut.1);
        new_area.y = area.y + strut.2;
        new_area.height = area.height - (strut.2 + strut.3);

        self.layout.apply(new_area, ws, stack)
    }
}

#[derive(Serialize, Deserialize)]
pub struct Full {
    focus: Option<Window>
}

impl Full {
    pub fn new() -> Box<dyn Layout> {
        Box::new(Full{
            focus: None
        })
    }
}

#[typetag::serde]
impl Layout for Full {
    fn name(&self) -> String {
        "Full".to_string()
    }

    fn send_msg(&mut self, _msg: LayoutMsg) {}

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        stack.nodes.iter()
            .enumerate()
            .map(|(i,node)| {
                if Some(i) != stack.focus {
                    match node {
                        Node::Window(w) => ws.lower_window(*w),
                        Node::Container(c) => c.stack.all_windows().iter().for_each(|&w| ws.lower_window(w)),
                    }
                }

                Rect {
                    x: area.x,
                    y: area.y,
                    width: area.width,
                    height: area.height,
                }
            }).collect()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Gap {
    screen_gap: u32,
    window_gap: u32,
    layout: Box<dyn Layout>,
}

impl Gap {
    pub fn new(screen_gap: u32, window_gap: u32, layout: Box<dyn Layout>) -> Box<dyn Layout> {
        Box::new(Gap {
            screen_gap,
            window_gap,
            layout,
        })
    }
}

#[typetag::serde]
impl Layout for Gap {
    fn name(&self) -> String {
        self.layout.name()
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        self.layout.send_msg(msg);
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        let area = Rect {
            x: area.x + self.screen_gap,
            y: area.y + self.screen_gap,
            width: area.width - (2 * self.screen_gap),
            height: area.height - (2 * self.screen_gap),
        };

        let mut rects = self.layout.apply(area, ws, stack);

        for rect in rects.iter_mut() {
            rect.x += self.window_gap;
            rect.y += self.window_gap;
            rect.width -= 2 * self.window_gap;
            rect.height -= 2 * self.window_gap;
        }

        rects
    }
}

#[derive(Serialize, Deserialize)]
pub enum MirrorStyle {
    Horizontal,
    Vertical,
}

#[derive(Serialize, Deserialize)]
pub struct Mirror {
    style: MirrorStyle,
    layout: Box<dyn Layout>,
}

impl Mirror {
    pub fn new(style: MirrorStyle, layout: Box<dyn Layout>) -> Box<dyn Layout> {
        Box::new(Mirror {
            style,
            layout
        })
    }
}

#[typetag::serde]
impl Layout for Mirror {
    fn name(&self) -> String {
        format!("Mirror({})", self.layout.name())
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        self.layout.send_msg(msg);
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        let mut rects = self.layout.apply(area, ws, stack);

        match self.style {
            MirrorStyle::Horizontal => {
                rects.iter_mut().for_each(|r| r.y = area.y + area.height - min(r.y + r.height - area.y, area.height))
            }
            MirrorStyle::Vertical => {
                rects.iter_mut().for_each(|r| r.x = area.width - min(r.x + r.width, area.width))
            }
        }

        rects
    }
}

#[derive(Serialize, Deserialize)]
pub struct Rotate {
    layout: Box<dyn Layout>,
}

impl Rotate {
    pub fn new(layout: Box<dyn Layout>) -> Box<dyn Layout> {
        Box::new(Rotate {
            layout
        })
    }

    fn rotate_rect(rect: Rect) -> Rect {
        Rect {
            x: rect.y,
            y: rect.x,
            width: rect.height,
            height: rect.width,
        }
    }
}

#[typetag::serde]
impl Layout for Rotate {
    fn name(&self) -> String {
        format!("Rotate({})", self.layout.name())
    }

    fn send_msg(&mut self, msg: LayoutMsg) {
        self.layout.send_msg(msg);
    }

    fn apply(&self, area: Rect, ws: &XlibWindowSystem, stack: &Stack) -> Vec<Rect> {
        self.layout
            .apply(Self::rotate_rect(area), ws, stack)
            .iter()
            .map(|&r| {
                Self::rotate_rect(r)
            })
            .collect()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Horizontal;

impl Horizontal {
    pub fn new() -> Box<dyn Layout> {
        Box::new(Horizontal {})
    }
}

#[typetag::serde]
impl Layout for Horizontal {
    fn name(&self) -> String {
        "Horizontal".to_string()
    }

    fn send_msg(&mut self, _msg: LayoutMsg) {}

    fn simple_apply(&self, area: Rect, windows: &[Node]) -> Vec<Rect> {
        let nwindows = windows.len();

        (0..nwindows)
            .map(|i| {
                   let yoff = area.height / nwindows as u32;

                    Rect {
                        x: area.x,
                        y: area.y + (yoff * i as u32),
                        width: area.width,
                        height: yoff,
                    }
            })
            .collect()
    }
}

#[derive(Serialize, Deserialize)]
pub struct Vertical;

impl Vertical {
    pub fn new() -> Box<dyn Layout> {
        Box::new(Vertical {})
    }
}

#[typetag::serde]
impl Layout for Vertical {
    fn name(&self) -> String {
        "Vertical".to_string()
    }

    fn send_msg(&mut self, _msg: LayoutMsg) {}

    fn simple_apply(&self, area: Rect, windows: &[Node]) -> Vec<Rect> {
        let nwindows = windows.len();

        (0..nwindows)
            .map(|i| {
                   let xoff = area.width / nwindows as u32;

                    Rect {
                        x: area.x + (xoff * i as u32),
                        y: area.y,
                        width: xoff,
                        height: area.height,
                    }
            })
            .collect()
    }
}
<|endoftext|>


<commit_before>use core_arch::x86::*;

#[cfg(test)]
use stdsimd_test::assert_instr;

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the high 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512IFMA52&expand=3488)
#[inline]
#[target_feature(enable = "avx512ifma")]
#[cfg_attr(test, assert_instr(vpmadd52huq))]
pub unsafe fn _mm512_madd52hi_epu64(a: __m512i, b: __m512i, c: __m512i) -> __m512i {
    vpmadd52huq_512(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the low 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=3497&avx512techs=AVX512IFMA52)
#[inline]
#[target_feature(enable = "avx512ifma")]
#[cfg_attr(test, assert_instr(vpmadd52huq))]
pub unsafe fn _mm512_madd52lo_epu64(a: __m512i, b: __m512i, c: __m512i) -> __m512i {
    vpmadd52luq_512(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the high 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=vpmadd52&avx512techs=AVX512IFMA52,AVX512VL&expand=3485)
#[inline]
#[target_feature(enable = "avx512ifma,avx512vl")]
#[cfg_attr(test, assert_instr(vpmadd52huq))]
pub unsafe fn _mm256_madd52hi_epu64(a: __m256i, b: __m256i, c: __m256i) -> __m256i {
    vpmadd52huq_256(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the low 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=vpmadd52&avx512techs=AVX512IFMA52,AVX512VL&expand=3494)
#[inline]
#[target_feature(enable = "avx512ifma,avx512vl")]
#[cfg_attr(test, assert_instr(vpmadd52huq))]
pub unsafe fn _mm256_madd52lo_epu64(a: __m256i, b: __m256i, c: __m256i) -> __m256i {
    vpmadd52luq_256(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the high 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=3488,3482&text=vpmadd52&avx512techs=AVX512IFMA52,AVX512VL)
#[inline]
#[target_feature(enable = "avx512ifma,avx512vl")]
#[cfg_attr(test, assert_instr(vpmadd52huq))]
pub unsafe fn _mm_madd52hi_epu64(a: __m128i, b: __m128i, c: __m128i) -> __m128i {
    vpmadd52huq_128(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the low 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=3488,3491&text=vpmadd52&avx512techs=AVX512IFMA52,AVX512VL)
#[inline]
#[target_feature(enable = "avx512ifma,avx512vl")]
#[cfg_attr(test, assert_instr(vpmadd52huq))]
pub unsafe fn _mm_madd52lo_epu64(a: __m128i, b: __m128i, c: __m128i) -> __m128i {
    vpmadd52luq_128(a, b, c)
}

#[allow(improper_ctypes)]
extern "C" {
    #[link_name = "llvm.x86.avx512.vpmadd52l.uq.128"]
    fn vpmadd52luq_128(z: __m128i, x: __m128i, y: __m128i) -> __m128i;
    #[link_name = "llvm.x86.avx512.vpmadd52h.uq.128"]
    fn vpmadd52huq_128(z: __m128i, x: __m128i, y: __m128i) -> __m128i;
    #[link_name = "llvm.x86.avx512.vpmadd52l.uq.256"]
    fn vpmadd52luq_256(z: __m256i, x: __m256i, y: __m256i) -> __m256i;
    #[link_name = "llvm.x86.avx512.vpmadd52h.uq.256"]
    fn vpmadd52huq_256(z: __m256i, x: __m256i, y: __m256i) -> __m256i;
    #[link_name = "llvm.x86.avx512.vpmadd52l.uq.512"]
    fn vpmadd52luq_512(z: __m512i, x: __m512i, y: __m512i) -> __m512i;
    #[link_name = "llvm.x86.avx512.vpmadd52h.uq.512"]
    fn vpmadd52huq_512(z: __m512i, x: __m512i, y: __m512i) -> __m512i;
}

#[cfg(test)]
mod tests {
    use std;
    use stdsimd_test::simd_test;

    use core_arch::x86::*;

    #[simd_test(enable = "avx512ifma")]
    unsafe fn test_mm512_madd52hi_epu64() {
        let mut a = _mm512_set1_epi64(10 << 40);
        let b = _mm512_set1_epi64((11 << 40) + 4);
        let c = _mm512_set1_epi64((12 << 40) + 3);

        a = _mm512_madd52hi_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) >> 52)
        let expected = _mm512_set1_epi64(11030549757952);

        assert_eq_m512i(a, expected);
    }

    #[simd_test(enable = "avx512ifma")]
    unsafe fn test_mm512_madd52lo_epu64() {
        let mut a = _mm512_set1_epi64(10 << 40);
        let b = _mm512_set1_epi64((11 << 40) + 4);
        let c = _mm512_set1_epi64((12 << 40) + 3);

        a = _mm512_madd52lo_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) % (1 << 52))
        let expected = _mm512_set1_epi64(100055558127628);

        assert_eq_m512i(a, expected);
    }

    #[simd_test(enable = "avx512ifma,avx512vl")]
    unsafe fn test_mm256_madd52hi_epu64() {
        let mut a = _mm256_set1_epi64x(10 << 40);
        let b = _mm256_set1_epi64x((11 << 40) + 4);
        let c = _mm256_set1_epi64x((12 << 40) + 3);

        a = _mm256_madd52hi_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) >> 52)
        let expected = _mm256_set1_epi64x(11030549757952);

        assert_eq_m256i(a, expected);
    }

    #[simd_test(enable = "avx512ifma,avx512vl")]
    unsafe fn test_mm256_madd52lo_epu64() {
        let mut a = _mm256_set1_epi64x(10 << 40);
        let b = _mm256_set1_epi64x((11 << 40) + 4);
        let c = _mm256_set1_epi64x((12 << 40) + 3);

        a = _mm256_madd52lo_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) % (1 << 52))
        let expected = _mm256_set1_epi64x(100055558127628);

        assert_eq_m256i(a, expected);
    }

    #[simd_test(enable = "avx512ifma,avx512vl")]
    unsafe fn test_mm_madd52hi_epu64() {
        let mut a = _mm_set1_epi64x(10 << 40);
        let b = _mm_set1_epi64x((11 << 40) + 4);
        let c = _mm_set1_epi64x((12 << 40) + 3);

        a = _mm_madd52hi_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) >> 52)
        let expected = _mm_set1_epi64x(11030549757952);

        assert_eq_m128i(a, expected);
    }

    #[simd_test(enable = "avx512ifma,avx512vl")]
    unsafe fn test_mm_madd52lo_epu64() {
        let mut a = _mm_set1_epi64x(10 << 40);
        let b = _mm_set1_epi64x((11 << 40) + 4);
        let c = _mm_set1_epi64x((12 << 40) + 3);

        a = _mm_madd52hi_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) >> 52)
        let expected = _mm_set1_epi64x(11030549757952);

        assert_eq_m128i(a, expected);
    }
}
<commit_msg>Fix incorrect assert_instr tests.<commit_after>use core_arch::x86::*;

#[cfg(test)]
use stdsimd_test::assert_instr;

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the high 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512IFMA52&expand=3488)
#[inline]
#[target_feature(enable = "avx512ifma")]
#[cfg_attr(test, assert_instr(vpmadd52huq))]
pub unsafe fn _mm512_madd52hi_epu64(a: __m512i, b: __m512i, c: __m512i) -> __m512i {
    vpmadd52huq_512(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the low 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=3497&avx512techs=AVX512IFMA52)
#[inline]
#[target_feature(enable = "avx512ifma")]
#[cfg_attr(test, assert_instr(vpmadd52luq))]
pub unsafe fn _mm512_madd52lo_epu64(a: __m512i, b: __m512i, c: __m512i) -> __m512i {
    vpmadd52luq_512(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the high 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=vpmadd52&avx512techs=AVX512IFMA52,AVX512VL&expand=3485)
#[inline]
#[target_feature(enable = "avx512ifma,avx512vl")]
#[cfg_attr(test, assert_instr(vpmadd52huq))]
pub unsafe fn _mm256_madd52hi_epu64(a: __m256i, b: __m256i, c: __m256i) -> __m256i {
    vpmadd52huq_256(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the low 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=vpmadd52&avx512techs=AVX512IFMA52,AVX512VL&expand=3494)
#[inline]
#[target_feature(enable = "avx512ifma,avx512vl")]
#[cfg_attr(test, assert_instr(vpmadd52luq))]
pub unsafe fn _mm256_madd52lo_epu64(a: __m256i, b: __m256i, c: __m256i) -> __m256i {
    vpmadd52luq_256(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the high 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=3488,3482&text=vpmadd52&avx512techs=AVX512IFMA52,AVX512VL)
#[inline]
#[target_feature(enable = "avx512ifma,avx512vl")]
#[cfg_attr(test, assert_instr(vpmadd52huq))]
pub unsafe fn _mm_madd52hi_epu64(a: __m128i, b: __m128i, c: __m128i) -> __m128i {
    vpmadd52huq_128(a, b, c)
}

/// Multiply packed unsigned 52-bit integers in each 64-bit element of
/// `b` and `c` to form a 104-bit intermediate result. Add the low 52-bit
/// unsigned integer from the intermediate result with the
/// corresponding unsigned 64-bit integer in `a`, and store the
/// results in `dst`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=3488,3491&text=vpmadd52&avx512techs=AVX512IFMA52,AVX512VL)
#[inline]
#[target_feature(enable = "avx512ifma,avx512vl")]
#[cfg_attr(test, assert_instr(vpmadd52luq))]
pub unsafe fn _mm_madd52lo_epu64(a: __m128i, b: __m128i, c: __m128i) -> __m128i {
    vpmadd52luq_128(a, b, c)
}

#[allow(improper_ctypes)]
extern "C" {
    #[link_name = "llvm.x86.avx512.vpmadd52l.uq.128"]
    fn vpmadd52luq_128(z: __m128i, x: __m128i, y: __m128i) -> __m128i;
    #[link_name = "llvm.x86.avx512.vpmadd52h.uq.128"]
    fn vpmadd52huq_128(z: __m128i, x: __m128i, y: __m128i) -> __m128i;
    #[link_name = "llvm.x86.avx512.vpmadd52l.uq.256"]
    fn vpmadd52luq_256(z: __m256i, x: __m256i, y: __m256i) -> __m256i;
    #[link_name = "llvm.x86.avx512.vpmadd52h.uq.256"]
    fn vpmadd52huq_256(z: __m256i, x: __m256i, y: __m256i) -> __m256i;
    #[link_name = "llvm.x86.avx512.vpmadd52l.uq.512"]
    fn vpmadd52luq_512(z: __m512i, x: __m512i, y: __m512i) -> __m512i;
    #[link_name = "llvm.x86.avx512.vpmadd52h.uq.512"]
    fn vpmadd52huq_512(z: __m512i, x: __m512i, y: __m512i) -> __m512i;
}

#[cfg(test)]
mod tests {
    use std;
    use stdsimd_test::simd_test;

    use core_arch::x86::*;

    #[simd_test(enable = "avx512ifma")]
    unsafe fn test_mm512_madd52hi_epu64() {
        let mut a = _mm512_set1_epi64(10 << 40);
        let b = _mm512_set1_epi64((11 << 40) + 4);
        let c = _mm512_set1_epi64((12 << 40) + 3);

        a = _mm512_madd52hi_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) >> 52)
        let expected = _mm512_set1_epi64(11030549757952);

        assert_eq_m512i(a, expected);
    }

    #[simd_test(enable = "avx512ifma")]
    unsafe fn test_mm512_madd52lo_epu64() {
        let mut a = _mm512_set1_epi64(10 << 40);
        let b = _mm512_set1_epi64((11 << 40) + 4);
        let c = _mm512_set1_epi64((12 << 40) + 3);

        a = _mm512_madd52lo_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) % (1 << 52))
        let expected = _mm512_set1_epi64(100055558127628);

        assert_eq_m512i(a, expected);
    }

    #[simd_test(enable = "avx512ifma,avx512vl")]
    unsafe fn test_mm256_madd52hi_epu64() {
        let mut a = _mm256_set1_epi64x(10 << 40);
        let b = _mm256_set1_epi64x((11 << 40) + 4);
        let c = _mm256_set1_epi64x((12 << 40) + 3);

        a = _mm256_madd52hi_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) >> 52)
        let expected = _mm256_set1_epi64x(11030549757952);

        assert_eq_m256i(a, expected);
    }

    #[simd_test(enable = "avx512ifma,avx512vl")]
    unsafe fn test_mm256_madd52lo_epu64() {
        let mut a = _mm256_set1_epi64x(10 << 40);
        let b = _mm256_set1_epi64x((11 << 40) + 4);
        let c = _mm256_set1_epi64x((12 << 40) + 3);

        a = _mm256_madd52lo_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) % (1 << 52))
        let expected = _mm256_set1_epi64x(100055558127628);

        assert_eq_m256i(a, expected);
    }

    #[simd_test(enable = "avx512ifma,avx512vl")]
    unsafe fn test_mm_madd52hi_epu64() {
        let mut a = _mm_set1_epi64x(10 << 40);
        let b = _mm_set1_epi64x((11 << 40) + 4);
        let c = _mm_set1_epi64x((12 << 40) + 3);

        a = _mm_madd52hi_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) >> 52)
        let expected = _mm_set1_epi64x(11030549757952);

        assert_eq_m128i(a, expected);
    }

    #[simd_test(enable = "avx512ifma,avx512vl")]
    unsafe fn test_mm_madd52lo_epu64() {
        let mut a = _mm_set1_epi64x(10 << 40);
        let b = _mm_set1_epi64x((11 << 40) + 4);
        let c = _mm_set1_epi64x((12 << 40) + 3);

        a = _mm_madd52hi_epu64(a, b, c);

        // (10 << 40) + ((((11 << 40) + 4) * ((12 << 40) + 3)) >> 52)
        let expected = _mm_set1_epi64x(11030549757952);

        assert_eq_m128i(a, expected);
    }
}
<|endoftext|>


<commit_before>use ide_db::{base_db::Upcast, helpers::pick_best_token, RootDatabase};
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TextRange, T};

use crate::{display::TryToNav, FilePosition, NavigationTarget, RangeInfo};

// Feature: Go to Type Definition
//
// Navigates to the type of an identifier.
//
// |===
// | Editor  | Action Name
//
// | VS Code | **Go to Type Definition*
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif[]
pub(crate) fn goto_type_definition(
    db: &RootDatabase,
    position: FilePosition,
) -> Option<RangeInfo<Vec<NavigationTarget>>> {
    let sema = hir::Semantics::new(db);

    let file: ast::SourceFile = sema.parse(position.file_id);
    let token: SyntaxToken =
        pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind {
            IDENT | INT_NUMBER | T![self] => 2,
            kind if kind.is_trivia() => 0,
            _ => 1,
        })?;

    let mut res = Vec::new();
    let mut push = |def: hir::ModuleDef| {
        if let Some(nav) = def.try_to_nav(db) {
            if !res.contains(&nav) {
                res.push(nav);
            }
        }
    };

    // TODO this became pretty baroque after refactoring for `descend_into_macros(_many)`
    let range = sema
        .descend_into_macros(token)
        .iter()
        .filter_map(|token| {
            let ty_range = sema.token_ancestors_with_macros(token.clone()).find_map(|node| {
                let ty = match_ast! {
                    match node {
                        ast::Expr(it) => sema.type_of_expr(&it)?.original,
                        ast::Pat(it) => sema.type_of_pat(&it)?.original,
                        ast::SelfParam(it) => sema.type_of_self(&it)?,
                        ast::Type(it) => sema.resolve_type(&it)?,
                        ast::RecordField(it) => sema.to_def(&it).map(|d| d.ty(db.upcast()))?,
                        // can't match on RecordExprField directly as `ast::Expr` will match an iteration too early otherwise
                        ast::NameRef(it) => {
                            if let Some(record_field) = ast::RecordExprField::for_name_ref(&it) {
                                let (_, _, ty) = sema.resolve_record_field(&record_field)?;
                                ty
                            } else {
                                let record_field = ast::RecordPatField::for_field_name_ref(&it)?;
                                sema.resolve_record_pat_field(&record_field)?.ty(db)
                            }
                        },
                        _ => return None,
                    }
                };

                let range = node.text_range();
                Some((ty, range.start(), range.end()))
            });
            ty_range
        })
        .inspect(|(ty, _range_start, _range_end)| {
            // collect from each `ty` into the `res` result vec
            let ty = ty.strip_references();
            ty.walk(db, |t| {
                if let Some(adt) = t.as_adt() {
                    push(adt.into());
                } else if let Some(trait_) = t.as_dyn_trait() {
                    push(trait_.into());
                } else if let Some(traits) = t.as_impl_traits(db) {
                    traits.into_iter().for_each(|it| push(it.into()));
                } else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
                    push(trait_.into());
                }
            });
        }) // reduce all ranges into a single umbrella span (TODO fishy?)
        .map(|(_, range_start, range_end)| (range_start, range_end))
        .reduce(|(start_acc, end_acc), (start_cur, end_cur)| {
            (start_acc.min(start_cur), end_acc.max(end_cur))
        })
        .map(|(range_start, range_end)| TextRange::new(range_start, range_end))?; // TODO easy to miss `?` bail

    Some(RangeInfo::new(range, res))
}

#[cfg(test)]
mod tests {
    use ide_db::base_db::FileRange;
    use itertools::Itertools;

    use crate::fixture;

    fn check(ra_fixture: &str) {
        let (analysis, position, expected) = fixture::annotations(ra_fixture);
        let navs = analysis.goto_type_definition(position).unwrap().unwrap().info;
        assert_ne!(navs.len(), 0);

        let cmp = |&FileRange { file_id, range }: &_| (file_id, range.start());
        let navs = navs
            .into_iter()
            .map(|nav| FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() })
            .sorted_by_key(cmp)
            .collect::<Vec<_>>();
        let expected = expected
            .into_iter()
            .map(|(FileRange { file_id, range }, _)| FileRange { file_id, range })
            .sorted_by_key(cmp)
            .collect::<Vec<_>>();
        assert_eq!(expected, navs);
    }

    #[test]
    fn goto_type_definition_works_simple() {
        check(
            r#"
struct Foo;
     //^^^
fn foo() {
    let f: Foo; f$0
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_record_expr_field() {
        check(
            r#"
struct Bar;
    // ^^^
struct Foo { foo: Bar }
fn foo() {
    Foo { foo$0 }
}
"#,
        );
        check(
            r#"
struct Bar;
    // ^^^
struct Foo { foo: Bar }
fn foo() {
    Foo { foo$0: Bar }
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_record_pat_field() {
        check(
            r#"
struct Bar;
    // ^^^
struct Foo { foo: Bar }
fn foo() {
    let Foo { foo$0 };
}
"#,
        );
        check(
            r#"
struct Bar;
    // ^^^
struct Foo { foo: Bar }
fn foo() {
    let Foo { foo$0: bar };
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_works_simple_ref() {
        check(
            r#"
struct Foo;
     //^^^
fn foo() {
    let f: &Foo; f$0
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_works_through_macro() {
        check(
            r#"
macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
struct Foo {}
     //^^^
id! {
    fn bar() { let f$0 = Foo {}; }
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_for_param() {
        check(
            r#"
struct Foo;
     //^^^
fn foo($0f: Foo) {}
"#,
        );
    }

    #[test]
    fn goto_type_definition_for_tuple_field() {
        check(
            r#"
struct Foo;
     //^^^
struct Bar(Foo);
fn foo() {
    let bar = Bar(Foo);
    bar.$00;
}
"#,
        );
    }

    #[test]
    fn goto_def_for_self_param() {
        check(
            r#"
struct Foo;
     //^^^
impl Foo {
    fn f(&self$0) {}
}
"#,
        )
    }

    #[test]
    fn goto_def_for_type_fallback() {
        check(
            r#"
struct Foo;
     //^^^
impl Foo$0 {}
"#,
        )
    }

    #[test]
    fn goto_def_for_struct_field() {
        check(
            r#"
struct Bar;
     //^^^

struct Foo {
    bar$0: Bar,
}
"#,
        );
    }

    #[test]
    fn goto_def_for_enum_struct_field() {
        check(
            r#"
struct Bar;
     //^^^

enum Foo {
    Bar {
        bar$0: Bar
    },
}
"#,
        );
    }

    #[test]
    fn goto_def_considers_generics() {
        check(
            r#"
struct Foo;
     //^^^
struct Bar<T, U>(T, U);
     //^^^
struct Baz<T>(T);
     //^^^

fn foo(x$0: Bar<Baz<Foo>, Baz<usize>) {}
"#,
        );
    }
}
<commit_msg>simplify<commit_after>use ide_db::{base_db::Upcast, helpers::pick_best_token, RootDatabase};
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TextRange, T};

use crate::{display::TryToNav, FilePosition, NavigationTarget, RangeInfo};

// Feature: Go to Type Definition
//
// Navigates to the type of an identifier.
//
// |===
// | Editor  | Action Name
//
// | VS Code | **Go to Type Definition*
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif[]
pub(crate) fn goto_type_definition(
    db: &RootDatabase,
    position: FilePosition,
) -> Option<RangeInfo<Vec<NavigationTarget>>> {
    let sema = hir::Semantics::new(db);

    let file: ast::SourceFile = sema.parse(position.file_id);
    let token: SyntaxToken =
        pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind {
            IDENT | INT_NUMBER | T![self] => 2,
            kind if kind.is_trivia() => 0,
            _ => 1,
        })?;

    let mut res = Vec::new();
    let mut push = |def: hir::ModuleDef| {
        if let Some(nav) = def.try_to_nav(db) {
            if !res.contains(&nav) {
                res.push(nav);
            }
        }
    };
    let range = token.text_range();
    sema.descend_into_macros(token)
        .iter()
        .filter_map(|token| {
            let ty = sema.token_ancestors_with_macros(token.clone()).find_map(|node| {
                let ty = match_ast! {
                    match node {
                        ast::Expr(it) => sema.type_of_expr(&it)?.original,
                        ast::Pat(it) => sema.type_of_pat(&it)?.original,
                        ast::SelfParam(it) => sema.type_of_self(&it)?,
                        ast::Type(it) => sema.resolve_type(&it)?,
                        ast::RecordField(it) => sema.to_def(&it).map(|d| d.ty(db.upcast()))?,
                        // can't match on RecordExprField directly as `ast::Expr` will match an iteration too early otherwise
                        ast::NameRef(it) => {
                            if let Some(record_field) = ast::RecordExprField::for_name_ref(&it) {
                                let (_, _, ty) = sema.resolve_record_field(&record_field)?;
                                ty
                            } else {
                                let record_field = ast::RecordPatField::for_field_name_ref(&it)?;
                                sema.resolve_record_pat_field(&record_field)?.ty(db)
                            }
                        },
                        _ => return None,
                    }
                };

                Some(ty)
            });
            ty
        })
        .for_each(|ty| {
            // collect from each `ty` into the `res` result vec
            let ty = ty.strip_references();
            ty.walk(db, |t| {
                if let Some(adt) = t.as_adt() {
                    push(adt.into());
                } else if let Some(trait_) = t.as_dyn_trait() {
                    push(trait_.into());
                } else if let Some(traits) = t.as_impl_traits(db) {
                    traits.into_iter().for_each(|it| push(it.into()));
                } else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
                    push(trait_.into());
                }
            });
        });
    if res.is_empty() {
        None
    } else {
        Some(RangeInfo::new(range, res))
    }
}

#[cfg(test)]
mod tests {
    use ide_db::base_db::FileRange;
    use itertools::Itertools;

    use crate::fixture;

    fn check(ra_fixture: &str) {
        let (analysis, position, expected) = fixture::annotations(ra_fixture);
        let navs = analysis.goto_type_definition(position).unwrap().unwrap().info;
        assert_ne!(navs.len(), 0);

        let cmp = |&FileRange { file_id, range }: &_| (file_id, range.start());
        let navs = navs
            .into_iter()
            .map(|nav| FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() })
            .sorted_by_key(cmp)
            .collect::<Vec<_>>();
        let expected = expected
            .into_iter()
            .map(|(FileRange { file_id, range }, _)| FileRange { file_id, range })
            .sorted_by_key(cmp)
            .collect::<Vec<_>>();
        assert_eq!(expected, navs);
    }

    #[test]
    fn goto_type_definition_works_simple() {
        check(
            r#"
struct Foo;
     //^^^
fn foo() {
    let f: Foo; f$0
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_record_expr_field() {
        check(
            r#"
struct Bar;
    // ^^^
struct Foo { foo: Bar }
fn foo() {
    Foo { foo$0 }
}
"#,
        );
        check(
            r#"
struct Bar;
    // ^^^
struct Foo { foo: Bar }
fn foo() {
    Foo { foo$0: Bar }
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_record_pat_field() {
        check(
            r#"
struct Bar;
    // ^^^
struct Foo { foo: Bar }
fn foo() {
    let Foo { foo$0 };
}
"#,
        );
        check(
            r#"
struct Bar;
    // ^^^
struct Foo { foo: Bar }
fn foo() {
    let Foo { foo$0: bar };
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_works_simple_ref() {
        check(
            r#"
struct Foo;
     //^^^
fn foo() {
    let f: &Foo; f$0
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_works_through_macro() {
        check(
            r#"
macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
struct Foo {}
     //^^^
id! {
    fn bar() { let f$0 = Foo {}; }
}
"#,
        );
    }

    #[test]
    fn goto_type_definition_for_param() {
        check(
            r#"
struct Foo;
     //^^^
fn foo($0f: Foo) {}
"#,
        );
    }

    #[test]
    fn goto_type_definition_for_tuple_field() {
        check(
            r#"
struct Foo;
     //^^^
struct Bar(Foo);
fn foo() {
    let bar = Bar(Foo);
    bar.$00;
}
"#,
        );
    }

    #[test]
    fn goto_def_for_self_param() {
        check(
            r#"
struct Foo;
     //^^^
impl Foo {
    fn f(&self$0) {}
}
"#,
        )
    }

    #[test]
    fn goto_def_for_type_fallback() {
        check(
            r#"
struct Foo;
     //^^^
impl Foo$0 {}
"#,
        )
    }

    #[test]
    fn goto_def_for_struct_field() {
        check(
            r#"
struct Bar;
     //^^^

struct Foo {
    bar$0: Bar,
}
"#,
        );
    }

    #[test]
    fn goto_def_for_enum_struct_field() {
        check(
            r#"
struct Bar;
     //^^^

enum Foo {
    Bar {
        bar$0: Bar
    },
}
"#,
        );
    }

    #[test]
    fn goto_def_considers_generics() {
        check(
            r#"
struct Foo;
     //^^^
struct Bar<T, U>(T, U);
     //^^^
struct Baz<T>(T);
     //^^^

fn foo(x$0: Bar<Baz<Foo>, Baz<usize>) {}
"#,
        );
    }
}
<|endoftext|>


<commit_before>use {
    BackEnd,
    Borrowed,
    Clear,
    Field,
    Fill,
    Image,
    Value,
};
use triangulation::{
    with_round_rectangle_tri_list_xy_f32_rgba_f32
};
use internal::{
    CanColor,
    CanRectangle,
    CanTransform,
    CanViewTransform,
    Color,
    HasColor,
    HasRectangle,
    HasTransform,
    HasViewTransform,
    Matrix2d,
    Radius,
    Rectangle,
};

/// A rectangle color context.
pub struct BevelRectangleColorContext<'a> {
    /// View transformation.
    pub view: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current bevel radius.
    pub bevel_radius: Field<'a, Radius>,
    /// Current color.
    pub color: Field<'a, Color>,
}

impl<'a> Clone for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn clone(&self) -> BevelRectangleColorContext<'static> {
        BevelRectangleColorContext {
            view: Value(*self.view.get()),
            transform: Value(*self.transform.get()),
            rect: Value(*self.rect.get()),
            bevel_radius: Value(*self.bevel_radius.get()),
            color: Value(*self.color.get()),
        }
    }
}

impl<'a> HasTransform<'a, Matrix2d> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, BevelRectangleColorContext<'a>, Matrix2d> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Value(value),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> HasViewTransform<'a, Matrix2d> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn get_view_transform(&'a self) -> &'a Matrix2d {
        self.view.get()
    }
}

impl<'a> CanViewTransform<'a, BevelRectangleColorContext<'a>, Matrix2d>
for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn view_transform(&'a self, value: Matrix2d) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Value(value),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> HasColor<'a, Color> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn get_color(&'a self) -> &'a Color {
        self.color.get()
    }
}

impl<'a> CanColor<'a, BevelRectangleColorContext<'a>, Color> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn color(&'a self, value: Color) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            color: Value(value),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

impl<'a> HasRectangle<'a, Rectangle> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn get_rectangle(&'a self) -> &'a Rectangle {
        self.rect.get()
    }
}

impl<'a> CanRectangle<'a, BevelRectangleColorContext<'a>, Rectangle> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn rectangle(&'a self, rect: Rectangle) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Value(rect),
            bevel_radius: Borrowed(self.bevel_radius.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a, B: BackEnd<I>, I: Image> Clear<B, I> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn clear(&self, back_end: &mut B) {
        if back_end.supports_clear_rgba() {
            let color = self.color.get();
            back_end.clear_rgba(color[0], color[1], color[2], color[3]);
        } else {
            unimplemented!();
        }
    }
}

impl<'a> Fill<'a> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn fill<B: BackEnd<I>, I: Image>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32() {
            let rect = self.rect.get();
            let bevel_radius = self.bevel_radius.get();
            let color = self.color.get();
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_round_rectangle_tri_list_xy_f32_rgba_f32(
                2,
                *self.transform.get(),
                *rect,
                *bevel_radius,
                *color,
                |vertices, colors| {
                    back_end.tri_list_xy_f32_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

<commit_msg>Implemented `AddBorder` for `BevelRectangleBorderColorContext`<commit_after>use {
    AddBorder,
    BackEnd,
    BevelRectangleBorderColorContext,
    Borrowed,
    Clear,
    Field,
    Fill,
    Image,
    Value,
};
use triangulation::{
    with_round_rectangle_tri_list_xy_f32_rgba_f32
};
use internal::{
    CanColor,
    CanRectangle,
    CanTransform,
    CanViewTransform,
    Color,
    HasColor,
    HasRectangle,
    HasTransform,
    HasViewTransform,
    Matrix2d,
    Radius,
    Rectangle,
};

/// A rectangle color context.
pub struct BevelRectangleColorContext<'a> {
    /// View transformation.
    pub view: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current bevel radius.
    pub bevel_radius: Field<'a, Radius>,
    /// Current color.
    pub color: Field<'a, Color>,
}

impl<'a> Clone for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn clone(&self) -> BevelRectangleColorContext<'static> {
        BevelRectangleColorContext {
            view: Value(*self.view.get()),
            transform: Value(*self.transform.get()),
            rect: Value(*self.rect.get()),
            bevel_radius: Value(*self.bevel_radius.get()),
            color: Value(*self.color.get()),
        }
    }
}

impl<'a> HasTransform<'a, Matrix2d> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, BevelRectangleColorContext<'a>, Matrix2d> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Value(value),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> HasViewTransform<'a, Matrix2d> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn get_view_transform(&'a self) -> &'a Matrix2d {
        self.view.get()
    }
}

impl<'a> CanViewTransform<'a, BevelRectangleColorContext<'a>, Matrix2d>
for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn view_transform(&'a self, value: Matrix2d) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Value(value),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> HasColor<'a, Color> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn get_color(&'a self) -> &'a Color {
        self.color.get()
    }
}

impl<'a> CanColor<'a, BevelRectangleColorContext<'a>, Color> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn color(&'a self, value: Color) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            color: Value(value),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

impl<'a> HasRectangle<'a, Rectangle> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn get_rectangle(&'a self) -> &'a Rectangle {
        self.rect.get()
    }
}

impl<'a> CanRectangle<'a, BevelRectangleColorContext<'a>, Rectangle> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn rectangle(&'a self, rect: Rectangle) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Value(rect),
            bevel_radius: Borrowed(self.bevel_radius.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a, B: BackEnd<I>, I: Image> Clear<B, I> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn clear(&self, back_end: &mut B) {
        if back_end.supports_clear_rgba() {
            let color = self.color.get();
            back_end.clear_rgba(color[0], color[1], color[2], color[3]);
        } else {
            unimplemented!();
        }
    }
}

impl<'a> Fill<'a> for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn fill<B: BackEnd<I>, I: Image>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32() {
            let rect = self.rect.get();
            let bevel_radius = self.bevel_radius.get();
            let color = self.color.get();
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_round_rectangle_tri_list_xy_f32_rgba_f32(
                2,
                *self.transform.get(),
                *rect,
                *bevel_radius,
                *color,
                |vertices, colors| {
                    back_end.tri_list_xy_f32_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> AddBorder<'a, BevelRectangleBorderColorContext<'a>>
for BevelRectangleColorContext<'a> {
    #[inline(always)]
    fn border_radius(&'a self, radius: f64) -> BevelRectangleBorderColorContext<'a> {
        BevelRectangleBorderColorContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
            color: Borrowed(self.color.get()),
            border: Value(radius),
        }
    }
}

<|endoftext|>


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

// error-pattern:explicit failure

#[no_uv];

extern mod native;

#[start]
fn start(argc: int, argv: **u8) -> int {
    do native::start(argc, argv) {
        fail!();
    }
}
<commit_msg>xfail another native test on android (#11419)<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-android (FIXME #11419)
// error-pattern:explicit failure

#[no_uv];

extern mod native;

#[start]
fn start(argc: int, argv: **u8) -> int {
    do native::start(argc, argv) {
        fail!();
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::collections::HashMap;

use asnom::structure::StructureTag;
use asnom::structures::{Tag, Sequence, Integer, OctetString, Boolean};
use asnom::common::TagClass::*;

use filter::parse;

use futures::{Future, stream, Stream};
use tokio_service::Service;

use ldap::Ldap;
use service::{LdapMessage, LdapMessageStream};

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Scope {
    BaseObject   = 0,
    SingleLevel  = 1,
    WholeSubtree = 2,
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum DerefAliases {
    Never             = 0,
    InSearch          = 1,
    FindingBaseObject = 2,
    Always            = 3,
}

#[derive(Clone, Debug, PartialEq)]
pub enum SearchEntry {
    Reference(Vec<String>),
    Object {
        object_name: String,
        attributes: HashMap<String, Vec<String>>,
    },
}

impl SearchEntry {
    pub fn construct(tag: Tag) -> SearchEntry {
        match tag {
            Tag::StructureTag(t) => {
                match t.id {
                    // Search Result Entry
                    // Search Result Done (if the result set is empty)
                    4|5 => {
                        let mut tags = t.expect_constructed().unwrap();
                        let attributes = tags.pop().unwrap();
                        let object_name = tags.pop().unwrap();
                        let object_name = String::from_utf8(object_name.expect_primitive().unwrap()).unwrap();

                        let a = construct_attributes(attributes.expect_constructed().unwrap_or(vec![])).unwrap();

                        SearchEntry::Object {
                            object_name: object_name,
                            attributes: a,
                        }
                    },
                    // Search Result Reference
                    19 => {
                        // TODO actually handle this case
                        SearchEntry::Reference(vec![])
                    },
                    _ => panic!("Search received a non-search tag!"),
                }
            }
            _ => unimplemented!()
        }
    }
}

fn construct_attributes(tags: Vec<StructureTag>) -> Option<HashMap<String, Vec<String>>> {
    let mut map = HashMap::new();
    for tag in tags.into_iter() {
        let mut inner = tag.expect_constructed().unwrap();

        let values = inner.pop().unwrap();
        let valuev = values.expect_constructed().unwrap()
                           .into_iter()
                           .map(|t| t.expect_primitive().unwrap())
                           .map(|v| String::from_utf8(v).unwrap())
                           .collect();
        let key = inner.pop().unwrap();
        let keystr = String::from_utf8(key.expect_primitive().unwrap()).unwrap();

        map.insert(keystr, valuev);
    }

    Some(map)
}

impl Ldap {
    pub fn search(&self,
                    base: String,
                    scope: Scope,
                    deref: DerefAliases,
                    typesonly: bool,
                    filter: String,
                    attrs: Vec<String>) ->
        Box<Future<Item = Vec<SearchEntry>, Error = io::Error>> {
        let req = Tag::Sequence(Sequence {
            id: 3,
            class: Application,
            inner: vec![
                   Tag::OctetString(OctetString {
                       inner: base.into_bytes(),
                       .. Default::default()
                   }),
                   Tag::Integer(Integer {
                       inner: scope as i64,
                       .. Default::default()
                   }),
                   Tag::Integer(Integer {
                       inner: deref as i64,
                       .. Default::default()
                   }),
                   Tag::Integer(Integer {
                       inner: 0,
                       .. Default::default()
                   }),
                   Tag::Integer(Integer {
                       inner: 0,
                       .. Default::default()
                   }),
                   Tag::Boolean(Boolean {
                       inner: typesonly,
                       .. Default::default()
                   }),
                   parse(&filter).unwrap(),
                   Tag::Sequence(Sequence {
                       inner: attrs.into_iter().map(|s|
                            Tag::OctetString(OctetString { inner: s.into_bytes(), ..Default::default() })).collect(),
                       .. Default::default()
                   })
            ],
        });

        let fut = self.call(req).and_then(|res| {
            let ostr = match res {
                LdapMessage::Stream(first, body) => {
                    let fstr = stream::once(Ok(first));
                    fstr.chain(body)
                },
                LdapMessage::Once(first) => {
                    let fstr = stream::once(Ok(first));
                    fstr.chain(LdapMessageStream::empty())
                },
            };
            ostr.map(|x| SearchEntry::construct(x))
                .collect()
                .and_then(|x| Ok(x))
        });

        Box::new(fut)
    }
}

<commit_msg>Rename scope constants<commit_after>use std::io;
use std::collections::HashMap;

use asnom::structure::StructureTag;
use asnom::structures::{Tag, Sequence, Integer, OctetString, Boolean};
use asnom::common::TagClass::*;

use filter::parse;

use futures::{Future, stream, Stream};
use tokio_service::Service;

use ldap::Ldap;
use service::{LdapMessage, LdapMessageStream};

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Scope {
    Base     = 0,
    OneLevel = 1,
    Subtree  = 2,
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum DerefAliases {
    Never             = 0,
    InSearch          = 1,
    FindingBaseObject = 2,
    Always            = 3,
}

#[derive(Clone, Debug, PartialEq)]
pub enum SearchEntry {
    Reference(Vec<String>),
    Object {
        object_name: String,
        attributes: HashMap<String, Vec<String>>,
    },
}

impl SearchEntry {
    pub fn construct(tag: Tag) -> SearchEntry {
        match tag {
            Tag::StructureTag(t) => {
                match t.id {
                    // Search Result Entry
                    // Search Result Done (if the result set is empty)
                    4|5 => {
                        let mut tags = t.expect_constructed().unwrap();
                        let attributes = tags.pop().unwrap();
                        let object_name = tags.pop().unwrap();
                        let object_name = String::from_utf8(object_name.expect_primitive().unwrap()).unwrap();

                        let a = construct_attributes(attributes.expect_constructed().unwrap_or(vec![])).unwrap();

                        SearchEntry::Object {
                            object_name: object_name,
                            attributes: a,
                        }
                    },
                    // Search Result Reference
                    19 => {
                        // TODO actually handle this case
                        SearchEntry::Reference(vec![])
                    },
                    _ => panic!("Search received a non-search tag!"),
                }
            }
            _ => unimplemented!()
        }
    }
}

fn construct_attributes(tags: Vec<StructureTag>) -> Option<HashMap<String, Vec<String>>> {
    let mut map = HashMap::new();
    for tag in tags.into_iter() {
        let mut inner = tag.expect_constructed().unwrap();

        let values = inner.pop().unwrap();
        let valuev = values.expect_constructed().unwrap()
                           .into_iter()
                           .map(|t| t.expect_primitive().unwrap())
                           .map(|v| String::from_utf8(v).unwrap())
                           .collect();
        let key = inner.pop().unwrap();
        let keystr = String::from_utf8(key.expect_primitive().unwrap()).unwrap();

        map.insert(keystr, valuev);
    }

    Some(map)
}

impl Ldap {
    pub fn search(&self,
                    base: String,
                    scope: Scope,
                    deref: DerefAliases,
                    typesonly: bool,
                    filter: String,
                    attrs: Vec<String>) ->
        Box<Future<Item = Vec<SearchEntry>, Error = io::Error>> {
        let req = Tag::Sequence(Sequence {
            id: 3,
            class: Application,
            inner: vec![
                   Tag::OctetString(OctetString {
                       inner: base.into_bytes(),
                       .. Default::default()
                   }),
                   Tag::Integer(Integer {
                       inner: scope as i64,
                       .. Default::default()
                   }),
                   Tag::Integer(Integer {
                       inner: deref as i64,
                       .. Default::default()
                   }),
                   Tag::Integer(Integer {
                       inner: 0,
                       .. Default::default()
                   }),
                   Tag::Integer(Integer {
                       inner: 0,
                       .. Default::default()
                   }),
                   Tag::Boolean(Boolean {
                       inner: typesonly,
                       .. Default::default()
                   }),
                   parse(&filter).unwrap(),
                   Tag::Sequence(Sequence {
                       inner: attrs.into_iter().map(|s|
                            Tag::OctetString(OctetString { inner: s.into_bytes(), ..Default::default() })).collect(),
                       .. Default::default()
                   })
            ],
        });

        let fut = self.call(req).and_then(|res| {
            let ostr = match res {
                LdapMessage::Stream(first, body) => {
                    let fstr = stream::once(Ok(first));
                    fstr.chain(body)
                },
                LdapMessage::Once(first) => {
                    let fstr = stream::once(Ok(first));
                    fstr.chain(LdapMessageStream::empty())
                },
            };
            ostr.map(|x| SearchEntry::construct(x))
                .collect()
                .and_then(|x| Ok(x))
        });

        Box::new(fut)
    }
}

<|endoftext|>


<commit_before>use bus::Addressable;

const ADDR_SB: u16 = 0xFF01;
const ADDR_SC: u16 = 0xFF02;

// Internal clock for the serial port runs at 8192Hz
const INT_CLOCK_CYCLES: usize = 8192;

bitflags! {
    struct Sc: u8 {
        const SC_START_TRANSFER    = 0b1000_0000;   // Setting bit enables transfer. Bit is reset upon completion.
        const SC_CLOCK             = 0b0000_0001;   // Setting bit enables internal clock.
    }
}

#[derive(Default)]
pub struct SerialResult {
    pub interrupt: bool         // Interrupt is raised after a byte is transferred
}

pub struct Serial {
    sb: u8,                     // SB stores the byte of data to be transferred out the serial port. It is replaced with a byte coming from the other side.
    sc: Sc,                     // SC controls the serial interface
    transfer_bit: usize,        // The current bit being transferred out of the serial connection
    transfer_bit_cycles: usize  // Running tally of clock cycles for the current bit transfer
}

impl Serial {
    pub fn new() -> Self {
        Self {
            sb: 0,
            sc: Sc::empty(),
            transfer_bit: 0,
            transfer_bit_cycles: 0
        }
    }

    pub fn step(&mut self, cycles: usize) -> SerialResult {
        let mut interrupt = false;

        // When a serial transfer is initiated and the GB is using an internal clock, a bit is transferred at a rate of 8192Hz.
        // Nothing is done when using an external clock. I don't see any other GB around here!
        if self.sc.contains(Sc::SC_CLOCK) && self.sc.contains(Sc::SC_START_TRANSFER) {
            self.transfer_bit_cycles += cycles;

            // On every tick of the serial clock, shift a bit off of SB
            // In a real GB, the bit from the other GB would be shifted in
            if self.transfer_bit_cycles >= INT_CLOCK_CYCLES {
                self.sb = self.sb << 1;

                // When all 8 bits are transferred, raise an interrupt and update SC to disable transfer
                if self.transfer_bit == 7 {
                    interrupt = true;

                    self.transfer_bit = 0;
                    self.sc.remove(Sc::SC_START_TRANSFER);
                } else {
                    self.transfer_bit += 1;
                }
            }
        }

        SerialResult {
            interrupt: interrupt
        }
    }
}

impl Addressable for Serial {
    fn read(&self, addr: u16) -> u8 {
        return match addr {
            ADDR_SB => self.sb,
            ADDR_SC => self.sc.bits(),
            _ => unreachable!()
        }
    }

    fn write(&mut self, addr: u16, byte: u8) {
        match addr {
            ADDR_SB => self.sb = byte,
            ADDR_SC => self.sc = Sc::from_bits(byte).unwrap(),
            _ => unreachable!()
        };
    }
}<commit_msg>GBC serial double  speed bit<commit_after>use bus::Addressable;

const ADDR_SB: u16 = 0xFF01;
const ADDR_SC: u16 = 0xFF02;

// Internal clock for the serial port runs at 8192Hz
const INT_CLOCK_CYCLES: usize = 8192;

bitflags! {
    struct Sc: u8 {
        const SC_START_TRANSFER    = 0b1000_0000;   // Setting bit enables transfer. Bit is reset upon completion.
        const SC_FAST_SPEED_GBC    = 0b0000_0010;
        const SC_CLOCK             = 0b0000_0001;   // Setting bit enables internal clock.
    }
}

#[derive(Default)]
pub struct SerialResult {
    pub interrupt: bool         // Interrupt is raised after a byte is transferred
}

pub struct Serial {
    sb: u8,                     // SB stores the byte of data to be transferred out the serial port. It is replaced with a byte coming from the other side.
    sc: Sc,                     // SC controls the serial interface
    transfer_bit: usize,        // The current bit being transferred out of the serial connection
    transfer_bit_cycles: usize  // Running tally of clock cycles for the current bit transfer
}

impl Serial {
    pub fn new() -> Self {
        Self {
            sb: 0,
            sc: Sc::empty(),
            transfer_bit: 0,
            transfer_bit_cycles: 0
        }
    }

    pub fn step(&mut self, cycles: usize) -> SerialResult {
        let mut interrupt = false;

        // When a serial transfer is initiated and the GB is using an internal clock, a bit is transferred at a rate of 8192Hz.
        // Nothing is done when using an external clock. I don't see any other GB around here!
        if self.sc.contains(Sc::SC_CLOCK) && self.sc.contains(Sc::SC_START_TRANSFER) {
            self.transfer_bit_cycles += cycles;

            // On every tick of the serial clock, shift a bit off of SB
            // In a real GB, the bit from the other GB would be shifted in
            if self.transfer_bit_cycles >= INT_CLOCK_CYCLES {
                self.sb = self.sb << 1;

                // When all 8 bits are transferred, raise an interrupt and update SC to disable transfer
                if self.transfer_bit == 7 {
                    interrupt = true;

                    self.transfer_bit = 0;
                    self.sc.remove(Sc::SC_START_TRANSFER);
                } else {
                    self.transfer_bit += 1;
                }
            }
        }

        SerialResult {
            interrupt: interrupt
        }
    }
}

impl Addressable for Serial {
    fn read(&self, addr: u16) -> u8 {
        return match addr {
            ADDR_SB => self.sb,
            ADDR_SC => self.sc.bits(),
            _ => unreachable!()
        }
    }

    fn write(&mut self, addr: u16, byte: u8) {
        match addr {
            ADDR_SB => self.sb = byte,
            ADDR_SC => self.sc = Sc::from_bits(byte & 0b1000_0001).unwrap(),
            _ => unreachable!()
        };
    }
}<|endoftext|>


<commit_before>//! Iron web server that serves the API.
use diesel::migrations::run_pending_migrations;
use hyper::server::Listening;
use iron::{Chain, Handler, Iron};
use iron::error::HttpResult;
use mount::Mount;
use persistent::{Read, Write};
use r2d2::{Config as R2D2Config, Pool};
use r2d2_diesel::ConnectionManager;
use router::Router;

use api::r0::registration::Register;
use api::r0::versions::Versions;
use config::FinalConfig;
use error::CLIError;
use db::DB;

/// Ruma's web server.
pub struct Server<'a, T> where T: Handler {
    config: &'a FinalConfig,
    iron: Iron<T>,
}

impl<'a> Server<'a, Mount> {
    /// Create a new `Server` from a `FinalConfig`.
    pub fn new(config: &FinalConfig) -> Result<Server<Mount>, CLIError> {
        let mut router = Router::new();

        router.post("/register", Register::chain());

        let mut r0 = Chain::new(router);

        debug!("Connecting to PostgreSQL.");
        let r2d2_config = R2D2Config::default();
        let connection_manager = ConnectionManager::new(&config.postgres_url[..]);
        let connection_pool = try!(Pool::new(r2d2_config, connection_manager));
        let connection = try!(connection_pool.get());

        debug!("Running pending migrations.");
        match run_pending_migrations(&*connection) {
            Ok(_) => {},
            Err(error) => return Err(CLIError::new(format!("{:?}", error))),
        }

        r0.link_before(Read::<FinalConfig>::one(config.clone()));
        r0.link_before(Write::<DB>::one(connection_pool));

        let mut versions = Router::new();
        versions.get("/versions", Versions::new(vec!["r0.0.1"]));

        let mut mount = Mount::new();

        mount.mount("/_matrix/client/", versions);
        mount.mount("/_matrix/client/r0/", r0);

        Ok(Server {
            config: config,
            iron: Iron::new(mount),
        })
    }

    /// Run the server and block the current thread until stopped or interrupted.
    pub fn run(self) -> HttpResult<Listening> {
        let address = format!("{}:{}", self.config.bind_address, self.config.bind_port);

        info!("Starting Ruma server on {}.", address);

        self.iron.http(&address[..])
    }
}
<commit_msg>Ensure Diesel's timestamp SQL helper is added to the DB.<commit_after>//! Iron web server that serves the API.
use diesel::migrations::{run_pending_migrations, setup_database};
use hyper::server::Listening;
use iron::{Chain, Handler, Iron};
use iron::error::HttpResult;
use mount::Mount;
use persistent::{Read, Write};
use r2d2::{Config as R2D2Config, Pool};
use r2d2_diesel::ConnectionManager;
use router::Router;

use api::r0::registration::Register;
use api::r0::versions::Versions;
use config::FinalConfig;
use error::CLIError;
use db::DB;

/// Ruma's web server.
pub struct Server<'a, T> where T: Handler {
    config: &'a FinalConfig,
    iron: Iron<T>,
}

impl<'a> Server<'a, Mount> {
    /// Create a new `Server` from a `FinalConfig`.
    pub fn new(config: &FinalConfig) -> Result<Server<Mount>, CLIError> {
        let mut router = Router::new();

        router.post("/register", Register::chain());

        let mut r0 = Chain::new(router);

        debug!("Connecting to PostgreSQL.");
        let r2d2_config = R2D2Config::default();
        let connection_manager = ConnectionManager::new(&config.postgres_url[..]);
        let connection_pool = try!(Pool::new(r2d2_config, connection_manager));
        let connection = try!(connection_pool.get());

        debug!("Setting up database.");
        if let Err(error) =  setup_database(&*connection) {
            return Err(CLIError::new(format!("{:?}", error)));
        }

        debug!("Running pending database migrations.");
        if let Err(error) = run_pending_migrations(&*connection) {
            return Err(CLIError::new(format!("{:?}", error)));
        }

        r0.link_before(Read::<FinalConfig>::one(config.clone()));
        r0.link_before(Write::<DB>::one(connection_pool));

        let mut versions = Router::new();
        versions.get("/versions", Versions::new(vec!["r0.0.1"]));

        let mut mount = Mount::new();

        mount.mount("/_matrix/client/", versions);
        mount.mount("/_matrix/client/r0/", r0);

        Ok(Server {
            config: config,
            iron: Iron::new(mount),
        })
    }

    /// Run the server and block the current thread until stopped or interrupted.
    pub fn run(self) -> HttpResult<Listening> {
        let address = format!("{}:{}", self.config.bind_address, self.config.bind_port);

        info!("Starting Ruma server on {}.", address);

        self.iron.http(&address[..])
    }
}
<|endoftext|>