<commit_before>use wlroots_sys::wlr_drag_icon;
use std::cell::Cell;
use std::rc::{Rc, Weak};
use std::panic;
use errors::{HandleErr, HandleResult};
use DragIconHandler;

#[derive(Debug)]
pub struct DragIcon {
    liveliness: Rc<Cell<bool>>,
    drag_icon: *mut wlr_drag_icon
}

impl DragIcon {
    pub(crate) unsafe fn new(drag_icon: *mut wlr_drag_icon) -> Self {
        let liveliness = Rc::new(Cell::new(false));
        let state = Box::new(DragIconState {
            handle: Rc::downgrade(&liveliness),
            drag_icon
        });
        (*drag_icon).data = Box::into_raw(state) as *mut _;
        DragIcon {
            liveliness,
            drag_icon
        }
    }

    unsafe fn from_handle(handle: &DragIconHandle) -> HandleResult<Self> {
        let liveliness = handle.handle
                               .upgrade()
                               .ok_or_else(|| HandleErr::AlreadyDropped)?;
        Ok(DragIcon { liveliness,
                      drag_icon: handle.as_ptr() })
    }

    pub fn weak_reference(&self) -> DragIconHandle {
        DragIconHandle {
            handle: Rc::downgrade(&self.liveliness),
            drag_icon: self.drag_icon
        }
    }
}

pub struct DragIconHandle {
    handle: Weak<Cell<bool>>,
    drag_icon: *mut wlr_drag_icon
}

impl DragIconHandle {
    pub(crate) unsafe fn from_ptr(drag_icon: *mut wlr_drag_icon) -> Self {
        if drag_icon.is_null() {
            panic!("drag icon was null");
        }
        let data = (*drag_icon).data as *mut DragIconState;
        if data.is_null() {
            panic!("Cannot construct handle from drag icon that has not been set up!");
        }

        let handle = (*data).handle.clone();

        DragIconHandle {
            handle,
            drag_icon
        }
    }

    pub(crate) unsafe fn upgrade(&self) -> HandleResult<DragIcon> {
        self.handle.upgrade()
            .ok_or(HandleErr::AlreadyDropped)
            // NOTE
            // We drop the Rc here because having two would allow a dangling
            // pointer to exist!
            .and_then(|check| {
                let drag_icon = DragIcon::from_handle(self)?;
                if check.get() {
                    return Err(HandleErr::AlreadyBorrowed)
                }
                check.set(true);
                Ok(drag_icon)
            })
    }

    pub fn run<F, R>(&self, runner: F) -> HandleResult<R>
        where F: FnOnce(&mut DragIcon) -> R
    {
        let mut drag_icon = unsafe { self.upgrade()? };
        let res = panic::catch_unwind(panic::AssertUnwindSafe(|| runner(&mut drag_icon)));
        self.handle.upgrade().map(|check| {
                                      // Sanity check that it hasn't been tampered with.
                                      if !check.get() {
                                          wlr_log!(L_ERROR,
                                                   "After running DragIcon callback, \
                                                    mutable lock was false for: {:?}",
                                                   drag_icon);
                                          panic!("Lock in incorrect state!");
                                      }
                                      check.set(false);
                                  });
        match res {
            Ok(res) => Ok(res),
            Err(err) => panic::resume_unwind(err)
        }
    }

    unsafe fn as_ptr(&self) -> *mut wlr_drag_icon {
        self.drag_icon
    }
}

pub(crate) struct DragIconState {
    pub(crate) handle: Weak<Cell<bool>>,
    pub(crate) drag_icon: *mut wlr_drag_icon
}
<commit_msg>add drag icon properties<commit_after>use wlroots_sys::wlr_drag_icon;
use std::cell::Cell;
use std::rc::{Rc, Weak};
use std::panic;
use errors::{HandleErr, HandleResult};
use DragIconHandler;

use {SurfaceHandle};

#[derive(Debug)]
pub struct DragIcon {
    liveliness: Rc<Cell<bool>>,
    drag_icon: *mut wlr_drag_icon
}

impl DragIcon {
    pub(crate) unsafe fn new(drag_icon: *mut wlr_drag_icon) -> Self {
        let liveliness = Rc::new(Cell::new(false));
        let state = Box::new(DragIconState {
            handle: Rc::downgrade(&liveliness),
            drag_icon
        });
        (*drag_icon).data = Box::into_raw(state) as *mut _;
        DragIcon {
            liveliness,
            drag_icon
        }
    }

    /// Get a handle for the surface associated with this drag icon
    pub fn surface(&mut self) -> SurfaceHandle {
        unsafe {
            let surface = (*self.drag_icon).surface;
			if surface.is_null() {
				panic!("drag icon had a null surface!");
			}
			SurfaceHandle::from_ptr(surface)
        }
    }

    /// The position to place the surface of the drag icon relative to the cursor position
	pub fn position(&mut self) -> (i32, i32) {
        unsafe { ((*self.drag_icon).sx, (*self.drag_icon).sy) }
	}

    /// Whether or not to display the drag icon
    pub fn mapped(&mut self) -> bool {
        unsafe { (*self.drag_icon).mapped }
    }

    /// Whether or not this drag icon comes from a pointer-drive dnd operation
    pub fn is_pointer(&mut self) -> bool {
        unsafe { (*self.drag_icon).is_pointer }
    }

    /// If this is a touch-driven dnd operation, the id of the touch point that started it
    pub fn touch_id(&mut self) -> i32 {
        unsafe { (*self.drag_icon).touch_id }
    }

    unsafe fn from_handle(handle: &DragIconHandle) -> HandleResult<Self> {
        let liveliness = handle.handle
                               .upgrade()
                               .ok_or_else(|| HandleErr::AlreadyDropped)?;
        Ok(DragIcon { liveliness,
                      drag_icon: handle.as_ptr() })
    }

    pub fn weak_reference(&self) -> DragIconHandle {
        DragIconHandle {
            handle: Rc::downgrade(&self.liveliness),
            drag_icon: self.drag_icon
        }
    }
}

pub struct DragIconHandle {
    handle: Weak<Cell<bool>>,
    drag_icon: *mut wlr_drag_icon
}

impl DragIconHandle {
    pub(crate) unsafe fn from_ptr(drag_icon: *mut wlr_drag_icon) -> Self {
        if drag_icon.is_null() {
            panic!("drag icon was null");
        }
        let data = (*drag_icon).data as *mut DragIconState;
        if data.is_null() {
            panic!("Cannot construct handle from drag icon that has not been set up!");
        }

        let handle = (*data).handle.clone();

        DragIconHandle {
            handle,
            drag_icon
        }
    }

    pub(crate) unsafe fn upgrade(&self) -> HandleResult<DragIcon> {
        self.handle.upgrade()
            .ok_or(HandleErr::AlreadyDropped)
            // NOTE
            // We drop the Rc here because having two would allow a dangling
            // pointer to exist!
            .and_then(|check| {
                let drag_icon = DragIcon::from_handle(self)?;
                if check.get() {
                    return Err(HandleErr::AlreadyBorrowed)
                }
                check.set(true);
                Ok(drag_icon)
            })
    }

    pub fn run<F, R>(&self, runner: F) -> HandleResult<R>
        where F: FnOnce(&mut DragIcon) -> R
    {
        let mut drag_icon = unsafe { self.upgrade()? };
        let res = panic::catch_unwind(panic::AssertUnwindSafe(|| runner(&mut drag_icon)));
        self.handle.upgrade().map(|check| {
                                      // Sanity check that it hasn't been tampered with.
                                      if !check.get() {
                                          wlr_log!(L_ERROR,
                                                   "After running DragIcon callback, \
                                                    mutable lock was false for: {:?}",
                                                   drag_icon);
                                          panic!("Lock in incorrect state!");
                                      }
                                      check.set(false);
                                  });
        match res {
            Ok(res) => Ok(res),
            Err(err) => panic::resume_unwind(err)
        }
    }

    unsafe fn as_ptr(&self) -> *mut wlr_drag_icon {
        self.drag_icon
    }
}

pub(crate) struct DragIconState {
    pub(crate) handle: Weak<Cell<bool>>,
    pub(crate) drag_icon: *mut wlr_drag_icon
}
<|endoftext|>


<commit_before>use std::str::Chars;

pub struct Position {
    pub line: usize,
    pub column: usize,
}

pub enum Token {
    Empty,
    Invalid,
    Identifier(String),
    Literal(Literal),
    Punctuation(String),
}

pub enum Literal {
    StringLiteral(String),
    Character(char),
    Integer(String),
    FloatingPoint(String),
    Hex(String),
}

pub struct Lexer<'a> {
    pub token: Token,
    character: Option<char>,
    chars: Chars<'a>,
    previous_line: usize,
    previous_column: usize,
    pub line: usize,
    pub column: usize,
}

impl<'a> Lexer<'a> {
    pub fn new(deck: &'a str) -> Lexer {
        let mut lexer = Lexer {
            chars: deck.chars(),
            token: Token::Empty,
            character: None,
            previous_line: 1,
            previous_column: 0,
            line: 1,
            column: 0,
        };
        lexer.read_character();
        lexer
    }

    fn read_character(&mut self) {
        self.character = self.chars.next();
        match self.character {
            None => (),
            Some(c) => match c {
                '\r' => (),
                '\n' => {
                    self.column = 0;
                    self.line = self.line + 1;
                }
                '\t' => self.column = self.column + 4,
                _ => self.column = self.column + 1,
            },
        }
    }

