<commit_before>use std::{
    cell::RefCell,
    rc::Rc,
    sync::{Arc, Mutex},
};

use rand;

use smithay::{
    reexports::wayland_server::{
        protocol::{wl_buffer, wl_shell_surface, wl_surface},
        Display,
    },
    utils::Rectangle,
    wayland::{
        compositor::{compositor_init, CompositorToken, RegionAttributes, SurfaceAttributes, SurfaceEvent},
        data_device::DnDIconRole,
        seat::CursorImageRole,
        shell::{
            legacy::{
                wl_shell_init, ShellRequest, ShellState as WlShellState, ShellSurfaceKind, ShellSurfaceRole,
            },
            xdg::{
                xdg_shell_init, PopupConfigure, ShellState as XdgShellState, ToplevelConfigure, XdgRequest,
                XdgSurfaceRole,
            },
        },
    },
};

use crate::window_map::{Kind as SurfaceKind, WindowMap};

define_roles!(Roles =>
    [ XdgSurface, XdgSurfaceRole ]
    [ ShellSurface, ShellSurfaceRole]
    [ DnDIcon, DnDIconRole ]
    [ CursorImage, CursorImageRole ]
);

pub type MyWindowMap = WindowMap<
    Roles,
    fn(&SurfaceAttributes) -> Option<(i32, i32)>,
    fn(&SurfaceAttributes, (f64, f64)) -> bool,
>;

pub type MyCompositorToken = CompositorToken<Roles>;

pub fn init_shell(
    display: &mut Display,
    log: ::slog::Logger,
) -> (
    CompositorToken<Roles>,
    Arc<Mutex<XdgShellState<Roles>>>,
    Arc<Mutex<WlShellState<Roles>>>,
    Rc<RefCell<MyWindowMap>>,
) {
    // Create the compositor
    let (compositor_token, _, _) = compositor_init(
        display,
        move |request, surface, ctoken| match request {
            SurfaceEvent::Commit => surface_commit(&surface, ctoken),
            SurfaceEvent::Frame { callback } => callback
                .implement_closure(|_, _| unreachable!(), None::<fn(_)>, ())
                .done(0),
        },
        log.clone(),
    );

    // Init a window map, to track the location of our windows
    let window_map = Rc::new(RefCell::new(WindowMap::new(
        compositor_token,
        get_size as _,
        contains_point as _,
    )));

    // init the xdg_shell
    let xdg_window_map = window_map.clone();
    let (xdg_shell_state, _, _) = xdg_shell_init(
        display,
        compositor_token,
        move |shell_event| match shell_event {
            XdgRequest::NewToplevel { surface } => {
                // place the window at a random location in the [0;800]x[0;800] square
                use rand::distributions::{Distribution, Uniform};
                let range = Uniform::new(0, 800);
                let mut rng = rand::thread_rng();
                let x = range.sample(&mut rng);
                let y = range.sample(&mut rng);
                surface.send_configure(ToplevelConfigure {
                    size: None,
                    states: vec![],
                    serial: 42,
                });
                xdg_window_map
                    .borrow_mut()
                    .insert(SurfaceKind::Xdg(surface), (x, y));
            }
            XdgRequest::NewPopup { surface } => surface.send_configure(PopupConfigure {
                size: (10, 10),
                position: (10, 10),
                serial: 42,
            }),
            _ => (),
        },
        log.clone(),
    );

    // init the wl_shell
    let shell_window_map = window_map.clone();
    let (wl_shell_state, _) = wl_shell_init(
        display,
        compositor_token,
        move |req: ShellRequest<_>| {
            if let ShellRequest::SetKind {
                surface,
                kind: ShellSurfaceKind::Toplevel,
            } = req
            {
                // place the window at a random location in the [0;800]x[0;800] square
                use rand::distributions::{Distribution, Uniform};
                let range = Uniform::new(0, 800);
                let mut rng = rand::thread_rng();
                let x = range.sample(&mut rng);
                let y = range.sample(&mut rng);
                surface.send_configure((0, 0), wl_shell_surface::Resize::None);
                shell_window_map
                    .borrow_mut()
                    .insert(SurfaceKind::Wl(surface), (x, y));
            }
        },
        log.clone(),
    );

    (compositor_token, xdg_shell_state, wl_shell_state, window_map)
}

#[derive(Default)]
pub struct SurfaceData {
    pub buffer: Option<wl_buffer::WlBuffer>,
    pub texture: Option<crate::glium_drawer::TextureMetadata>,
    pub input_region: Option<RegionAttributes>,
}

fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>) {
    token.with_surface_data(surface, |attributes| {
        attributes.user_data.insert_if_missing(SurfaceData::default);
        let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();

        data.input_region = attributes.input_region.clone();

        // we retrieve the contents of the associated buffer and copy it
        match attributes.buffer.take() {
            Some(Some((buffer, (_x, _y)))) => {
                // new contents
                // TODO: handle hotspot coordinates
                if let Some(old_buffer) = data.buffer.replace(buffer) {
                    old_buffer.release();
                }
                data.texture = None;
            }
            Some(None) => {
                // erase the contents
                if let Some(old_buffer) = data.buffer.take() {
                    old_buffer.release();
                }
                data.texture = None;
            }
            None => {}
        }
    });
}

fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> {
    attrs.user_data.get::<SurfaceData>().and_then(|data| {
        data.texture
            .as_ref()
            .map(|ref meta| meta.dimensions)
            .map(|(x, y)| (x as i32, y as i32))
    })
}

fn contains_point(attrs: &SurfaceAttributes, point: (f64, f64)) -> bool {
    let (w, h) = match get_size(attrs) {
        None => return false, // If the surface has no size, it can't have an input region.
        Some(wh) => wh,
    };

    let rect = Rectangle {
        x: 0,
        y: 0,
        width: w,
        height: h,
    };

    let point = (point.0 as i32, point.1 as i32);

    // The input region is always within the surface itself, so if the surface itself doesn't contain the
    // point we can return false.
    if !rect.contains(point) {
        return false;
    }

    let input_region = &attrs.user_data.get::<SurfaceData>().unwrap().input_region;

    // If there's no input region, we're done.
    if input_region.is_none() {
        return true;
    }

    input_region.as_ref().unwrap().contains(point)
}
<commit_msg>anvil.shell: implement the Move request<commit_after>use std::{
    cell::RefCell,
    rc::Rc,
    sync::{Arc, Mutex},
};

use rand;

use smithay::{
    reexports::wayland_server::{
        protocol::{wl_buffer, wl_pointer::ButtonState, wl_shell_surface, wl_surface},
        Display,
    },
    utils::Rectangle,
    wayland::{
        compositor::{compositor_init, CompositorToken, RegionAttributes, SurfaceAttributes, SurfaceEvent},
        data_device::DnDIconRole,
        seat::{AxisFrame, CursorImageRole, PointerGrab, PointerInnerHandle, Seat},
        shell::{
            legacy::{
                wl_shell_init, ShellRequest, ShellState as WlShellState, ShellSurfaceKind, ShellSurfaceRole,
            },
            xdg::{
                xdg_shell_init, PopupConfigure, ShellState as XdgShellState, ToplevelConfigure, XdgRequest,
                XdgSurfaceRole,
            },
        },
        SERIAL_COUNTER as SCOUNTER,
    },
};

use crate::window_map::{Kind as SurfaceKind, WindowMap};

define_roles!(Roles =>
    [ XdgSurface, XdgSurfaceRole ]
    [ ShellSurface, ShellSurfaceRole]
    [ DnDIcon, DnDIconRole ]
    [ CursorImage, CursorImageRole ]
);

pub type MyWindowMap = WindowMap<
    Roles,
    fn(&SurfaceAttributes) -> Option<(i32, i32)>,
    fn(&SurfaceAttributes, (f64, f64)) -> bool,
>;

pub type MyCompositorToken = CompositorToken<Roles>;

struct MoveSurfaceGrab {
    window_map: Rc<RefCell<MyWindowMap>>,
    toplevel: SurfaceKind<Roles>,
    initial_pointer_location: (f64, f64),
    initial_window_location: (i32, i32),
}

impl PointerGrab for MoveSurfaceGrab {
    fn motion(
        &mut self,
        _handle: &mut PointerInnerHandle<'_>,
        location: (f64, f64),
        _focus: Option<(wl_surface::WlSurface, (f64, f64))>,
        _serial: u32,
        _time: u32,
    ) {
        let dx = location.0 - self.initial_pointer_location.0;
        let dy = location.1 - self.initial_pointer_location.1;
        let new_window_x = (self.initial_window_location.0 as f64 + dx) as i32;
        let new_window_y = (self.initial_window_location.1 as f64 + dy) as i32;

        self.window_map
            .borrow_mut()
            .set_location(&self.toplevel, (new_window_x, new_window_y));
    }

    fn button(
        &mut self,
        handle: &mut PointerInnerHandle<'_>,
        button: u32,
        state: ButtonState,
        serial: u32,
        time: u32,
    ) {
        handle.button(button, state, serial, time);
        if handle.current_pressed().is_empty() {
            // No more buttons are pressed, release the grab.
            handle.unset_grab(serial, time);
        }
    }

    fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame) {
        handle.axis(details)
    }
}

