<commit_before>use redox::*;

pub struct Editor {
    url: String,
    file: Option<File>,
    string: String,
    offset: usize,
    scroll_x: isize,
    scroll_y: isize,
}

impl Editor {
    #[inline(never)]
    pub fn new() -> Self {
        Editor {
            url: String::new(),
            file: Option::None,
            string: String::new(),
            offset: 0,
            scroll_x: 0,
            scroll_y: 0,
        }
    }

    fn reload(&mut self, window: &mut Window) {
        window.set_title(&("Editor (".to_string() + &self.url + ")"));
        self.offset = 0;
        self.scroll_x = 0;
        self.scroll_y = 0;

        match self.file {
            Option::Some(ref mut file) => {
                file.seek(Seek::Start(0));
                let mut vec: Vec<u8> = Vec::new();
                file.read_to_end(&mut vec);
                self.string = unsafe { String::from_utf8_unchecked(vec) };
            }
            Option::None => self.string = String::new(),
        }
    }

    fn save(&mut self, window: &mut Window) {
        match self.file {
            Option::Some(ref mut file) => {
                window.set_title(&("Editor (".to_string() + &self.url + ") Saved"));
                file.seek(Seek::Start(0));
                file.write(&self.string.as_bytes());
                file.sync();
            }
            Option::None => {
                //TODO: Ask for file to save to
                window.set_title(&("Editor (".to_string() + &self.url + ") No Open File"));
            }
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        let mut redraw = false;

        {
            window.set([255, 255, 255, 255]);

            let scroll_x = self.scroll_x;
            let scroll_y = self.scroll_y;

            let mut offset = 0;

            let mut col = -scroll_x;
            let cols = window.width() as isize / 8;

            let mut row = -scroll_y;
            let rows = window.height() as isize / 16;

            for c in self.string.chars() {
                if offset == self.offset {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                    } else {
                        if col < 0 { //Too far to the left
                            self.scroll_x += col;
                        } else if col >= cols { //Too far to the right
                            self.scroll_x += cols - col + 1;
                        }
                        if row < 0 { //Too far up
                            self.scroll_y += row;
                        } else if row >= rows { //Too far down
                            self.scroll_y += rows - row + 1;
                        }

                        redraw = true;
                    }
                }

                if c == '\n' {
                    col = -scroll_x;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, c, [0, 0, 0, 255]);
                    }
                    col += 1;
                }

                offset += 1;
            }

            if offset == self.offset {
                if col >= 0 && col < cols && row >= 0 && row < rows {
                    window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                } else {
                    if col < 0 { //Too far to the left
                        self.scroll_x += col;
                    } else if col >= cols { //Too far to the right
                        self.scroll_x += cols - col + 1;
                    }
                    if row < 0 { //Too far up
                        self.scroll_y += row;
                    } else if row >= rows { //Too far down
                        self.scroll_y += rows - row + 1;
                    }

                    redraw = true;
                }
            }

            window.sync();
        }

        if redraw {
            self.draw_content(window);
        }
    }

    fn main(&mut self, url: &str) {
        let mut window = Window::new((rand() % 400 + 50) as isize,
                                     (rand() % 300 + 50) as isize,
                                     576,
                                     400,
                                      &("Editor (".to_string() + url + ")"));

        self.url = url.to_string();
        self.file = Option::Some(File::open(&self.url));

        self.reload(&mut window);
        self.draw_content(&mut window);

        while let Option::Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        match key_event.scancode {
                            K_ESC => break,
                            K_BKSP => if self.offset > 0 {
                                window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
                                self.string = self.string[0 .. self.offset - 1].to_string() +
                                              &self.string[self.offset .. self.string.len()];
                                self.offset -= 1;
                            },
                            K_DEL => if self.offset < self.string.len() {
                                window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
                                self.string = self.string[0 .. self.offset].to_string() +
                                              &self.string[self.offset + 1 .. self.string.len() - 1];
                            },
                            K_F5 => self.reload(&mut window),
                            K_F6 => self.save(&mut window),
                            K_HOME => self.offset = 0,
                            K_UP => {
                                let mut new_offset = 0;
                                for i in 2..self.offset {
                                    match self.string.as_bytes()[self.offset - i] {
                                        0 => break,
                                        10 => {
                                            new_offset = self.offset - i + 1;
                                            break;
                                        }
                                        _ => (),
                                    }
                                }
                                self.offset = new_offset;
                            }
                            K_LEFT => if self.offset > 0 {
                                self.offset -= 1;
                            },
                            K_RIGHT => if self.offset < self.string.len() {
                                self.offset += 1;
                            },
                            K_END => self.offset = self.string.len(),
                            K_DOWN => {
                                let mut new_offset = self.string.len();
                                for i in self.offset..self.string.len() {
                                    match self.string.as_bytes()[i] {
                                        0 => break,
                                        10 => {
                                            new_offset = i + 1;
                                            break;
                                        }
                                        _ => (),
                                    }
                                }
                                self.offset = new_offset;
                            }
                            _ => match key_event.character {
                                '\0' => (),
                                _ => {
                                    window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
                                    self.string = self.string[0 .. self.offset].to_string() +
                                                  &key_event.character.to_string() +
                                                  &self.string[self.offset .. self.string.len()];
                                    self.offset += 1;
                                }
                            },
                        }

                        self.draw_content(&mut window);
                    }
                }
                _ => (),
            }
        }
    }
}

pub fn main() {
    match args().get(1) {
        Option::Some(arg) => Editor::new().main(&arg),
        Option::None => Editor::new().main("none://"),
    }
}
<commit_msg>Make editor behave more Vi-like<commit_after>use redox::*;

#[derive(Copy, Clone)]
pub enum Mode {
    Insert,
    Normal,
}

pub struct Editor {
    url: String,
    file: Option<File>,
    string: String,
    offset: usize,
    scroll_x: isize,
    scroll_y: isize,
}

impl Editor {
    #[inline(never)]
    pub fn new() -> Self {
        Editor {
            url: String::new(),
            file: Option::None,
            string: String::new(),
            offset: 0,
            scroll_x: 0,
            scroll_y: 0,
        }
    }