    pub fn advance(&mut self) {
        self.skip_whitespace();
        self.previous_line = self.line;
        self.previous_column = self.column;
        match self.character {
            None => return,
            Some(c) => {
                if ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) {
                    let mut name = String::new();
                    name.push(c);
                    self.token = self.scan_identifier(name);
                    return;
                }

                if (c >= '1') && (c <= '9') {
                    let mut value = String::new();
                    value.push(c);
                    self.token = self.scan_numeric_literal(value);
                    return;
                }

                match c {
                    '0' => {
                        let mut value = String::new();
                        value.push(c);
                        self.token = self.scan_numeric_or_hex_literal(value);
                    }
                    '+' | '-' | '*' | '/' | '=' | '%' | '&' | '|' | '^' | '~' | '<' | '>' => {
                        let mut operation = String::new();
                        operation.push(c);
                        self.token = self.scan_operator(operation)
                    }
                    '\"' => self.token = { self.scan_string_literal() },
                    '\'' => self.token = { self.scan_character_literal() },
                    '{' | '}' | '(' | ')' | '[' | ']' | '.' | ',' | ':' | ';' | '?' | '!' | '@'
                    | '#' | '$' | '_' | '`' => {
                        let mut punctuation_string = String::new();
                        punctuation_string.push(c);
                        self.token = Token::Punctuation(punctuation_string);
                    }
                    _ => self.token = Token::Invalid,
                }
            }
        }
    }

    pub fn empty(&mut self) {
        self.token = Token::Empty;
    }

    fn scan_identifier(&mut self, mut name: String) -> Token {
        loop {
            match self.character {
                None => {
                    if name.len() == 0 {
                        return Token::Invalid;
                    } else {
                        return Token::Identifier(name);
                    }
                }

                Some(c) => match c {
                    'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => {
                        name.push(c);
                        self.read_character();
                    }
                    _ => return Token::Identifier(name),
                },
            }
        }
    }

    fn scan_operator(&mut self, mut operation: String) -> Token {
        loop {
            match self.character {
                None => {
                    if operation.len() == 0 {
                        return Token::Invalid;
                    } else {
                        return Token::Identifier(operation);
                    }
                }
                Some(c) => match c {
                    '+' | '-' | '*' | '/' | '=' | '%' | '&' | '|' | '^' | '~' | '<' | '>' => {
                        operation.push(c);
                    }

                    _ => return Token::Identifier(operation),
                },
            }
        }
    }

    fn scan_string_literal(&mut self) -> Token {
        let mut value = String::new();

        loop {
            self.read_character();

            match self.character {
                None => return Token::Invalid,
                Some(c) => match c {
                    '\"' => {
                        self.read_character();
                        return Token::Literal(Literal::StringLiteral(value));
                    }

                    '\\' => {
                        self.read_character();
                        match self.character {
                            None => return Token::Invalid,
                            Some(c) => match c {
                                '\"' | '\\' | '\'' => {
                                    value.push('\\');
                                    value.push(c);
                                }
                                'n' => {
                                    value.push('\\');
                                    value.push('n');
                                }
                                'r' => {
                                    value.push('\\');
                                    value.push('r');
                                }
                                't' => {
                                    value.push('\\');
                                    value.push('t');
                                }
                                '0' => {
                                    value.push('\\');
                                    value.push('0');
                                }
                                _ => return Token::Invalid,
                            },
                        }
                    }

                    _ => {
                        value.push(c);
                    }
                },
            }
        }
    }

    fn scan_character_literal(&mut self) -> Token {
        let value: char;
        self.read_character();

        match self.character {
            None => return Token::Invalid,
            Some(c) => match c {
                '\'' => return Token::Invalid,
                '\\' => {
                    self.read_character();
                    match self.character {
                        None => return Token::Invalid,
                        Some(c) => match c {
                            '\"' | '\\' | '\'' => value = c,
                            'n' => value = '\n',
                            'r' => value = '\r',
                            't' => value = '\t',
                            '0' => value = '\0',
                            _ => return Token::Invalid,
                        },
                    }
                }
                _ => value = c,
            },
        }
        self.read_character();
        match self.character {
            None => Token::Invalid,
            Some(c) => match c {
                '\'' => Token::Literal(Literal::Character(value)),
                _ => Token::Invalid,
            },
        }
    }

    fn scan_numeric_or_hex_literal(&mut self, mut value: String) -> Token {
        self.read_character();
        match self.character {
            None => return Token::Literal(Literal::Integer(value)),
            Some(c) => match c {
                '0'..='9' => {
                    value.push(c);
                    return self.scan_numeric_literal(value);
                }
                '.' => {
                    value.push(c);
                    return self.scan_fraction(value);
                }
                'E' | 'e' => {
                    value.push(c);
                    return self.scan_exponent(value);
                }
                'x' => {
                    return self.scan_hex_literal();
                }
                _ => return Token::Literal(Literal::Integer(value)),
            },
        }
    }

    fn scan_numeric_literal(&mut self, mut value: String) -> Token {
        loop {
            self.read_character();
            match self.character {
                None => {
                    return Token::Literal(Literal::Integer(value));
                }
                Some(c) => match c {
                    '0'..='9' => {
                        value.push(c);
                    }
                    '.' => {
                        value.push(c);
                        return self.scan_fraction(value);
                    }
                    'E' | 'e' => {
                        value.push(c);
                        return self.scan_exponent(value);
                    }
                    _ => return Token::Literal(Literal::Integer(value)),
                },
            }
        }
    }

    fn scan_fraction(&mut self, mut value: String) -> Token {
        loop {
            self.read_character();
            match self.character {
                None => {
                    return Token::Literal(Literal::FloatingPoint(value));
                }
                Some(c) => match c {
                    '0'..='9' => {
                        value.push(c);
                    }
                    'E' | 'e' => {
                        value.push(c);
                        return self.scan_exponent(value);
                    }
                    _ => return Token::Literal(Literal::FloatingPoint(value)),
                },
            }
        }
    }

    fn scan_exponent(&mut self, mut value: String) -> Token {
        loop {
            self.read_character();
            match self.character {
                None => {
                    return Token::Literal(Literal::FloatingPoint(value));
                }
                Some(c) => match c {
                    '0'..='9' => {
                        value.push(c);
                    }
                    _ => return Token::Literal(Literal::FloatingPoint(value)),
                },
            }
        }
    }

    fn scan_hex_literal(&mut self) -> Token {
        let mut value = String::new();
        loop {
            self.read_character();
            match self.character {
                None => {
                    return Token::Literal(Literal::FloatingPoint(value));
                }
                Some(c) => match c {
                    '0'..='9' | 'a'..='f' | 'A'..='F' => {
                        value.push(c);
                    }
                    _ => return Token::Literal(Literal::Hex(value)),
                },
            }
        }
    }

    fn skip_whitespace(&mut self) {
        loop {
            match self.character {
                None => return,
                Some(c) => match c {
                    ' ' => {
                        self.read_character();
                        continue;
                    }
                    '\t' => {
                        self.read_character();
                        continue;
                    }
                    '\r' => {
                        self.read_character();
                        continue;
                    }
                    '\n' => {
                        self.line = self.line + 1;
                        self.read_character();
                        continue;
                    }
                    '/' => {
                        self.read_character();
                        match self.character {
                            None => return,
                            Some(c) => match c {
                                '/' => {
                                    self.read_character();
                                    self.handle_single_line_comment()
                                }
                                '*' => {
                                    self.read_character();
                                    self.handle_multi_line_comment()
                                }
                                _ => return,
                            },
                        }
                    }

                    _ => {
                        return;
                    }
                },
            }
        }
    }

    fn handle_single_line_comment(&mut self) {
        loop {
            match self.character {
                None => return,
                Some(c) => match c {
                    '\t' => {
                        self.read_character();
                        continue;
                    }
                    '\r' => {
                        continue;
                    }
                    '\n' => {
                        self.read_character();
                        return;
                    }
                    _ => {
                        self.read_character();
                        continue;
                    }
                },
            }
        }
    }

    fn handle_multi_line_comment(&mut self) {
        loop {
            match self.character {
                None => return,
                Some(c) => match c {
                    '/' => {
                        self.read_character();
                        match self.character {
                            None => return,
                            Some(c) => match c {
                                '*' => self.handle_multi_line_comment(),
                                _ => return,
                            },
                        }
                    }

                    '*' => {
                        self.read_character();
                        match self.character {
                            None => return,
                            Some(c) => match c {
                                '/' => {
                                    self.read_character();
                                    return;
                                }
                                _ => (),
                            },
                        }
                    }

                    '\t' => {
                        self.read_character();
                        continue;
                    }

                    '\r' => {
                        continue;
                    }

                    '\n' => {
                        self.read_character();
                        self.line = self.line + 1;
                        continue;
                    }

                    _ => {
                        self.read_character();
                        continue;
                    }
                },
            }
        }
    }

    pub fn _parse_keyword(&mut self, fixed_string: String) -> bool {
        match &self.token {
            Token::Empty => self.advance(),
            _ => (),
        }
        match &self.token {
            Token::Identifier(name) => {
                let right_keyword = *name == fixed_string;
                self.empty();
                return right_keyword;
            }
            _ => return false,
        }
    }

    pub fn _parse_identifier(&mut self) -> Option<String> {
        match &self.token {
            Token::Empty => self.advance(),
            _ => (),
        }
        match &self.token {
            Token::Identifier(name) => {
                let ret = String::from(name);
                self.empty();
                return Some(ret);
            }
            _ => return None,
        }
    }

    pub fn parse_punctuation(&mut self, fixed_string: String) -> bool {
        match &self.token {
            Token::Empty => self.advance(),
            _ => (),
        }
        match &self.token {
            Token::Punctuation(name) => {
                let ret = *name == fixed_string;
                if ret {
                    self.empty();
                }
                return ret;
            }
            _ => return false,
        }
    }

    pub fn parse_literal(&mut self) -> Option<Literal> {
        match &self.token {
            Token::Empty => self.advance(),
            _ => (),
        }
        match &self.token {
            Token::Literal(Literal::StringLiteral(name)) => {
                let ret = String::from(name);
                self.empty();
                Some(Literal::StringLiteral(ret))
            }
            Token::Literal(Literal::Character(character)) => {
                let ret = *character;
                self.empty();
                Some(Literal::Character(ret))
            }
            Token::Literal(Literal::Integer(name)) => {
                let ret = String::from(name);
                self.empty();
                Some(Literal::Integer(ret))
            }
            Token::Literal(Literal::FloatingPoint(name)) => {
                let ret = String::from(name);
                self.empty();
                Some(Literal::FloatingPoint(ret))
            }
            Token::Literal(Literal::Hex(name)) => {
                let ret = String::from(name);
                self.empty();
                Some(Literal::Hex(ret))
            }
            _ => None,
        }
    }

    pub fn is_at_end(&mut self) -> bool {
        match self.character {
            None => true,
            Some(_) => false,
        }
    }

    pub fn get_position(&self) -> Position {
        Position {
            line: self.line,
            column: self.column,
        }
    }

    pub fn get_previous_position(&self) -> Position {
        Position {
            line: self.previous_line,
            column: self.previous_column,
        }
    }
}
<commit_msg>lexer fix<commit_after>use std::str::Chars;

pub struct Position {
    pub line: usize,
    pub column: usize,
}

pub enum Token {
    Empty,
    Invalid,
    Identifier(String),
    Literal(Literal),
    Punctuation(String),
}

pub enum Literal {
    StringLiteral(String),
    Character(char),
    Integer(String),
    FloatingPoint(String),
    Hex(String),
}

pub struct Lexer<'a> {
    pub token: Token,
    character: Option<char>,
    chars: Chars<'a>,
    previous_line: usize,
    previous_column: usize,
    pub line: usize,
    pub column: usize,
}