pub fn init_shell(
    display: &mut Display,
    log: ::slog::Logger,
) -> (
    CompositorToken<Roles>,
    Arc<Mutex<XdgShellState<Roles>>>,
    Arc<Mutex<WlShellState<Roles>>>,
    Rc<RefCell<MyWindowMap>>,
) {
    // Create the compositor
    let (compositor_token, _, _) = compositor_init(
        display,
        move |request, surface, ctoken| match request {
            SurfaceEvent::Commit => surface_commit(&surface, ctoken),
            SurfaceEvent::Frame { callback } => callback
                .implement_closure(|_, _| unreachable!(), None::<fn(_)>, ())
                .done(0),
        },
        log.clone(),
    );

    // Init a window map, to track the location of our windows
    let window_map = Rc::new(RefCell::new(WindowMap::new(
        compositor_token,
        get_size as _,
        contains_point as _,
    )));

    // init the xdg_shell
    let xdg_window_map = window_map.clone();
    let (xdg_shell_state, _, _) = xdg_shell_init(
        display,
        compositor_token,
        move |shell_event| match shell_event {
            XdgRequest::NewToplevel { surface } => {
                // place the window at a random location in the [0;800]x[0;800] square
                use rand::distributions::{Distribution, Uniform};
                let range = Uniform::new(0, 800);
                let mut rng = rand::thread_rng();
                let x = range.sample(&mut rng);
                let y = range.sample(&mut rng);
                surface.send_configure(ToplevelConfigure {
                    size: None,
                    states: vec![],
                    serial: 42,
                });
                xdg_window_map
                    .borrow_mut()
                    .insert(SurfaceKind::Xdg(surface), (x, y));
            }
            XdgRequest::NewPopup { surface } => surface.send_configure(PopupConfigure {
                size: (10, 10),
                position: (10, 10),
                serial: 42,
            }),
            XdgRequest::Move {
                surface,
                seat,
                serial,
            } => {
                let seat = Seat::from_resource(&seat).unwrap();
                // TODO: touch move.
                let pointer = seat.get_pointer().unwrap();

                let toplevel = SurfaceKind::Xdg(surface);
                let initial_window_location = xdg_window_map.borrow().location(&toplevel).unwrap();

                let grab = MoveSurfaceGrab {
                    window_map: xdg_window_map.clone(),
                    toplevel,
                    initial_pointer_location: pointer.current_location(),
                    initial_window_location,
                };

                pointer.set_grab(grab, serial);
            }
            _ => (),
        },
        log.clone(),
    );

    // init the wl_shell
    let shell_window_map = window_map.clone();
    let (wl_shell_state, _) = wl_shell_init(
        display,
        compositor_token,
        move |req: ShellRequest<_>| {
            match req {
                ShellRequest::SetKind {
                    surface,
                    kind: ShellSurfaceKind::Toplevel,
                } => {
                    // place the window at a random location in the [0;800]x[0;800] square
                    use rand::distributions::{Distribution, Uniform};
                    let range = Uniform::new(0, 800);
                    let mut rng = rand::thread_rng();
                    let x = range.sample(&mut rng);
                    let y = range.sample(&mut rng);
                    surface.send_configure((0, 0), wl_shell_surface::Resize::None);
                    shell_window_map
                        .borrow_mut()
                        .insert(SurfaceKind::Wl(surface), (x, y));
                }
                ShellRequest::Move {
                    surface,
                    seat,
                    serial,
                } => {
                    let seat = Seat::from_resource(&seat).unwrap();
                    // TODO: touch move.
                    let pointer = seat.get_pointer().unwrap();

                    let toplevel = SurfaceKind::Wl(surface);
                    let initial_window_location = shell_window_map.borrow().location(&toplevel).unwrap();

                    let grab = MoveSurfaceGrab {
                        window_map: shell_window_map.clone(),
                        toplevel,
                        initial_pointer_location: pointer.current_location(),
                        initial_window_location,
                    };

                    pointer.set_grab(grab, serial);
                }
                _ => (),
            }
        },
        log.clone(),
    );

    (compositor_token, xdg_shell_state, wl_shell_state, window_map)
}

#[derive(Default)]
pub struct SurfaceData {
    pub buffer: Option<wl_buffer::WlBuffer>,
    pub texture: Option<crate::glium_drawer::TextureMetadata>,
    pub input_region: Option<RegionAttributes>,
}

fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>) {
    token.with_surface_data(surface, |attributes| {
        attributes.user_data.insert_if_missing(SurfaceData::default);
        let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();

        data.input_region = attributes.input_region.clone();

        // we retrieve the contents of the associated buffer and copy it
        match attributes.buffer.take() {
            Some(Some((buffer, (_x, _y)))) => {
                // new contents
                // TODO: handle hotspot coordinates
                if let Some(old_buffer) = data.buffer.replace(buffer) {
                    old_buffer.release();
                }
                data.texture = None;
            }
            Some(None) => {
                // erase the contents
                if let Some(old_buffer) = data.buffer.take() {
                    old_buffer.release();
                }
                data.texture = None;
            }
            None => {}
        }
    });
}

fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> {
    attrs.user_data.get::<SurfaceData>().and_then(|data| {
        data.texture
            .as_ref()
            .map(|ref meta| meta.dimensions)
            .map(|(x, y)| (x as i32, y as i32))
    })
}

fn contains_point(attrs: &SurfaceAttributes, point: (f64, f64)) -> bool {
    let (w, h) = match get_size(attrs) {
        None => return false, // If the surface has no size, it can't have an input region.
        Some(wh) => wh,
    };

    let rect = Rectangle {
        x: 0,
        y: 0,
        width: w,
        height: h,
    };

    let point = (point.0 as i32, point.1 as i32);

    // The input region is always within the surface itself, so if the surface itself doesn't contain the
    // point we can return false.
    if !rect.contains(point) {
        return false;
    }

    let input_region = &attrs.user_data.get::<SurfaceData>().unwrap().input_region;

    // If there's no input region, we're done.
    if input_region.is_none() {
        return true;
    }

    input_region.as_ref().unwrap().contains(point)
}
<|endoftext|>


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

use super::lexer::{Lexer, LexError};
use super::token::{TokenSpan, Token, Lit};
use super::exec::*; // TODO: remove * import

pub struct Parser<'a> {
    lexer: Lexer<'a>,

    curr: Option<TokenSpan>,
    last: Option<TokenSpan>,
    peek: Option<TokenSpan>,
}

impl<'a> Parser<'a> {
    pub fn from_query(q: &'a str) -> Parser<'a> {
        let lex = Lexer::from_query(q);
        Parser {
            lexer: lex,
            curr: None,
            last: None,
            peek: None,
        }
    }

    pub fn parse(&mut self) -> Result<Query, ParserError> {
        // TODO: handle this with a better error message
        try!(self.bump());
        try!(self.bump());

        self.parse_commands()
    }

    fn bump(&mut self) -> Result<(), ParserError> {
        // do stuff. Mainly swap last = curr, curr = peek, then peek = next_real
        mem::swap(&mut self.last, &mut self.curr);
        mem::swap(&mut self.curr, &mut self.peek);
        self.peek = try!(self.lexer.next_real());
        Ok(())
    }

    // SQL Commands

    fn parse_commands(&mut self) -> Result<Query, ParserError> {
        let curr = self.curr.clone();

        // Parse first word that
        match curr.unwrap().token {
            Token::Word(val) => self.run_major_command(val),
            _ => Err(ParserError::FirstCmdNotWord),
        }
    }

    fn run_major_command(&mut self, cmd: String) -> Result<Query, ParserError> {
        match Keyword::from_str(&*cmd).unwrap() { // TODO: clean up unwrap
            Keyword::Select => self.parse_select(),
            Keyword::Insert => self.parse_insert(),

            _ => Err(ParserError::FirstCmdNotMajor),
        }
    }

    fn parse_select(&mut self) -> Result<Query, ParserError> {
        // TODO: impl parse_select

        Ok(Query::Table(TableStmt::Select(SelectStmt {
            cols: vec![Col { name: "id".to_owned() }],
            table: Table {
                name: "user_v1".to_owned(),
                alias: None,
            },
        })))
    }

    fn parse_insert(&mut self) -> Result<Query, ParserError> {
        // TODO: impl parse_insert
        try!(self.expect_keyword(Keyword::Into));

        //try!();

        try!(self.expect_token(Token::ParentOP));

        let mut cols = Vec::<Col>::new();
        cols.push(Col { name: try!(self.expect_word())});

        Ok(Query::Table(TableStmt::Insert(InsertStmt {
            table: Table {
                name: "user_v1".to_owned(),
                alias: None,
            },
            cols: HashMap::new(),
        })))
    }
}

// Helper function
impl<'a> Parser<'a> {
    fn expect_keyword(&mut self, exp: Keyword) -> Result<Keyword, ParserError> {
        // TODO: clean up unwrap but they should be safe for the moment

        try!(self.bump());
        let curr = {
            let token = &self.curr.clone().unwrap();

            match &token.token {
                &Token::Word(ref word) => word.clone(),
                t => return Err(ParserError::ExpectedKeyword(exp, format!("{:?}", t))),
            }
        };

        let actual = try!(Keyword::from_str(&curr));

        if actual == exp {
            Ok(actual)
        } else {
            Err(ParserError::ExpectedKeyword(exp, curr))
        }
    }