    fn up(&mut self) {
        let mut new_offset = 0;
        for i in 2..self.offset {
            match self.string.as_bytes()[self.offset - i] {
                0 => break,
                10 => {
                    new_offset = self.offset - i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn left(&mut self) {
        if self.offset > 0 {
            self.offset -= 1;
        }
    }

    fn right(&mut self) {
        if self.offset < self.string.len() {
            self.offset += 1;
        }
    }

    fn down(&mut self) {
        let mut new_offset = self.string.len();
        for i in self.offset..self.string.len() {
            match self.string.as_bytes()[i] {
                0 => break,
                10 => {
                    new_offset = i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn reload(&mut self, window: &mut Window) {
        window.set_title(&("Editor (".to_string() + &self.url + ")"));
        self.offset = 0;
        self.scroll_x = 0;
        self.scroll_y = 0;

        match self.file {
            Option::Some(ref mut file) => {
                file.seek(Seek::Start(0));
                let mut vec: Vec<u8> = Vec::new();
                file.read_to_end(&mut vec);
                self.string = unsafe { String::from_utf8_unchecked(vec) };
            },
            Option::None => self.string = String::new(),
        }
    }

    fn save(&mut self, window: &mut Window) {
        match self.file {
            Option::Some(ref mut file) => {
                window.set_title(&("Editor (".to_string() + &self.url + ") Saved"));
                file.seek(Seek::Start(0));
                file.write(&self.string.as_bytes());
                file.sync();
            }
            Option::None => {
                //TODO: Ask for file to save to
                window.set_title(&("Editor (".to_string() + &self.url + ") No Open File"));
            }
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        let mut redraw = false;

        {
            window.set([255, 255, 255, 255]);

            let scroll_x = self.scroll_x;
            let scroll_y = self.scroll_y;

            let mut offset = 0;

            let mut col = -scroll_x;
            let cols = window.width() as isize / 8;

            let mut row = -scroll_y;
            let rows = window.height() as isize / 16;

            for c in self.string.chars() {
                if offset == self.offset {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                    } else {
                        if col < 0 { //Too far to the left
                            self.scroll_x += col;
                        } else if col >= cols { //Too far to the right
                            self.scroll_x += cols - col + 1;
                        }
                        if row < 0 { //Too far up
                            self.scroll_y += row;
                        } else if row >= rows { //Too far down
                            self.scroll_y += rows - row + 1;
                        }

                        redraw = true;
                    }
                }

                if c == '\n' {
                    col = -scroll_x;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, c, [0, 0, 0, 255]);
                    }
                    col += 1;
                }

                offset += 1;
            }

            if offset == self.offset {
                if col >= 0 && col < cols && row >= 0 && row < rows {
                    window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                } else {
                    if col < 0 { //Too far to the left
                        self.scroll_x += col;
                    } else if col >= cols { //Too far to the right
                        self.scroll_x += cols - col + 1;
                    }
                    if row < 0 { //Too far up
                        self.scroll_y += row;
                    } else if row >= rows { //Too far down
                        self.scroll_y += rows - row + 1;
                    }

                    redraw = true;
                }
            }

            window.sync();
        }

        if redraw {
            self.draw_content(window);
        }
    }

    fn main(&mut self, url: &str) {
        let mut window = Window::new((rand() % 400 + 50) as isize,
                                     (rand() % 300 + 50) as isize,
                                     576,
                                     400,
                                      &("Editor (".to_string() + url + ")"));

        self.url = url.to_string();
        self.file = Option::Some(File::open(&self.url));

        self.reload(&mut window);
        self.draw_content(&mut window);

        let mut mode = Mode::Normal;

        while let Option::Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        use self::Mode::*;
                        match (mode, key_event.scancode) {
                            (Insert, K_ESC) => mode = Normal,
                            (Insert, K_BKSP) => if self.offset > 0 {
                                window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
                                self.string = self.string[0 .. self.offset - 1].to_string() +
                                              &self.string[self.offset .. self.string.len()];
                                self.offset -= 1;
                            },
                            (Insert, K_DEL) => if self.offset < self.string.len() {
                                window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
                                self.string = self.string[0 .. self.offset].to_string() +
                                              &self.string[self.offset + 1 .. self.string.len() - 1];
                            },
                            (_, K_F5) => self.reload(&mut window),
                            (_, K_F6) => self.save(&mut window),
                            (_, K_HOME) => self.offset = 0,
                            (_, K_UP) => self.up(),
                            (_, K_LEFT) => self.left(),
                            (_, K_RIGHT) => self.right(),
                            (_, K_END) => self.offset = self.string.len(),
                            (_, K_DOWN) => self.down(),
                            (m, _) => match (m, key_event.character) {
                                (Normal, 'i') => mode = Insert,
                                (Normal, 'h') => self.left(),
                                (Normal, 'l') => self.right(),
                                (Normal, 'k') => self.up(),
                                (Normal, 'j') => self.down(),
                                (Normal, 'G') => self.offset = self.string.len(),
                                (Normal, 'a') => {
                                    self.right();
                                    mode = Insert;
                                },
                                (Insert, '\0') => (),
                                (Insert, _) => {
                                    window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
                                    self.string = self.string[0 .. self.offset].to_string() +
                                                  &key_event.character.to_string() +
                                                  &self.string[self.offset .. self.string.len()];
                                    self.offset += 1;
                                },
                                _ => {},
                            }
                        }

                        self.draw_content(&mut window);
                    }
                }
                _ => (),
            }
        }
    }
}

pub fn main() {
    match args().get(1) {
        Option::Some(arg) => Editor::new().main(&arg),
        Option::None => Editor::new().main("none://"),
    }
}
<|endoftext|>


<commit_before>// TODO: Refactor using a matrix for performance

use redox::*;

mod cmd;

#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Mode {
    Insert,
    Normal,
}

pub struct Editor {
    url: String,
    file: Option<File>,
    string: String,
    offset: usize,
    scroll_x: isize,
    scroll_y: isize,
}

impl Editor {
    #[inline(never)]
    pub fn new() -> Self {
        Editor {
            url: String::new(),
            file: Option::None,
            string: String::new(),
            offset: 0,
            scroll_x: 0,
            scroll_y: 0,
        }
    }

    fn backspace(&mut self, window: &mut Window) {
         if self.offset > 0 {
             window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
             self.string = self.string[0 .. self.offset - 1].to_string() +
                 &self.string[self.offset .. self.string.len()];
             self.offset -= 1;
         }
    }

    fn delete(&mut self, window: &mut Window) {
        if self.offset < self.string.len() {
            window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
            self.string = self.string[0 .. self.offset].to_string() +
                &self.string[self.offset + 1 .. self.string.len()];
        }
    }

    // TODO: Add methods for multiple movements
    fn up(&mut self) {
        let mut new_offset = 0;
        for i in 2..self.offset {
            match self.string.as_bytes()[self.offset - i] {
                0 => break,
                10 => {
                    new_offset = self.offset - i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn left(&mut self) {
        if self.offset > 0 {
            self.offset -= 1;
        }
    }

    fn right(&mut self) {
        if self.offset < self.string.len() {
            self.offset += 1;
        }
    }

    fn down(&mut self) {
        let mut new_offset = self.string.len();
        for i in self.offset..self.string.len() {
            match self.string.as_bytes()[i] {
                0 => break,
                10 => {
                    new_offset = i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn cur(&self) -> char {
        self.string.chars().nth(self.offset).unwrap_or('\0')
    }

    fn insert(&mut self, c: char, window: &mut Window) {
        window.set_title(&format!("{}{}{}","self (", &self.url, ") Changed"));
        self.string = self.string[0 .. self.offset].to_string() +
            &c.to_string() +
            &self.string[self.offset .. self.string.len()];
        self.offset += 1;
    }

    fn reload(&mut self, window: &mut Window) {
        window.set_title(&("Editor (".to_string() + &self.url + ")"));
        self.offset = 0;
        self.scroll_x = 0;
        self.scroll_y = 0;

        match self.file {
            Option::Some(ref mut file) => {
                file.seek(Seek::Start(0));
                let mut vec: Vec<u8> = Vec::new();
                file.read_to_end(&mut vec);
                self.string = unsafe { String::from_utf8_unchecked(vec) };
            },
            Option::None => self.string = String::new(),
        }
    }

    fn save(&mut self, window: &mut Window) {
        match self.file {
            Option::Some(ref mut file) => {
                window.set_title(&("Editor (".to_string() + &self.url + ") Saved"));
                file.seek(Seek::Start(0));
                file.write(&self.string.as_bytes());
                file.sync();
            }
            Option::None => {
                //TODO: Ask for file to save to
                window.set_title(&("Editor (".to_string() + &self.url + ") No Open File"));
            }
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        let mut redraw = false;

        {
            window.set([255, 255, 255, 255]);

            let scroll_x = self.scroll_x;
            let scroll_y = self.scroll_y;

            let mut offset = 0;

            let mut col = -scroll_x;
            let cols = window.width() as isize / 8;

            let mut row = -scroll_y;
            let rows = window.height() as isize / 16;

            for c in self.string.chars() {
                if offset == self.offset {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                    } else {
                        if col < 0 { //Too far to the left
                            self.scroll_x += col;
                        } else if col >= cols { //Too far to the right
                            self.scroll_x += cols - col + 1;
                        }
                        if row < 0 { //Too far up
                            self.scroll_y += row;
                        } else if row >= rows { //Too far down
                            self.scroll_y += rows - row + 1;
                        }

                        redraw = true;
                    }
                }

                if c == '\n' {
                    col = -scroll_x;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, c, [0, 0, 0, 255]);
                    }
                    col += 1;
                }

                offset += 1;
            }

            if offset == self.offset {
                if col >= 0 && col < cols && row >= 0 && row < rows {
                    window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                } else {
                    if col < 0 { //Too far to the left
                        self.scroll_x += col;
                    } else if col >= cols { //Too far to the right
                        self.scroll_x += cols - col + 1;
                    }
                    if row < 0 { //Too far up
                        self.scroll_y += row;
                    } else if row >= rows { //Too far down
                        self.scroll_y += rows - row + 1;
                    }

                    redraw = true;
                }
            }

            window.sync();
        }

        if redraw {
            self.draw_content(window);
        }
    }

    fn main(&mut self, url: &str) {
        let mut window = Window::new((rand() % 400 + 50) as isize,
                                     (rand() % 300 + 50) as isize,
                                     576,
                                     400,
                                      &("Editor (".to_string() + url + ")"));

        self.url = url.to_string();
        self.file = Option::Some(File::open(&self.url));

        self.reload(&mut window);
        self.draw_content(&mut window);

        let mut mode = Mode::Normal;

        let mut last_change = String::new();
        let mut multiplier: Option<u32> = None;
        let mut swap = 0;
        let mut period = String::new();
        let mut is_recording = false;

        while let Option::Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        cmd::exec(self, &mut mode, &mut multiplier, &mut last_change, key_event, &mut window, &mut swap, &mut period, &mut is_recording);

                        self.draw_content(&mut window);
                    }
                }
                _ => (),
            }
        }
    }
}

pub fn main() {
    match args().get(1) {
        Option::Some(arg) => Editor::new().main(&arg),
        Option::None => Editor::new().main("none://"),
    }
}
<commit_msg>Fix indentation<commit_after>// TODO: Refactor using a matrix for performance

use redox::*;

mod cmd;

#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Mode {
    Insert,
    Normal,
}

pub struct Editor {
    url: String,
    file: Option<File>,
    string: String,
    offset: usize,
    scroll_x: isize,
    scroll_y: isize,
}

impl Editor {
    #[inline(never)]
    pub fn new() -> Self {
        Editor {
            url: String::new(),
            file: Option::None,
            string: String::new(),
            offset: 0,
            scroll_x: 0,
            scroll_y: 0,
        }
    }