impl<'a> Lexer<'a> {
    pub fn new(deck: &'a str) -> Lexer {
        let mut lexer = Lexer {
            chars: deck.chars(),
            token: Token::Empty,
            character: None,
            previous_line: 1,
            previous_column: 0,
            line: 1,
            column: 0,
        };
        lexer.read_character();
        lexer
    }

    fn read_character(&mut self) {
        self.character = self.chars.next();
        match self.character {
            None => (),
            Some(c) => match c {
                '\r' => (),
                '\n' => {
                    self.column = 0;
                    self.line = self.line + 1;
                }
                '\t' => self.column = self.column + 4,
                _ => self.column = self.column + 1,
            },
        }
    }

    pub fn advance(&mut self) {
        self.skip_whitespace();
        self.previous_line = self.line;
        self.previous_column = self.column;
        match self.character {
            None => return,
            Some(c) => {
                if ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) {
                    let mut name = String::new();
                    name.push(c);
                    self.token = self.scan_identifier(name);
                    return;
                }

                if (c >= '1') && (c <= '9') {
                    let mut value = String::new();
                    value.push(c);
                    self.token = self.scan_numeric_literal(value);
                    return;
                }

                match c {
                    '0' => {
                        let mut value = String::new();
                        value.push(c);
                        self.token = self.scan_numeric_or_hex_literal(value);
                    }
                    '+' | '-' | '*' | '/' | '=' | '%' | '&' | '|' | '^' | '~' | '<' | '>' => {
                        let mut operation = String::new();
                        operation.push(c);
                        self.token = self.scan_operator(operation)
                    }
                    '\"' => self.token = { self.scan_string_literal() },
                    '\'' => self.token = { self.scan_character_literal() },
                    '{' | '}' | '(' | ')' | '[' | ']' | '.' | ',' | ':' | ';' | '?' | '!' | '@'
                    | '#' | '$' | '_' | '`' => {
                        let mut punctuation_string = String::new();
                        punctuation_string.push(c);
                        self.token = Token::Punctuation(punctuation_string);
                    }
                    _ => self.token = Token::Invalid,
                }
            }
        }
    }

    pub fn empty(&mut self) {
        self.token = Token::Empty;
    }

    fn scan_identifier(&mut self, mut name: String) -> Token {
        loop {
            match self.character {
                None => {
                    if name.len() == 0 {
                        return Token::Invalid;
                    } else {
                        return Token::Identifier(name);
                    }
                }

                Some(c) => match c {
                    'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => {
                        name.push(c);
                        self.read_character();
                    }
                    _ => return Token::Identifier(name),
                },
            }
        }
    }

    fn scan_operator(&mut self, mut operation: String) -> Token {
        loop {
            match self.character {
                None => {
                    if operation.len() == 0 {
                        return Token::Invalid;
                    } else {
                        return Token::Identifier(operation);
                    }
                }
                Some(c) => match c {
                    '+' | '-' | '*' | '/' | '=' | '%' | '&' | '|' | '^' | '~' | '<' | '>' => {
                        operation.push(c);
                    }

                    _ => return Token::Identifier(operation),
                },
            }
        }
    }

    fn scan_string_literal(&mut self) -> Token {
        let mut value = String::new();

        loop {
            self.read_character();

            match self.character {
                None => return Token::Invalid,
                Some(c) => match c {
                    '\"' => {
                        self.read_character();
                        return Token::Literal(Literal::StringLiteral(value));
                    }

                    '\\' => {
                        self.read_character();
                        match self.character {
                            None => return Token::Invalid,
                            Some(c) => match c {
                                '\"' | '\\' | '\'' => {
                                    value.push('\\');
                                    value.push(c);
                                }
                                'n' => {
                                    value.push('\\');
                                    value.push('n');
                                }
                                'r' => {
                                    value.push('\\');
                                    value.push('r');
                                }
                                't' => {
                                    value.push('\\');
                                    value.push('t');
                                }
                                '0' => {
                                    value.push('\\');
                                    value.push('0');
                                }
                                _ => return Token::Invalid,
                            },
                        }
                    }

                    _ => {
                        value.push(c);
                    }
                },
            }
        }
    }

    fn scan_character_literal(&mut self) -> Token {
        let value: char;
        self.read_character();

        match self.character {
            None => return Token::Invalid,
            Some(c) => match c {
                '\'' => return Token::Invalid,
                '\\' => {
                    self.read_character();
                    match self.character {
                        None => return Token::Invalid,
                        Some(c) => match c {
                            '\"' | '\\' | '\'' => value = c,
                            'n' => value = '\n',
                            'r' => value = '\r',
                            't' => value = '\t',
                            '0' => value = '\0',
                            _ => return Token::Invalid,
                        },
                    }
                }
                _ => value = c,
            },
        }
        self.read_character();
        match self.character {
            None => Token::Invalid,
            Some(c) => match c {
                '\'' => Token::Literal(Literal::Character(value)),
                _ => Token::Invalid,
            },
        }
    }

    fn scan_numeric_or_hex_literal(&mut self, mut value: String) -> Token {
        self.read_character();
        match self.character {
            None => return Token::Literal(Literal::Integer(value)),
            Some(c) => match c {
                '0'..='9' => {
                    value.push(c);
                    return self.scan_numeric_literal(value);
                }
                '.' => {
                    value.push(c);
                    return self.scan_fraction(value);
                }
                'E' | 'e' => {
                    value.push(c);
                    return self.scan_exponent(value);
                }
                'x' => {
                    return self.scan_hex_literal();
                }
                _ => return Token::Literal(Literal::Integer(value)),
            },
        }
    }

    fn scan_numeric_literal(&mut self, mut value: String) -> Token {
        loop {
            self.read_character();
            match self.character {
                None => {
                    return Token::Literal(Literal::Integer(value));
                }
                Some(c) => match c {
                    '0'..='9' => {
                        value.push(c);
                    }
                    '.' => {
                        value.push(c);
                        return self.scan_fraction(value);
                    }
                    'E' | 'e' => {
                        value.push(c);
                        return self.scan_exponent(value);
                    }
                    _ => return Token::Literal(Literal::Integer(value)),
                },
            }
        }
    }

    fn scan_fraction(&mut self, mut value: String) -> Token {
        loop {
            self.read_character();
            match self.character {
                None => {
                    return Token::Literal(Literal::FloatingPoint(value));
                }
                Some(c) => match c {
                    '0'..='9' => {
                        value.push(c);
                    }
                    'E' | 'e' => {
                        value.push(c);
                        return self.scan_exponent(value);
                    }
                    _ => return Token::Literal(Literal::FloatingPoint(value)),
                },
            }
        }
    }

    fn scan_exponent(&mut self, mut value: String) -> Token {
        loop {
            self.read_character();
            match self.character {
                None => {
                    return Token::Literal(Literal::FloatingPoint(value));
                }
                Some(c) => match c {
                    '0'..='9' => {
                        value.push(c);
                    }
                    _ => return Token::Literal(Literal::FloatingPoint(value)),
                },
            }
        }
    }

    fn scan_hex_literal(&mut self) -> Token {
        let mut value = String::new();
        loop {
            self.read_character();
            match self.character {
                None => {
                    return Token::Literal(Literal::FloatingPoint(value));
                }
                Some(c) => match c {
                    '0'..='9' | 'a'..='f' | 'A'..='F' => {
                        value.push(c);
                    }
                    _ => return Token::Literal(Literal::Hex(value)),
                },
            }
        }
    }

    fn skip_whitespace(&mut self) {
        loop {
            match self.character {
                None => return,
                Some(c) => match c {
                    ' ' => {
                        self.read_character();
                        continue;
                    }
                    '\t' => {
                        self.read_character();
                        continue;
                    }
                    '\r' => {
                        self.read_character();
                        continue;
                    }
                    '\n' => {
                        self.read_character();
                        continue;
                    }
                    '/' => {
                        self.read_character();
                        match self.character {
                            None => return,
                            Some(c) => match c {
                                '/' => {
                                    self.read_character();
                                    self.handle_single_line_comment()
                                }
                                '*' => {
                                    self.read_character();
                                    self.handle_multi_line_comment()
                                }
                                _ => return,
                            },
                        }
                    }

                    _ => {
                        return;
                    }
                },
            }
        }
    }

    fn handle_single_line_comment(&mut self) {
        loop {
            match self.character {
                None => return,
                Some(c) => match c {
                    '\t' => {
                        self.read_character();
                        continue;
                    }
                    '\r' => {
                        continue;
                    }
                    '\n' => {
                        self.read_character();
                        return;
                    }
                    _ => {
                        self.read_character();
                        continue;
                    }
                },
            }
        }
    }

    fn handle_multi_line_comment(&mut self) {
        loop {
            match self.character {
                None => return,
                Some(c) => match c {
                    '/' => {
                        self.read_character();
                        match self.character {
                            None => return,
                            Some(c) => match c {
                                '*' => self.handle_multi_line_comment(),
                                _ => return,
                            },
                        }
                    }

                    '*' => {
                        self.read_character();
                        match self.character {
                            None => return,
                            Some(c) => match c {
                                '/' => {
                                    self.read_character();
                                    return;
                                }
                                _ => (),
                            },
                        }
                    }

                    '\t' => {
                        self.read_character();
                        continue;
                    }

                    '\r' => {
                        continue;
                    }

                    '\n' => {
                        self.read_character();
                        continue;
                    }

                    _ => {
                        self.read_character();
                        continue;
                    }
                },
            }
        }
    }

    pub fn _parse_keyword(&mut self, fixed_string: String) -> bool {
        match &self.token {
            Token::Empty => self.advance(),
            _ => (),
        }
        match &self.token {
            Token::Identifier(name) => {
                let right_keyword = *name == fixed_string;
                self.empty();
                return right_keyword;
            }
            _ => return false,
        }
    }

    pub fn _parse_identifier(&mut self) -> Option<String> {
        match &self.token {
            Token::Empty => self.advance(),
            _ => (),
        }
        match &self.token {
            Token::Identifier(name) => {
                let ret = String::from(name);
                self.empty();
                return Some(ret);
            }
            _ => return None,
        }
    }

    pub fn parse_punctuation(&mut self, fixed_string: String) -> bool {
        match &self.token {
            Token::Empty => self.advance(),
            _ => (),
        }
        match &self.token {
            Token::Punctuation(name) => {
                let ret = *name == fixed_string;
                if ret {
                    self.empty();
                }
                return ret;
            }
            _ => return false,
        }
    }

    pub fn parse_literal(&mut self) -> Option<Literal> {
        match &self.token {
            Token::Empty => self.advance(),
            _ => (),
        }
        match &self.token {
            Token::Literal(Literal::StringLiteral(name)) => {
                let ret = String::from(name);
                self.empty();
                Some(Literal::StringLiteral(ret))
            }
            Token::Literal(Literal::Character(character)) => {
                let ret = *character;
                self.empty();
                Some(Literal::Character(ret))
            }
            Token::Literal(Literal::Integer(name)) => {
                let ret = String::from(name);
                self.empty();
                Some(Literal::Integer(ret))
            }
            Token::Literal(Literal::FloatingPoint(name)) => {
                let ret = String::from(name);
                self.empty();
                Some(Literal::FloatingPoint(ret))
            }
            Token::Literal(Literal::Hex(name)) => {
                let ret = String::from(name);
                self.empty();
                Some(Literal::Hex(ret))
            }
            _ => None,
        }
    }

    pub fn is_at_end(&mut self) -> bool {
        match self.character {
            None => true,
            Some(_) => false,
        }
    }

    pub fn get_position(&self) -> Position {
        Position {
            line: self.line,
            column: self.column,
        }
    }

    pub fn get_previous_position(&self) -> Position {
        Position {
            line: self.previous_line,
            column: self.previous_column,
        }
    }
}
<|endoftext|>