    fn expect_token(&mut self, exp: Token)  -> Result<Token, ParserError> {
        try!(self.bump());

        let token = self.curr.clone().unwrap();
        let actual = token.token.clone();

        if actual == exp {
            Ok(actual)
        } else {
            Err(ParserError::ExpectedToken(exp, format!("{:?}", actual)))
        }
    }

    // expect word case insensitive.
    fn expect_word(&mut self) -> Result<String, ParserError> {
        try!(self.bump());

        let token = match self.curr.clone() {
            Some(t) => t,
            None => return Err(ParserError::ExpectedTokenButGotNone),
        };
        let actual = token.token.clone();

        let word = match actual {
            Token::Word(ref word) => word.to_lowercase(), // always lowercase
            t => return Err(ParserError::ExpectedToken(Token::Word(String::new()), format!("{:?}", t))),
        };

        Ok(word)
    }

    fn expect_lit(&mut self) -> Result<Lit, ParserError> {
        try!(self.bump());

        let token = self.curr.clone().unwrap();
        let actual = token.token.clone();

        match actual {
            Token::Literal(lit) => Ok(lit),
            t => Err(ParserError::ExpectedToken(Token::Literal(Lit::String(String::new())), format!("{:?}", t))),
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum Keyword {
    // Major
    Select,
    Insert,

    // Minor
    From,
    Into,
}

impl Keyword {
    pub fn from_str(k: &str) -> Result<Keyword, ParserError> {
        let keyword = match &*k.to_lowercase() {
            "select" => Keyword::Select,
            "insert" => Keyword::Insert,

            "from" => Keyword::From,
            "into" => Keyword::Into,

            // Keyword not found
            keyword => return Err(ParserError::UnexpectedKeyword(keyword.to_owned())), // TODO: clean up panic
        };

        Ok(keyword)
    }
}

#[derive(Debug)]
pub enum ParserError {
    InvalidCommand,
    LexerError(LexError),

    FirstCmdNotWord,
    FirstCmdNotMajor,

    ExpectedKeyword(Keyword, String), // exp, actual
    ExpectedToken(Token, String), // exp, actual
    ExpectedTokenButGotNone,

    UnexpectedKeyword(String),
}

impl From<LexError> for ParserError {
    fn from(e: LexError) -> ParserError {
        ParserError::LexerError(e)
    }
}

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

    #[test]
    fn select() {
        let mut p = Parser::from_query("select");
        p.parse().unwrap();
    }

    #[test]
    fn insert() {
        let mut p = Parser::from_query("insert into (name)");
        let q = p.parse().unwrap();

    }

    // #[test]
    // fn first_non_major() {
    //     let err = Parser::from_query("alskdfj").parse();
    //     assert!(err.is_err());
    // }
}
<commit_msg>added test for parer fail and added some more impl to insert<commit_after>use std::mem;
use std::collections::HashMap;

use super::lexer::{Lexer, LexError};
use super::token::{TokenSpan, Token, Lit};
use super::exec::*; // TODO: remove * import

pub struct Parser<'a> {
    lexer: Lexer<'a>,

    curr: Option<TokenSpan>,
    last: Option<TokenSpan>,
    peek: Option<TokenSpan>,
}

impl<'a> Parser<'a> {
    pub fn from_query(q: &'a str) -> Parser<'a> {
        let lex = Lexer::from_query(q);
        Parser {
            lexer: lex,
            curr: None,
            last: None,
            peek: None,
        }
    }

    pub fn parse(&mut self) -> Result<Query, ParserError> {
        // TODO: handle this with a better error message
        try!(self.bump());
        try!(self.bump());

        self.parse_commands()
    }

    fn bump(&mut self) -> Result<(), ParserError> {
        // do stuff. Mainly swap last = curr, curr = peek, then peek = next_real
        mem::swap(&mut self.last, &mut self.curr);
        mem::swap(&mut self.curr, &mut self.peek);
        self.peek = try!(self.lexer.next_real());
        Ok(())
    }

    // SQL Commands

    fn parse_commands(&mut self) -> Result<Query, ParserError> {
        let curr = self.curr.clone();

        // Parse first word that
        match curr.unwrap().token {
            Token::Word(val) => self.run_major_command(val),
            _ => Err(ParserError::FirstCmdNotWord),
        }
    }

    fn run_major_command(&mut self, cmd: String) -> Result<Query, ParserError> {
        match Keyword::from_str(&*cmd).unwrap() { // TODO: clean up unwrap
            Keyword::Select => self.parse_select(),
            Keyword::Insert => self.parse_insert(),

            _ => Err(ParserError::FirstCmdNotMajor),
        }
    }

    fn parse_select(&mut self) -> Result<Query, ParserError> {
        // TODO: impl parse_select

        Ok(Query::Table(TableStmt::Select(SelectStmt {
            cols: vec![Col { name: "id".to_owned() }],
            table: Table {
                name: "user_v1".to_owned(),
                alias: None,
            },
        })))
    }

    fn parse_insert(&mut self) -> Result<Query, ParserError> {
        // TODO: impl parse_insert
        try!(self.expect_keyword(Keyword::Into));

        //try!();

        try!(self.expect_token(Token::ParentOP));

        let mut cols = Vec::new();

        loop {
            match self.expect_word() {
                Ok(ref word) => {
                    cols.push(word.to_owned());
                    try!(self.expect_token(Token::Comma));
                },
                Err(ParserError::ExpectedToken(_, _)) => {
                    let curr = self.curr.clone().unwrap().token;
                    println!("blah {:?}", curr);

                    match curr {
                        Token::Comma => try!(self.bump()),
                        Token::ParentCL => {
                            try!(self.bump());
                            break;
                        },
                        token => return Err(ParserError::ExpectedToken(Token::Comma, format!("{:?}", token))),
                    }
                },
                Err(err) => return Err(err),
            }
        }

        Ok(Query::Table(TableStmt::Insert(InsertStmt {
            table: Table {
                name: "user_v1".to_owned(),
                alias: None,
            },
            cols: HashMap::new(),
        })))
    }
}

// Helper function
impl<'a> Parser<'a> {
    fn expect_keyword(&mut self, exp: Keyword) -> Result<Keyword, ParserError> {
        // TODO: clean up unwrap but they should be safe for the moment

        try!(self.bump());
        let curr = {
            let token = &self.curr.clone().unwrap();

            match &token.token {
                &Token::Word(ref word) => word.clone(),
                t => return Err(ParserError::ExpectedKeyword(exp, format!("{:?}", t))),
            }
        };

        let actual = try!(Keyword::from_str(&curr));

        if actual == exp {
            Ok(actual)
        } else {
            Err(ParserError::ExpectedKeyword(exp, curr))
        }
    }

    fn expect_token(&mut self, exp: Token)  -> Result<Token, ParserError> {
        try!(self.bump());

        let token = self.curr.clone().unwrap();
        let actual = token.token.clone();

        if actual == exp {
            Ok(actual)
        } else {
            Err(ParserError::ExpectedToken(exp, format!("{:?}", actual)))
        }
    }

    // expect word case insensitive.
    fn expect_word(&mut self) -> Result<String, ParserError> {
        try!(self.bump());

        let token = match self.curr.clone() {
            Some(t) => t,
            None => return Err(ParserError::ExpectedTokenButGotNone),
        };
        let actual = token.token.clone();

        let word = match actual {
            Token::Word(ref word) => word.to_lowercase(), // always lowercase
            t => return Err(ParserError::ExpectedToken(Token::Word(String::new()), format!("{:?}", t))),
        };

        Ok(word)
    }