    fn backspace(&mut self, window: &mut Window) {
        if self.offset > 0 {
            window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
            self.string = self.string[0 .. self.offset - 1].to_string() +
                &self.string[self.offset .. self.string.len()];
            self.offset -= 1;
        }
    }

    fn delete(&mut self, window: &mut Window) {
        if self.offset < self.string.len() {
            window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
            self.string = self.string[0 .. self.offset].to_string() +
                &self.string[self.offset + 1 .. self.string.len()];
        }
    }

    // TODO: Add methods for multiple movements
    fn up(&mut self) {
        let mut new_offset = 0;
        for i in 2..self.offset {
            match self.string.as_bytes()[self.offset - i] {
                0 => break,
                10 => {
                    new_offset = self.offset - i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn left(&mut self) {
        if self.offset > 0 {
            self.offset -= 1;
        }
    }

    fn right(&mut self) {
        if self.offset < self.string.len() {
            self.offset += 1;
        }
    }

    fn down(&mut self) {
        let mut new_offset = self.string.len();
        for i in self.offset..self.string.len() {
            match self.string.as_bytes()[i] {
                0 => break,
                10 => {
                    new_offset = i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn cur(&self) -> char {
        self.string.chars().nth(self.offset).unwrap_or('\0')
    }

    fn insert(&mut self, c: char, window: &mut Window) {
        window.set_title(&format!("{}{}{}","self (", &self.url, ") Changed"));
        self.string = self.string[0 .. self.offset].to_string() +
            &c.to_string() +
            &self.string[self.offset .. self.string.len()];
        self.offset += 1;
    }

    fn reload(&mut self, window: &mut Window) {
        window.set_title(&("Editor (".to_string() + &self.url + ")"));
        self.offset = 0;
        self.scroll_x = 0;
        self.scroll_y = 0;

        match self.file {
            Option::Some(ref mut file) => {
                file.seek(Seek::Start(0));
                let mut vec: Vec<u8> = Vec::new();
                file.read_to_end(&mut vec);
                self.string = unsafe { String::from_utf8_unchecked(vec) };
            },
            Option::None => self.string = String::new(),
        }
    }

    fn save(&mut self, window: &mut Window) {
        match self.file {
            Option::Some(ref mut file) => {
                window.set_title(&("Editor (".to_string() + &self.url + ") Saved"));
                file.seek(Seek::Start(0));
                file.write(&self.string.as_bytes());
                file.sync();
            }
            Option::None => {
                //TODO: Ask for file to save to
                window.set_title(&("Editor (".to_string() + &self.url + ") No Open File"));
            }
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        let mut redraw = false;

        {
            window.set([255, 255, 255, 255]);

            let scroll_x = self.scroll_x;
            let scroll_y = self.scroll_y;

            let mut offset = 0;

            let mut col = -scroll_x;
            let cols = window.width() as isize / 8;

            let mut row = -scroll_y;
            let rows = window.height() as isize / 16;

            for c in self.string.chars() {
                if offset == self.offset {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                    } else {
                        if col < 0 { //Too far to the left
                            self.scroll_x += col;
                        } else if col >= cols { //Too far to the right
                            self.scroll_x += cols - col + 1;
                        }
                        if row < 0 { //Too far up
                            self.scroll_y += row;
                        } else if row >= rows { //Too far down
                            self.scroll_y += rows - row + 1;
                        }

                        redraw = true;
                    }
                }

                if c == '\n' {
                    col = -scroll_x;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, c, [0, 0, 0, 255]);
                    }
                    col += 1;
                }

                offset += 1;
            }

            if offset == self.offset {
                if col >= 0 && col < cols && row >= 0 && row < rows {
                    window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                } else {
                    if col < 0 { //Too far to the left
                        self.scroll_x += col;
                    } else if col >= cols { //Too far to the right
                        self.scroll_x += cols - col + 1;
                    }
                    if row < 0 { //Too far up
                        self.scroll_y += row;
                    } else if row >= rows { //Too far down
                        self.scroll_y += rows - row + 1;
                    }

                    redraw = true;
                }
            }

            window.sync();
        }

        if redraw {
            self.draw_content(window);
        }
    }

    fn main(&mut self, url: &str) {
        let mut window = Window::new((rand() % 400 + 50) as isize,
        (rand() % 300 + 50) as isize,
        576,
        400,
        &("Editor (".to_string() + url + ")"));

        self.url = url.to_string();
        self.file = Option::Some(File::open(&self.url));

        self.reload(&mut window);
        self.draw_content(&mut window);

        let mut mode = Mode::Normal;

        let mut last_change = String::new();
        let mut multiplier: Option<u32> = None;
        let mut swap = 0;
        let mut period = String::new();
        let mut is_recording = false;

        while let Option::Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        cmd::exec(self, &mut mode, &mut multiplier, &mut last_change, key_event, &mut window, &mut swap, &mut period, &mut is_recording);

                        self.draw_content(&mut window);
                    }
                }
                _ => (),
            }
        }
    }
}

pub fn main() {
    match args().get(1) {
        Option::Some(arg) => Editor::new().main(&arg),
        Option::None => Editor::new().main("none://"),
    }
}
<|endoftext|>


<commit_before><commit_msg>added merge sort<commit_after>pub fn sort<T: PartialOrd + Copy>(arr: &mut [T]) {
    let len = arr.len();
    if len > 1 {
        sort(&mut arr[..(len / 2)]);
        sort(&mut arr[(len / 2)..]);

        merge(arr);
    }
}

fn merge<T: PartialOrd + Copy>(arr: &mut [T]) {
    let len = arr.len();
    let left_len = len / 2;
    let right_len = len - left_len;

    let mut left = Vec::<T>::with_capacity(left_len);
    let mut right = Vec::<T>::with_capacity(right_len);

    left.extend_from_slice(&arr[..left_len]);
    right.extend_from_slice(&arr[left_len..]);

    let mut i = 0;
    let mut j = 0;

    for k in 0..len {
        if i < left_len && (j == right_len || left[i] < right[j]) {
            arr[k] = left[i];
            i = i + 1;
        } else {
            arr[k] = right[j];
            j = j + 1;
        }
    }
}

#[test]
fn test_sort() {
    let mut arr = [-5, 4, 1, -3, 2];

    sort(&mut arr);

    assert!(arr == [-5, -3, 1, 2, 4]);
}

#[bench]
fn bench_sort(b: &mut ::test::Bencher) {
    b.iter(|| {
        let mut arr: Vec<u32> = (0..1000).rev().collect();

        sort(&mut arr);
    })
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for ICE #4579<commit_after>#![allow(clippy::single_match)]

use std::ptr;

fn main() {
    match Some(0_usize) {
        Some(_) => {
            let s = "012345";
            unsafe { ptr::read(s.as_ptr().offset(1) as *const [u8; 5]) };
        },
        _ => (),
    };
}
<|endoftext|>


<commit_before><commit_msg>unconditionally trim path seperators<commit_after><|endoftext|>


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

use dom::attr::AttrValue;
use dom::bindings::codegen::Bindings::HTMLImageElementBinding;
use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods;
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLElementCast, HTMLImageElementDerived};
use dom::bindings::js::{JS, JSRef, Temporary};
use dom::bindings::trace::Untraceable;
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::Document;
use dom::element::{Element, HTMLImageElementTypeId};
use dom::element::AttributeHandlers;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node};
use dom::virtualmethods::VirtualMethods;
use servo_net::image_cache_task;
use servo_util::geometry::to_px;
use servo_util::str::DOMString;
use string_cache::Atom;

use url::{Url, UrlParser};

use std::cell::RefCell;

#[jstraceable]
#[must_root]
pub struct HTMLImageElement {
    pub htmlelement: HTMLElement,
    image: Untraceable<RefCell<Option<Url>>>,
}

impl HTMLImageElementDerived for EventTarget {
    fn is_htmlimageelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLImageElementTypeId))
    }
}