<commit_before>use rusqlite::Connection;
use std::result;

#[derive(Debug)]
pub struct VariablePair {
    id: i32,
    fk_variable: i32,
    variable_value: String,
}

pub fn table_create_variable_pair(conn: &Connection) {
    let load_table = conn.execute(
        "CREATE TABLE  VARIABLE_PAIR (
                  id            INTEGER PRIMARY KEY ASC,
                  fk_variable   INTEGER NOT NULL,
                  variable_value  TEXT,
                  FOREIGN KEY(fk_variable) REFERENCES VARIABLE_NAME(id) ON UPDATE CASCADE
                  )",
        &[],
    );
    if load_table.is_err() {
        println!("table_create_job Failed {:?}", load_table);
        return;
    }
    load_table.unwrap();
}

pub fn insert_variable_pair(
    conn: &Connection,
    fk_variable: &i32,
    name: &str,
) -> Result<i32, &'static str> {
    let bill = fk_variable;
    let mut john = String::from(name);
    let me = VariablePair {
        id: 0,
        fk_variable: bill.clone(),
        variable_value: john,
    };
    let variable_pair_instance = conn.execute(
        "INSERT INTO VARIABLE_PAIR (fk_variable, variable_value)
                  VALUES (?1 ?2)",
        &[&me.fk_variable, &me.variable_value],
    );
    if variable_pair_instance.is_err() {
        return Err("Insert failed");
    }
    variable_pair_instance.unwrap();
    return Ok(0);
}

pub fn list_variable_pair(conn: &Connection) -> Vec<VariablePair> {
    let mut stmt = conn.prepare("SELECT id, fk_variable, variable_value  FROM VARIABLE_PAIR")
        .unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        VariablePair {
            id: row.get(0),
            fk_variable: row.get(1),
            variable_value: row.get(2),
        }
    });
    let mut items = Vec::<VariablePair>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn variable_pair_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, fk_variable, variable_value FROM VARIABLE_PAIR")
        .unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        VariablePair {
            id: row.get(0),
            fk_variable: row.get(1),
            variable_value: row.get(2),
        }
    }).unwrap();

    for person in person_iter {
        println!("Found variable_pair {:?}", person.unwrap());
    }
}

pub fn pk_variable_pair_by_name(
    conn: &Connection,
    fk_variable: &i32,
    name: &str,
) -> Result<i32, &'static str> {
    let mut output = 0;
    let bill = String::from(name);
    let mut stmt = conn.prepare("SELECT VARIABLE_PAIR.id, VARIABLE_PAIR.fk_variable, VARIABLE_PAIR.variable_value  FROM VARIABLE_PAIR
		WHERE VARIABLE_PAIR.fk_variable = ?1 AND VARIABLE_PAIR.variable_value = ?2").unwrap();
    let variable_pair_iter = stmt.query_map(&[fk_variable, &bill], |row| {
        VariablePair {
            id: row.get(0),
            fk_variable: row.get(1),
            variable_value: row.get(2),
        }
    });
    if variable_pair_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = variable_pair_iter.unwrap();
    let mut found = 0;
    let mut items = Vec::<i32>::new();
    for person in result {
        let bill = person.unwrap();
        output = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(output);
    }
    return Err("None found");
}
<commit_msg>Bugfix insert_variable_pair<commit_after>use rusqlite::Connection;
use std::result::Result;

#[derive(Debug)]
pub struct VariablePair {
    id: i32,
    fk_variable: i32,
    variable_value: String,
}

pub fn table_create_variable_pair(conn: &Connection) {
    let load_table = conn.execute(
        "CREATE TABLE  VARIABLE_PAIR (
                  id            INTEGER PRIMARY KEY ASC,
                  fk_variable   INTEGER NOT NULL,
                  variable_value  TEXT,
                  FOREIGN KEY (fk_variable) REFERENCES VARIABLE_NAME(id) ON UPDATE CASCADE
                  )",
        &[],
    );
    if load_table.is_err() {
        println!("table_create_variable_pair Failed {:?}", load_table);
        return;
    }
    load_table.unwrap();
}

pub fn insert_variable_pair(
    conn: &Connection,
    fk_variable: &i32,
    name: &str,
) -> Result<i32, &'static str> {
    let me = VariablePair {
        id: 0,
        variable_value: name.to_string(),
        fk_variable: fk_variable.clone(),
    };
    let variable_pair_instance = conn.execute(
        "INSERT INTO VARIABLE_PAIR (fk_variable, variable_value)
                 VALUES (?1, ?2)",
        &[&me.fk_variable, &me.variable_value],
    );
    if variable_pair_instance.is_err() {
        println!("Failed to insert:{:?}", me);
        return Err("INSERT INTO VARIABLE_PAIR failed");
    }
    variable_pair_instance.unwrap();
    return Ok(0);
}

pub fn list_variable_pair(conn: &Connection) -> Vec<VariablePair> {
    let mut stmt = conn.prepare("SELECT id, fk_variable, variable_value  FROM VARIABLE_PAIR")
        .unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        VariablePair {
            id: row.get(0),
            fk_variable: row.get(1),
            variable_value: row.get(2),
        }
    });
    let mut items = Vec::<VariablePair>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn variable_pair_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, fk_variable, variable_value FROM VARIABLE_PAIR")
        .unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        VariablePair {
            id: row.get(0),
            fk_variable: row.get(1),
            variable_value: row.get(2),
        }
    }).unwrap();

    for person in person_iter {
        println!("Found variable_pair {:?}", person.unwrap());
    }
}

pub fn pk_variable_pair_by_name(
    conn: &Connection,
    fk_variable: &i32,
    name: &str,
) -> Result<i32, &'static str> {
    let mut output = 0;
    let bill = String::from(name);
    let mut stmt = conn.prepare(
        "SELECT VARIABLE_PAIR.id, VARIABLE_PAIR.fk_variable, VARIABLE_PAIR.variable_value
        FROM VARIABLE_PAIR
		WHERE VARIABLE_PAIR.fk_variable = ?1 AND VARIABLE_PAIR.variable_value = ?2",
    ).unwrap();
    let variable_pair_iter = stmt.query_map(&[fk_variable, &bill], |row| {
        VariablePair {
            id: row.get(0),
            fk_variable: row.get(1),
            variable_value: row.get(2),
        }
    });
    if variable_pair_iter.is_err() {
        return Err("Select failed dfdf");
    }
    let result = variable_pair_iter.unwrap();
    let mut found = 0;
    for person in result {
        let bill = person.unwrap();
        output = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(output);
    }
    return Err("None found");
}
<|endoftext|>


<commit_before>// 32-bit fixed point. Haven't decided on the fractional bits yet

extern crate int_traits;

use std::cmp::Ordering;
use std::cmp::PartialOrd;
use std::ops::Add;
use std::ops::Neg;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use self::int_traits::IntTraits;

type Int = i32;
type DoubleInt = i64;

// Adjust this to balance between range and granularity
// 6 --> 20.12
// 8 --> 16.16
// 10 --> 12.20
pub const HALF_FRACTIONAL_BITS: Int = 8;

pub const FRACTIONAL_BITS: Int = HALF_FRACTIONAL_BITS * 2;
pub const ROOT_DENOMINATOR: Int = 1 << HALF_FRACTIONAL_BITS;
pub const DENOMINATOR: Int = 1 << FRACTIONAL_BITS;

#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Fx32 {
	pub x: Int,
}

impl Fx32 {
	pub fn new (x: Int) -> Fx32 {
		Fx32 {
			x: x,
		}
	}

	pub fn from_float (x: f32) -> Fx32 {
		Fx32::new ((x * DENOMINATOR as f32) as Int)
	}

	pub fn from_q (num: Int, den: Int) -> Fx32 {
		Fx32::new ((num * DENOMINATOR) / den)
	}

	pub fn from_int (x: Int) -> Fx32 {
		Fx32::from_q (x, 1)
	}

	pub fn to_f64 (&self) -> f64 {
		self.x as f64 / DENOMINATOR as f64
	}

	pub fn to_i32 (&self) -> i32 {
		self.x / DENOMINATOR
	}
	/*
	pub fn to_small (self) -> Fx32Small {
		assert! (self.abs () < 2);
		Fx32Small {
			x: self,
		}
	}
	*/
	pub fn abs (&self) -> Fx32 {
		Fx32::new (self.x.abs ())
	}

	// More precise and automatic but requires a branch
	pub fn mul_precise (self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		if a.abs () > b.abs () {
			Fx32::new ((a / ROOT_DENOMINATOR) * (b) / ROOT_DENOMINATOR)
		}
		else {
			Fx32::new ((a) * (b / ROOT_DENOMINATOR) / ROOT_DENOMINATOR)
		}
	}

	// For multiplying two numbers <= 1.0 such as
	// color mixing or dotting unit vectors
	pub fn mul_small (&self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		Fx32::new (((a / 2) * (b / 2)) / (DENOMINATOR / 4))
	}

	pub fn mul_big (&self, o: Fx32) -> Fx32 {
		/*
		let c be the fixed point 'factor'
		a = 1.0
		b = 2.0
		c = 65536

		(a * c) * (b * c) ---> (a * b * c)

		We must end up dividing by c
		We can do this by dividing both a and b by root c
		*/

		Fx32::new ((self.x / ROOT_DENOMINATOR) * (o.x / ROOT_DENOMINATOR))
	}