    fn expect_lit(&mut self) -> Result<Lit, ParserError> {
        try!(self.bump());

        let token = self.curr.clone().unwrap();
        let actual = token.token.clone();

        match actual {
            Token::Literal(lit) => Ok(lit),
            t => Err(ParserError::ExpectedToken(Token::Literal(Lit::String(String::new())), format!("{:?}", t))),
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum Keyword {
    // Major
    Select,
    Insert,

    // Minor
    From,
    Into,
}

impl Keyword {
    pub fn from_str(k: &str) -> Result<Keyword, ParserError> {
        let keyword = match &*k.to_lowercase() {
            "select" => Keyword::Select,
            "insert" => Keyword::Insert,

            "from" => Keyword::From,
            "into" => Keyword::Into,

            // Keyword not found
            keyword => return Err(ParserError::UnexpectedKeyword(keyword.to_owned())), // TODO: clean up panic
        };

        Ok(keyword)
    }
}

#[derive(Debug)]
pub enum ParserError {
    InvalidCommand,
    LexerError(LexError),

    FirstCmdNotWord,
    FirstCmdNotMajor,

    ExpectedKeyword(Keyword, String), // exp, actual
    ExpectedToken(Token, String), // exp, actual
    ExpectedTokenButGotNone,

    UnexpectedKeyword(String),
}

impl From<LexError> for ParserError {
    fn from(e: LexError) -> ParserError {
        ParserError::LexerError(e)
    }
}

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

    #[test]
    fn select() {
        let mut p = Parser::from_query("select");
        p.parse().unwrap();
    }

    #[test]
    fn insert() {
        let mut p = Parser::from_query("insert into (name)");
        let q = p.parse().unwrap();

    }

    #[test]
    #[should_panic]
    fn insert_panic() {
        Parser::from_query("insert into (asdf aslkdfhjahh dsfkjals)").parse().unwrap();
    }

    #[test]
    #[should_panic]
    fn first_non_major() {
        let err = Parser::from_query("alskdfj").parse();
        assert!(err.is_err());
    }
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # Parser Nodes
//!
//! Parser nodes represent the grammar that is defined
//! by the currently permissible set of commands and their
//! parameters.

use std::rc::Rc;

/// Minimum priority.
pub const PRIORITY_MINIMUM: i32 = -10000;
/// The default priority for a parameter.
pub const PRIORITY_PARAMETER: i32 = -10;
/// The default priority.
pub const PRIORITY_DEFAULT: i32 = 0;

/// A node in the tree of commands and their parameters
/// used by the `Parser`.
pub trait Node {
    /// The data describing this node.
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields;

    /// The text used to identify this node in help text.
    /// This is typically the node name, either in plain
    /// form or decorated for parameters.
    fn help_symbol(&self) -> String {
        // XXX:Make this return a &String.
        self.node_data().help_symbol.clone()
    }

    /// Help text describing this node.
    fn help_text(&self) -> &Option<String> {
        &self.node_data().help_text
    }

    /// Hidden nodes are still found for matching, but are
    /// hidden from completion.
    fn hidden(&self) -> bool {
        self.node_data().hidden
    }

    /// The name of this node.
    fn name(&self) -> &String {
        &self.node_data().name
    }

    /// This priority of this node during matching and completion.
    fn priority(&self) -> i32 {
        self.node_data().priority
    }

    /// Nodes that are children of this node. Used to
    /// by the `Parser` during `advance`, `complete`, etc.
    fn successors(&self) -> &Vec<Rc<Node>> {
        &self.node_data().successors
    }
}

impl PartialEq for Node {
    /// Nodes are equal based on pointer equality.
    fn eq(&self, other: &Self) -> bool {
        self as *const _ == other as *const _
    }
}

/// A parse tree node.
#[doc(hidden)]
pub struct NodeFields {
    /// The name of this node.
    name: String,
    /// The text used to identify this node in help text.
    /// This is typically the node name, either in plain
    /// form or decorated for parameters.
    help_symbol: String,
    /// Help text describing this node.
    help_text: Option<String>,
    /// Hidden nodes are not completed. This doesn't modify matching.
    hidden: bool,
    /// Match and complete priority.
    priority: i32,
    /// Possible successor nodes. Collected while building.
    successors: Vec<Rc<Node>>,
}

/// The root of a command tree.
///
/// ```
/// use commands::parser::nodes::RootNode;
///
/// let root = RootNode::new();
/// ```
pub struct RootNode {
    node_fields: NodeFields,
}

impl RootNode {
    /// Create a new `RootNode`
    pub fn new() -> Rc<Self> {
        Rc::new(RootNode {
            node_fields: NodeFields {
                name: "__root__".to_string(),
                help_symbol: "".to_string(),
                help_text: None,
                hidden: false,
                priority: PRIORITY_DEFAULT,
                successors: vec![],
            },
        })
    }
}

impl Node for RootNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

/// A node representing a command.
pub struct CommandNode {
    node_fields: NodeFields,
    command_fields: CommandNodeFields,
}

struct CommandNodeFields {
    handler: Option<fn(&node: Node) -> ()>,
    parameters: Vec<Rc<ParameterNode>>,
}

impl CommandNode {
    /// Construct a new `CommandNode`.
    pub fn new(name: &str,
               priority: i32,
               hidden: bool,
               help_text: Option<String>,
               handler: Option<fn(&node: Node) -> ()>)
               -> Rc<Self> {
        Rc::new(CommandNode {
            node_fields: NodeFields {
                successors: vec![],
                name: name.to_string(),
                priority: priority,
                help_symbol: name.to_string(),
                help_text: help_text,
                hidden: hidden,
            },
            command_fields: CommandNodeFields {
                handler: handler,
                parameters: vec![],
            },
        })
    }
}
impl Node for CommandNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl CommandNode {
    /// The handler which is executed once this node has been accepted.
    pub fn handler(&self) -> Option<fn(&node: Node) -> ()> {
        self.command_fields.handler
    }

    /// Get the parameter nodes for this command.
    pub fn parameters(&self) -> &Vec<Rc<ParameterNode>> {
        &self.command_fields.parameters
    }
}

/// A wrapper node wraps another command.
///
/// This is used for the help command so that it can complete
/// normal commands.
///
/// The `successors` will be those of the wrapped node.
pub struct WrapperNode {
    node_fields: NodeFields,
    #[allow(dead_code)]
    command_fields: CommandNodeFields,
    root: Rc<Node>,
}

impl Node for WrapperNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }

    fn successors(&self) -> &Vec<Rc<Node>> {
        self.root.successors()
    }
}

/// A repeatable node is an internal helper for representing
/// nodes that can be repeated, like some parameters.
pub trait RepeatableNode: Node {
    /// Internal data for a repeatable node.
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields;

    /// Whether or not this node can be repeated. A repeated
    /// node can be `accept`ed multiple times.
    fn repeatable(&self) -> bool {
        self.repeatable_data().repeatable
    }

    /// If present, this node will no longer be `acceptable`.
    fn repeat_marker(&self) -> &Option<Rc<Node>> {
        &self.repeatable_data().repeat_marker
    }
}

/// The data for a repeatable node.
#[doc(hidden)]
pub struct RepeatableNodeFields {
    repeatable: bool,
    repeat_marker: Option<Rc<Node>>,
}

/// A node that represented the name portion of a named
/// parameter.
pub struct ParameterNameNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter: Rc<Node>,
}

impl Node for ParameterNameNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }

    fn help_symbol(&self) -> String {
        self.node_fields.name.clone() + " " + self.parameter.help_symbol().as_str()
    }
}

impl RepeatableNode for ParameterNameNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

/// Parameter nodes.
pub trait ParameterNode: Node + RepeatableNode {
    /// Internal data for a parameter node.
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields;

    /// A `required` parameter must be supplied for the
    /// command line being parsed to be valid.
    fn required(&self) -> bool {
        self.parameter_data().required
    }
}

/// Data for parameter nodes.
#[doc(hidden)]
pub struct ParameterNodeFields {
    required: bool,
}

/// A flag parameter node.
///
/// When implemented, this will only have a value of
/// true when it is present.
pub struct FlagParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for FlagParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for FlagParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for FlagParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl FlagParameterNode {
    /// Construct a new `FlagParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        let help_symbol = String::from("<") + name +
                          if repeatable {
            ">..."
        } else {
            ">"
        };
        FlagParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: help_symbol,
                help_text: help_text,
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}

/// A named parameter node.
pub struct NamedParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for NamedParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for NamedParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for NamedParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl NamedParameterNode {
    /// Construct a new `NamedParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        NamedParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text,
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}

/// A simple parameter node. This is only present in a command
/// line as a value.
pub struct SimpleParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for SimpleParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for SimpleParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for SimpleParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl SimpleParameterNode {
    /// Construct a new `SimpleParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        SimpleParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text,
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}
<commit_msg>CommandNode::new() uses proper parameter order, returns bare CommandNode.<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # Parser Nodes
//!
//! Parser nodes represent the grammar that is defined
//! by the currently permissible set of commands and their
//! parameters.

use std::rc::Rc;

/// Minimum priority.
pub const PRIORITY_MINIMUM: i32 = -10000;
/// The default priority for a parameter.
pub const PRIORITY_PARAMETER: i32 = -10;
/// The default priority.
pub const PRIORITY_DEFAULT: i32 = 0;

/// A node in the tree of commands and their parameters
/// used by the `Parser`.
pub trait Node {
    /// The data describing this node.
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields;

    /// The text used to identify this node in help text.
    /// This is typically the node name, either in plain
    /// form or decorated for parameters.
    fn help_symbol(&self) -> String {
        // XXX:Make this return a &String.
        self.node_data().help_symbol.clone()
    }

    /// Help text describing this node.
    fn help_text(&self) -> &Option<String> {
        &self.node_data().help_text
    }

    /// Hidden nodes are still found for matching, but are
    /// hidden from completion.
    fn hidden(&self) -> bool {
        self.node_data().hidden
    }

    /// The name of this node.
    fn name(&self) -> &String {
        &self.node_data().name
    }

    /// This priority of this node during matching and completion.
    fn priority(&self) -> i32 {
        self.node_data().priority
    }