trait PrivateHTMLImageElementHelpers {
    fn update_image(self, value: Option<(DOMString, &Url)>);
}

impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> {
    /// Makes the local `image` member match the status of the `src` attribute and starts
    /// prefetching the image. This method must be called after `src` is changed.
    fn update_image(self, value: Option<(DOMString, &Url)>) {
        let node: JSRef<Node> = NodeCast::from_ref(self);
        let document = node.owner_doc().root();
        let window = document.deref().window.root();
        let image_cache = &window.image_cache_task;
        match value {
            None => {
                *self.image.deref().borrow_mut() = None;
            }
            Some((src, base_url)) => {
                let img_url = UrlParser::new().base_url(base_url).parse(src.as_slice());
                // FIXME: handle URL parse errors more gracefully.
                let img_url = img_url.unwrap();
                *self.image.deref().borrow_mut() = Some(img_url.clone());

                // inform the image cache to load this, but don't store a
                // handle.
                //
                // TODO (Issue #84): don't prefetch if we are within a
                // <noscript> tag.
                image_cache.send(image_cache_task::Prefetch(img_url));
            }
        }
    }
}

impl HTMLImageElement {
    fn new_inherited(localName: DOMString, document: JSRef<Document>) -> HTMLImageElement {
        HTMLImageElement {
            htmlelement: HTMLElement::new_inherited(HTMLImageElementTypeId, localName, document),
            image: Untraceable::new(RefCell::new(None)),
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: DOMString, document: JSRef<Document>) -> Temporary<HTMLImageElement> {
        let element = HTMLImageElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLImageElementBinding::Wrap)
    }
}

pub trait LayoutHTMLImageElementHelpers {
    unsafe fn image(&self) -> Option<Url>;
}

impl LayoutHTMLImageElementHelpers for JS<HTMLImageElement> {
    unsafe fn image(&self) -> Option<Url> {
        (*self.unsafe_get()).image.borrow().clone()
    }
}

impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> {
    make_getter!(Alt)

    fn SetAlt(self, alt: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("alt", alt)
    }

    make_getter!(Src)

    fn SetSrc(self, src: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_url_attribute("src", src)
    }

    make_getter!(UseMap)

    fn SetUseMap(self, use_map: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("usemap", use_map)
    }

    make_bool_getter!(IsMap)

    fn SetIsMap(self, is_map: bool) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("ismap", is_map.to_string())
    }

    fn Width(self) -> u32 {
        let node: JSRef<Node> = NodeCast::from_ref(self);
        let rect = node.get_bounding_content_box();
        to_px(rect.size.width) as u32
    }

    fn SetWidth(self, width: u32) {
        let elem: JSRef<Element> = ElementCast::from_ref(self);
        elem.set_uint_attribute("width", width)
    }

    fn Height(self) -> u32 {
        let node: JSRef<Node> = NodeCast::from_ref(self);
        let rect = node.get_bounding_content_box();
        to_px(rect.size.height) as u32
    }

    fn SetHeight(self, height: u32) {
        let elem: JSRef<Element> = ElementCast::from_ref(self);
        elem.set_uint_attribute("height", height)
    }

    make_getter!(Name)

    fn SetName(self, name: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("name", name)
    }

    make_getter!(Align)

    fn SetAlign(self, align: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("align", align)
    }

    make_uint_getter!(Hspace)

    fn SetHspace(self, hspace: u32) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_uint_attribute("hspace", hspace)
    }

    make_uint_getter!(Vspace)

    fn SetVspace(self, vspace: u32) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_uint_attribute("vspace", vspace)
    }

    make_getter!(LongDesc)

    fn SetLongDesc(self, longdesc: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("longdesc", longdesc)
    }

    make_getter!(Border)

    fn SetBorder(self, border: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("border", border)
    }
}

impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> {
    fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> {
        let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
        Some(htmlelement as &VirtualMethods)
    }

    fn after_set_attr(&self, name: &Atom, value: DOMString) {
        match self.super_type() {
            Some(ref s) => s.after_set_attr(name, value.clone()),
            _ => (),
        }

        if "src" == name.as_slice() {
            let window = window_from_node(*self).root();
            let url = window.deref().get_url();
            self.update_image(Some((value, &url)));
        }
    }

    fn before_remove_attr(&self, name: &Atom, value: DOMString) {
        match self.super_type() {
            Some(ref s) => s.before_remove_attr(name, value.clone()),
            _ => (),
        }

        if "src" == name.as_slice() {
            self.update_image(None);
        }
    }

    fn parse_plain_attribute(&self, name: &str, value: DOMString) -> AttrValue {
        match name {
            "width" | "height" | "hspace" | "vspace" => AttrValue::from_u32(value, 0),
            _ => self.super_type().unwrap().parse_plain_attribute(name, value),
        }
    }
}

impl Reflectable for HTMLImageElement {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.htmlelement.reflector()
    }
}
<commit_msg>Remove Untraceable from htmlimageelement.rs<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::attr::AttrValue;
use dom::bindings::codegen::Bindings::HTMLImageElementBinding;
use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods;
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLElementCast, HTMLImageElementDerived};
use dom::bindings::js::{JS, JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::Document;
use dom::element::{Element, HTMLImageElementTypeId};
use dom::element::AttributeHandlers;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node};
use dom::virtualmethods::VirtualMethods;
use servo_net::image_cache_task;
use servo_util::geometry::to_px;
use servo_util::str::DOMString;
use string_cache::Atom;

use url::{Url, UrlParser};

use std::cell::RefCell;

#[jstraceable]
#[must_root]
pub struct HTMLImageElement {
    pub htmlelement: HTMLElement,
    image: RefCell<Option<Url>>,
}

impl HTMLImageElementDerived for EventTarget {
    fn is_htmlimageelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLImageElementTypeId))
    }
}

trait PrivateHTMLImageElementHelpers {
    fn update_image(self, value: Option<(DOMString, &Url)>);
}

impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> {
    /// Makes the local `image` member match the status of the `src` attribute and starts
    /// prefetching the image. This method must be called after `src` is changed.
    fn update_image(self, value: Option<(DOMString, &Url)>) {
        let node: JSRef<Node> = NodeCast::from_ref(self);
        let document = node.owner_doc().root();
        let window = document.deref().window.root();
        let image_cache = &window.image_cache_task;
        match value {
            None => {
                *self.image.borrow_mut() = None;
            }
            Some((src, base_url)) => {
                let img_url = UrlParser::new().base_url(base_url).parse(src.as_slice());
                // FIXME: handle URL parse errors more gracefully.
                let img_url = img_url.unwrap();
                *self.image.borrow_mut() = Some(img_url.clone());

                // inform the image cache to load this, but don't store a
                // handle.
                //
                // TODO (Issue #84): don't prefetch if we are within a
                // <noscript> tag.
                image_cache.send(image_cache_task::Prefetch(img_url));
            }
        }
    }
}

impl HTMLImageElement {
    fn new_inherited(localName: DOMString, document: JSRef<Document>) -> HTMLImageElement {
        HTMLImageElement {
            htmlelement: HTMLElement::new_inherited(HTMLImageElementTypeId, localName, document),
            image: RefCell::new(None),
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: DOMString, document: JSRef<Document>) -> Temporary<HTMLImageElement> {
        let element = HTMLImageElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLImageElementBinding::Wrap)
    }
}

pub trait LayoutHTMLImageElementHelpers {
    unsafe fn image(&self) -> Option<Url>;
}

impl LayoutHTMLImageElementHelpers for JS<HTMLImageElement> {
    unsafe fn image(&self) -> Option<Url> {
        (*self.unsafe_get()).image.borrow().clone()
    }
}

impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> {
    make_getter!(Alt)

    fn SetAlt(self, alt: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("alt", alt)
    }

    make_getter!(Src)

    fn SetSrc(self, src: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_url_attribute("src", src)
    }

    make_getter!(UseMap)

    fn SetUseMap(self, use_map: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("usemap", use_map)
    }

    make_bool_getter!(IsMap)

    fn SetIsMap(self, is_map: bool) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("ismap", is_map.to_string())
    }

    fn Width(self) -> u32 {
        let node: JSRef<Node> = NodeCast::from_ref(self);
        let rect = node.get_bounding_content_box();
        to_px(rect.size.width) as u32
    }

    fn SetWidth(self, width: u32) {
        let elem: JSRef<Element> = ElementCast::from_ref(self);
        elem.set_uint_attribute("width", width)
    }

    fn Height(self) -> u32 {
        let node: JSRef<Node> = NodeCast::from_ref(self);
        let rect = node.get_bounding_content_box();
        to_px(rect.size.height) as u32
    }

    fn SetHeight(self, height: u32) {
        let elem: JSRef<Element> = ElementCast::from_ref(self);
        elem.set_uint_attribute("height", height)
    }

    make_getter!(Name)

    fn SetName(self, name: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("name", name)
    }

    make_getter!(Align)

    fn SetAlign(self, align: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("align", align)
    }

    make_uint_getter!(Hspace)

    fn SetHspace(self, hspace: u32) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_uint_attribute("hspace", hspace)
    }

    make_uint_getter!(Vspace)

    fn SetVspace(self, vspace: u32) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_uint_attribute("vspace", vspace)
    }

    make_getter!(LongDesc)

    fn SetLongDesc(self, longdesc: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("longdesc", longdesc)
    }

    make_getter!(Border)

    fn SetBorder(self, border: DOMString) {
        let element: JSRef<Element> = ElementCast::from_ref(self);
        element.set_string_attribute("border", border)
    }
}

impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> {
    fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> {
        let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
        Some(htmlelement as &VirtualMethods)
    }

    fn after_set_attr(&self, name: &Atom, value: DOMString) {
        match self.super_type() {
            Some(ref s) => s.after_set_attr(name, value.clone()),
            _ => (),
        }

        if "src" == name.as_slice() {
            let window = window_from_node(*self).root();
            let url = window.deref().get_url();
            self.update_image(Some((value, &url)));
        }
    }

    fn before_remove_attr(&self, name: &Atom, value: DOMString) {
        match self.super_type() {
            Some(ref s) => s.before_remove_attr(name, value.clone()),
            _ => (),
        }

        if "src" == name.as_slice() {
            self.update_image(None);
        }
    }

    fn parse_plain_attribute(&self, name: &str, value: DOMString) -> AttrValue {
        match name {
            "width" | "height" | "hspace" | "vspace" => AttrValue::from_u32(value, 0),
            _ => self.super_type().unwrap().parse_plain_attribute(name, value),
        }
    }
}

impl Reflectable for HTMLImageElement {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.htmlelement.reflector()
    }
}
<|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2401<commit_after>// https://leetcode.com/problems/longest-nice-subarray/
pub fn longest_nice_subarray(nums: Vec<i32>) -> i32 {
    todo!()
}

fn main() {
    println!("{}", longest_nice_subarray(vec![1, 3, 8, 48, 10])); // 3
    println!("{}", longest_nice_subarray(vec![3, 1, 5, 11, 13])); // 1
}
<|endoftext|>


<commit_before><commit_msg>Fix broken pipe errors<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test for sparc64 ABI issue<commit_after>// Copyright 2018 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.
//
// Checks that we correctly codegen extern "C" functions returning structs.
// See issue #52638.

// compile-flags: -O --target=sparc64-unknown-linux-gnu --crate-type=rlib
#![feature(no_core, lang_items)]
#![no_core]

#[lang="sized"]
trait Sized { }
#[lang="freeze"]
trait Freeze { }
#[lang="copy"]
trait Copy { }

#[repr(C)]
pub struct Bool {
    b: bool,
}

// CHECK: define i64 @structbool()
// CHECK-NEXT: start:
// CHECK-NEXT: ret i64 72057594037927936
#[no_mangle]
pub extern "C" fn structbool() -> Bool {
    Bool { b: true }
}
<|endoftext|>


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

enum Foo {
    Bar { bar: Bar, id: usize }
}

enum Bar {
    A, B, C, D, E, F
}

fn test(f: Foo) {
    match f {
        //~^ ERROR non-exhaustive patterns
        //~| patterns
        Foo::Bar { bar: Bar::A, .. } => (),
        Foo::Bar { bar: Bar::B, .. } => (),
    }
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>:art: Improve the expect message<commit_after><|endoftext|>


<commit_before>//! Cookie headers, as defined in RFC 6265

use time::Tm;
use std::collections::TreeMap;

/// The headers used to set a cookie.
///
/// These headers are defined by [RFC 6265](http://tools.ietf.org/html/rfc6265)
pub struct HeaderCollection {
    /// An absolute date/time at which this cookie should expire.
    pub expires:    Option<Tm>,
    /// A relative time (in seconds) at which this cookie should expire.
    pub max_age:    Option<u32>,
    /// The scope of the cookie.
    ///
    /// If set, the browser will send this cookie to the set domain and all subdomains.
    /// If not set, the browser will only send this cookie to the originating domain.
    ///
    /// This may only be set to the sending domain and its subdomains.
    pub domain:     Option<String>,
    /// The scope of the cookie.
    pub path:       Option<String>,
    /// A cookie with this flag should only be sent over secured/encrypted connections.
    ///
    /// This will be respected by the browser.
    pub secure:     bool,
    /// A cookie with this flag is only accessible through HTTP and HTTPS.
    ///
    /// This helps to prevent Javascript and, specifically, XSS attacks.
    pub http_only:  bool,
    /// Any additional headers.
    ///
    /// This may be any sequence of valid characters.
    ///
    /// Extensions will be separated with `;`.
    /// If a value is specified in the `Map`, the extension will be
    /// written as `[key]=[value]`.
    pub extensions: Option<TreeMap<String, Option<String>>>
}

impl HeaderCollection {
    #[doc(hidden)]
    pub fn to_cookie_av(self) -> String {
        let mut options = String::new()
            .append(head("Expires", self.expires, |v| v.rfc822()).as_slice())
            .append(head("Max-Age", self.max_age, |v| v.to_str()).as_slice())
            .append(head("Domain", self.domain, |v| v).as_slice())
            .append(head("Path", self.path, |v| v).as_slice());
        if self.secure { options.push_str("; Secure"); }
        if self.http_only { options.push_str("; Http-Only"); }
        match self.extensions {
            Some(map) => {
                for (header, value) in map.iter() {
                    options.push_str(extension(header, value.clone()).as_slice());
                }
            },
            None      => ()
        }
        options
    }
}

impl HeaderCollection {
    /// Convenience function for a set of empty cookie headers
    pub fn empty() -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: None,
            domain: None,
            path: None,
            secure: false,
            http_only: false,
            extensions: None
        }
    }

    /// Convenience function for a set of cookie headers
    /// that will expire the cookie in `seconds` seconds
    pub fn aged(seconds: u32) -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: Some(seconds),
            domain: None,
            path: None,
            secure: false,
            http_only: false,
            extensions: None
        }
    }

    /// Convenience function for a set of cookie headers
    /// declaring the cookie `Secure` and `HttpOnly`
    pub fn secured() -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: None,
            domain: None,
            path: None,
            secure: true,
            http_only: true,
            extensions: None
        }
    }
}

fn head<V>(header: &str, value: Option<V>, mutator: |V| -> String) -> String {
    match value {
        Some(val) => {
            // Delimit from previous cookie/options
            "; ".to_string()
            // Add the header
                .append(header).append("=")
            // Add the mutated value
                .append(mutator(val).as_slice())
        },
        None      => String::new()
    }
}

fn extension(header: &String, value: Option<String>) -> String {
    match value {
        Some(val) => head(header.as_slice(), Some(val), |v| v),
        None      => header.clone()
    }
}
<commit_msg>(fix) Fixed extension headers in response.<commit_after>//! Cookie headers, as defined in RFC 6265

use time::Tm;
use std::collections::TreeMap;

/// The headers used to set a cookie.
///
/// These headers are defined by [RFC 6265](http://tools.ietf.org/html/rfc6265)
pub struct HeaderCollection {
    /// An absolute date/time at which this cookie should expire.
    pub expires:    Option<Tm>,
    /// A relative time (in seconds) at which this cookie should expire.
    pub max_age:    Option<u32>,
    /// The scope of the cookie.
    ///
    /// If set, the browser will send this cookie to the set domain and all subdomains.
    /// If not set, the browser will only send this cookie to the originating domain.
    ///
    /// This may only be set to the sending domain and its subdomains.
    pub domain:     Option<String>,
    /// The scope of the cookie.
    pub path:       Option<String>,
    /// A cookie with this flag should only be sent over secured/encrypted connections.
    ///
    /// This will be respected by the browser.
    pub secure:     bool,
    /// A cookie with this flag is only accessible through HTTP and HTTPS.
    ///
    /// This helps to prevent Javascript and, specifically, XSS attacks.
    pub http_only:  bool,
    /// Any additional headers.
    ///
    /// This may be any sequence of valid characters.
    ///
    /// Extensions will be separated with `;`.
    /// If a value is specified in the `Map`, the extension will be
    /// written as `[key]=[value]`.
    pub extensions: Option<TreeMap<String, Option<String>>>
}