	/*
	I think this is the canonical way to do it,
	but it does require i64. Will need performance testing
	on the Pandora.

	I would recommend starting with this as a reference,
	and dropping precision where we can afford it based on
	regression testing.
	*/
	pub fn mul_64 (self, o: Fx32) -> Fx32 {
		let c = self.x as DoubleInt * o.x as DoubleInt;
		Fx32::new ((c / DENOMINATOR as DoubleInt) as Int)
	}

	pub fn div_64 (self, o: Fx32) -> Fx32 {
		let a2 = self.x as DoubleInt * DENOMINATOR as DoubleInt;
		Fx32::new ((a2 / o.x as DoubleInt) as Int)
	}

	pub fn square_64 (self) -> Fx32 {
		Fx32::mul_64 (self, self)
	}

	pub fn sqrt_64 (self) -> Fx32 {
		Fx32 {
			x: (self.x as DoubleInt * DENOMINATOR as DoubleInt).sqrt () as Int,
		}
	}
}
/*
impl fmt::Debug for Fx32 {
    fn fmt (&self, f: &mut fmt::Formatter) -> fmt::Result {
        write! (f, "Fx32 ({})", self.to_f64 ())
    }
}
*/
impl Add <Fx32> for Fx32 {
	type Output = Fx32;

	fn add (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x + o.x)
	}
}
/*
// This is stupid
impl <'a, 'b> Add <&'a Fx32> for &'b Fx32 {
	type Output = Fx32;

	fn add (self, o: &'a Fx32) -> Fx32 {
		Fx32::new (self.x + o.x)
	}
}
*/
impl Sub <Fx32> for Fx32 {
	type Output = Fx32;

	fn sub (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x - o.x)
	}
}

impl Neg for Fx32 {
	type Output = Fx32;

	fn neg (self) -> Fx32 {
		Fx32::new (-self.x)
	}
}

impl Mul <Fx32> for Fx32 {
	type Output = Fx32;

	fn mul (self, o: Fx32) -> Fx32 {
		Fx32::mul_64 (self, o)
	}
}

impl Div <Fx32> for Fx32 {
	type Output = Fx32;

	fn div (self, o: Fx32) -> Fx32 {
		Fx32::div_64 (self, o)
	}
}

impl PartialOrd for Fx32 {
	fn partial_cmp (&self, o: &Fx32) -> Option <Ordering> {
		self.x.partial_cmp (&o.x)
	}
}

impl PartialEq <i32> for Fx32 {
	fn eq (&self, o: &i32) -> bool {
		self.x == Fx32::from_int (*o).x
	}
}

impl PartialOrd <i32> for Fx32 {
	fn partial_cmp (&self, o: &i32) -> Option <Ordering> {
		self.x.partial_cmp (&Fx32::from_int (*o).x)
	}
}

/*
A specialized fixed-point number with the same fractional bits,
but compile-time hints that it should fall in the range (-2.0, +2.0)
and asserts.

#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Fx32Small {
	pub x: Fx32,
}

impl Fx32Small {
	pub fn mul_by_big (o: Fx32) -> Fx32 {

	}
}

impl Mul <Fx32Small> for Fx32 {

}
*/
<commit_msg>Replacing multiplies / divides with bitshifts where appropriate<commit_after>// 32-bit fixed point. Haven't decided on the fractional bits yet

extern crate int_traits;

use std::cmp::Ordering;
use std::cmp::PartialOrd;
use std::ops::Add;
use std::ops::Neg;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use self::int_traits::IntTraits;

type Int = i32;
type DoubleInt = i64;

// Adjust this to balance between range and granularity
// 6 --> 20.12
// 8 --> 16.16
// 10 --> 12.20
pub const HALF_FRACTIONAL_BITS: Int = 8;

pub const FRACTIONAL_BITS: Int = HALF_FRACTIONAL_BITS * 2;
pub const DENOMINATOR: Int = 1 << FRACTIONAL_BITS;

#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Fx32 {
	pub x: Int,
}

impl Fx32 {
	pub fn new (x: Int) -> Fx32 {
		Fx32 {
			x: x,
		}
	}

	pub fn from_float (x: f32) -> Fx32 {
		Fx32::new ((x * DENOMINATOR as f32) as Int)
	}

	pub fn from_q (num: Int, den: Int) -> Fx32 {
		Fx32::new ((num << FRACTIONAL_BITS) / den)
	}

	pub fn from_int (x: Int) -> Fx32 {
		Fx32::from_q (x, 1)
	}

	pub fn to_f64 (&self) -> f64 {
		self.x as f64 / DENOMINATOR as f64
	}

	pub fn to_i32 (&self) -> i32 {
		self.x >> FRACTIONAL_BITS
	}
	/*
	pub fn to_small (self) -> Fx32Small {
		assert! (self.abs () < 2);
		Fx32Small {
			x: self,
		}
	}
	*/
	pub fn abs (&self) -> Fx32 {
		Fx32::new (self.x.abs ())
	}

	// More precise and automatic but requires a branch
	pub fn mul_precise (self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		if a.abs () > b.abs () {
			Fx32::new ((a >> HALF_FRACTIONAL_BITS) * (b) >> HALF_FRACTIONAL_BITS)
		}
		else {
			Fx32::new ((a) * (b >> HALF_FRACTIONAL_BITS) >> HALF_FRACTIONAL_BITS)
		}
	}

	// For multiplying two numbers <= 1.0 such as
	// color mixing or dotting unit vectors
	pub fn mul_small (&self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		Fx32::new (((a / 2) * (b / 2)) >> (FRACTIONAL_BITS - 2))
	}

	pub fn mul_big (&self, o: Fx32) -> Fx32 {
		/*
		let c be the fixed point 'factor'
		a = 1.0
		b = 2.0
		c = 65536

		(a * c) * (b * c) ---> (a * b * c)

		We must end up dividing by c
		We can do this by dividing both a and b by root c
		*/

		Fx32::new ((self.x >> HALF_FRACTIONAL_BITS) * (o.x >> HALF_FRACTIONAL_BITS))
	}

	/*
	I think this is the canonical way to do it,
	but it does require i64. Will need performance testing
	on the Pandora.

	I would recommend starting with this as a reference,
	and dropping precision where we can afford it based on
	regression testing.
	*/
	pub fn mul_64 (self, o: Fx32) -> Fx32 {
		let c = self.x as DoubleInt * o.x as DoubleInt;
		Fx32::new ((c >> FRACTIONAL_BITS as DoubleInt) as Int)
	}

	pub fn div_64 (self, o: Fx32) -> Fx32 {
		let a2 = (self.x as DoubleInt) << FRACTIONAL_BITS as DoubleInt;
		Fx32::new ((a2 / o.x as DoubleInt) as Int)
	}

	pub fn square_64 (self) -> Fx32 {
		Fx32::mul_64 (self, self)
	}

	pub fn sqrt_64 (self) -> Fx32 {
		Fx32 {
			x: ((self.x as DoubleInt) << FRACTIONAL_BITS).sqrt () as Int,
		}
	}
}
/*
impl fmt::Debug for Fx32 {
    fn fmt (&self, f: &mut fmt::Formatter) -> fmt::Result {
        write! (f, "Fx32 ({})", self.to_f64 ())
    }
}
*/
impl Add <Fx32> for Fx32 {
	type Output = Fx32;

	fn add (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x + o.x)
	}
}
/*
// This is stupid
impl <'a, 'b> Add <&'a Fx32> for &'b Fx32 {
	type Output = Fx32;

	fn add (self, o: &'a Fx32) -> Fx32 {
		Fx32::new (self.x + o.x)
	}
}
*/
impl Sub <Fx32> for Fx32 {
	type Output = Fx32;

	fn sub (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x - o.x)
	}
}

impl Neg for Fx32 {
	type Output = Fx32;

	fn neg (self) -> Fx32 {
		Fx32::new (-self.x)
	}
}

impl Mul <Fx32> for Fx32 {
	type Output = Fx32;

	fn mul (self, o: Fx32) -> Fx32 {
		Fx32::mul_64 (self, o)
	}
}

impl Div <Fx32> for Fx32 {
	type Output = Fx32;

	fn div (self, o: Fx32) -> Fx32 {
		Fx32::div_64 (self, o)
	}
}

impl PartialOrd for Fx32 {
	fn partial_cmp (&self, o: &Fx32) -> Option <Ordering> {
		self.x.partial_cmp (&o.x)
	}
}

impl PartialEq <i32> for Fx32 {
	fn eq (&self, o: &i32) -> bool {
		self.x == Fx32::from_int (*o).x
	}
}

impl PartialOrd <i32> for Fx32 {
	fn partial_cmp (&self, o: &i32) -> Option <Ordering> {
		self.x.partial_cmp (&Fx32::from_int (*o).x)
	}
}

/*
A specialized fixed-point number with the same fractional bits,
but compile-time hints that it should fall in the range (-2.0, +2.0)
and asserts.

#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Fx32Small {
	pub x: Fx32,
}

impl Fx32Small {
	pub fn mul_by_big (o: Fx32) -> Fx32 {

	}
}

impl Mul <Fx32Small> for Fx32 {

}
*/
<|endoftext|>


<commit_before>//! With a Hotkey System the runner can use hotkeys on their keyboard to control
//! the Timer. The hotkeys are global, so the application doesn't need to be in
//! focus. The behavior of the hotkeys depends on the platform and is stubbed
//! out on platforms that don't support hotkeys. You can turn off a Hotkey
//! System temporarily. By default the Hotkey System is activated.

use crate::hotkey_config::OwnedHotkeyConfig;
use crate::shared_timer::OwnedSharedTimer;
use livesplit_core::HotkeySystem;

/// type
pub type OwnedHotkeySystem = Box<HotkeySystem>;
/// type
pub type NullableOwnedHotkeySystem = Option<OwnedHotkeySystem>;

/// Creates a new Hotkey System for a Timer with the default hotkeys.
#[no_mangle]
pub extern "C" fn HotkeySystem_new(shared_timer: OwnedSharedTimer) -> NullableOwnedHotkeySystem {
    HotkeySystem::new(*shared_timer).ok().map(Box::new)
}

/// Creates a new Hotkey System for a Timer with a custom configuration for the
/// hotkeys.
#[no_mangle]
pub extern "C" fn HotkeySystem_with_config(
    shared_timer: OwnedSharedTimer,
    config: OwnedHotkeyConfig,
) -> NullableOwnedHotkeySystem {
    HotkeySystem::with_config(*shared_timer, *config)
        .ok()
        .map(Box::new)
}