    /// Nodes that are children of this node. Used to
    /// by the `Parser` during `advance`, `complete`, etc.
    fn successors(&self) -> &Vec<Rc<Node>> {
        &self.node_data().successors
    }
}

impl PartialEq for Node {
    /// Nodes are equal based on pointer equality.
    fn eq(&self, other: &Self) -> bool {
        self as *const _ == other as *const _
    }
}

/// A parse tree node.
#[doc(hidden)]
pub struct NodeFields {
    /// The name of this node.
    name: String,
    /// The text used to identify this node in help text.
    /// This is typically the node name, either in plain
    /// form or decorated for parameters.
    help_symbol: String,
    /// Help text describing this node.
    help_text: Option<String>,
    /// Hidden nodes are not completed. This doesn't modify matching.
    hidden: bool,
    /// Match and complete priority.
    priority: i32,
    /// Possible successor nodes. Collected while building.
    successors: Vec<Rc<Node>>,
}

/// The root of a command tree.
///
/// ```
/// use commands::parser::nodes::RootNode;
///
/// let root = RootNode::new();
/// ```
pub struct RootNode {
    node_fields: NodeFields,
}

impl RootNode {
    /// Create a new `RootNode`
    pub fn new() -> Rc<Self> {
        Rc::new(RootNode {
            node_fields: NodeFields {
                name: "__root__".to_string(),
                help_symbol: "".to_string(),
                help_text: None,
                hidden: false,
                priority: PRIORITY_DEFAULT,
                successors: vec![],
            },
        })
    }
}

impl Node for RootNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

/// A node representing a command.
pub struct CommandNode {
    node_fields: NodeFields,
    command_fields: CommandNodeFields,
}

struct CommandNodeFields {
    handler: Option<fn(&node: Node) -> ()>,
    parameters: Vec<Rc<ParameterNode>>,
}

impl CommandNode {
    /// Construct a new `CommandNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               handler: Option<fn(&node: Node) -> ()>)
               -> Self {
        CommandNode {
            node_fields: NodeFields {
                successors: vec![],
                name: name.to_string(),
                priority: priority,
                help_symbol: name.to_string(),
                help_text: help_text,
                hidden: hidden,
            },
            command_fields: CommandNodeFields {
                handler: handler,
                parameters: vec![],
            },
        }
    }
}
impl Node for CommandNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl CommandNode {
    /// The handler which is executed once this node has been accepted.
    pub fn handler(&self) -> Option<fn(&node: Node) -> ()> {
        self.command_fields.handler
    }

    /// Get the parameter nodes for this command.
    pub fn parameters(&self) -> &Vec<Rc<ParameterNode>> {
        &self.command_fields.parameters
    }
}

/// A wrapper node wraps another command.
///
/// This is used for the help command so that it can complete
/// normal commands.
///
/// The `successors` will be those of the wrapped node.
pub struct WrapperNode {
    node_fields: NodeFields,
    #[allow(dead_code)]
    command_fields: CommandNodeFields,
    root: Rc<Node>,
}

impl Node for WrapperNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }

    fn successors(&self) -> &Vec<Rc<Node>> {
        self.root.successors()
    }
}

/// A repeatable node is an internal helper for representing
/// nodes that can be repeated, like some parameters.
pub trait RepeatableNode: Node {
    /// Internal data for a repeatable node.
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields;

    /// Whether or not this node can be repeated. A repeated
    /// node can be `accept`ed multiple times.
    fn repeatable(&self) -> bool {
        self.repeatable_data().repeatable
    }

    /// If present, this node will no longer be `acceptable`.
    fn repeat_marker(&self) -> &Option<Rc<Node>> {
        &self.repeatable_data().repeat_marker
    }
}

/// The data for a repeatable node.
#[doc(hidden)]
pub struct RepeatableNodeFields {
    repeatable: bool,
    repeat_marker: Option<Rc<Node>>,
}

/// A node that represented the name portion of a named
/// parameter.
pub struct ParameterNameNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter: Rc<Node>,
}

impl Node for ParameterNameNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }

    fn help_symbol(&self) -> String {
        self.node_fields.name.clone() + " " + self.parameter.help_symbol().as_str()
    }
}

impl RepeatableNode for ParameterNameNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

/// Parameter nodes.
pub trait ParameterNode: Node + RepeatableNode {
    /// Internal data for a parameter node.
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields;

    /// A `required` parameter must be supplied for the
    /// command line being parsed to be valid.
    fn required(&self) -> bool {
        self.parameter_data().required
    }
}

/// Data for parameter nodes.
#[doc(hidden)]
pub struct ParameterNodeFields {
    required: bool,
}

/// A flag parameter node.
///
/// When implemented, this will only have a value of
/// true when it is present.
pub struct FlagParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for FlagParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for FlagParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for FlagParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl FlagParameterNode {
    /// Construct a new `FlagParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        let help_symbol = String::from("<") + name +
                          if repeatable {
            ">..."
        } else {
            ">"
        };
        FlagParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: help_symbol,
                help_text: help_text,
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}

/// A named parameter node.
pub struct NamedParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for NamedParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for NamedParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for NamedParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl NamedParameterNode {
    /// Construct a new `NamedParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        NamedParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text,
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}

/// A simple parameter node. This is only present in a command
/// line as a value.
pub struct SimpleParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for SimpleParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for SimpleParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for SimpleParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl SimpleParameterNode {
    /// Construct a new `SimpleParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        SimpleParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text,
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}
<|endoftext|>


<commit_before>//! # Parser Nodes
//!
//! Parser nodes represent the grammar that is defined
//! by the currently permissible set of commands and their
//! parameters.

#![allow(dead_code, missing_docs, unused_variables)]

use std::rc::Rc;

/// Minimum priority.
pub const PRIORITY_MINIMUM: i32 = -10000;
/// The default priority for a parameter.
pub const PRIORITY_PARAMETER: i32 = -10;
/// The default priority.
pub const PRIORITY_DEFAULT: i32 = 0;

pub trait Node {
    fn node_data(&self) -> &NodeFields;

    fn successors(&self) -> &Vec<Rc<Node>> {
        &self.node_data().successors
    }

    fn help_symbol(&self) -> String {
        self.node_data().name.to_string()
    }

    fn help_text(&self) -> &String {
        unimplemented!();
    }

    fn hidden(&self) -> bool {
        self.node_data().hidden
    }

    fn name(&self) -> &String {
        &self.node_data().name
    }

    fn priority(&self) -> i32 {
        self.node_data().priority
    }
}

/// A parse tree node.
pub struct NodeFields {
    /// Possible successor nodes. Collected while building.
    pub successors: Vec<Rc<Node>>,
    /// The name of this node.
    pub name: String,
    /// Match and complete priority.
    pub priority: i32,
    /// Hidden nodes are not completed. This doesn't modify matching.
    pub hidden: bool,
}

pub struct CommandNode {
    fields: CommandNodeFields,
}

pub struct CommandNodeFields {
    node: NodeFields,
    help: String,
    handler: Option<fn(&node: Node) -> ()>,
    parameters: Vec<Rc<ParameterNode>>,
}

impl Node for CommandNode {
    fn node_data(&self) -> &NodeFields {
        &self.fields.node
    }
}

impl CommandNode {
    pub fn handler(&self) -> Option<fn(&node: Node) -> ()> {
        self.fields.handler
    }

    /// Get the parameter nodes for this command
    pub fn parameters(&self) -> &Vec<Rc<ParameterNode>> {
        &self.fields.parameters
    }
}

pub struct WrapperNode {
    fields: WrapperNodeFields,
}

pub struct WrapperNodeFields {
    command: CommandNodeFields,
    root: Rc<Node>,
}

impl Node for WrapperNode {
    fn node_data(&self) -> &NodeFields {
        &self.fields.command.node
    }

    fn successors(&self) -> &Vec<Rc<Node>> {
        &self.fields.root.successors()
    }
}

pub struct ParameterNameNode {
    fields: ParameterNameNodeFields,
}

pub struct RepeatableNodeFields {
    repeatable: bool,
    repeat_marker: Option<Rc<Node>>,
}

pub struct ParameterNameNodeFields {
    node: NodeFields,
    repeatable: RepeatableNodeFields,
    help: String,
    parameter: Rc<Node>,
}

impl Node for ParameterNameNode {
    fn node_data(&self) -> &NodeFields {
        &self.fields.node
    }

    fn help_symbol(&self) -> String {
        self.fields.node.name.clone() + " " + self.fields.parameter.help_symbol().as_str()
    }

    fn help_text(&self) -> &String {
        &self.fields.help
    }
}

impl ParameterNameNode {
    pub fn repeatable(&self) -> bool {
        self.fields.repeatable.repeatable
    }

    pub fn repeat_marker(&self) -> &Option<Rc<Node>> {
        &self.fields.repeatable.repeat_marker
    }
}

pub trait ParameterNode {
    fn parameter_data(&self) -> &ParameterNodeFields;

    fn repeatable(&self) -> bool {
        self.parameter_data().repeatable.repeatable
    }

    fn repeat_marker(&self) -> &Option<Rc<Node>> {
        &self.parameter_data().repeatable.repeat_marker
    }

    fn required(&self) -> bool {
        self.parameter_data().required
    }
}

pub struct ParameterNodeFields {
    node: NodeFields,
    repeatable: RepeatableNodeFields,
    help: String,
    required: bool,
}

impl Node for ParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.parameter_data().node
    }

    fn help_symbol(&self) -> String {
        String::from("<") + self.node_data().name.as_str() +
        if self.repeatable() {
            ">..."
        } else {
            ">"
        }
    }

    fn help_text(&self) -> &String {
        &self.parameter_data().help
    }
}

pub struct FlagParameterNode {
    fields: ParameterNodeFields,
}