impl HeaderCollection {
    #[doc(hidden)]
    pub fn to_cookie_av(self) -> String {
        let mut options = String::new()
            .append(head("Expires", self.expires, |v| v.rfc822()).as_slice())
            .append(head("Max-Age", self.max_age, |v| v.to_str()).as_slice())
            .append(head("Domain", self.domain, |v| v).as_slice())
            .append(head("Path", self.path, |v| v).as_slice());
        if self.secure { options.push_str("; Secure"); }
        if self.http_only { options.push_str("; Http-Only"); }
        match self.extensions {
            Some(map) => {
                for (header, value) in map.iter() {
                    options.push_str(extension(header, value.clone()).as_slice());
                }
            },
            None      => ()
        }
        options
    }
}

impl HeaderCollection {
    /// Convenience function for a set of empty cookie headers
    pub fn empty() -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: None,
            domain: None,
            path: None,
            secure: false,
            http_only: false,
            extensions: None
        }
    }

    /// Convenience function for a set of cookie headers
    /// that will expire the cookie in `seconds` seconds
    pub fn aged(seconds: u32) -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: Some(seconds),
            domain: None,
            path: None,
            secure: false,
            http_only: false,
            extensions: None
        }
    }

    /// Convenience function for a set of cookie headers
    /// declaring the cookie `Secure` and `HttpOnly`
    pub fn secured() -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: None,
            domain: None,
            path: None,
            secure: true,
            http_only: true,
            extensions: None
        }
    }
}

fn head<V>(header: &str, value: Option<V>, mutator: |V| -> String) -> String {
    match value {
        Some(val) => {
            // Delimit from previous cookie/options
            "; ".to_string()
            // Add the header
                .append(header).append("=")
            // Add the mutated value
                .append(mutator(val).as_slice())
        },
        None      => String::new()
    }
}

fn extension(header: &String, value: Option<String>) -> String {
    match value {
        Some(val) => head(header.as_slice(), Some(val), |v| v),
        None      => "; ".to_string().append(header.as_slice())
    }
}
<|endoftext|>


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

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

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

impl HTMLDivElementDerived for EventTarget {
    fn is_htmldivelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLDivElementTypeId))
    }
}

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

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

pub trait HTMLDivElementMethods {
    fn Align(&self) -> DOMString;
    fn SetAlign(&mut self, _align: DOMString) -> ErrorResult;
}

impl<'a> HTMLDivElementMethods for JSRef<'a, HTMLDivElement> {
    fn Align(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAlign(&mut self, _align: DOMString) -> ErrorResult {
        Ok(())
    }
}
<commit_msg>Remove needless '&mut self' from HTMLDivElementMethods.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

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

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

impl HTMLDivElementDerived for EventTarget {
    fn is_htmldivelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLDivElementTypeId))
    }
}

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

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

pub trait HTMLDivElementMethods {
    fn Align(&self) -> DOMString;
    fn SetAlign(&self, _align: DOMString) -> ErrorResult;
}

impl<'a> HTMLDivElementMethods for JSRef<'a, HTMLDivElement> {
    fn Align(&self) -> DOMString {
        "".to_owned()
    }

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


<commit_before><commit_msg>immutable reference added<commit_after><|endoftext|>


<commit_before><commit_msg>Added code for s02c12: breaking aes ecb. Needs work on main loop. Won't compile.<commit_after>
use common::{err, ascii, base64};
use common::cipher::{aes, oracle};

struct CipherBox {
    key:    Vec<u8>,
    data:   Vec<u8>,
    mode:   aes::Mode
}

impl CipherBox {
    fn new(&self, data: &str, mode: &aes::Mode) -> Result<Self, err::Error> {
        Ok(CipherBox {
            key:    try!(key::random(mode.blocksize)),
            data:   try!(ascii::str_to_raw(&data)),
            mode:   mode
        })
    }

    fn gen(&self, prefix: &str) -> Result<Vec<u8>, err::Error> {
        let mut final_input = try!(ascii::str_to_raw(&prefix));
        final_input.extend(&self.data);

        aes::encrypt(&final_input, &self.key, &self.mode)
    }
}

pub fn break_aes_ecb(cipherbox: &CipherBox) -> Result<String, err::Error> {
    let blocksize = try!(detect_block_size(&cipherbox, max_blocksize));
    ctry!(!try!(oracle::detect_aes_ecb(&try!(cipherbox.gen(&String::from(&[65, 2*blocksize]))), blocksize)),
        "cipher is not aes ecb, can't break with this module");

    let range: Range<u8> = Range{ start: 1, end: 127 };

    let mut plaintext = String::new();
    let mut block_no: usize = 0;

    for i in ... {
        let prefix = String::from(&[65, 15]);

        let cipher = try!(cipherbox.gen(&prefix));

        let dict = try!(make_dict(&prefix, &cipherbox, &range));

        let cipher_block = cipher.chunks().nth(block_no);

        let m = dict.chunks().filter(|&ch| ch == cipher_block).collect();
        ctry!(m.len() == 0 || m.len() > 1, format!("no match or multiple matches for character at pos: {}", i));

        let dec_char = m

        plaintext.push(dec_char);

    }
    Ok(plaintext)
}

pub fn make_dict(prefix: &str, cipherbox: &CipherBox, range: &Range<u8>) -> Result<Vec<Vec<u8>>, err::Error> {
    let mut dict = Vec::<Vec<u8>>::new();
    let mut plain = String::from(&prefix);

    for i in range {
        plain.push(i as char);
        let cipher = try!(cipherbox.gen(&plain));
        dict.push(cipher);
        plain.pop();
    }
    Ok(dict)
}

pub fn detect_block_size(cipherbox: &CipherBox, max: usize) -> Result<usize, err::Error> {
    let len1 = try!(cipherbox.gen("")).len();

    let mut prefix = String::from("A");
    for i in 0 .. max {
        let len2 = try!(cipherbox.gen(&prefix)).len();
        if len2 > len1 {
            return Ok(len2 - len1);
        }
        prefix.push('A');
    }
    mkerr!("failed to detect cipher block size")
}

pub fn init_cipherbox(filepath: &str) -> Result<CipherBox, err::Error> {
    let plainbase64 = try!(util::read_file_to_str(&filepath));
    let plainraw = try!(base64::base64_to_raw(&try!(ascii::filter_whitespace(&plainbase64))));
    let plaintext = try!(ascii::raw_to_str(&plainraw));

    CipherBox::new(&plaintext, &aes::ecb_128_pkcs7)
}

pub fn interactive() -> u32 {
    let input_filepath = match env::args().nth(2) {
        Some(v) => v,
        None    => { println!("please specify input data (base64 encoded) filepath"); return 1; }
    };

    let cipherbox = rtry!(init_cipherbox(&input_filepath), 1);
    let plaintext = rtry!(break_aes_ecb(&cipherbox), 1);

    println!("{}", plaintext);
    0
}
<|endoftext|>


<commit_before><commit_msg>Add problem #18<commit_after>const triangle: &[&[uint]] = &[
    &[75],
    &[95, 64],
    &[17, 47, 82],
    &[18, 35, 87, 10],
    &[20, 04, 82, 47, 65],
    &[19, 01, 23, 75, 03, 34],
    &[88, 02, 77, 73, 07, 63, 67],
    &[99, 65, 04, 28, 06, 16, 70, 92],
    &[41, 41, 26, 56, 83, 40, 80, 70, 33],
    &[41, 48, 72, 33, 47, 32, 37, 16, 94, 29],
    &[53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14],
    &[70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57],
    &[91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48],
    &[63, 66, 04, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31],
    &[04, 62, 98, 27, 23, 09, 70, 98, 73, 93, 38, 53, 60, 04, 23]
];

fn main() {
    let init = vec::view(triangle, 0, triangle.len() - 1);
    let last = vec::last(triangle);
    let answer = do init.foldr(vec::from_slice(last)) |elm, prev| {
        do vec::from_fn(elm.len()) |i| {
            elm[i] + uint::max(prev[i], prev[i + 1])
        }
    };
    io::println(fmt!("%u", answer[0]));
}<|endoftext|>