/// drop
#[no_mangle]
pub extern "C" fn HotkeySystem_drop(this: OwnedHotkeySystem) {
    drop(this);
}

/// Deactivates the Hotkey System. No hotkeys will go through until it gets
/// activated again. If it's already deactivated, nothing happens.
#[no_mangle]
pub extern "C" fn HotkeySystem_deactivate(this: &mut HotkeySystem) {
    this.deactivate();
}

/// Activates a previously deactivated Hotkey System. If it's already
/// active, nothing happens.
#[no_mangle]
pub extern "C" fn HotkeySystem_activate(this: &mut HotkeySystem) {
    this.activate();
}

/// Returns the hotkey configuration currently in use by the Hotkey System.
#[no_mangle]
pub extern "C" fn HotkeySystem_config(this: &HotkeySystem) -> OwnedHotkeyConfig {
    Box::new(this.config())
}

/// Applies a new hotkey configuration to the Hotkey System. Each hotkey is
/// changed to the one specified in the configuration. This operation may fail
/// if you provide a hotkey configuration where a hotkey is used for multiple
/// operations. Returns <FALSE> if the operation failed.
#[no_mangle]
pub extern "C" fn HotkeySystem_set_config(
    this: &mut HotkeySystem,
    config: OwnedHotkeyConfig,
) -> bool {
    this.set_config(*config).is_ok()
}
<commit_msg>changed activate function in capi to return a bool<commit_after>//! With a Hotkey System the runner can use hotkeys on their keyboard to control
//! the Timer. The hotkeys are global, so the application doesn't need to be in
//! focus. The behavior of the hotkeys depends on the platform and is stubbed
//! out on platforms that don't support hotkeys. You can turn off a Hotkey
//! System temporarily. By default the Hotkey System is activated.

use crate::hotkey_config::OwnedHotkeyConfig;
use crate::shared_timer::OwnedSharedTimer;
use livesplit_core::HotkeySystem;

/// type
pub type OwnedHotkeySystem = Box<HotkeySystem>;
/// type
pub type NullableOwnedHotkeySystem = Option<OwnedHotkeySystem>;

/// Creates a new Hotkey System for a Timer with the default hotkeys.
#[no_mangle]
pub extern "C" fn HotkeySystem_new(shared_timer: OwnedSharedTimer) -> NullableOwnedHotkeySystem {
    HotkeySystem::new(*shared_timer).ok().map(Box::new)
}

/// Creates a new Hotkey System for a Timer with a custom configuration for the
/// hotkeys.
#[no_mangle]
pub extern "C" fn HotkeySystem_with_config(
    shared_timer: OwnedSharedTimer,
    config: OwnedHotkeyConfig,
) -> NullableOwnedHotkeySystem {
    HotkeySystem::with_config(*shared_timer, *config)
        .ok()
        .map(Box::new)
}

/// drop
#[no_mangle]
pub extern "C" fn HotkeySystem_drop(this: OwnedHotkeySystem) {
    drop(this);
}

/// Deactivates the Hotkey System. No hotkeys will go through until it gets
/// activated again. If it's already deactivated, nothing happens.
#[no_mangle]
pub extern "C" fn HotkeySystem_deactivate(this: &mut HotkeySystem) -> bool {
    this.deactivate().is_ok()
}

/// Activates a previously deactivated Hotkey System. If it's already
/// active, nothing happens.
#[no_mangle]
pub extern "C" fn HotkeySystem_activate(this: &mut HotkeySystem) -> bool {
    this.activate().is_ok()
}

/// Returns the hotkey configuration currently in use by the Hotkey System.
#[no_mangle]
pub extern "C" fn HotkeySystem_config(this: &HotkeySystem) -> OwnedHotkeyConfig {
    Box::new(this.config())
}

/// Applies a new hotkey configuration to the Hotkey System. Each hotkey is
/// changed to the one specified in the configuration. This operation may fail
/// if you provide a hotkey configuration where a hotkey is used for multiple
/// operations. Returns <FALSE> if the operation failed.
#[no_mangle]
pub extern "C" fn HotkeySystem_set_config(
    this: &mut HotkeySystem,
    config: OwnedHotkeyConfig,
) -> bool {
    this.set_config(*config).is_ok()
}
<|endoftext|>


<commit_before>use std::thread::sleep;
use std::time::{Instant, Duration};

use rand::random;
use kvproto::pdpb;

use super::node::new_node_cluster;
use super::server::new_server_cluster;
use super::cluster::{Cluster, Simulator};
use super::transport_simulate::Isolate;

fn wait_down_peers<T: Simulator>(cluster: &Cluster<T>, count: u64) -> u64 {
    let begin = Instant::now();
    for _ in 1..100 {
        if cluster.get_down_peers().len() != count as usize {
            sleep(Duration::from_millis(100));
        } else {
            break;
        }
    }
    begin.elapsed().as_secs()
}

fn check_down_seconds(peer: &pdpb::PeerStats, secs: u64) {
    assert!(peer.get_down_seconds() == secs || secs > 0 && peer.get_down_seconds() == secs - 1);
}

fn test_leader_down_and_become_leader_again<T: Simulator>(cluster: &mut Cluster<T>, count: u64) {
    // Isolate node.
    let node = cluster.leader_of_region(1).unwrap();
    let node_id = node.get_id();
    cluster.add_send_filter(Isolate::new(node_id));
    // Kill another node.
    let next_id = if node_id < count {
        node_id + 1
    } else {
        1
    };
    cluster.stop_node(next_id);
    let secs = wait_down_peers(cluster, 2);

    // Check node and another are down.
    let down_peers = cluster.get_down_peers();
    check_down_seconds(down_peers.get(&node_id).unwrap(), secs);
    check_down_seconds(down_peers.get(&next_id).unwrap(), secs);

    // Restart node and sleep a few seconds.
    let sleep_secs = 3;
    cluster.clear_send_filters();
    wait_down_peers(cluster, 1);
    sleep(Duration::from_secs(sleep_secs));

    // Wait node to become leader again.
    loop {
        cluster.transfer_leader(1, node.clone());
        if let Some(peer) = cluster.leader_of_region(1) {
            if peer.get_id() == node_id {
                break;
            }
        }
        sleep(Duration::from_millis(100));
    }
    wait_down_peers(cluster, 1);

    // Ensure that node will not reuse the previous peer heartbeats.
    let prev_secs = cluster.get_down_peers().get(&next_id).unwrap().get_down_seconds();
    for _ in 1..100 {
        let down_secs = cluster.get_down_peers().get(&next_id).unwrap().get_down_seconds();
        if down_secs != prev_secs {
            assert!(down_secs < sleep_secs);
            break;
        }
        sleep(Duration::from_millis(100));
    }
}

fn test_down_peers<T: Simulator>(cluster: &mut Cluster<T>, count: u64) {
    cluster.cfg.raft_store.max_peer_down_duration = Duration::from_millis(100);
    cluster.run();

    // Kill 1, 3
    cluster.stop_node(1);
    cluster.stop_node(3);
    let secs = wait_down_peers(cluster, 2);

    // Check 1, 3 are down.
    let down_peers = cluster.get_down_peers();
    check_down_seconds(down_peers.get(&1).unwrap(), secs);
    check_down_seconds(down_peers.get(&3).unwrap(), secs);

    // Restart 1, 3
    cluster.run_node(1);
    cluster.run_node(3);
    wait_down_peers(cluster, 0);

    for _ in 0..3 {
        let n = random::<u64>() % count + 1;

        // kill n.
        cluster.stop_node(n);
        let secs = wait_down_peers(cluster, 1);

        // Check i is down and others are not down.
        for i in 1..(count + 1) {
            match cluster.get_down_peers().get(&i) {
                Some(peer) => {
                    assert_eq!(i, n);
                    check_down_seconds(peer, secs);
                }
                None => assert!(i != n),
            }
        }

        // Restart n.
        cluster.run_node(n);
        wait_down_peers(cluster, 0);
    }

    test_leader_down_and_become_leader_again(cluster, count);
}

#[test]
fn test_node_down_peers() {
    let mut cluster = new_node_cluster(0, 5);
    test_down_peers(&mut cluster, 5);
}