impl ParameterNode for FlagParameterNode {
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.fields
    }
}

pub struct NamedParameterNode {
    fields: ParameterNodeFields,
}

impl ParameterNode for NamedParameterNode {
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.fields
    }
}

pub struct SimpleParameterNode {
    fields: ParameterNodeFields,
}

impl ParameterNode for SimpleParameterNode {
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.fields
    }
}
<commit_msg>CommandNode: Implement help_text correctly.<commit_after>//! # Parser Nodes
//!
//! Parser nodes represent the grammar that is defined
//! by the currently permissible set of commands and their
//! parameters.

#![allow(dead_code, missing_docs, unused_variables)]

use std::rc::Rc;

/// Minimum priority.
pub const PRIORITY_MINIMUM: i32 = -10000;
/// The default priority for a parameter.
pub const PRIORITY_PARAMETER: i32 = -10;
/// The default priority.
pub const PRIORITY_DEFAULT: i32 = 0;

pub trait Node {
    fn node_data(&self) -> &NodeFields;

    fn successors(&self) -> &Vec<Rc<Node>> {
        &self.node_data().successors
    }

    fn help_symbol(&self) -> String {
        self.node_data().name.to_string()
    }

    fn help_text(&self) -> &String {
        unimplemented!();
    }

    fn hidden(&self) -> bool {
        self.node_data().hidden
    }

    fn name(&self) -> &String {
        &self.node_data().name
    }

    fn priority(&self) -> i32 {
        self.node_data().priority
    }
}

/// A parse tree node.
pub struct NodeFields {
    /// Possible successor nodes. Collected while building.
    pub successors: Vec<Rc<Node>>,
    /// The name of this node.
    pub name: String,
    /// Match and complete priority.
    pub priority: i32,
    /// Hidden nodes are not completed. This doesn't modify matching.
    pub hidden: bool,
}

pub struct CommandNode {
    fields: CommandNodeFields,
}

pub struct CommandNodeFields {
    node: NodeFields,
    help: String,
    handler: Option<fn(&node: Node) -> ()>,
    parameters: Vec<Rc<ParameterNode>>,
}

impl Node for CommandNode {
    fn node_data(&self) -> &NodeFields {
        &self.fields.node
    }

    fn help_text(&self) -> &String {
        &self.fields.help
    }
}

impl CommandNode {
    pub fn handler(&self) -> Option<fn(&node: Node) -> ()> {
        self.fields.handler
    }

    /// Get the parameter nodes for this command
    pub fn parameters(&self) -> &Vec<Rc<ParameterNode>> {
        &self.fields.parameters
    }
}

pub struct WrapperNode {
    fields: WrapperNodeFields,
}

pub struct WrapperNodeFields {
    command: CommandNodeFields,
    root: Rc<Node>,
}

impl Node for WrapperNode {
    fn node_data(&self) -> &NodeFields {
        &self.fields.command.node
    }

    fn successors(&self) -> &Vec<Rc<Node>> {
        &self.fields.root.successors()
    }
}

pub struct ParameterNameNode {
    fields: ParameterNameNodeFields,
}

pub struct RepeatableNodeFields {
    repeatable: bool,
    repeat_marker: Option<Rc<Node>>,
}

pub struct ParameterNameNodeFields {
    node: NodeFields,
    repeatable: RepeatableNodeFields,
    help: String,
    parameter: Rc<Node>,
}

impl Node for ParameterNameNode {
    fn node_data(&self) -> &NodeFields {
        &self.fields.node
    }

    fn help_symbol(&self) -> String {
        self.fields.node.name.clone() + " " + self.fields.parameter.help_symbol().as_str()
    }

    fn help_text(&self) -> &String {
        &self.fields.help
    }
}

impl ParameterNameNode {
    pub fn repeatable(&self) -> bool {
        self.fields.repeatable.repeatable
    }

    pub fn repeat_marker(&self) -> &Option<Rc<Node>> {
        &self.fields.repeatable.repeat_marker
    }
}

pub trait ParameterNode {
    fn parameter_data(&self) -> &ParameterNodeFields;

    fn repeatable(&self) -> bool {
        self.parameter_data().repeatable.repeatable
    }

    fn repeat_marker(&self) -> &Option<Rc<Node>> {
        &self.parameter_data().repeatable.repeat_marker
    }

    fn required(&self) -> bool {
        self.parameter_data().required
    }
}

pub struct ParameterNodeFields {
    node: NodeFields,
    repeatable: RepeatableNodeFields,
    help: String,
    required: bool,
}

impl Node for ParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.parameter_data().node
    }

    fn help_symbol(&self) -> String {
        String::from("<") + self.node_data().name.as_str() +
        if self.repeatable() {
            ">..."
        } else {
            ">"
        }
    }

    fn help_text(&self) -> &String {
        &self.parameter_data().help
    }
}

pub struct FlagParameterNode {
    fields: ParameterNodeFields,
}

impl ParameterNode for FlagParameterNode {
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.fields
    }
}

pub struct NamedParameterNode {
    fields: ParameterNodeFields,
}

impl ParameterNode for NamedParameterNode {
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.fields
    }
}

pub struct SimpleParameterNode {
    fields: ParameterNodeFields,
}

impl ParameterNode for SimpleParameterNode {
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.fields
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;

use irc::client::prelude::*;

use plugin::*;
use FrippyClient;

use error::ErrorKind as FrippyErrorKind;
use error::FrippyError;
use failure::ResultExt;

#[derive(PluginName, Default, Debug)]
pub struct Help<C> {
    phantom: PhantomData<C>,
}

impl<C: FrippyClient> Help<C> {
    pub fn new() -> Self {
        Help {
            phantom: PhantomData,
        }
    }
}

impl<C: FrippyClient> Plugin for Help<C> {
    type Client = C;
    fn execute(&self, _: &Self::Client, _: &Message) -> ExecutionStatus {
        ExecutionStatus::Done
    }

    fn execute_threaded(&self, _: &Self::Client, _: &Message) -> Result<(), FrippyError> {
        panic!("Help should not use threading")
    }

    fn command(&self, client: &Self::Client, command: PluginCommand) -> Result<(), FrippyError> {
        client
            .send_notice(
                &command.source,
                "Available commands: help, currency, tell, factoids, remind\r\n\
                 For more detailed help call help on the specific command.\r\n\
                 Example: 'currency help'",
            )
            .context(FrippyErrorKind::Connection)?;

        Ok(())
    }

    fn evaluate(&self, _: &Self::Client, _: PluginCommand) -> Result<String, String> {
        Err(String::from("Help has not been added yet."))
    }
}
<commit_msg>Help: Remove mentions of the currency plugin<commit_after>use std::marker::PhantomData;

use irc::client::prelude::*;

use plugin::*;
use FrippyClient;

use error::ErrorKind as FrippyErrorKind;
use error::FrippyError;
use failure::ResultExt;

#[derive(PluginName, Default, Debug)]
pub struct Help<C> {
    phantom: PhantomData<C>,
}

impl<C: FrippyClient> Help<C> {
    pub fn new() -> Self {
        Help {
            phantom: PhantomData,
        }
    }
}

impl<C: FrippyClient> Plugin for Help<C> {
    type Client = C;
    fn execute(&self, _: &Self::Client, _: &Message) -> ExecutionStatus {
        ExecutionStatus::Done
    }

    fn execute_threaded(&self, _: &Self::Client, _: &Message) -> Result<(), FrippyError> {
        panic!("Help should not use threading")
    }

    fn command(&self, client: &Self::Client, command: PluginCommand) -> Result<(), FrippyError> {
        client
            .send_notice(
                &command.source,
                "Available commands: help, tell, factoids, remind\r\n\
                 For more detailed help call help on the specific command.\r\n\
                 Example: 'remind help'",
            )
            .context(FrippyErrorKind::Connection)?;

        Ok(())
    }

    fn evaluate(&self, _: &Self::Client, _: PluginCommand) -> Result<String, String> {
        Err(String::from("Help has not been added yet."))
    }
}
<|endoftext|>


<commit_before>
#![allow(dead_code)]
#![allow(deprecated)]
use protobuf;
use proto::raftpb::{HardState, ConfState, Entry, Snapshot};
use raft::errors::{Result, Error, StorageError};

#[derive(Debug, Clone)]
pub struct RaftState {
    hard_state: HardState,
    conf_state: ConfState,
}

pub trait Storage {
    fn initial_state(&self) -> Result<RaftState>;
    fn entries(&self, low: u64, high: u64, max_size: u64) -> Result<&[Entry]>;
    fn term(&self, idx: u64) -> Result<u64>;
    fn first_index(&self) -> Result<u64>;
    fn last_index(&self) -> Result<u64>;
    fn snapshot(&self) -> Result<&Snapshot>;
}

pub struct MemStorage {
    hard_state: HardState,
    snapshot: Snapshot,
    // TODO: maybe vec_deque
    entries: Vec<Entry>,
}

impl MemStorage {
    pub fn new() -> MemStorage {
        MemStorage {
            // When starting from scratch populate the list with a dummy entry at term zero.
            entries: vec![Entry::new()],
            hard_state: HardState::new(),
            snapshot: Snapshot::new(),
        }
    }

    pub fn set_hardstate(&mut self, hs: HardState) {
        self.hard_state = hs;
    }