<commit_before><commit_msg>Build script needs an entry point on non-Windows<commit_after><|endoftext|>


<commit_before>use super::*;
use redox::*;

impl Editor {
    /// Redraw the window
    pub fn redraw(&mut self) {
        // TODO: Only draw when relevant for the window
        let x = self.x();
        let y = self.y();
        // Redraw window
        self.window.set(Color::BLACK);

        self.window.rect(8 * (x - self.scroll_y) as isize,
                         16 * (y - self.scroll_x) as isize,
                         8,
                         16,
                         Color::WHITE);

        for (y, row) in self.text.iter().enumerate() {
            for (x, c) in row.iter().enumerate() {
                if self.x() == x && self.y() == y {
                    self.window.char(8 * (x - self.scroll_y) as isize,
                                     16 * (y - self.scroll_x) as isize,
                                     *c,
                                     Color::BLACK);
                } else {
                    self.window.char(8 * (x - self.scroll_y) as isize,
                                     16 * (y - self.scroll_x) as isize,
                                     *c,
                                     Color::WHITE);
                }
            }
        }
        let h = self.window.height();
        let w = self.window.width();
        self.window.rect(0, h as isize - 18, w, 18, Color::rgba(74, 74, 74, 255));

        for (n, c) in (if self.status_bar.mode.len() > w / (8 * 4) {
            self.status_bar.mode.chars().take(w / (8 * 4) - 5).chain(vec!['.', '.', '.']).collect::<Vec<_>>()
        } else {
            self.status_bar.mode.chars().collect()
        }).into_iter().enumerate() {
            self.window.char(n as isize * 8, h as isize - 16 - 1, if c == '\t' { ' ' } else { c }, [255, 255, 255, 255]);
        }

        self.window.sync();
    }
}

/// The statubar (showing various info about the current state of the editor)
pub struct StatusBar {
    /// The current mode
    pub mode: String,
    /// The cureent char
    pub file: String,
    /// The current command
    pub cmd: String,
    /// A message (such as an error or other info to the user)
    pub msg: String,
}

impl StatusBar {
    /// Create new status bar
    pub fn new() -> Self {
        StatusBar {
            mode: "Normal".to_string(),
            file: String::new(),
            cmd: String::new(),
            msg: String::new(),
        }
    }
}
<commit_msg>Make it up-to-date with libredox<commit_after>use super::*;
use redox::*;

impl Editor {
    /// Redraw the window
    pub fn redraw(&mut self) {
        // TODO: Only draw when relevant for the window
        let x = self.x();
        let y = self.y();
        // Redraw window
        self.window.set(Color::BLACK);

        self.window.rect(8 * (x - self.scroll_y) as isize,
                         16 * (y - self.scroll_x) as isize,
                         8,
                         16,
                         Color::WHITE);

        for (y, row) in self.text.iter().enumerate() {
            for (x, c) in row.iter().enumerate() {
                if self.x() == x && self.y() == y {
                    self.window.char(8 * (x - self.scroll_y) as isize,
                                     16 * (y - self.scroll_x) as isize,
                                     *c,
                                     Color::BLACK);
                } else {
                    self.window.char(8 * (x - self.scroll_y) as isize,
                                     16 * (y - self.scroll_x) as isize,
                                     *c,
                                     Color::WHITE);
                }
            }
        }
        let h = self.window.height();
        let w = self.window.width();
        self.window.rect(0, h as isize - 18, w, 18, Color::rgba(74, 74, 74, 255));

        for (n, c) in (if self.status_bar.mode.len() > w / (8 * 4) {
            self.status_bar.mode.chars().take(w / (8 * 4) - 5).chain(vec!['.', '.', '.']).collect::<Vec<_>>()
        } else {
            self.status_bar.mode.chars().collect()
        }).into_iter().enumerate() {
            self.window.char(n as isize * 8, h as isize - 16 - 1, if c == '\t' { ' ' } else { c }, Color::WHITE);
        }

        self.window.sync();
    }
}

/// The statubar (showing various info about the current state of the editor)
pub struct StatusBar {
    /// The current mode
    pub mode: String,
    /// The cureent char
    pub file: String,
    /// The current command
    pub cmd: String,
    /// A message (such as an error or other info to the user)
    pub msg: String,
}

impl StatusBar {
    /// Create new status bar
    pub fn new() -> Self {
        StatusBar {
            mode: "Normal".to_string(),
            file: String::new(),
            cmd: String::new(),
            msg: String::new(),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Removed inline assembly in favor of calling x86 library.<commit_after><|endoftext|>


<commit_before>use std::path::PathBuf;
use std::path::Path;
use std::fmt::{Debug, Formatter, Error as FmtError};
use std::result::Result as RResult;

use toml::Value;

use libimagerror::into::IntoError;
use libimagerror::trace::trace_error;
use libimagstore::hook::Hook;
use libimagstore::hook::accessor::StoreIdAccessor;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::result::HookResult;
use libimagstore::storeid::StoreId;
use libimagutil::debug_result::*;

use vcs::git::error::GitHookError as GHE;
use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::error::MapIntoHookError;
use vcs::git::result::Result;
use vcs::git::runtime::Runtime as GRuntime;

pub struct UpdateHook {
    storepath: PathBuf,

    runtime: GRuntime,

    position: HookPosition,
}

impl UpdateHook {

    pub fn new(storepath: PathBuf, p: HookPosition) -> UpdateHook {
        UpdateHook {
            runtime: GRuntime::new(&storepath),
            storepath: storepath,
            position: p,
        }
    }

}

impl Debug for UpdateHook {
    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "UpdateHook(storepath={:?}, repository={}, pos={:?}, cfg={:?}",
               self.storepath,
               (if self.runtime.has_repository() { "Some(_)" } else { "None" }),
               self.position,
               self.runtime.has_config())
    }
}

impl Hook for UpdateHook {

    fn name(&self) -> &'static str {
        "stdhook_git_update"
    }

    fn set_config(&mut self, config: &Value) {
        if let Err(e) = self.runtime.set_config(config) {
            trace_error(&e);
        }
    }

}

impl HookDataAccessorProvider for UpdateHook {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl StoreIdAccessor for UpdateHook {

    /// The implementation of the UpdateHook
    ///
    /// # Scope
    ///
    /// This hook takes the git index and commits it either interactively or with a default message,
    /// if there is no configuration for an interactive commit.
    ///
    fn access(&self, id: &StoreId) -> HookResult<()> {
        use vcs::git::action::StoreAction;
        use vcs::git::config::commit_message;
        use vcs::git::error::MapIntoHookError;
        use vcs::git::util::fetch_index;
        use git2::{Reference as GitReference, Repository, Error as Git2Error};
        use git2::{ADD_DEFAULT, STATUS_WT_NEW, STATUS_WT_MODIFIED, IndexMatchedPath};

        debug!("[GIT UPDATE HOOK]: {:?}", id);

        let action    = StoreAction::Update;
        let cfg       = try!(self.runtime.config_value_or_err(&action));
        let repo      = try!(self.runtime.repository(&action));
        let mut index = try!(fetch_index(repo, &action));

        let signature = try!(
            repo.signature()
                .map_err_into(GHEK::MkSignature)
                .map_dbg_err_str("Failed to fetch signature")
                .map_into_hook_error()
        );

        let head = try!(
            repo.head()
                .map_err_into(GHEK::HeadFetchError)
                .map_dbg_err_str("Failed to fetch HEAD")
                .map_into_hook_error()
        );

        let file_status = try!(
            repo
                .status_file(id.local())
                .map_dbg_err_str("Failed to fetch file status")
                .map_dbg_err(|e| format!("\t->  {:?}", e))
                .map_err_into(GHEK::RepositoryFileStatusError)
                .map_into_hook_error()
        );

        let cb = &mut |path: &Path, _matched_spec: &[u8]| -> i32 {
            if file_status.contains(STATUS_WT_NEW) || file_status.contains(STATUS_WT_MODIFIED) {
                debug!("[GIT CREATE HOOK]: File is modified/new: {}", path.display());
                0
            } else {
                debug!("[GIT CREATE HOOK]: Ignoring file: {}", path.display());
                1
            }
        };

        try!(
            index.add_all(&[id.local()], ADD_DEFAULT, Some(cb as &mut IndexMatchedPath))
                .map_err_into(GHEK::RepositoryPathAddingError)
                .map_dbg_err_str("Failed to add to index")
                .map_into_hook_error()
        );

        let mut parents = Vec::new();
        {
            let commit = try!(
                repo.find_commit(head.target().unwrap())
                    .map_err_into(GHEK::RepositoryParentFetchingError)
                    .map_dbg_err_str("Failed to find commit HEAD")
                    .map_into_hook_error()
            );
            parents.push(commit);
        }

        // for converting from Vec<Commit> to Vec<&Commit>
        let parents = parents.iter().collect::<Vec<_>>();

        let tree_id = try!(
            index.write_tree()
                .map_err_into(GHEK::RepositoryIndexWritingError)
                .map_dbg_err_str("Failed to write tree")
                .map_into_hook_error()
        );

        let tree = try!(
            repo.find_tree(tree_id)
                .map_err_into(GHEK::RepositoryParentFetchingError)
                .map_dbg_err_str("Failed to find tree")
                .map_into_hook_error()
        );

        let message = try!(commit_message(cfg, StoreAction::Update)
                .map_dbg_err_str("Failed to get commit message"));

        repo.commit(Some("HEAD"), &signature, &signature, &message, &tree, &parents)
            .map_dbg_str("Committed")
            .map_dbg_err_str("Failed to commit")
            .map_err_into(GHEK::RepositoryCommittingError)
            .map_into_hook_error()
            .map(|_| ())
    }

}

<commit_msg>Write the tree before finding the parent commits<commit_after>use std::path::PathBuf;
use std::path::Path;
use std::fmt::{Debug, Formatter, Error as FmtError};
use std::result::Result as RResult;

use toml::Value;

use libimagerror::into::IntoError;
use libimagerror::trace::trace_error;
use libimagstore::hook::Hook;
use libimagstore::hook::accessor::StoreIdAccessor;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::result::HookResult;
use libimagstore::storeid::StoreId;
use libimagutil::debug_result::*;

use vcs::git::error::GitHookError as GHE;
use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::error::MapIntoHookError;
use vcs::git::result::Result;
use vcs::git::runtime::Runtime as GRuntime;

pub struct UpdateHook {
    storepath: PathBuf,