#[test]
fn test_server_down_peers() {
    let mut cluster = new_server_cluster(0, 5);
    test_down_peers(&mut cluster, 5);
}
<commit_msg>tests: fix test_down_peers. (#910)<commit_after>use std::thread::sleep;
use std::time::{Instant, Duration};

use rand::random;
use kvproto::pdpb;

use super::node::new_node_cluster;
use super::server::new_server_cluster;
use super::cluster::{Cluster, Simulator};
use super::transport_simulate::Isolate;

fn wait_down_peers<T: Simulator>(cluster: &Cluster<T>, count: u64) -> u64 {
    let begin = Instant::now();
    for _ in 1..100 {
        if cluster.get_down_peers().len() != count as usize {
            sleep(Duration::from_millis(100));
        } else {
            break;
        }
    }
    begin.elapsed().as_secs()
}

fn check_down_seconds(peer: &pdpb::PeerStats, secs: u64) {
    debug!("down {} secs {}", peer.get_down_seconds(), secs);
    assert!(peer.get_down_seconds() <= secs);

}

fn test_leader_down_and_become_leader_again<T: Simulator>(cluster: &mut Cluster<T>, count: u64) {
    // Isolate node.
    let node = cluster.leader_of_region(1).unwrap();
    let node_id = node.get_id();
    cluster.add_send_filter(Isolate::new(node_id));
    // Kill another node.
    let next_id = if node_id < count {
        node_id + 1
    } else {
        1
    };
    cluster.stop_node(next_id);
    let secs = wait_down_peers(cluster, 2);

    // Check node and another are down.
    let down_peers = cluster.get_down_peers();
    check_down_seconds(down_peers.get(&node_id).unwrap(), secs);
    check_down_seconds(down_peers.get(&next_id).unwrap(), secs);

    // Restart node and sleep a few seconds.
    let sleep_secs = 3;
    cluster.clear_send_filters();
    wait_down_peers(cluster, 1);
    sleep(Duration::from_secs(sleep_secs));

    // Wait node to become leader again.
    loop {
        cluster.transfer_leader(1, node.clone());
        if let Some(peer) = cluster.leader_of_region(1) {
            if peer.get_id() == node_id {
                break;
            }
        }
        sleep(Duration::from_millis(100));
    }
    wait_down_peers(cluster, 1);

    // Ensure that node will not reuse the previous peer heartbeats.
    let prev_secs = cluster.get_down_peers().get(&next_id).unwrap().get_down_seconds();
    for _ in 1..100 {
        let down_secs = cluster.get_down_peers().get(&next_id).unwrap().get_down_seconds();
        if down_secs != prev_secs {
            assert!(down_secs < sleep_secs);
            break;
        }
        sleep(Duration::from_millis(100));
    }
}

fn test_down_peers<T: Simulator>(cluster: &mut Cluster<T>, count: u64) {
    cluster.cfg.raft_store.max_peer_down_duration = Duration::from_millis(100);
    cluster.run();

    // Kill 1, 3
    cluster.stop_node(1);
    cluster.stop_node(3);
    let secs = wait_down_peers(cluster, 2);

    // Check 1, 3 are down.
    let down_peers = cluster.get_down_peers();
    check_down_seconds(down_peers.get(&1).unwrap(), secs);
    check_down_seconds(down_peers.get(&3).unwrap(), secs);

    // Restart 1, 3
    cluster.run_node(1);
    cluster.run_node(3);
    wait_down_peers(cluster, 0);

    for _ in 0..3 {
        let n = random::<u64>() % count + 1;

        // kill n.
        cluster.stop_node(n);
        let secs = wait_down_peers(cluster, 1);

        // Check i is down and others are not down.
        for i in 1..(count + 1) {
            match cluster.get_down_peers().get(&i) {
                Some(peer) => {
                    assert_eq!(i, n);
                    check_down_seconds(peer, secs);
                }
                None => assert!(i != n),
            }
        }

        // Restart n.
        cluster.run_node(n);
        wait_down_peers(cluster, 0);
    }

    test_leader_down_and_become_leader_again(cluster, count);
}

#[test]
fn test_node_down_peers() {
    let mut cluster = new_node_cluster(0, 5);
    test_down_peers(&mut cluster, 5);
}

#[test]
fn test_server_down_peers() {
    let mut cluster = new_server_cluster(0, 5);
    test_down_peers(&mut cluster, 5);
}
<|endoftext|>


<commit_before>use crate::{
    backend::Backend,
    buffer::{Buffer, Cell},
    layout::Rect,
};
use std::{fmt::Write, io};
use unicode_width::UnicodeWidthStr;

/// A backend used for the integration tests.
#[derive(Debug)]
pub struct TestBackend {
    width: u16,
    buffer: Buffer,
    height: u16,
    cursor: bool,
    pos: (u16, u16),
}

/// Returns a string representation of the given buffer for debugging purpose.
fn buffer_view(buffer: &Buffer) -> String {
    let mut view = String::with_capacity(buffer.content.len() + buffer.area.height as usize * 3);
    for cells in buffer.content.chunks(buffer.area.width as usize) {
        let mut overwritten = vec![];
        let mut skip: usize = 0;
        view.push('"');
        for (x, c) in cells.iter().enumerate() {
            if skip == 0 {
                view.push_str(&c.symbol);
            } else {
                overwritten.push((x, &c.symbol))
            }
            skip = std::cmp::max(skip, c.symbol.width()).saturating_sub(1);
        }
        view.push('"');
        if !overwritten.is_empty() {
            write!(
                &mut view,
                " Hidden by multi-width symbols: {:?}",
                overwritten
            )
            .unwrap();
        }
        view.push('\n');
    }
    view
}

impl TestBackend {
    pub fn new(width: u16, height: u16) -> TestBackend {
        TestBackend {
            width,
            height,
            buffer: Buffer::empty(Rect::new(0, 0, width, height)),
            cursor: false,
            pos: (0, 0),
        }
    }

    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn resize(&mut self, width: u16, height: u16) {
        self.buffer.resize(Rect::new(0, 0, width, height));
        self.width = width;
        self.height = height;
    }

    pub fn assert_buffer(&self, expected: &Buffer) {
        assert_eq!(expected.area, self.buffer.area);
        let diff = expected.diff(&self.buffer);
        if diff.is_empty() {
            return;
        }

        let mut debug_info = String::from("Buffers are not equal");
        debug_info.push('\n');
        debug_info.push_str("Expected:");
        debug_info.push('\n');
        let expected_view = buffer_view(expected);
        debug_info.push_str(&expected_view);
        debug_info.push('\n');
        debug_info.push_str("Got:");
        debug_info.push('\n');
        let view = buffer_view(&self.buffer);
        debug_info.push_str(&view);
        debug_info.push('\n');

        debug_info.push_str("Diff:");
        debug_info.push('\n');
        let nice_diff = diff
            .iter()
            .enumerate()
            .map(|(i, (x, y, cell))| {
                let expected_cell = expected.get(*x, *y);
                format!(
                    "{}: at ({}, {}) expected {:?} got {:?}",
                    i, x, y, expected_cell, cell
                )
            })
            .collect::<Vec<String>>()
            .join("\n");
        debug_info.push_str(&nice_diff);
        panic!(debug_info);
    }
}

impl Backend for TestBackend {
    fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error>
    where
        I: Iterator<Item = (u16, u16, &'a Cell)>,
    {
        for (x, y, c) in content {
            let cell = self.buffer.get_mut(x, y);
            *cell = c.clone();
        }
        Ok(())
    }

    fn hide_cursor(&mut self) -> Result<(), io::Error> {
        self.cursor = false;
        Ok(())
    }

    fn show_cursor(&mut self) -> Result<(), io::Error> {
        self.cursor = true;
        Ok(())
    }

    fn get_cursor(&mut self) -> Result<(u16, u16), io::Error> {
        Ok(self.pos)
    }

    fn set_cursor(&mut self, x: u16, y: u16) -> Result<(), io::Error> {
        self.pos = (x, y);
        Ok(())
    }

    fn clear(&mut self) -> Result<(), io::Error> {
        Ok(())
    }

    fn size(&self) -> Result<Rect, io::Error> {
        Ok(Rect::new(0, 0, self.width, self.height))
    }

    fn flush(&mut self) -> Result<(), io::Error> {
        Ok(())
    }
}
<commit_msg>fix(test): remove compile warning in TestBackend::assert_buffer (#466)<commit_after>use crate::{
    backend::Backend,
    buffer::{Buffer, Cell},
    layout::Rect,
};
use std::{fmt::Write, io};
use unicode_width::UnicodeWidthStr;

/// A backend used for the integration tests.
#[derive(Debug)]
pub struct TestBackend {
    width: u16,
    buffer: Buffer,
    height: u16,
    cursor: bool,
    pos: (u16, u16),
}

/// Returns a string representation of the given buffer for debugging purpose.
fn buffer_view(buffer: &Buffer) -> String {
    let mut view = String::with_capacity(buffer.content.len() + buffer.area.height as usize * 3);
    for cells in buffer.content.chunks(buffer.area.width as usize) {
        let mut overwritten = vec![];
        let mut skip: usize = 0;
        view.push('"');
        for (x, c) in cells.iter().enumerate() {
            if skip == 0 {
                view.push_str(&c.symbol);
            } else {
                overwritten.push((x, &c.symbol))
            }
            skip = std::cmp::max(skip, c.symbol.width()).saturating_sub(1);
        }
        view.push('"');
        if !overwritten.is_empty() {
            write!(
                &mut view,
                " Hidden by multi-width symbols: {:?}",
                overwritten
            )
            .unwrap();
        }
        view.push('\n');
    }
    view
}

impl TestBackend {
    pub fn new(width: u16, height: u16) -> TestBackend {
        TestBackend {
            width,
            height,
            buffer: Buffer::empty(Rect::new(0, 0, width, height)),
            cursor: false,
            pos: (0, 0),
        }
    }

    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn resize(&mut self, width: u16, height: u16) {
        self.buffer.resize(Rect::new(0, 0, width, height));
        self.width = width;
        self.height = height;
    }

    pub fn assert_buffer(&self, expected: &Buffer) {
        assert_eq!(expected.area, self.buffer.area);
        let diff = expected.diff(&self.buffer);
        if diff.is_empty() {
            return;
        }

        let mut debug_info = String::from("Buffers are not equal");
        debug_info.push('\n');
        debug_info.push_str("Expected:");
        debug_info.push('\n');
        let expected_view = buffer_view(expected);
        debug_info.push_str(&expected_view);
        debug_info.push('\n');
        debug_info.push_str("Got:");
        debug_info.push('\n');
        let view = buffer_view(&self.buffer);
        debug_info.push_str(&view);
        debug_info.push('\n');

        debug_info.push_str("Diff:");
        debug_info.push('\n');
        let nice_diff = diff
            .iter()
            .enumerate()
            .map(|(i, (x, y, cell))| {
                let expected_cell = expected.get(*x, *y);
                format!(
                    "{}: at ({}, {}) expected {:?} got {:?}",
                    i, x, y, expected_cell, cell
                )
            })
            .collect::<Vec<String>>()
            .join("\n");
        debug_info.push_str(&nice_diff);
        panic!("{}", debug_info);
    }
}

impl Backend for TestBackend {
    fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error>
    where
        I: Iterator<Item = (u16, u16, &'a Cell)>,
    {
        for (x, y, c) in content {
            let cell = self.buffer.get_mut(x, y);
            *cell = c.clone();
        }
        Ok(())
    }

    fn hide_cursor(&mut self) -> Result<(), io::Error> {
        self.cursor = false;
        Ok(())
    }

    fn show_cursor(&mut self) -> Result<(), io::Error> {
        self.cursor = true;
        Ok(())
    }

    fn get_cursor(&mut self) -> Result<(u16, u16), io::Error> {
        Ok(self.pos)
    }

    fn set_cursor(&mut self, x: u16, y: u16) -> Result<(), io::Error> {
        self.pos = (x, y);
        Ok(())
    }

    fn clear(&mut self) -> Result<(), io::Error> {
        Ok(())
    }

    fn size(&self) -> Result<Rect, io::Error> {
        Ok(Rect::new(0, 0, self.width, self.height))
    }

    fn flush(&mut self) -> Result<(), io::Error> {
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::{
    fs::{copy, create_dir_all, remove_file},
    path::Path,
};

use binary_stencila::{BinaryTrait, StencilaBinary};
use buildpack::{
    eyre,
    fs_utils::symlink_file,
    libcnb::{
        self,
        build::{BuildContext, BuildResult, BuildResultBuilder},
        data::{
            build_plan::BuildPlan,
            launch::{Launch, ProcessBuilder},
            layer_content_metadata::LayerTypes,
            layer_name, process_type,
        },
        detect::{DetectContext, DetectResult, DetectResultBuilder},
        generic::{GenericMetadata, GenericPlatform},
        layer::{ExistingLayerStrategy, Layer, LayerResult, LayerResultBuilder},
        Buildpack,
    },
    maplit::hashmap,
    tracing, BuildpackContext, BuildpackTrait, LayerOptions, LayerVersionMetadata,
};

pub struct StencilaBuildpack;

impl BuildpackTrait for StencilaBuildpack {
    fn toml() -> &'static str {
        include_str!("../buildpack.toml")
    }
}

const TOOL_VERSIONS: &str = ".tool-versions";

impl Buildpack for StencilaBuildpack {
    type Platform = GenericPlatform;
    type Metadata = GenericMetadata;
    type Error = eyre::Report;

    fn detect(&self, _context: DetectContext<Self>) -> libcnb::Result<DetectResult, Self::Error> {
        // Read `.tool-versions` for Stencila version
        let tool_versions = Self::tool_versions();

        // Resolve Stencila version from `.tool-versions`
        let (version, source) = if let Some(version) = tool_versions.get("stencila") {
            (version.to_string(), TOOL_VERSIONS)
        } else {
            // Default to at least 1.1.0 which is the first version with a `musl` binary suitable for
            // use in a CNB container
            (">=1.1.0".to_string(), "")
        };

        // Require and provide Stencila
        let (require, provide) = Self::require_and_provide(
            "stencila",
            source,
            format!("Install Stencila {}", version).trim(),
            Some(hashmap! {
                "version" => version
            }),
        );

        let mut build_plan = BuildPlan::new();
        build_plan.requires = vec![require];
        build_plan.provides = vec![provide];
        DetectResultBuilder::pass().build_plan(build_plan).build()
    }

    fn build(&self, context: BuildContext<Self>) -> libcnb::Result<BuildResult, Self::Error> {
        let entries = self.buildpack_plan_entries(&context.buildpack_plan);

        if let Some(options) = entries.get("stencila") {
            context.handle_layer(layer_name!("stencila"), StencilaLayer::new(options))?;
        }

        let launch = Launch::new().process(
            ProcessBuilder::new(process_type!("server"), "stencila")
                .args(["server", "start"])
                .direct(true)
                .default(true)
                .build(),
        );

        BuildResultBuilder::new().launch(launch).build()
    }
}

struct StencilaLayer {
    /// The semantic version requirement for the `stencila` binary
    requirement: String,
}

impl StencilaLayer {
    fn new(options: &LayerOptions) -> Self {
        let requirement = options
            .get("version")
            .cloned()
            .unwrap_or_else(|| "*".to_string());

        Self { requirement }
    }
}

impl Layer for StencilaLayer {
    type Buildpack = StencilaBuildpack;
    type Metadata = LayerVersionMetadata;

    fn types(&self) -> LayerTypes {
        LayerTypes {
            build: true,
            launch: true,
            cache: true,
        }
    }

    fn existing_layer_strategy(
        &self,
        _context: &BuildContext<Self::Buildpack>,
        layer_data: &libcnb::layer::LayerData<Self::Metadata>,
    ) -> Result<libcnb::layer::ExistingLayerStrategy, <Self::Buildpack as Buildpack>::Error> {
        let version = &layer_data.content_metadata.metadata.version;
        let installed = StencilaBinary {}.semver_version_matches(version, &self.requirement)?;
        let strategy = if installed {
            tracing::info!(
                "Existing `stencila` layer has `stencila {}` which matches semver requirement `{}`; will keep",
                version,
                self.requirement
            );
            ExistingLayerStrategy::Keep
        } else {
            tracing::info!(
                "Existing `stencila` layer has `stencila {}` which does not match semver requirement `{}`; will recreate",
                version,
                self.requirement
            );
            ExistingLayerStrategy::Recreate
        };
        Ok(strategy)
    }

    fn create(
        &self,
        context: &BuildContext<Self::Buildpack>,
        layer_path: &Path,
    ) -> Result<LayerResult<Self::Metadata>, eyre::Report> {
        tracing::info!(
            "Creating `stencila` layer with semver requirement `{}`",
            self.requirement
        );

        let stencila = StencilaBinary {}.ensure_version_sync(&self.requirement)?;
        let version = stencila.version()?.to_string();

        let bin_path = layer_path.join("bin");
        create_dir_all(&bin_path)?;

        if context.is_local() {
            tracing::info!("Linking to `stencila {}`", version);

            symlink_file(stencila.path, bin_path.join(stencila.name))?;
        } else {
            #[allow(clippy::collapsible_else_if)]
            if stencila.is_stencila_install() {
                tracing::info!("Moving `stencila {}`", version);

                copy(&stencila.path, bin_path.join(stencila.name))?;
                remove_file(stencila.path)?;
            } else {
                tracing::info!("Linking to `stencila {}` installed on stack image", version);

                symlink_file(stencila.path, bin_path.join(stencila.name))?;
            }
        }

        // Store version in metadata to detect if layer is stale in `existing_layer_strategy()`
        let metadata = LayerVersionMetadata { version };

        LayerResultBuilder::new(metadata).build()
    }
}
<commit_msg>fix(Stencila buildpack): Launch with `--url` suitable for use in container<commit_after>use std::{
    fs::{copy, create_dir_all, remove_file},
    path::Path,
};

use binary_stencila::{BinaryTrait, StencilaBinary};
use buildpack::{
    eyre,
    fs_utils::symlink_file,
    libcnb::{
        self,
        build::{BuildContext, BuildResult, BuildResultBuilder},
        data::{
            build_plan::BuildPlan,
            launch::{Launch, ProcessBuilder},
            layer_content_metadata::LayerTypes,
            layer_name, process_type,
        },
        detect::{DetectContext, DetectResult, DetectResultBuilder},
        generic::{GenericMetadata, GenericPlatform},
        layer::{ExistingLayerStrategy, Layer, LayerResult, LayerResultBuilder},
        Buildpack,
    },
    maplit::hashmap,
    tracing, BuildpackContext, BuildpackTrait, LayerOptions, LayerVersionMetadata,
};

pub struct StencilaBuildpack;

impl BuildpackTrait for StencilaBuildpack {
    fn toml() -> &'static str {
        include_str!("../buildpack.toml")
    }
}

const TOOL_VERSIONS: &str = ".tool-versions";

impl Buildpack for StencilaBuildpack {
    type Platform = GenericPlatform;
    type Metadata = GenericMetadata;
    type Error = eyre::Report;

    fn detect(&self, _context: DetectContext<Self>) -> libcnb::Result<DetectResult, Self::Error> {
        // Read `.tool-versions` for Stencila version
        let tool_versions = Self::tool_versions();

        // Resolve Stencila version from `.tool-versions`
        let (version, source) = if let Some(version) = tool_versions.get("stencila") {
            (version.to_string(), TOOL_VERSIONS)
        } else {
            // Default to at least 1.1.0 which is the first version with a `musl` binary suitable for
            // use in a CNB container
            (">=1.1.0".to_string(), "")
        };

        // Require and provide Stencila
        let (require, provide) = Self::require_and_provide(
            "stencila",
            source,
            format!("Install Stencila {}", version).trim(),
            Some(hashmap! {
                "version" => version
            }),
        );

        let mut build_plan = BuildPlan::new();
        build_plan.requires = vec![require];
        build_plan.provides = vec![provide];
        DetectResultBuilder::pass().build_plan(build_plan).build()
    }

    fn build(&self, context: BuildContext<Self>) -> libcnb::Result<BuildResult, Self::Error> {
        let entries = self.buildpack_plan_entries(&context.buildpack_plan);

        if let Some(options) = entries.get("stencila") {
            context.handle_layer(layer_name!("stencila"), StencilaLayer::new(options))?;
        }

        let launch = Launch::new().process(
            ProcessBuilder::new(process_type!("server"), "stencila")
                .args(["server", "start", "--url=0.0.0.0:9000"])
                .direct(true)
                .default(true)
                .build(),
        );

        BuildResultBuilder::new().launch(launch).build()
    }
}

struct StencilaLayer {
    /// The semantic version requirement for the `stencila` binary
    requirement: String,
}

impl StencilaLayer {
    fn new(options: &LayerOptions) -> Self {
        let requirement = options
            .get("version")
            .cloned()
            .unwrap_or_else(|| "*".to_string());

        Self { requirement }
    }
}

impl Layer for StencilaLayer {
    type Buildpack = StencilaBuildpack;
    type Metadata = LayerVersionMetadata;

    fn types(&self) -> LayerTypes {
        LayerTypes {
            build: true,
            launch: true,
            cache: true,
        }
    }

    fn existing_layer_strategy(
        &self,
        _context: &BuildContext<Self::Buildpack>,
        layer_data: &libcnb::layer::LayerData<Self::Metadata>,
    ) -> Result<libcnb::layer::ExistingLayerStrategy, <Self::Buildpack as Buildpack>::Error> {
        let version = &layer_data.content_metadata.metadata.version;
        let installed = StencilaBinary {}.semver_version_matches(version, &self.requirement)?;
        let strategy = if installed {
            tracing::info!(
                "Existing `stencila` layer has `stencila {}` which matches semver requirement `{}`; will keep",
                version,
                self.requirement
            );
            ExistingLayerStrategy::Keep
        } else {
            tracing::info!(
                "Existing `stencila` layer has `stencila {}` which does not match semver requirement `{}`; will recreate",
                version,
                self.requirement
            );
            ExistingLayerStrategy::Recreate
        };
        Ok(strategy)
    }

    fn create(
        &self,
        context: &BuildContext<Self::Buildpack>,
        layer_path: &Path,
    ) -> Result<LayerResult<Self::Metadata>, eyre::Report> {
        tracing::info!(
            "Creating `stencila` layer with semver requirement `{}`",
            self.requirement
        );

        let stencila = StencilaBinary {}.ensure_version_sync(&self.requirement)?;
        let version = stencila.version()?.to_string();

        let bin_path = layer_path.join("bin");
        create_dir_all(&bin_path)?;

        if context.is_local() {
            tracing::info!("Linking to `stencila {}`", version);

            symlink_file(stencila.path, bin_path.join(stencila.name))?;
        } else {
            #[allow(clippy::collapsible_else_if)]
            if stencila.is_stencila_install() {
                tracing::info!("Moving `stencila {}`", version);

                copy(&stencila.path, bin_path.join(stencila.name))?;
                remove_file(stencila.path)?;
            } else {
                tracing::info!("Linking to `stencila {}` installed on stack image", version);

                symlink_file(stencila.path, bin_path.join(stencila.name))?;
            }
        }

        // Store version in metadata to detect if layer is stale in `existing_layer_strategy()`
        let metadata = LayerVersionMetadata { version };

        LayerResultBuilder::new(metadata).build()
    }
}
<|endoftext|>