    fn inner_last_index(&self) -> u64 {
        return self.entries[0].get_Index() + self.entries.len() as u64 - 1;
    }

    fn limit_size(entries: &[Entry], max: u64) -> Result<&[Entry]> {
        if entries.len() == 0 {
            return Ok(entries);
        }

        let mut size = protobuf::Message::compute_size(&entries[0]) as u64;
        let mut limit = 1u64;
        while limit < entries.len() as u64 {
            size += protobuf::Message::compute_size(&entries[limit as usize]) as u64;
            if size > max {
                break;
            }
            limit += 1;
        }
        let ents = &entries[..limit as usize];
        Ok(ents)
    }

    fn apply_snapshot(&mut self, snapshot: Snapshot) -> Result<()> {
        let mut e = Entry::new();
        e.set_Term(snapshot.get_metadata().get_term());
        e.set_Index(snapshot.get_metadata().get_index());
        self.entries = vec![e];
        self.snapshot = snapshot;
        Ok(())
    }

    fn create_snapshot(&mut self,
                       idx: u64,
                       cs: Option<ConfState>,
                       data: Vec<u8>)
                       -> Result<&Snapshot> {
        if idx <= self.snapshot.get_metadata().get_index() {
            return Err(Error::Store(StorageError::SnapshotOutOfDate));
        }

        let offset = self.entries[0].get_Index();
        if idx > self.last_index().unwrap() {
            panic!("snapshot {} is out of bound lastindex({})",
                   idx,
                   self.last_index().unwrap())
        }
        self.snapshot.mut_metadata().set_index(idx);
        self.snapshot.mut_metadata().set_term(self.entries[(idx - offset) as usize].get_Term());
        match cs {
            Some(cs) => self.snapshot.mut_metadata().set_conf_state(cs),
            None => {}
        }
        self.snapshot.set_data(data);
        Ok(&self.snapshot)
    }

    pub fn compact(&mut self, compact_index: u64) -> Result<()> {
        let offset = self.entries[0].get_Index();
        if compact_index <= offset {
            return Err(Error::Store(StorageError::Compacted));
        }
        if compact_index > self.last_index().unwrap() {
            panic!("compact {} is out of bound lastindex({})",
                   compact_index,
                   self.last_index().unwrap())
        }

        let i = (compact_index - offset) as usize;
        let new_length = self.entries.len() + 1 - i;
        let mut entries: Vec<Entry> = Vec::with_capacity(new_length);
        entries.push(Entry::new());
        entries[0].set_Index(self.entries[i].get_Index());
        entries[0].set_Term(self.entries[i].get_Term());
        entries.append(&mut self.entries[i + 1..].to_vec());
        self.entries = entries;
        Ok(())
    }

    pub fn append(&mut self, ents: &[Entry]) -> Result<()> {
        if ents.len() == 0 {
            return Ok(());
        }
        let first: u64 = self.entries[0].get_Index() + 1;
        let last: u64 = ents[0].get_Index() + ents.len() as u64 - 1;

        if last < first {
            return Ok(());
        }
        // truncate compacted entries
        let mut te: &[Entry] = ents;
        if first > ents[0].get_Index() {
            let start = (first - ents[0].get_Index()) as usize;
            te = &ents[start..ents.len()];
        }

        let offset = te[0].get_Index() - self.entries[0].get_Index();
        if self.entries.len() as u64 > offset {
            let mut new_entries: Vec<Entry> = vec![];
            new_entries.extend_from_slice(&self.entries[..offset as usize]);
            new_entries.extend_from_slice(te);
            self.entries = new_entries;
        } else if self.entries.len() as u64 == offset {
            self.entries.extend_from_slice(te);
        } else {
            panic!("missing log entry [last: {}, append at: {}]",
                   self.last_index().unwrap(),
                   te[0].get_Index())
        }

        Ok(())
    }
}

impl Storage for MemStorage {
    fn initial_state(&self) -> Result<RaftState> {
        Ok(RaftState {
            hard_state: self.hard_state.clone(),
            conf_state: self.snapshot.get_metadata().get_conf_state().clone(),
        })
    }

    fn entries(&self, low: u64, high: u64, max_size: u64) -> Result<&[Entry]> {
        let offset = self.entries[0].get_Index();
        if low <= offset {
            return Err(Error::Store(StorageError::Compacted));
        }

        if high > self.inner_last_index() + 1 {
            panic!("index out of bound")
        }
        // only contains dummy entries.
        if self.entries.len() == 1 {
            return Err(Error::Store(StorageError::Unavailable));
        }

        let lo = (low - offset) as usize;
        let hi = (high - offset) as usize;
        let ents: &[Entry] = &self.entries[lo..hi];
        return MemStorage::limit_size(ents, max_size);
    }

    fn term(&self, idx: u64) -> Result<u64> {
        let offset = self.entries[0].get_Index();
        if idx < offset {
            return Err(Error::Store(StorageError::Compacted));
        }
        Ok(self.entries[(idx - offset) as usize].get_Term())
    }

    fn first_index(&self) -> Result<u64> {
        Ok(self.entries[0].get_Index() + 1)
    }

    fn last_index(&self) -> Result<u64> {
        Ok(self.inner_last_index())
    }

    fn snapshot(&self) -> Result<&Snapshot> {
        Ok(&self.snapshot)
    }
}
<commit_msg>address comment: drain<commit_after>
#![allow(dead_code)]
#![allow(deprecated)]
use protobuf;
use proto::raftpb::{HardState, ConfState, Entry, Snapshot};
use raft::errors::{Result, Error, StorageError};

#[derive(Debug, Clone)]
pub struct RaftState {
    hard_state: HardState,
    conf_state: ConfState,
}

pub trait Storage {
    fn initial_state(&self) -> Result<RaftState>;
    fn entries(&self, low: u64, high: u64, max_size: u64) -> Result<&[Entry]>;
    fn term(&self, idx: u64) -> Result<u64>;
    fn first_index(&self) -> Result<u64>;
    fn last_index(&self) -> Result<u64>;
    fn snapshot(&self) -> Result<&Snapshot>;
}

pub struct MemStorage {
    hard_state: HardState,
    snapshot: Snapshot,
    // TODO: maybe vec_deque
    entries: Vec<Entry>,
}

impl MemStorage {
    pub fn new() -> MemStorage {
        MemStorage {
            // When starting from scratch populate the list with a dummy entry at term zero.
            entries: vec![Entry::new()],
            hard_state: HardState::new(),
            snapshot: Snapshot::new(),
        }
    }

    pub fn set_hardstate(&mut self, hs: HardState) {
        self.hard_state = hs;
    }

    fn inner_last_index(&self) -> u64 {
        return self.entries[0].get_Index() + self.entries.len() as u64 - 1;
    }

    fn limit_size(entries: &[Entry], max: u64) -> Result<&[Entry]> {
        if entries.len() == 0 {
            return Ok(entries);
        }

        let mut size = protobuf::Message::compute_size(&entries[0]) as u64;
        let mut limit = 1u64;
        while limit < entries.len() as u64 {
            size += protobuf::Message::compute_size(&entries[limit as usize]) as u64;
            if size > max {
                break;
            }
            limit += 1;
        }
        let ents = &entries[..limit as usize];
        Ok(ents)
    }

    fn apply_snapshot(&mut self, snapshot: Snapshot) -> Result<()> {
        let mut e = Entry::new();
        e.set_Term(snapshot.get_metadata().get_term());
        e.set_Index(snapshot.get_metadata().get_index());
        self.entries = vec![e];
        self.snapshot = snapshot;
        Ok(())
    }

    fn create_snapshot(&mut self,
                       idx: u64,
                       cs: Option<ConfState>,
                       data: Vec<u8>)
                       -> Result<&Snapshot> {
        if idx <= self.snapshot.get_metadata().get_index() {
            return Err(Error::Store(StorageError::SnapshotOutOfDate));
        }

        let offset = self.entries[0].get_Index();
        if idx > self.last_index().unwrap() {
            panic!("snapshot {} is out of bound lastindex({})",
                   idx,
                   self.last_index().unwrap())
        }
        self.snapshot.mut_metadata().set_index(idx);
        self.snapshot.mut_metadata().set_term(self.entries[(idx - offset) as usize].get_Term());
        match cs {
            Some(cs) => self.snapshot.mut_metadata().set_conf_state(cs),
            None => {}
        }
        self.snapshot.set_data(data);
        Ok(&self.snapshot)
    }

    pub fn compact(&mut self, compact_index: u64) -> Result<()> {
        let offset = self.entries[0].get_Index();
        if compact_index <= offset {
            return Err(Error::Store(StorageError::Compacted));
        }
        if compact_index > self.last_index().unwrap() {
            panic!("compact {} is out of bound lastindex({})",
                   compact_index,
                   self.last_index().unwrap())
        }

        let i = (compact_index - offset) as usize;
        let entries = self.entries.drain(i..).collect();
        self.entries = entries;
        Ok(())
    }