    runtime: GRuntime,

    position: HookPosition,
}

impl UpdateHook {

    pub fn new(storepath: PathBuf, p: HookPosition) -> UpdateHook {
        UpdateHook {
            runtime: GRuntime::new(&storepath),
            storepath: storepath,
            position: p,
        }
    }

}

impl Debug for UpdateHook {
    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "UpdateHook(storepath={:?}, repository={}, pos={:?}, cfg={:?}",
               self.storepath,
               (if self.runtime.has_repository() { "Some(_)" } else { "None" }),
               self.position,
               self.runtime.has_config())
    }
}

impl Hook for UpdateHook {

    fn name(&self) -> &'static str {
        "stdhook_git_update"
    }

    fn set_config(&mut self, config: &Value) {
        if let Err(e) = self.runtime.set_config(config) {
            trace_error(&e);
        }
    }

}

impl HookDataAccessorProvider for UpdateHook {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl StoreIdAccessor for UpdateHook {

    /// The implementation of the UpdateHook
    ///
    /// # Scope
    ///
    /// This hook takes the git index and commits it either interactively or with a default message,
    /// if there is no configuration for an interactive commit.
    ///
    fn access(&self, id: &StoreId) -> HookResult<()> {
        use vcs::git::action::StoreAction;
        use vcs::git::config::commit_message;
        use vcs::git::error::MapIntoHookError;
        use vcs::git::util::fetch_index;
        use git2::{Reference as GitReference, Repository, Error as Git2Error};
        use git2::{ADD_DEFAULT, STATUS_WT_NEW, STATUS_WT_MODIFIED, IndexMatchedPath};

        debug!("[GIT UPDATE HOOK]: {:?}", id);

        let action    = StoreAction::Update;
        let cfg       = try!(self.runtime.config_value_or_err(&action));
        let repo      = try!(self.runtime.repository(&action));
        let mut index = try!(fetch_index(repo, &action));

        let signature = try!(
            repo.signature()
                .map_err_into(GHEK::MkSignature)
                .map_dbg_err_str("Failed to fetch signature")
                .map_into_hook_error()
        );

        let head = try!(
            repo.head()
                .map_err_into(GHEK::HeadFetchError)
                .map_dbg_err_str("Failed to fetch HEAD")
                .map_into_hook_error()
        );

        let file_status = try!(
            repo
                .status_file(id.local())
                .map_dbg_err_str("Failed to fetch file status")
                .map_dbg_err(|e| format!("\t->  {:?}", e))
                .map_err_into(GHEK::RepositoryFileStatusError)
                .map_into_hook_error()
        );

        let cb = &mut |path: &Path, _matched_spec: &[u8]| -> i32 {
            if file_status.contains(STATUS_WT_NEW) || file_status.contains(STATUS_WT_MODIFIED) {
                debug!("[GIT CREATE HOOK]: File is modified/new: {}", path.display());
                0
            } else {
                debug!("[GIT CREATE HOOK]: Ignoring file: {}", path.display());
                1
            }
        };

        try!(
            index.add_all(&[id.local()], ADD_DEFAULT, Some(cb as &mut IndexMatchedPath))
                .map_err_into(GHEK::RepositoryPathAddingError)
                .map_dbg_err_str("Failed to add to index")
                .map_into_hook_error()
        );

        let tree_id = try!(
            index.write_tree()
                .map_err_into(GHEK::RepositoryIndexWritingError)
                .map_dbg_err_str("Failed to write tree")
                .map_into_hook_error()
        );

        let mut parents = Vec::new();
        {
            let commit = try!(
                repo.find_commit(head.target().unwrap())
                    .map_err_into(GHEK::RepositoryParentFetchingError)
                    .map_dbg_err_str("Failed to find commit HEAD")
                    .map_into_hook_error()
            );
            parents.push(commit);
        }

        // for converting from Vec<Commit> to Vec<&Commit>
        let parents = parents.iter().collect::<Vec<_>>();

        let tree = try!(
            repo.find_tree(tree_id)
                .map_err_into(GHEK::RepositoryParentFetchingError)
                .map_dbg_err_str("Failed to find tree")
                .map_into_hook_error()
        );

        let message = try!(commit_message(cfg, StoreAction::Update)
                .map_dbg_err_str("Failed to get commit message"));

        repo.commit(Some("HEAD"), &signature, &signature, &message, &tree, &parents)
            .map_dbg_str("Committed")
            .map_dbg_err_str("Failed to commit")
            .map_err_into(GHEK::RepositoryCommittingError)
            .map_into_hook_error()
            .map(|_| ())
    }

}

<|endoftext|>


<commit_before><commit_msg>Jump search in Rust<commit_after><|endoftext|>


<commit_before><commit_msg>Add new function PacketType::id<commit_after><|endoftext|>


<commit_before><commit_msg>Add tests for helpful error messages<commit_after>use std::process;

fn assert_output_contains(output: &process::Output, needle: &str) {
    let stdout = String::from_utf8_lossy(&output.stdout);
    let stderr = String::from_utf8_lossy(&output.stderr);
    if stderr.to_lowercase().find(needle).is_none() && stdout.to_lowercase().find(needle).is_none()  {
        panic!("Match was unsuccessful.\nSTDOUT: {:?}\nSTDERR: {:?}\nNEEDLE: {:?}",
            stdout, stderr, needle);
    }
}

mod cargo_add {
    use super::assert_output_contains;
    use std::process;

    #[test]
    fn invalid_arguments() {
        // - should state that the argument is invalid
        // - should provide usage information
        let call = process::Command::new("target/debug/cargo-add")
            .output().unwrap();

        assert!(!call.status.success());
        assert_output_contains(&call, "invalid argument");
        assert_output_contains(&call, "usage:");

        let call = process::Command::new("target/debug/cargo-add")
            .arg("invalid").arg("arguments").arg("here")
            .output().unwrap();

        assert!(!call.status.success());
        assert_output_contains(&call, "invalid argument");
        assert_output_contains(&call, "usage:");
    }

    #[test]
    fn nonexistant_files() {
        // - should state that file could not be found

        let call = process::Command::new("target/debug/cargo-add")
            .arg("add") /* always necessary */ .arg("pkg")
            .arg("--manifest-path").arg("this-file-doesnt-exist.txt")
            .output().unwrap();

        assert!(!call.status.success());
        assert_output_contains(&call, "no such file or directory");
    }
}
<|endoftext|>