    pub fn append(&mut self, ents: &[Entry]) -> Result<()> {
        if ents.len() == 0 {
            return Ok(());
        }
        let first: u64 = self.entries[0].get_Index() + 1;
        let last: u64 = ents[0].get_Index() + ents.len() as u64 - 1;

        if last < first {
            return Ok(());
        }
        // truncate compacted entries
        let mut te: &[Entry] = ents;
        if first > ents[0].get_Index() {
            let start = (first - ents[0].get_Index()) as usize;
            te = &ents[start..ents.len()];
        }

        let offset = te[0].get_Index() - self.entries[0].get_Index();
        if self.entries.len() as u64 > offset {
            let mut new_entries: Vec<Entry> = vec![];
            new_entries.extend_from_slice(&self.entries[..offset as usize]);
            new_entries.extend_from_slice(te);
            self.entries = new_entries;
        } else if self.entries.len() as u64 == offset {
            self.entries.extend_from_slice(te);
        } else {
            panic!("missing log entry [last: {}, append at: {}]",
                   self.last_index().unwrap(),
                   te[0].get_Index())
        }

        Ok(())
    }
}

impl Storage for MemStorage {
    fn initial_state(&self) -> Result<RaftState> {
        Ok(RaftState {
            hard_state: self.hard_state.clone(),
            conf_state: self.snapshot.get_metadata().get_conf_state().clone(),
        })
    }

    fn entries(&self, low: u64, high: u64, max_size: u64) -> Result<&[Entry]> {
        let offset = self.entries[0].get_Index();
        if low <= offset {
            return Err(Error::Store(StorageError::Compacted));
        }

        if high > self.inner_last_index() + 1 {
            panic!("index out of bound")
        }
        // only contains dummy entries.
        if self.entries.len() == 1 {
            return Err(Error::Store(StorageError::Unavailable));
        }

        let lo = (low - offset) as usize;
        let hi = (high - offset) as usize;
        let ents: &[Entry] = &self.entries[lo..hi];
        return MemStorage::limit_size(ents, max_size);
    }

    fn term(&self, idx: u64) -> Result<u64> {
        let offset = self.entries[0].get_Index();
        if idx < offset {
            return Err(Error::Store(StorageError::Compacted));
        }
        Ok(self.entries[(idx - offset) as usize].get_Term())
    }

    fn first_index(&self) -> Result<u64> {
        Ok(self.entries[0].get_Index() + 1)
    }

    fn last_index(&self) -> Result<u64> {
        Ok(self.inner_last_index())
    }

    fn snapshot(&self) -> Result<&Snapshot> {
        Ok(&self.snapshot)
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "gfx_rs_renderer")]
pub mod renderer {

}

#[cfg(not(feature = "gfx_rs_renderer"))]
pub mod renderer {
    use px8;
    use gfx::{Scale, Screen};

    use sdl2::VideoSubsystem;
    use sdl2::render;
    use sdl2::pixels::PixelFormatEnum;
    use std::sync::{Arc, Mutex};

    #[derive(Clone, Debug)]
    pub enum RendererError {
//        Sdl(String),
//        Renderer(String),
//        Other(String),
    }

    pub type RendererResult<T> = Result<T, RendererError>;

    pub struct Renderer {
        pub renderer: render::Renderer<'static>,
        pub texture: render::Texture,
    }

    impl Renderer {
        pub fn new(sdl_video: VideoSubsystem, fullscreen: bool, opengl: bool, scale: Scale) -> RendererResult<Renderer> {
            info!("[SDL] Creating window fullscreen={:?} opengl={:?}", fullscreen, opengl);

            let mut window_builder = sdl_video.window("PX8",
                                                      (px8::SCREEN_WIDTH as usize * scale.factor()) as u32,
                                                      (px8::SCREEN_HEIGHT as usize * scale.factor()) as u32);

            let window;
            if opengl {
                if fullscreen {
                    window = window_builder.fullscreen().opengl().build().unwrap();
                } else {
                    window = window_builder.resizable().position_centered().opengl().build().unwrap();
                }
            } else {
                if fullscreen {
                    window = window_builder.fullscreen().build().unwrap();
                } else {
                    window = window_builder.resizable().position_centered().build().unwrap();
                }
            }

            info!("[SDL] Creating renderer");
            let renderer = window.renderer().accelerated().present_vsync().build().unwrap();

            info!("[SDL] Creating texture");
            let texture = renderer.create_texture(PixelFormatEnum::BGR24,
                                                  render::TextureAccess::Streaming,
                                                  px8::SCREEN_WIDTH as u32,
                                                  px8::SCREEN_HEIGHT as u32).unwrap();

            Ok(Renderer {
                renderer: renderer,
                texture: texture,
            })
        }

        pub fn blit(&mut self, screen: Arc<Mutex<Screen>>) {
            self.texture.update(None,
                                &mut *screen.lock().unwrap().buffer_rgb,
                                px8::SCREEN_WIDTH * 3).unwrap();

            self.renderer.clear();
            self.renderer.copy(&self.texture, None, None).unwrap();
            self.renderer.present();
        }

        pub fn update_dimensions(&mut self) {
        }

        pub fn get_dimensions(&mut self) -> (u32, u32) {
            let size = self.renderer.window().unwrap().size();

            return (size.0, size.1)
        }
    }
}<commit_msg>Display game with correct aspect ratio (normally 1:1) for all window shapes<commit_after>#[cfg(feature = "gfx_rs_renderer")]
pub mod renderer {

}

#[cfg(not(feature = "gfx_rs_renderer"))]
pub mod renderer {
    use px8;
    use gfx::{Scale, Screen};

    use sdl2::VideoSubsystem;
    use sdl2::render;
    use sdl2::rect::Rect;
    use sdl2::rect::Point;
    use sdl2::pixels::PixelFormatEnum;
    use std::sync::{Arc, Mutex};

    #[derive(Clone, Debug)]
    pub enum RendererError {
//        Sdl(String),
//        Renderer(String),
//        Other(String),
    }

    pub type RendererResult<T> = Result<T, RendererError>;

    pub struct Renderer {
        pub renderer: render::Renderer<'static>,
        pub texture: render::Texture,

        window_width: u32,
        window_height: u32,
        viewport_width: u32,
        viewport_height: u32,
        viewport_offset: Point
    }

    impl Renderer {
        pub fn new(sdl_video: VideoSubsystem, fullscreen: bool, opengl: bool, scale: Scale) -> RendererResult<Renderer> {
            info!("[SDL] Creating window fullscreen={:?} opengl={:?}", fullscreen, opengl);

            let mut window_builder = sdl_video.window("PX8",
                                                      (px8::SCREEN_WIDTH as usize * scale.factor()) as u32,
                                                      (px8::SCREEN_HEIGHT as usize * scale.factor()) as u32);

            let wb = if fullscreen {
               window_builder.fullscreen()
            } else {
               window_builder.resizable().position_centered()
            };

            let window = (if opengl { wb.opengl() } else { wb }).build().unwrap();

            info!("[SDL] Creating renderer");
            let renderer = window.renderer().accelerated().present_vsync().build().unwrap();

            info!("[SDL] Creating texture");
            let texture = renderer.create_texture(PixelFormatEnum::BGR24,
                                                  render::TextureAccess::Streaming,
                                                  px8::SCREEN_WIDTH as u32,
                                                  px8::SCREEN_HEIGHT as u32).unwrap();

            Ok(Renderer {
                renderer: renderer,
                texture: texture,
                window_width: 0,
                window_height: 0,
                viewport_width: 0,
                viewport_height: 0,
                viewport_offset: Point::new(0, 0)
            })
        }

        pub fn blit(&mut self, screen: Arc<Mutex<Screen>>) {
            if self.viewport_width == 0 {
                self.update_dimensions();
            }
            self.texture.update(None,
                                &mut *screen.lock().unwrap().buffer_rgb,
                                px8::SCREEN_WIDTH * 3).unwrap();

            self.renderer.clear();
            self.renderer.copy(
                &self.texture,
                Some(Rect::new(
                    0, 0,
                    px8::SCREEN_WIDTH as u32,
                    px8::SCREEN_HEIGHT as u32)),
                Some(Rect::new(
                    self.viewport_offset.x(),
                    self.viewport_offset.y(),
                    self.viewport_width,
                    self.viewport_height))).unwrap();
            self.renderer.present();
        }

        pub fn update_dimensions(&mut self) {
            let (w, h) = self.get_dimensions();
            self.window_width = w;
            self.window_height = h;

            let window_aspect_ratio = (w as f32) / (h as f32);
            let viewport_aspect_ratio = (px8::SCREEN_WIDTH as f32) / (px8::SCREEN_HEIGHT as f32);

            self.viewport_offset =
                if viewport_aspect_ratio > window_aspect_ratio {
                    // Need margin at top and bottom
                    self.viewport_width = self.window_width;
                    self.viewport_height = (self.viewport_width as f32 / viewport_aspect_ratio) as u32;
                    Point::new(0, (self.window_height - self.viewport_height) as i32 / 2)
                } else {
                    // Need margin at left and right
                    self.viewport_height = self.window_height;
                    self.viewport_width = (self.viewport_height as f32 * viewport_aspect_ratio) as u32;
                    Point::new((self.window_width - self.viewport_width) as i32 / 2, 0)
                };
        }

        pub fn get_dimensions(&mut self) -> (u32, u32) {
            self.renderer.window().unwrap().size()
        }
    }
}<|endoftext|>