<commit_before>use crate::{imp::FileResolverImp, FileId};
use ra_syntax::{
    ast::{self, AstNode, NameOwner},
    text_utils::is_subrange,
    SmolStr,
};
use relative_path::RelativePathBuf;

use std::collections::BTreeMap;

#[derive(Debug, PartialEq, Eq, Hash)]
pub struct ModuleDescriptor {
    pub submodules: Vec<Submodule>,
}

impl ModuleDescriptor {
    pub fn new(root: ast::Root) -> ModuleDescriptor {
        let submodules = modules(root).map(|(name, _)| Submodule { name }).collect();

        ModuleDescriptor { submodules }
    }
}

fn modules<'a>(root: ast::Root<'a>) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> {
    root.modules().filter_map(|module| {
        let name = module.name()?.text();
        if !module.has_semi() {
            return None;
        }
        Some((name, module))
    })
}

#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub struct Submodule {
    pub name: SmolStr,
}

#[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct ModuleTreeDescriptor {
    nodes: Vec<NodeData>,
    links: Vec<LinkData>,
    file_id2node: BTreeMap<FileId, Node>,
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
struct Node(usize);
#[derive(Hash, Debug, PartialEq, Eq)]
struct NodeData {
    file_id: FileId,
    links: Vec<Link>,
    parents: Vec<Link>,
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) struct Link(usize);
#[derive(Hash, Debug, PartialEq, Eq)]
struct LinkData {
    owner: Node,
    name: SmolStr,
    points_to: Vec<Node>,
    problem: Option<Problem>,
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum Problem {
    UnresolvedModule {
        candidate: RelativePathBuf,
    },
    NotDirOwner {
        move_to: RelativePathBuf,
        candidate: RelativePathBuf,
    },
}

impl ModuleTreeDescriptor {
    pub(crate) fn new<'a>(
        files: impl Iterator<Item = (FileId, &'a ModuleDescriptor)> + Clone,
        file_resolver: &FileResolverImp,
    ) -> ModuleTreeDescriptor {
        let mut file_id2node = BTreeMap::new();
        let mut nodes: Vec<NodeData> = files
            .clone()
            .enumerate()
            .map(|(idx, (file_id, _))| {
                file_id2node.insert(file_id, Node(idx));
                NodeData {
                    file_id,
                    links: Vec::new(),
                    parents: Vec::new(),
                }
            })
            .collect();
        let mut links = Vec::new();

        for (idx, (file_id, descr)) in files.enumerate() {
            let owner = Node(idx);
            for sub in descr.submodules.iter() {
                let link = Link(links.len());
                nodes[owner.0].links.push(link);
                let (points_to, problem) = resolve_submodule(file_id, &sub.name, file_resolver);
                let points_to = points_to
                    .into_iter()
                    .map(|file_id| {
                        let node = file_id2node[&file_id];
                        nodes[node.0].parents.push(link);
                        node
                    })
                    .collect();

                links.push(LinkData {
                    owner,
                    name: sub.name.clone(),
                    points_to,
                    problem,
                })
            }
        }

        ModuleTreeDescriptor {
            nodes,
            links,
            file_id2node,
        }
    }

    pub(crate) fn parent_modules(&self, file_id: FileId) -> Vec<Link> {
        let node = self.file_id2node[&file_id];
        self.node(node).parents.clone()
    }
    pub(crate) fn child_module_by_name(&self, file_id: FileId, name: &str) -> Vec<FileId> {
        let node = self.file_id2node[&file_id];
        self.node(node)
            .links
            .iter()
            .filter(|it| it.name(self) == name)
            .flat_map(|link| {
                link.points_to(self)
                    .iter()
                    .map(|&node| self.node(node).file_id)
            })
            .collect()
    }
    pub(crate) fn problems<'a, 'b>(
        &'b self,
        file_id: FileId,
        root: ast::Root<'a>,
    ) -> Vec<(ast::Name<'a>, &'b Problem)> {
        let node = self.file_id2node[&file_id];
        self.node(node)
            .links
            .iter()
            .filter_map(|&link| {
                let problem = self.link(link).problem.as_ref()?;
                let name = link.bind_source(self, root).name()?;
                Some((name, problem))
            })
            .collect()
    }

    fn node(&self, node: Node) -> &NodeData {
        &self.nodes[node.0]
    }
    fn link(&self, link: Link) -> &LinkData {
        &self.links[link.0]
    }
}

impl Link {
    pub(crate) fn name(self, tree: &ModuleTreeDescriptor) -> SmolStr {
        tree.link(self).name.clone()
    }
    pub(crate) fn owner(self, tree: &ModuleTreeDescriptor) -> FileId {
        let owner = tree.link(self).owner;
        tree.node(owner).file_id
    }
    fn points_to(self, tree: &ModuleTreeDescriptor) -> &[Node] {
        &tree.link(self).points_to
    }
    pub(crate) fn bind_source<'a>(
        self,
        tree: &ModuleTreeDescriptor,
        root: ast::Root<'a>,
    ) -> ast::Module<'a> {
        modules(root)
            .filter(|(name, _)| name == &tree.link(self).name)
            .next()
            .unwrap()
            .1
    }
}

fn resolve_submodule(
    file_id: FileId,
    name: &SmolStr,
    file_resolver: &FileResolverImp,
) -> (Vec<FileId>, Option<Problem>) {
    let mod_name = file_resolver.file_stem(file_id);
    let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main";

    let file_mod = RelativePathBuf::from(format!("../{}.rs", name));
    let dir_mod = RelativePathBuf::from(format!("../{}/mod.rs", name));
    let points_to: Vec<FileId>;
    let problem: Option<Problem>;
    if is_dir_owner {
        points_to = [&file_mod, &dir_mod]
            .iter()
            .filter_map(|path| file_resolver.resolve(file_id, path))
            .collect();
        problem = if points_to.is_empty() {
            Some(Problem::UnresolvedModule {
                candidate: file_mod,
            })
        } else {
            None
        }
    } else {
        points_to = Vec::new();
        problem = Some(Problem::NotDirOwner {
            move_to: RelativePathBuf::from(format!("../{}/mod.rs", mod_name)),
            candidate: file_mod,
        });
    }
    (points_to, problem)
}

#[derive(Debug, Clone)]
pub struct FnDescriptor {
    pub name: String,
    pub label: String,
    pub ret_type: Option<String>,
    pub params: Vec<String>,
}

impl FnDescriptor {
    pub fn new_opt(node: ast::FnDef) -> Option<Self> {
        let name = node.name()?.text().to_string();

        // Strip the body out for the label.
        let label: String = if let Some(body) = node.body() {
            let body_range = body.syntax().range();
            let label: String = node
                .syntax()
                .children()
                .filter(|child| !is_subrange(body_range, child.range()))
                .map(|node| node.text().to_string())
                .collect();
            label
        } else {
            node.syntax().text().to_string()
        };

        let params = FnDescriptor::param_list(node);
        let ret_type = node.ret_type().map(|r| r.syntax().text().to_string());

        Some(FnDescriptor {
            name,
            ret_type,
            params,
            label,
        })
    }

    fn param_list(node: ast::FnDef) -> Vec<String> {
        let mut res = vec![];
        if let Some(param_list) = node.param_list() {
            if let Some(self_param) = param_list.self_param() {
                res.push(self_param.syntax().text().to_string())
            }

            // Maybe use param.pat here? See if we can just extract the name?
            //res.extend(param_list.params().map(|p| p.syntax().text().to_string()));
            res.extend(
                param_list
                    .params()
                    .filter_map(|p| p.pat())
                    .map(|pat| pat.syntax().text().to_string()),
            );
        }
        res
    }
}
<commit_msg>clippy: needless_lifetimes<commit_after>use crate::{imp::FileResolverImp, FileId};
use ra_syntax::{
    ast::{self, AstNode, NameOwner},
    text_utils::is_subrange,
    SmolStr,
};
use relative_path::RelativePathBuf;

use std::collections::BTreeMap;

#[derive(Debug, PartialEq, Eq, Hash)]
pub struct ModuleDescriptor {
    pub submodules: Vec<Submodule>,
}

impl ModuleDescriptor {
    pub fn new(root: ast::Root) -> ModuleDescriptor {
        let submodules = modules(root).map(|(name, _)| Submodule { name }).collect();

        ModuleDescriptor { submodules }
    }
}

fn modules(root: ast::Root<'_>) -> impl Iterator<Item = (SmolStr, ast::Module<'_>)> {
    root.modules().filter_map(|module| {
        let name = module.name()?.text();
        if !module.has_semi() {
            return None;
        }
        Some((name, module))
    })
}

#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub struct Submodule {
    pub name: SmolStr,
}

#[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct ModuleTreeDescriptor {
    nodes: Vec<NodeData>,
    links: Vec<LinkData>,
    file_id2node: BTreeMap<FileId, Node>,
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
struct Node(usize);
#[derive(Hash, Debug, PartialEq, Eq)]
struct NodeData {
    file_id: FileId,
    links: Vec<Link>,
    parents: Vec<Link>,
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) struct Link(usize);
#[derive(Hash, Debug, PartialEq, Eq)]
struct LinkData {
    owner: Node,
    name: SmolStr,
    points_to: Vec<Node>,
    problem: Option<Problem>,
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum Problem {
    UnresolvedModule {
        candidate: RelativePathBuf,
    },
    NotDirOwner {
        move_to: RelativePathBuf,
        candidate: RelativePathBuf,
    },
}

impl ModuleTreeDescriptor {
    pub(crate) fn new<'a>(
        files: impl Iterator<Item = (FileId, &'a ModuleDescriptor)> + Clone,
        file_resolver: &FileResolverImp,
    ) -> ModuleTreeDescriptor {
        let mut file_id2node = BTreeMap::new();
        let mut nodes: Vec<NodeData> = files
            .clone()
            .enumerate()
            .map(|(idx, (file_id, _))| {
                file_id2node.insert(file_id, Node(idx));
                NodeData {
                    file_id,
                    links: Vec::new(),
                    parents: Vec::new(),
                }
            })
            .collect();
        let mut links = Vec::new();

        for (idx, (file_id, descr)) in files.enumerate() {
            let owner = Node(idx);
            for sub in descr.submodules.iter() {
                let link = Link(links.len());
                nodes[owner.0].links.push(link);
                let (points_to, problem) = resolve_submodule(file_id, &sub.name, file_resolver);
                let points_to = points_to
                    .into_iter()
                    .map(|file_id| {
                        let node = file_id2node[&file_id];
                        nodes[node.0].parents.push(link);
                        node
                    })
                    .collect();

                links.push(LinkData {
                    owner,
                    name: sub.name.clone(),
                    points_to,
                    problem,
                })
            }
        }

        ModuleTreeDescriptor {
            nodes,
            links,
            file_id2node,
        }
    }

    pub(crate) fn parent_modules(&self, file_id: FileId) -> Vec<Link> {
        let node = self.file_id2node[&file_id];
        self.node(node).parents.clone()
    }
    pub(crate) fn child_module_by_name(&self, file_id: FileId, name: &str) -> Vec<FileId> {
        let node = self.file_id2node[&file_id];
        self.node(node)
            .links
            .iter()
            .filter(|it| it.name(self) == name)
            .flat_map(|link| {
                link.points_to(self)
                    .iter()
                    .map(|&node| self.node(node).file_id)
            })
            .collect()
    }
    pub(crate) fn problems<'a, 'b>(
        &'b self,
        file_id: FileId,
        root: ast::Root<'a>,
    ) -> Vec<(ast::Name<'a>, &'b Problem)> {
        let node = self.file_id2node[&file_id];
        self.node(node)
            .links
            .iter()
            .filter_map(|&link| {
                let problem = self.link(link).problem.as_ref()?;
                let name = link.bind_source(self, root).name()?;
                Some((name, problem))
            })
            .collect()
    }

    fn node(&self, node: Node) -> &NodeData {
        &self.nodes[node.0]
    }
    fn link(&self, link: Link) -> &LinkData {
        &self.links[link.0]
    }
}

impl Link {
    pub(crate) fn name(self, tree: &ModuleTreeDescriptor) -> SmolStr {
        tree.link(self).name.clone()
    }
    pub(crate) fn owner(self, tree: &ModuleTreeDescriptor) -> FileId {
        let owner = tree.link(self).owner;
        tree.node(owner).file_id
    }
    fn points_to(self, tree: &ModuleTreeDescriptor) -> &[Node] {
        &tree.link(self).points_to
    }
    pub(crate) fn bind_source<'a>(
        self,
        tree: &ModuleTreeDescriptor,
        root: ast::Root<'a>,
    ) -> ast::Module<'a> {
        modules(root)
            .filter(|(name, _)| name == &tree.link(self).name)
            .next()
            .unwrap()
            .1
    }
}

fn resolve_submodule(
    file_id: FileId,
    name: &SmolStr,
    file_resolver: &FileResolverImp,
) -> (Vec<FileId>, Option<Problem>) {
    let mod_name = file_resolver.file_stem(file_id);
    let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main";

    let file_mod = RelativePathBuf::from(format!("../{}.rs", name));
    let dir_mod = RelativePathBuf::from(format!("../{}/mod.rs", name));
    let points_to: Vec<FileId>;
    let problem: Option<Problem>;
    if is_dir_owner {
        points_to = [&file_mod, &dir_mod]
            .iter()
            .filter_map(|path| file_resolver.resolve(file_id, path))
            .collect();
        problem = if points_to.is_empty() {
            Some(Problem::UnresolvedModule {
                candidate: file_mod,
            })
        } else {
            None
        }
    } else {
        points_to = Vec::new();
        problem = Some(Problem::NotDirOwner {
            move_to: RelativePathBuf::from(format!("../{}/mod.rs", mod_name)),
            candidate: file_mod,
        });
    }
    (points_to, problem)
}

#[derive(Debug, Clone)]
pub struct FnDescriptor {
    pub name: String,
    pub label: String,
    pub ret_type: Option<String>,
    pub params: Vec<String>,
}

impl FnDescriptor {
    pub fn new_opt(node: ast::FnDef) -> Option<Self> {
        let name = node.name()?.text().to_string();

        // Strip the body out for the label.
        let label: String = if let Some(body) = node.body() {
            let body_range = body.syntax().range();
            let label: String = node
                .syntax()
                .children()
                .filter(|child| !is_subrange(body_range, child.range()))
                .map(|node| node.text().to_string())
                .collect();
            label
        } else {
            node.syntax().text().to_string()
        };

        let params = FnDescriptor::param_list(node);
        let ret_type = node.ret_type().map(|r| r.syntax().text().to_string());

        Some(FnDescriptor {
            name,
            ret_type,
            params,
            label,
        })
    }

    fn param_list(node: ast::FnDef) -> Vec<String> {
        let mut res = vec![];
        if let Some(param_list) = node.param_list() {
            if let Some(self_param) = param_list.self_param() {
                res.push(self_param.syntax().text().to_string())
            }

            // Maybe use param.pat here? See if we can just extract the name?
            //res.extend(param_list.params().map(|p| p.syntax().text().to_string()));
            res.extend(
                param_list
                    .params()
                    .filter_map(|p| p.pat())
                    .map(|pat| pat.syntax().text().to_string()),
            );
        }
        res
    }
}
<|endoftext|>


<commit_before>extern crate simple_csv;

use std::fs::File;
use std::io::BufReader;
use std::str::FromStr;
use simple_csv::{SimpleCsvWriter, SimpleCsvReader};

fn main(){
    let f = File::open("../long-cadence.csv").unwrap();
    let buf = BufReader::new(f);
    let reader = SimpleCsvReader::new(buf);

    let o = File::create("average.csv").unwrap();
    let mut writer = SimpleCsvWriter::new(o);

    for (_, r) in reader.enumerate() {
        let row = r.unwrap();
        let (time, brightness) = sum(row);

        writer.write(
            &vec!(time.to_string(), brightness.to_string())
        ).unwrap();
    }

}

fn sum(row: Vec<String>) -> (f64, f64) {
    let mut iter = row.iter();
    let time: f64 = f64::from_str(iter.next().unwrap()).unwrap();

    let raw: Vec<f64> = iter
        .map(|s| f64::from_str(s).unwrap())
        .collect();
    let sum: f64 = raw
        .iter()
        .fold(0f64, |acc, v| acc+v);

    (time, sum)
}
<commit_msg>Remove background noise from signal<commit_after>extern crate simple_csv;

use std::fs::File;
use std::io::BufReader;
use std::str::FromStr;
use simple_csv::{SimpleCsvWriter, SimpleCsvReader};

fn main(){
    let f = File::open("../long-cadence.csv").unwrap();
    let buf = BufReader::new(f);
    let reader = SimpleCsvReader::new(buf);

    let o = File::create("average.csv").unwrap();
    let mut writer = SimpleCsvWriter::new(o);

    for (_, r) in reader.enumerate() {
        let row = r.unwrap();
        let (time, brightness, filtered) = sum(row);

        writer.write(
            &vec!(time.to_string(), brightness.to_string(), filtered.to_string())
        ).unwrap();
    }
}

fn sum(row: Vec<String>) -> (f64, f64, f64) {
    let mut iter = row.iter();
    let time: f64 = f64::from_str(iter.next().unwrap()).unwrap();

    let raw: Vec<f64> = iter
        .map(|s| f64::from_str(s).unwrap())
        .collect();
    let sum: f64 = raw
        .iter()
        .fold(0f64, |acc, v| acc+v);
    let average = sum / (row.len() as f64);
    let filtered: f64 = raw
        .iter()
        .filter(|&v| *v >= average)
        .fold(0f64, |acc, v| acc+v);

    (time, sum, filtered)
}
<|endoftext|>


<commit_before>use base::world::ChunkProvider;
use ghost::Ghost;
use event_manager::{CloseHandler, EventManager, EventResponse};
use glium::backend::glutin_backend::GlutinFacade;
use glium::{self, DisplayBuild, glutin};
use super::Renderer;
use super::{Config, GameContext, WorldManager};
use config::WindowMode;
use base::gen::WorldGenerator;
use std::time::{Duration, Instant};
use std::rc::Rc;
use std::net::{SocketAddr, TcpStream};
use std::error::Error;
use base::world::World;
use camera::Camera;
use base::world::PillarSection;
use base::world;
use base::world::HeightType; //WILL BE USED LATER
use base::math::*;
use base::world::PillarIndex;
use view::{SkyView, Sun};
use super::DayTime;
use super::weather::Weather;
use player::Player;
use control_switcher::ControlSwitcher;
use base::world::HexPillar;

pub struct Game {
    renderer: Renderer,
    event_manager: EventManager,
    world_manager: WorldManager,
    #[allow(dead_code)]
    server: TcpStream,
    sun: Sun,
    sky_view: SkyView,
    daytime: DayTime,
    weather: Weather,
    control_switcher: ControlSwitcher,
}

impl Game {
    pub fn new(config: Config, server: SocketAddr) -> Result<Self, Box<Error>> {
        info!("connecting to {}", server);
        let server = try!(TcpStream::connect(server));
        let facade = try!(create_context(&config));
        let context = Rc::new(GameContext::new(facade, config.clone()));
        let world_manager = WorldManager::new(create_chunk_provider(context.get_config()),
                                              context.clone());
        let world_weather = Weather::new(context.clone());

        Ok(Game {
            renderer: Renderer::new(context.clone()),
            event_manager: EventManager::new(context.get_facade().clone()),
            world_manager: world_manager.clone(),
            server: server,
            sun: Sun::new(context.clone()),
            sky_view: SkyView::new(context.clone()),
            daytime: DayTime::default(),
            weather: world_weather,
            control_switcher: ControlSwitcher::new(Player::new(context.clone(), world_manager),
                                                   Ghost::new(context.clone())),
        })
    }

    /// Main game function: contains the main render loop and owns all important
    /// components. This function should remain rather small, all heavy lifting
    /// should be done in other functions.
    pub fn run(mut self) -> Result<(), Box<Error>> {
        let mut frames = 0;
        let mut next_fps_measure = Instant::now() + Duration::from_secs(1);
        let mut time_prev = Instant::now();
        loop {
            self.world_manager.update_world(self.control_switcher.get_camera().position);

            let time_now = Instant::now();
            let duration_delta = time_now.duration_since(time_prev);
            // delta in seconds
            let delta = ((duration_delta.subsec_nanos() / 1_000) as f32) / 1_000_000.0 +
                        duration_delta.as_secs() as f32;
            time_prev = Instant::now();

            self.weather.update(&self.control_switcher.get_camera(),
                                delta,
                                &self.world_manager);
            self.world_manager.update_world(self.control_switcher.get_camera().position);

            self.daytime.update(delta);
            self.sky_view.update(self.daytime.get_sun_position());
            self.sun.update(self.daytime.get_sun_position());
            // Display Outline of Hexagon looking at
            let vec = get_pillarsectionpos_looking_at(&self.world_manager.get_world(),
                                                      self.control_switcher.get_camera());
            match vec {
                Some(n) => {
                    // self.remove_hexagon_at(n);
                    let mut view = self.world_manager.get_mut_view();
                    view.outline.display = true;
                    view.outline.pos = n;
                }
                None => {
                    let mut view = self.world_manager.get_mut_view();
                    view.outline.display = false;
                }
            }

            try!(self.renderer.render(&*self.world_manager.get_view(),
                                      &self.control_switcher.get_camera(),
                                      &self.sun,
                                      &mut self.weather,
                                      &self.sky_view));

            let event_resp = self.event_manager
                .poll_events(vec![&mut CloseHandler,
                                  &mut self.control_switcher,
                                  &mut self.daytime]);
            if event_resp == EventResponse::Quit {
                break;
            }

            self.control_switcher.update(delta);

            frames += 1;
            if next_fps_measure < Instant::now() {
                info!("{} FPS", frames);
                next_fps_measure = Instant::now() + Duration::from_secs(1);
                frames = 0;
            }
        }

        Ok(())
    }

    // need sorted pillars
    fn remove_hexagon_at(&mut self, pos: Vector3f) {
        let view_pos = Point2f::new(pos.x, pos.y);
        let pillar_index = PillarIndex(AxialPoint::from_real(view_pos));

        match self.world_manager.mut_world().pillar_at_mut(pillar_index) {
            Some(pillar) => {
                let bottom = pos.z - pos.z % world::PILLAR_STEP_HEIGHT;

                let mut i: usize = 0;
                for section in pillar.sections() {
                    if section.top.to_real() >= bottom {
                        break;
                    }
                    i += 1;
                }
                let mut pillar_section = pillar.sections_mut();
                if pillar_section.len() > i {
                    if pillar_section[i].top.to_real() != pos.z + world::PILLAR_STEP_HEIGHT {
                        let sec = PillarSection {
                            ground: pillar_section[i].ground.clone(),
                            top: pillar_section[i].top,
                            bottom:
                                HeightType::from_units((pos.z / world::PILLAR_STEP_HEIGHT) as u16),
                        };
                        pillar_section.insert(i, sec);
                        if i > 0 {
                            i -= 1;
                        }
                    }
                    pillar_section[i].top =
                        HeightType::from_units(HeightType::from_real(pos.z) as u16);
                    if pillar_section[i].top == pillar_section[i].bottom {
                        pillar_section.remove(i);
                    }
                } else {
                    return;
                }
            }
            None => return,
        };
        self.world_manager.recalulate_chunk(Point3f::new(pos.x, pos.y, pos.z));
    }
}

fn get_pillarsectionpos_looking_at(world: &World, cam: Camera) -> Option<Vector3f> {
    let cam_pos = cam.position;
    let mut look_vec = cam.get_look_at_vector().normalize();
    let view_distance = 12.0;

    let mut step = 0.0;
    while (look_vec.x * look_vec.x + look_vec.y * look_vec.y + look_vec.z * look_vec.z).sqrt() <=
          view_distance {
        step += 0.0005;
        look_vec = cam.get_look_at_vector().normalize() * step;

        let view_pos = Point2f::new(cam_pos.x + look_vec.x, cam_pos.y + look_vec.y);
        let pillar_index = PillarIndex(AxialPoint::from_real(view_pos));

        let mut height = cam_pos.z + look_vec.z;
        height -= height % world::PILLAR_STEP_HEIGHT;

        let final_pos = match world.pillar_at(pillar_index) {
            Some(n) => get_pillar_section_at_position(n, height),
            None => None,
        };

        match final_pos {
            Some(_) => {
                let ax_point = AxialPoint::from_real(view_pos);

                return Some(Vector3f::new(ax_point.to_real().x, ax_point.to_real().y, height));
            }
            None => {}
        };
    }
    None
}

fn get_pillar_section_at_position(pillar: &HexPillar, pos_z: f32) -> Option<&PillarSection> {
    for section in pillar.sections() {
        if section.top.to_real() > pos_z && section.bottom.to_real() < pos_z {
            return Some(section);
        }
    }
    None
}

fn create_chunk_provider(config: &Config) -> Box<ChunkProvider> {
    Box::new(WorldGenerator::with_seed(config.seed))
}

/// Creates the OpenGL context and prints useful information about the
/// success or failure of said action.
fn create_context(config: &Config) -> Result<GlutinFacade, Box<Error>> {

    // initialize window builder
    let mut window_builder = glutin::WindowBuilder::new();
    // check for window mode and set params
    match config.window_mode {
        WindowMode::Windowed => (),
        // TODO: if we add a fullscreen window mode
        // FullScreenWindow => (),
        WindowMode::FullScreen => {
            window_builder = window_builder.with_fullscreen(glutin::get_primary_monitor());
            window_builder = window_builder.with_decorations(false);
        }
    }
    // check for vsync
    if config.vsync {
        window_builder = window_builder.with_vsync();
    }
    // set title, resolution & create glium context
    window_builder = window_builder.with_title(config.window_title.clone());
    window_builder =
        window_builder.with_dimensions(config.resolution.width, config.resolution.height);
    let context = window_builder.with_depth_buffer(24).build_glium();

    match context {
        Err(e) => {
            // TODO: print more user friendly output
            error!("OpenGL context creation failed! Detailed error:");
            error!("{}", e);

            Err(e.into())
        }
        Ok(context) => {
            // Print some information about the acquired OpenGL context
            info!("OpenGL context was successfully built");

            let glium::Version(api, major, minor) = *context.get_opengl_version();
            info!("Version of context: {} {}.{}",
                  if api == glium::Api::Gl { "OpenGL" } else { "OpenGL ES" },
                  major,
                  minor);

            let glium::Version(api, major, minor) = context.get_supported_glsl_version();
            info!("Supported GLSL version: {} {}.{}",
                  if api == glium::Api::Gl { "GLSL" } else { "GLSL ES" },
                  major,
                  minor);

            if let Some(mem) = context.get_free_video_memory().map(|mem| mem as u64) {
                let (mem, unit) = match () {
                    _ if mem < (1 << 12) => (mem, "B"),
                    _ if mem < (1 << 22) => (mem >> 10, "KB"),
                    _ if mem < (1 << 32) => (mem >> 20, "MB"),
                    _ => (mem >> 30, "GB"),
                };
                info!("Free GPU memory (estimated): {}{}", mem, unit);
            }

            Ok(context)
        }
    }
}
<commit_msg>Fix warnings...<commit_after>use base::world::ChunkProvider;
use ghost::Ghost;
use event_manager::{CloseHandler, EventManager, EventResponse};
use glium::backend::glutin_backend::GlutinFacade;
use glium::{self, DisplayBuild, glutin};
use super::Renderer;
use super::{Config, GameContext, WorldManager};
use config::WindowMode;
use base::gen::WorldGenerator;
use std::time::{Duration, Instant};
use std::rc::Rc;
use std::net::{SocketAddr, TcpStream};
use std::error::Error;
use base::world::World;
use camera::Camera;
use base::world::PillarSection;
use base::world;
// use base::world::HeightType; //WILL BE USED LATER
use base::math::*;
use base::world::PillarIndex;
use view::{SkyView, Sun};
use super::DayTime;
use super::weather::Weather;
use player::Player;
use control_switcher::ControlSwitcher;
use base::world::HexPillar;

pub struct Game {
    renderer: Renderer,
    event_manager: EventManager,
    world_manager: WorldManager,
    #[allow(dead_code)]
    server: TcpStream,
    sun: Sun,
    sky_view: SkyView,
    daytime: DayTime,
    weather: Weather,
    control_switcher: ControlSwitcher,
}

impl Game {
    pub fn new(config: Config, server: SocketAddr) -> Result<Self, Box<Error>> {
        info!("connecting to {}", server);
        let server = try!(TcpStream::connect(server));
        let facade = try!(create_context(&config));
        let context = Rc::new(GameContext::new(facade, config.clone()));
        let world_manager = WorldManager::new(create_chunk_provider(context.get_config()),
                                              context.clone());
        let world_weather = Weather::new(context.clone());

        Ok(Game {
            renderer: Renderer::new(context.clone()),
            event_manager: EventManager::new(context.get_facade().clone()),
            world_manager: world_manager.clone(),
            server: server,
            sun: Sun::new(context.clone()),
            sky_view: SkyView::new(context.clone()),
            daytime: DayTime::default(),
            weather: world_weather,
            control_switcher: ControlSwitcher::new(Player::new(context.clone(), world_manager),
                                                   Ghost::new(context.clone())),
        })
    }

    /// Main game function: contains the main render loop and owns all important
    /// components. This function should remain rather small, all heavy lifting
    /// should be done in other functions.
    pub fn run(mut self) -> Result<(), Box<Error>> {
        let mut frames = 0;
        let mut next_fps_measure = Instant::now() + Duration::from_secs(1);
        let mut time_prev = Instant::now();
        loop {
            self.world_manager.update_world(self.control_switcher.get_camera().position);

            let time_now = Instant::now();
            let duration_delta = time_now.duration_since(time_prev);
            // delta in seconds
            let delta = ((duration_delta.subsec_nanos() / 1_000) as f32) / 1_000_000.0 +
                        duration_delta.as_secs() as f32;
            time_prev = Instant::now();

            self.weather.update(&self.control_switcher.get_camera(),
                                delta,
                                &self.world_manager);
            self.world_manager.update_world(self.control_switcher.get_camera().position);

            self.daytime.update(delta);
            self.sky_view.update(self.daytime.get_sun_position());
            self.sun.update(self.daytime.get_sun_position());
            // Display Outline of Hexagon looking at
            let vec = get_pillarsectionpos_looking_at(&self.world_manager.get_world(),
                                                      self.control_switcher.get_camera());
            match vec {
                Some(n) => {
                    // self.remove_hexagon_at(n);
                    let mut view = self.world_manager.get_mut_view();
                    view.outline.display = true;
                    view.outline.pos = n;
                }
                None => {
                    let mut view = self.world_manager.get_mut_view();
                    view.outline.display = false;
                }
            }

            try!(self.renderer.render(&*self.world_manager.get_view(),
                                      &self.control_switcher.get_camera(),
                                      &self.sun,
                                      &mut self.weather,
                                      &self.sky_view));

            let event_resp = self.event_manager
                .poll_events(vec![&mut CloseHandler,
                                  &mut self.control_switcher,
                                  &mut self.daytime]);
            if event_resp == EventResponse::Quit {
                break;
            }

            self.control_switcher.update(delta);

            frames += 1;
            if next_fps_measure < Instant::now() {
                info!("{} FPS", frames);
                next_fps_measure = Instant::now() + Duration::from_secs(1);
                frames = 0;
            }
        }

        Ok(())
    }

    // // need sorted pillars
    // fn remove_hexagon_at(&mut self, pos: Vector3f) {
    //     let view_pos = Point2f::new(pos.x, pos.y);
    //     let pillar_index = PillarIndex(AxialPoint::from_real(view_pos));

    //     match self.world_manager.mut_world().pillar_at_mut(pillar_index) {
    //         Some(pillar) => {
    //             let bottom = pos.z - pos.z % world::PILLAR_STEP_HEIGHT;

    //             let mut i: usize = 0;
    //             for section in pillar.sections() {
    //                 if section.top.to_real() >= bottom {
    //                     break;
    //                 }
    //                 i += 1;
    //             }
    //             let mut pillar_section = pillar.sections_mut();
    //             if pillar_section.len() > i {
    // if pillar_section[i].top.to_real() != pos.z +
    // world::PILLAR_STEP_HEIGHT {
    //                     let sec = PillarSection {
    //                         ground: pillar_section[i].ground.clone(),
    //                         top: pillar_section[i].top,
    //                         bottom:
    // HeightType::from_units((pos.z /
    // world::PILLAR_STEP_HEIGHT) as u16),
    //                     };
    //                     pillar_section.insert(i, sec);
    //                     if i > 0 {
    //                         i -= 1;
    //                     }
    //                 }
    //                 pillar_section[i].top =
    // HeightType::from_units(HeightType::from_real(pos.z) as
    // u16);
    //                 if pillar_section[i].top == pillar_section[i].bottom {
    //                     pillar_section.remove(i);
    //                 }
    //             } else {
    //                 return;
    //             }
    //         }
    //         None => return,
    //     };
    //     self.world_manager.recalulate_chunk(Point3f::new(pos.x, pos.y, pos.z));
    // }
}

fn get_pillarsectionpos_looking_at(world: &World, cam: Camera) -> Option<Vector3f> {
    let cam_pos = cam.position;
    let mut look_vec = cam.get_look_at_vector().normalize();
    let view_distance = 12.0;

    let mut step = 0.0;
    while (look_vec.x * look_vec.x + look_vec.y * look_vec.y + look_vec.z * look_vec.z).sqrt() <=
          view_distance {
        step += 0.0005;
        look_vec = cam.get_look_at_vector().normalize() * step;

        let view_pos = Point2f::new(cam_pos.x + look_vec.x, cam_pos.y + look_vec.y);
        let pillar_index = PillarIndex(AxialPoint::from_real(view_pos));

        let mut height = cam_pos.z + look_vec.z;
        height -= height % world::PILLAR_STEP_HEIGHT;

        let final_pos = match world.pillar_at(pillar_index) {
            Some(n) => get_pillar_section_at_position(n, height),
            None => None,
        };

        match final_pos {
            Some(_) => {
                let ax_point = AxialPoint::from_real(view_pos);

                return Some(Vector3f::new(ax_point.to_real().x, ax_point.to_real().y, height));
            }
            None => {}
        };
    }
    None
}

fn get_pillar_section_at_position(pillar: &HexPillar, pos_z: f32) -> Option<&PillarSection> {
    for section in pillar.sections() {
        if section.top.to_real() > pos_z && section.bottom.to_real() < pos_z {
            return Some(section);
        }
    }
    None
}

fn create_chunk_provider(config: &Config) -> Box<ChunkProvider> {
    Box::new(WorldGenerator::with_seed(config.seed))
}

/// Creates the OpenGL context and prints useful information about the
/// success or failure of said action.
fn create_context(config: &Config) -> Result<GlutinFacade, Box<Error>> {

    // initialize window builder
    let mut window_builder = glutin::WindowBuilder::new();
    // check for window mode and set params
    match config.window_mode {
        WindowMode::Windowed => (),
        // TODO: if we add a fullscreen window mode
        // FullScreenWindow => (),
        WindowMode::FullScreen => {
            window_builder = window_builder.with_fullscreen(glutin::get_primary_monitor());
            window_builder = window_builder.with_decorations(false);
        }
    }
    // check for vsync
    if config.vsync {
        window_builder = window_builder.with_vsync();
    }
    // set title, resolution & create glium context
    window_builder = window_builder.with_title(config.window_title.clone());
    window_builder =
        window_builder.with_dimensions(config.resolution.width, config.resolution.height);
    let context = window_builder.with_depth_buffer(24).build_glium();

    match context {
        Err(e) => {
            // TODO: print more user friendly output
            error!("OpenGL context creation failed! Detailed error:");
            error!("{}", e);

            Err(e.into())
        }
        Ok(context) => {
            // Print some information about the acquired OpenGL context
            info!("OpenGL context was successfully built");

            let glium::Version(api, major, minor) = *context.get_opengl_version();
            info!("Version of context: {} {}.{}",
                  if api == glium::Api::Gl { "OpenGL" } else { "OpenGL ES" },
                  major,
                  minor);

            let glium::Version(api, major, minor) = context.get_supported_glsl_version();
            info!("Supported GLSL version: {} {}.{}",
                  if api == glium::Api::Gl { "GLSL" } else { "GLSL ES" },
                  major,
                  minor);

            if let Some(mem) = context.get_free_video_memory().map(|mem| mem as u64) {
                let (mem, unit) = match () {
                    _ if mem < (1 << 12) => (mem, "B"),
                    _ if mem < (1 << 22) => (mem >> 10, "KB"),
                    _ if mem < (1 << 32) => (mem >> 20, "MB"),
                    _ => (mem >> 30, "GB"),
                };
                info!("Free GPU memory (estimated): {}{}", mem, unit);
            }

            Ok(context)
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Location in memory that contains data.
//!
//! A Vulkan buffer is very similar to a buffer that you would use in programming languages in
//! general, in the sense that it is a location in memory that contains data. The difference
//! between a Vulkan buffer and a regular buffer is that the content of a Vulkan buffer is
//! accessible from the GPU.
//!
//! # Various kinds of buffers
//!
//! The low level implementation of a buffer is [`UnsafeBuffer`](sys/struct.UnsafeBuffer.html).
//! This type makes it possible to use all the features that Vulkan is capable of, but as its name
//! tells it is unsafe to use.
//!
//! Instead you are encouraged to use one of the high-level wrappers that vulkano provides. Which
//! wrapper to use depends on the way you are going to use the buffer:
//!
//! - A [`DeviceLocalBuffer`](device_local/struct.DeviceLocalBuffer.html) designates a buffer
//!   usually located in video memory and whose content can't be directly accessed by your
//!   application. Accessing this buffer from the GPU is generally faster compared to accessing a
//!   CPU-accessible buffer.
//! - An [`ImmutableBuffer`](immutable/struct.ImmutableBuffer.html) designates a buffer in video
//!   memory and whose content can only be written at creation. Compared to `DeviceLocalBuffer`,
//!   this buffer requires less CPU processing because we don't need to keep track of the reads
//!   and writes.
//! - A [`CpuBufferPool`](cpu_pool/struct.CpuBufferPool.html) is a ring buffer that can be used to
//!   transfer data between the CPU and the GPU at a high rate.
//! - A [`CpuAccessibleBuffer`](cpu_access/struct.CpuAccessibleBuffer.html) is a simple buffer that
//!   can be used to prototype. It may be removed from vulkano in the far future.
//!
//! Here is a quick way to choose which buffer to use. Do you need to often need to read or write
//! the content of the buffer? If so, use a `CpuBufferPool`. Otherwise, do you need to be able to
//! modify the content of the buffer after its initialization? If so, use a `DeviceLocalBuffer`.
//! If no to both questions, use an `ImmutableBuffer`.
//!
//! When deciding how your buffer is going to be used, don't forget that sometimes the best
//! solution is to manipulate multiple buffers instead. For example if you need to update a buffer's
//! content only from time to time, it may be a good idea to simply recreate a new `ImmutableBuffer`
//! every time.
//! Another example: if a buffer is under constant access by the GPU but you need to
//! read its content on the CPU from time to time, it may be a good idea to use a
//! `DeviceLocalBuffer` as the main buffer and a `CpuBufferPool` for when you need to read it.
//! Then whenever you need to read the main buffer, ask the GPU to copy from the device-local
//! buffer to the CPU buffer pool, and read the CPU buffer pool instead.
//!
//! # Buffers usage
//!
//! When you create a buffer object, you have to specify its *usage*. In other words, you have to
//! specify the way it is going to be used. Trying to use a buffer in a way that wasn't specified
//! when you created it will result in a runtime error.
//!
//! You can use buffers for the following purposes:
//!
//! - Can contain arbitrary data that can be transferred from/to other buffers and images.
//! - Can be read and modified from a shader.
//! - Can be used as a source of vertices and indices.
//! - Can be used as a source of list of models for draw indirect commands.
//!
//! Accessing a buffer from a shader can be done in the following ways:
//!
//! - As a uniform buffer. Uniform buffers are read-only.
//! - As a storage buffer. Storage buffers can be read and written.
//! - As a uniform texel buffer. Contrary to a uniform buffer, the data is interpreted by the
//!   GPU and can be for example normalized.
//! - As a storage texel buffer. Additionally, some data formats can be modified with atomic
//!   operations.
//!
//! Using uniform/storage texel buffers requires creating a *buffer view*. See the `view` module
//! for how to create a buffer view.
//!

pub use self::cpu_access::CpuAccessibleBuffer;
pub use self::cpu_pool::CpuBufferPool;
pub use self::device_local::DeviceLocalBuffer;
pub use self::immutable::ImmutableBuffer;
pub use self::slice::BufferSlice;
pub use self::sys::BufferCreationError;
pub use self::traits::BufferAccess;
pub use self::traits::BufferInner;
pub use self::traits::TypedBufferAccess;
pub use self::usage::BufferUsage;
pub use self::view::BufferView;
pub use self::view::BufferViewRef;

pub mod cpu_access;
pub mod cpu_pool;
pub mod device_local;
pub mod immutable;
pub mod sys;
pub mod view;

mod slice;
mod traits;
mod usage;
<commit_msg>Remove superfluous "need" from the documentation of buffer module (#1093)<commit_after>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Location in memory that contains data.
//!
//! A Vulkan buffer is very similar to a buffer that you would use in programming languages in
//! general, in the sense that it is a location in memory that contains data. The difference
//! between a Vulkan buffer and a regular buffer is that the content of a Vulkan buffer is
//! accessible from the GPU.
//!
//! # Various kinds of buffers
//!
//! The low level implementation of a buffer is [`UnsafeBuffer`](sys/struct.UnsafeBuffer.html).
//! This type makes it possible to use all the features that Vulkan is capable of, but as its name
//! tells it is unsafe to use.
//!
//! Instead you are encouraged to use one of the high-level wrappers that vulkano provides. Which
//! wrapper to use depends on the way you are going to use the buffer:
//!
//! - A [`DeviceLocalBuffer`](device_local/struct.DeviceLocalBuffer.html) designates a buffer
//!   usually located in video memory and whose content can't be directly accessed by your
//!   application. Accessing this buffer from the GPU is generally faster compared to accessing a
//!   CPU-accessible buffer.
//! - An [`ImmutableBuffer`](immutable/struct.ImmutableBuffer.html) designates a buffer in video
//!   memory and whose content can only be written at creation. Compared to `DeviceLocalBuffer`,
//!   this buffer requires less CPU processing because we don't need to keep track of the reads
//!   and writes.
//! - A [`CpuBufferPool`](cpu_pool/struct.CpuBufferPool.html) is a ring buffer that can be used to
//!   transfer data between the CPU and the GPU at a high rate.
//! - A [`CpuAccessibleBuffer`](cpu_access/struct.CpuAccessibleBuffer.html) is a simple buffer that
//!   can be used to prototype. It may be removed from vulkano in the far future.
//!
//! Here is a quick way to choose which buffer to use. Do you often need to read or write
//! the content of the buffer? If so, use a `CpuBufferPool`. Otherwise, do you need to be able to
//! modify the content of the buffer after its initialization? If so, use a `DeviceLocalBuffer`.
//! If no to both questions, use an `ImmutableBuffer`.
//!
//! When deciding how your buffer is going to be used, don't forget that sometimes the best
//! solution is to manipulate multiple buffers instead. For example if you need to update a buffer's
//! content only from time to time, it may be a good idea to simply recreate a new `ImmutableBuffer`
//! every time.
//! Another example: if a buffer is under constant access by the GPU but you need to
//! read its content on the CPU from time to time, it may be a good idea to use a
//! `DeviceLocalBuffer` as the main buffer and a `CpuBufferPool` for when you need to read it.
//! Then whenever you need to read the main buffer, ask the GPU to copy from the device-local
//! buffer to the CPU buffer pool, and read the CPU buffer pool instead.
//!
//! # Buffers usage
//!
//! When you create a buffer object, you have to specify its *usage*. In other words, you have to
//! specify the way it is going to be used. Trying to use a buffer in a way that wasn't specified
//! when you created it will result in a runtime error.
//!
//! You can use buffers for the following purposes:
//!
//! - Can contain arbitrary data that can be transferred from/to other buffers and images.
//! - Can be read and modified from a shader.
//! - Can be used as a source of vertices and indices.
//! - Can be used as a source of list of models for draw indirect commands.
//!
//! Accessing a buffer from a shader can be done in the following ways:
//!
//! - As a uniform buffer. Uniform buffers are read-only.
//! - As a storage buffer. Storage buffers can be read and written.
//! - As a uniform texel buffer. Contrary to a uniform buffer, the data is interpreted by the
//!   GPU and can be for example normalized.
//! - As a storage texel buffer. Additionally, some data formats can be modified with atomic
//!   operations.
//!
//! Using uniform/storage texel buffers requires creating a *buffer view*. See the `view` module
//! for how to create a buffer view.
//!

pub use self::cpu_access::CpuAccessibleBuffer;
pub use self::cpu_pool::CpuBufferPool;
pub use self::device_local::DeviceLocalBuffer;
pub use self::immutable::ImmutableBuffer;
pub use self::slice::BufferSlice;
pub use self::sys::BufferCreationError;
pub use self::traits::BufferAccess;
pub use self::traits::BufferInner;
pub use self::traits::TypedBufferAccess;
pub use self::usage::BufferUsage;
pub use self::view::BufferView;
pub use self::view::BufferViewRef;

pub mod cpu_access;
pub mod cpu_pool;
pub mod device_local;
pub mod immutable;
pub mod sys;
pub mod view;

mod slice;
mod traits;
mod usage;
<|endoftext|>


<commit_before>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

use rand::distributions::{Sample, Range};
use rand::Rng;

use std::f64;
use std::mem;

use super::MCMove;

use types::{Matrix3, One};
use sys::{System, EnergyCache};

/// Monte Carlo move that changes the size of the simulation cell
pub struct Resize {
    /// Delta for translation of the box length
    delta: f64,
    /// Sampling range for volume scaling
    range: Range<f64>,
    /// System after applying changes to the simulation cell
    new_system: System,
    /// target pressure
    pressure: f64,
    /// largest cutoff diameter of potentials in `Interactions`
    maximum_cutoff: Option<f64>,
}

impl Resize {
    /// Create a new `Resize` move, with target pressure `pressure` and maximum
    /// displacement of `delta`.
    pub fn new(pressure: f64, delta: f64) -> Resize {
        assert!(delta > 0.0, "delta must be positive in Resize move");
        Resize {
            delta: delta,
            range: Range::new(-delta, delta),
            new_system: System::new(),
            pressure: pressure,
            maximum_cutoff: None,
        }
    }
}

impl MCMove for Resize {
    fn describe(&self) -> &str {
        "resizing of the cell"
    }

    fn setup(&mut self, system: &System) {
        // check if the cell is infinite
        if system.cell.is_infinite() {
            fatal_error!("Cannot use `Resize` move with infinite simulation cell.")
        }

        // Get the largest cutoff of all intermolecular interactions in the
        // system.
        self.maximum_cutoff = system.maximum_cutoff()
    }

    fn prepare(&mut self, system: &mut System, rng: &mut Box<Rng>) -> bool {
        let delta = self.range.sample(rng);

        // Copy the system: the proposed state will be stored here
        // TODO: we only need to store positions and the cell; all
        // other information stays the same.
        self.new_system = system.clone();

        let volume = system.volume();
        let scaling_factor = f64::cbrt((volume + delta) / volume);
        // Change the simulation cell
        self.new_system.cell.scale_mut(Matrix3::one() * scaling_factor);
        // Check the radius of the smallest inscribed sphere and compare to the
        // cut off distance.
        // Abort simulation when box gets smaller than twice the cutoff radius.
        if let Some(maximum_cutoff) = self.maximum_cutoff {
            if self.new_system.cell.lengths()
                                   .iter()
                                   .any(|&d| 0.5 * d <= maximum_cutoff) {
                fatal_error!(
                    "Tried to decrease the cell size but new size
                    conflicts with the cut off radius. \
                    Increase the number of particles to get rid of this problem."
                );
            }
        };

        // Loop over all molecules in the system.
        // We don't want to change the intramolecular distances
        // so we compute the translation vector of the center-of-mass
        // (com) of a molecule and apply it to all its particles.
        // Note that to do this, the com of a molecule *always* has
        // to reside inside the simulation cell.

        // TODO: Check if system.size == system.molecules().len
        // if that is the case, skip com computation since it is a
        // system without molecules.
        for (mi, molecule) in system
            .molecules()
            .iter()
            .enumerate() {
            let old_com = system.molecule_com(mi);
            let frac_com = system.cell.fractional(&old_com);
            // compute translation vector
            let delta_com =
                self.new_system.cell.cartesian(&frac_com) - old_com;
            // loop over all particles (indices) in the molecule
            for pi in molecule.iter() {
                self.new_system.particle_mut(pi).position += delta_com;
            }
        }
        true
    }

    fn cost(&self, system: &System, beta: f64, cache: &mut EnergyCache) -> f64 {
        let delta_energy = cache.move_all_rigid_molecules_cost(&self.new_system);
        let new_volume = self.new_system.volume();
        let old_volume = system.volume();
        let delta_volume = new_volume - old_volume;
        // Build and return the cost function.
        beta * (delta_energy + self.pressure * delta_volume) -
        (system.molecules().len() as f64) * f64::ln(new_volume / old_volume)
    }

    fn apply(&mut self, system: &mut System) {
        // Exchange systems: This will effectively update
        // new positions and cell.
        mem::swap(system, &mut self.new_system)
    }

    fn restore(&mut self, _: &mut System) {
        // Do nothing.
    }

    fn update_amplitude(&mut self, scaling_factor: Option<f64>) {
        if let Some(s) = scaling_factor {
            self.delta *= s;
            self.range = Range::new(-self.delta, self.delta);
        }
    }
}
<commit_msg>Only store the Configuration in resize<commit_after>// Cymbalum, an extensible molecular simulation engine
// Copyright (C) 2015-2016 G. Fraux — BSD license

use rand::distributions::{Sample, Range};
use rand::Rng;

use std::f64;
use std::mem;

use super::MCMove;

use types::{Matrix3, One};
use sys::{System, Configuration, EnergyCache};

/// Monte Carlo move that changes the size of the simulation cell
pub struct Resize {
    /// Delta for translation of the box length
    delta: f64,
    /// Sampling range for volume scaling
    range: Range<f64>,
    /// Configuration before applying changes to the simulation cell
    previous: Configuration,
    /// target pressure
    pressure: f64,
    /// largest cutoff diameter of potentials in `Interactions`
    maximum_cutoff: Option<f64>,
}

impl Resize {
    /// Create a new `Resize` move, with target pressure `pressure` and maximum
    /// displacement of `delta`.
    pub fn new(pressure: f64, delta: f64) -> Resize {
        assert!(delta > 0.0, "delta must be positive in Resize move");
        Resize {
            delta: delta,
            range: Range::new(-delta, delta),
            previous: Configuration::new(),
            pressure: pressure,
            maximum_cutoff: None,
        }
    }
}

impl MCMove for Resize {
    fn describe(&self) -> &str {
        "resizing of the cell"
    }

    fn setup(&mut self, system: &System) {
        // check if the cell is infinite
        if system.cell.is_infinite() {
            fatal_error!("Cannot use `Resize` move with infinite simulation cell.")
        }

        // Get the largest cutoff of all intermolecular interactions in the
        // system.
        self.maximum_cutoff = system.maximum_cutoff()
    }

    fn prepare(&mut self, system: &mut System, rng: &mut Box<Rng>) -> bool {
        let delta = self.range.sample(rng);

        // Store the previous configuration
        self.previous = (**system).clone();

        let volume = system.volume();
        let scaling_factor = f64::cbrt((volume + delta) / volume);
        // Change the simulation cell
        system.cell.scale_mut(Matrix3::one() * scaling_factor);
        // Check the radius of the smallest inscribed sphere and compare to the
        // cut off distance.
        // Abort simulation when box gets smaller than twice the cutoff radius.
        if let Some(maximum_cutoff) = self.maximum_cutoff {
            if system.cell.lengths().iter().any(|&d| 0.5 * d <= maximum_cutoff) {
                fatal_error!(
                    "Tried to decrease the cell size but new size
                    conflicts with the cut off radius. \
                    Increase the number of particles to get rid of this problem."
                );
            }
        };

        // Loop over all molecules in the system.
        // We don't want to change the intramolecular distances
        // so we compute the translation vector of the center-of-mass
        // (com) of a molecule and apply it to all its particles.
        // Note that to do this, the com of a molecule *always* has
        // to reside inside the simulation cell.

        // TODO: Check if system.size == system.molecules().len
        // if that is the case, skip com computation since it is a
        // system without molecules.
        for (mi, molecule) in self.previous.molecules().iter().enumerate() {
            let old_com = system.molecule_com(mi);
            let frac_com = system.cell.fractional(&old_com);
            // compute translation vector
            let delta_com = system.cell.cartesian(&frac_com) - old_com;
            // loop over all particles (indices) in the molecule
            for pi in molecule.iter() {
                system.particle_mut(pi).position += delta_com;
            }
        }
        true
    }

    fn cost(&self, system: &System, beta: f64, cache: &mut EnergyCache) -> f64 {
        let delta_energy = cache.move_all_rigid_molecules_cost(system);
        let new_volume = system.volume();
        let old_volume = self.previous.cell.volume();
        let delta_volume = new_volume - old_volume;
        // Build and return the cost function.
        beta * (delta_energy + self.pressure * delta_volume) -
        (system.molecules().len() as f64) * f64::ln(new_volume / old_volume)
    }

    fn apply(&mut self, _: &mut System) {
        // Nothing to do.
    }

    fn restore(&mut self, system: &mut System) {
        // Exchange configurations
        mem::swap(&mut **system, &mut self.previous)
    }

    fn update_amplitude(&mut self, scaling_factor: Option<f64>) {
        if let Some(s) = scaling_factor {
            self.delta *= s;
            self.range = Range::new(-self.delta, self.delta);
        }
    }
}
<|endoftext|>


<commit_before>use serde::de::{Deserialize, Deserializer};

use types::*;

/// This object represents an incoming update.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Update {
    /// The update‘s unique identifier. Update identifiers start from a certain
    /// positive number and increase sequentially.
    pub id: Integer,
    pub kind: UpdateKind,
}

/// Kind of incoming update.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum UpdateKind {
    /// New incoming message of any kind — text, photo, sticker, etc.
    Message(Message),
    /// New version of a message that is known to the bot and was edited
    EditedMessage(Message),
    /// New incoming channel post of any kind — text, photo, sticker, etc.
    ChannelPost(Message),
    /// New version of a channel post that is known to the bot and was edited
    EditedChannelPost(Message),
//    InlineQuery(InlineQuery),
//    ChosenInlineResult(ChosenInlineResult),
//    CallbackQuery(OptionCallbackQuery),
    #[doc(hidden)]
    Unknown(RawUpdate)
}

impl Deserialize for Update {
    fn deserialize<D>(deserializer: D) -> Result<Update, D::Error> where D: Deserializer {
        let raw: RawUpdate = Deserialize::deserialize(deserializer)?;
        macro_rules! maybe_field {
            ($name:ident, $variant:ident) => {{
                if let Some(val) = raw.$name {
                    return Ok(Update {
                        id: raw.update_id,
                        kind: UpdateKind::$variant(val),
                    })
                }
            }}
        }

        maybe_field!(message, Message);
        maybe_field!(edited_message, EditedMessage);
        maybe_field!(channel_post, ChannelPost);
        maybe_field!(edited_channel_post, EditedChannelPost);
//        maybe_field!(inline_query, InlineQuery);
//        maybe_field!(chosen_inline_result, ChosenInlineResult);
//        maybe_field!(callback_query, CallbackQuery);

        Ok(Update {
            id: raw.update_id,
            kind: UpdateKind::Unknown(raw),
        })
    }
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Deserialize)]
pub struct RawUpdate {
    /// The update‘s unique identifier. Update identifiers start from a certain
    /// positive number and increase sequentially.
    pub update_id: Integer,
    /// New incoming message of any kind — text, photo, sticker, etc.
    pub message: Option<Message>,
    /// New version of a message that is known to the bot and was edited
    pub edited_message: Option<Message>,
    /// New incoming channel post of any kind — text, photo, sticker, etc.
    pub channel_post: Option<Message>,
    /// New version of a channel post that is known to the bot and was edited
    pub edited_channel_post: Option<Message>,
//    pub inline_query: Option<InlineQuery>,
//    pub chosen_inline_result: Option<ChosenInlineResult>,
//    pub callback_query: Option<CallbackQuery>,
}
<commit_msg>docs: document update types<commit_after>use serde::de::{Deserialize, Deserializer};

use types::*;

/// This object represents an incoming update.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Update {
    /// The update‘s unique identifier. Update identifiers start from a certain
    /// positive number and increase sequentially.
    pub id: Integer,
    /// Kind of the incoming update.
    pub kind: UpdateKind,
}

/// Kind of the incoming update.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum UpdateKind {
    /// New incoming message of any kind — text, photo, sticker, etc.
    Message(Message),
    /// New version of a message that is known to the bot and was edited
    EditedMessage(Message),
    /// New incoming channel post of any kind — text, photo, sticker, etc.
    ChannelPost(Message),
    /// New version of a channel post that is known to the bot and was edited
    EditedChannelPost(Message),
//    InlineQuery(InlineQuery),
//    ChosenInlineResult(ChosenInlineResult),
//    CallbackQuery(OptionCallbackQuery),
    #[doc(hidden)]
    Unknown(RawUpdate)
}

impl Deserialize for Update {
    fn deserialize<D>(deserializer: D) -> Result<Update, D::Error> where D: Deserializer {
        let raw: RawUpdate = Deserialize::deserialize(deserializer)?;
        macro_rules! maybe_field {
            ($name:ident, $variant:ident) => {{
                if let Some(val) = raw.$name {
                    return Ok(Update {
                        id: raw.update_id,
                        kind: UpdateKind::$variant(val),
                    })
                }
            }}
        }

        maybe_field!(message, Message);
        maybe_field!(edited_message, EditedMessage);
        maybe_field!(channel_post, ChannelPost);
        maybe_field!(edited_channel_post, EditedChannelPost);
//        maybe_field!(inline_query, InlineQuery);
//        maybe_field!(chosen_inline_result, ChosenInlineResult);
//        maybe_field!(callback_query, CallbackQuery);

        Ok(Update {
            id: raw.update_id,
            kind: UpdateKind::Unknown(raw),
        })
    }
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Deserialize)]
pub struct RawUpdate {
    /// The update‘s unique identifier. Update identifiers start from a certain
    /// positive number and increase sequentially.
    pub update_id: Integer,
    /// New incoming message of any kind — text, photo, sticker, etc.
    pub message: Option<Message>,
    /// New version of a message that is known to the bot and was edited
    pub edited_message: Option<Message>,
    /// New incoming channel post of any kind — text, photo, sticker, etc.
    pub channel_post: Option<Message>,
    /// New version of a channel post that is known to the bot and was edited
    pub edited_channel_post: Option<Message>,
//    pub inline_query: Option<InlineQuery>,
//    pub chosen_inline_result: Option<ChosenInlineResult>,
//    pub callback_query: Option<CallbackQuery>,
}
<|endoftext|>


<commit_before>use pest::Parser;

use parser::{TeraParser, Rule};

macro_rules! assert_lex_rule {
    ($rule: expr, $input: expr) => {
        let res = TeraParser::parse_str($rule, $input);
        println!("{:?}", $input);
        println!("{:#?}", res);
        if res.is_err() {
            println!("{}", res.unwrap_err());
            panic!();
        }
        assert!(res.is_ok());
        assert_eq!(res.unwrap().last().unwrap().into_span().end(), $input.len());
    };
}

#[test]
fn lex_int() {
    let inputs = vec!["-10", "0", "100", "250000"];
    for i in inputs {
        assert_lex_rule!(Rule::int, i);
    }
}

#[test]
fn lex_float() {
    let inputs = vec!["123.5", "123.5", "0.1", "-1.1"];
    for i in inputs {
        assert_lex_rule!(Rule::float, i);
    }
}

#[test]
fn lex_string() {
    let inputs = vec!["\"Blabla\"", "\"123\"",
                      "\'123\'", "\'This is still a string\'",
                      "`this is backquted`", "`and this too`"
                ];
    for i in inputs {
        assert_lex_rule!(Rule::string, i);
    }
}

#[test]
fn lex_ident() {
    let inputs = vec!["hello", "hello_", "hello_1", "HELLO", "_1"];
    for i in inputs {
        assert_lex_rule!(Rule::ident, i);
    }

    assert!(TeraParser::parse_str(Rule::ident, "909").is_err());
}

#[test]
fn lex_dotted_ident() {
    let inputs = vec![
        "hello", "hello_", "hello_1", "HELLO", "_1", "hey.ho", "h", "ho",
        "hey.ho.hu", "hey.0", "h.u",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::dotted_ident, i);
    }

    let invalid_inputs = vec![".", "9.w"];
    for i in invalid_inputs {
        assert!(TeraParser::parse_str(Rule::dotted_ident, i).is_err());
    }
}

#[test]
fn lex_basic_expr() {
    let inputs = vec![
        "admin",
        "true",
        "macros::something()",
        "something()",
        r#""hey""#,
        "a is defined",
        "a is defined(2)",
        "1 + 1",
        "1 + counts",
        "1 + counts.first",
        "1 + 2 + 3 * 9/2 + 2.1",
        "(1 + 2 + 3) * 9/2 + 2.1",
        "10 * 2 % 5",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::basic_expr, i);
    }
}

#[test]
fn lex_comparison_val() {
    let inputs = vec![
        // all the basic expr still work
        "admin",
        "true",
        "macros::something()",
        "something()",
        r#""hey""#,
        "a is defined",
        "a is defined(2)",
        "1 + 1",
        "1 + counts",
        "1 + counts.first",
        "1 + 2 + 3 * 9/2 + 2.1",
        "(1 + 2 + 3) * 9/2 + 2.1",
        "10 * 2 % 5",
        // but now ones with filters also work
        "admin | upper",
        "admin | upper | round",
        "admin | upper | round(var=2)",
        "1.5 + a | round(var=2)",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::comparison_val, i);
    }
}

#[test]
fn lex_comparison_expr() {
    let inputs = vec![
        "1.5 + a | round(var=2) > 10",
        "1.5 + a | round(var=2) > a | round",
        "a == b",
        "a + 1 == b",
        "a != b",
        "a % 2 == 0",
        "a > b",
        "a >= b",
        "a < b",
        "a <= b",
        "true > false",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::comparison_expr, i);
    }
}

#[test]
fn lex_logic_val() {
    let inputs = vec![
        // all the basic expr still work
        "admin",
        "true",
        "macros::something()",
        "something()",
        r#""hey""#,
        "a is defined",
        "a is defined(2)",
        "1 + 1",
        "1 + counts",
        "1 + counts.first",
        "1 + 2 + 3 * 9/2 + 2.1",
        "(1 + 2 + 3) * 9/2 + 2.1",
        "10 * 2 % 5",
        // filters still work
        "admin | upper",
        "admin | upper | round",
        "admin | upper | round(var=2)",
        "1.5 + a | round(var=2)",
        // but now we can negate things
        "not true",
        "not admin",
        "not num + 1 == 0",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::logic_val, i);
    }
}

#[test]
fn lex_logic_expr() {
    let inputs = vec![
        "1.5 + a | round(var=2) > 10 and admin",
        "1.5 + a | round(var=2) > a | round or true",
        "1 > 0 and 2 < 3",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::logic_expr, i);
    }
}

#[test]
fn lex_kwarg() {
    let inputs = vec![
        "hello=1",
        "hello=1+1",
        "hello1=true",
        "hello=name",
        "hello=name|filter",
        "hello=name|filter(with_arg=true)",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::kwarg, i);
    }
}

#[test]
fn lex_kwargs() {
    let inputs = vec![
        "hello=1",
        "hello=1+1,hey=1",
        "hello1=true,name=name,admin=true",
        "hello=name",
        "hello=name|filter,id=1",
        "hello=name|filter(with_arg=true),id=1",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::kwargs, i);
    }
}

#[test]
fn lex_fn_call() {
    let inputs = vec![
        "fn(hello=1)",
        "fn(hello=1+1,hey=1)",
        "fn(hello1=true,name=name,admin=true)",
        "fn(hello=name)",
        "fn(hello=name|filter,id=1)",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::fn_call, i);
    }
}

#[test]
fn lex_filter() {
    let inputs = vec![
        "|attr",
        "|attr()",
        "|attr(key=1)",
        "|attr(key=1, more=true)",
        "|attr(key=1,more=true)",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::filter, i);
    }
}

#[test]
fn lex_macro_definition() {
    let inputs = vec![
        "hello()",
        "hello(name, admin)",
        "hello(name, admin=1)",
        "hello(name=\"bob\", admin)",
        "hello(name=\"bob\",admin=true)",
    ];
    for i in inputs {
        // The () are not counted as tokens for some reasons so can't use the macro
        assert!(TeraParser::parse_str(Rule::macro_fn, i).is_ok());
    }
}

#[test]
fn lex_test() {
    let inputs = vec![
        "a is defined",
        "a is defined()",
        "a is divisibleby(2)",
    ];
    for i in inputs {
        // The () are not counted as tokens for some reasons so can't use the macro
        assert!(TeraParser::parse_str(Rule::test, i).is_ok());
    }
}

#[test]
fn lex_include_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::include_tag,
            "{% include \"index.html\" %}"
        ).is_ok()
    );
}

#[test]
fn lex_import_macro_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::import_macro_tag,
            "{% import \"macros.html\" as macros %}"
        ).is_ok()
    );
}

#[test]
fn lex_extends_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::extends_tag,
            "{% extends \"index.html\" %}"
        ).is_ok()
    );
}

#[test]
fn lex_comment_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::comment_tag,
            "{# #comment# {{}} {%%} #}"
        ).is_ok()
    );
}

#[test]
fn lex_block_tag() {
    let inputs = vec![
        "{% block tag %}",
        "{% block my_block %}",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::block_tag, i);
    }
}

#[test]
fn lex_macro_tag() {
    let inputs = vec![
        "{%- macro tag() %}",
        "{% macro my_block(name) -%}",
        "{% macro my_block(name=42) %}",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::macro_tag, i);
    }
}

#[test]
fn lex_if_tag() {
    let inputs = vec![
        "{%- if name %}",
        "{% if true -%}",
        "{% if admin or show %}",
        "{% if 1 + 2 == 2 and true %}",
        "{% if 1 + 2 == 2 and admin is defined %}",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::if_tag, i);
    }
}

#[test]
fn lex_elif_tag() {
    let inputs = vec![
        "{%- elif name %}",
        "{% elif true -%}",
        "{% elif admin or show %}",
        "{% elif 1 + 2 == 2 and true %}",
        "{% elif 1 + 2 == 2 and admin is defined %}",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::elif_tag, i);
    }
}

#[test]
fn lex_else_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::else_tag,
            "{% else %}"
        ).is_ok()
    );
}

#[test]
fn lex_for_tag() {
    let inputs = vec![
        "{%- for a in array %}",
        "{% for a, b in object -%}",
        "{% for a, b in fn_call() %}",
        "{% for a in fn_call() %}",
        "{% for a,b in fn_call(with_args=true, name=name) %}",
        "{% for client in clients | slice(start=1, end=9) %}",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::for_tag, i);
    }
}

#[test]
fn lex_set_tag() {
    let inputs = vec![
        "{%- set a = true %}",
        "{% set a = object -%}",
        "{% set a = fn_call() %}",
        "{% set a = fn_call(with_args=true, name=name) %}",
        "{% set a = macros::fn_call(with_args=true, name=name) %}",
        "{% set a = var | caps %}",
        "{% set a = var +1 >= 2%}",
        "{% set_global a = var +1 >= 2%}",
        "{%- set_global a = var +1 >= 2 -%}",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::set_tag, i);
    }
}

#[test]
fn lex_variable_tag() {
    let inputs = vec![
        "{{ a }}",
        "{{ a | caps }}",
        "{{ \"hey\" }}",
        "{{ fn_call() }}",
        "{{ macros::fn() }}",
        "{{ name + 42 }}",
        "{{ loop.index + 1 }}",
        "{{ name is defined and name >= 42 }}",
        "{{ my_macros::macro1(hello=\"world\", foo=bar, hey=1+2) }}",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::variable_tag, i);
    }
}

#[test]
fn lex_content() {
    let inputs = vec![
        "some text",
        "{{ name }}",
        "{# comment #}",
        "{% filter upper %}hey{% endfilter %}",
        "{% filter upper() %}hey{% endfilter %}",
        "{% raw %}{{ hey }}{% endraw %}",
        "{% for a in b %}{{a}}{% endfor %}",
        "{% if i18n %}世界{% else %}world{% endif %}",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::content, i);
    }
}

#[test]
fn lex_template() {
    assert!(
        TeraParser::parse_str(
            Rule::template,
            "{# Greeter template #}
            Hello {% if i18n %}世界{% else %}world{% endif %}
            {% for country in countries %}
                {{ loop.index }}.{{ country }}
            {% endfor %}"
        ).is_ok()
    );
}
<commit_msg>Fix formatting of lexer test vec<commit_after>use pest::Parser;

use parser::{TeraParser, Rule};

macro_rules! assert_lex_rule {
    ($rule: expr, $input: expr) => {
        let res = TeraParser::parse_str($rule, $input);
        println!("{:?}", $input);
        println!("{:#?}", res);
        if res.is_err() {
            println!("{}", res.unwrap_err());
            panic!();
        }
        assert!(res.is_ok());
        assert_eq!(res.unwrap().last().unwrap().into_span().end(), $input.len());
    };
}

#[test]
fn lex_int() {
    let inputs = vec!["-10", "0", "100", "250000"];
    for i in inputs {
        assert_lex_rule!(Rule::int, i);
    }
}

#[test]
fn lex_float() {
    let inputs = vec!["123.5", "123.5", "0.1", "-1.1"];
    for i in inputs {
        assert_lex_rule!(Rule::float, i);
    }
}

#[test]
fn lex_string() {
    let inputs = vec![
        "\"Blabla\"", "\"123\"",
        "\'123\'", "\'This is still a string\'",
        "`this is backquted`", "`and this too`"
    ];
    for i in inputs {
        assert_lex_rule!(Rule::string, i);
    }
}

#[test]
fn lex_ident() {
    let inputs = vec!["hello", "hello_", "hello_1", "HELLO", "_1"];
    for i in inputs {
        assert_lex_rule!(Rule::ident, i);
    }

    assert!(TeraParser::parse_str(Rule::ident, "909").is_err());
}

#[test]
fn lex_dotted_ident() {
    let inputs = vec![
        "hello", "hello_", "hello_1", "HELLO", "_1", "hey.ho", "h", "ho",
        "hey.ho.hu", "hey.0", "h.u",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::dotted_ident, i);
    }

    let invalid_inputs = vec![".", "9.w"];
    for i in invalid_inputs {
        assert!(TeraParser::parse_str(Rule::dotted_ident, i).is_err());
    }
}

#[test]
fn lex_basic_expr() {
    let inputs = vec![
        "admin",
        "true",
        "macros::something()",
        "something()",
        r#""hey""#,
        "a is defined",
        "a is defined(2)",
        "1 + 1",
        "1 + counts",
        "1 + counts.first",
        "1 + 2 + 3 * 9/2 + 2.1",
        "(1 + 2 + 3) * 9/2 + 2.1",
        "10 * 2 % 5",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::basic_expr, i);
    }
}

#[test]
fn lex_comparison_val() {
    let inputs = vec![
        // all the basic expr still work
        "admin",
        "true",
        "macros::something()",
        "something()",
        r#""hey""#,
        "a is defined",
        "a is defined(2)",
        "1 + 1",
        "1 + counts",
        "1 + counts.first",
        "1 + 2 + 3 * 9/2 + 2.1",
        "(1 + 2 + 3) * 9/2 + 2.1",
        "10 * 2 % 5",
        // but now ones with filters also work
        "admin | upper",
        "admin | upper | round",
        "admin | upper | round(var=2)",
        "1.5 + a | round(var=2)",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::comparison_val, i);
    }
}

#[test]
fn lex_comparison_expr() {
    let inputs = vec![
        "1.5 + a | round(var=2) > 10",
        "1.5 + a | round(var=2) > a | round",
        "a == b",
        "a + 1 == b",
        "a != b",
        "a % 2 == 0",
        "a > b",
        "a >= b",
        "a < b",
        "a <= b",
        "true > false",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::comparison_expr, i);
    }
}

#[test]
fn lex_logic_val() {
    let inputs = vec![
        // all the basic expr still work
        "admin",
        "true",
        "macros::something()",
        "something()",
        r#""hey""#,
        "a is defined",
        "a is defined(2)",
        "1 + 1",
        "1 + counts",
        "1 + counts.first",
        "1 + 2 + 3 * 9/2 + 2.1",
        "(1 + 2 + 3) * 9/2 + 2.1",
        "10 * 2 % 5",
        // filters still work
        "admin | upper",
        "admin | upper | round",
        "admin | upper | round(var=2)",
        "1.5 + a | round(var=2)",
        // but now we can negate things
        "not true",
        "not admin",
        "not num + 1 == 0",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::logic_val, i);
    }
}

#[test]
fn lex_logic_expr() {
    let inputs = vec![
        "1.5 + a | round(var=2) > 10 and admin",
        "1.5 + a | round(var=2) > a | round or true",
        "1 > 0 and 2 < 3",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::logic_expr, i);
    }
}

#[test]
fn lex_kwarg() {
    let inputs = vec![
        "hello=1",
        "hello=1+1",
        "hello1=true",
        "hello=name",
        "hello=name|filter",
        "hello=name|filter(with_arg=true)",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::kwarg, i);
    }
}

#[test]
fn lex_kwargs() {
    let inputs = vec![
        "hello=1",
        "hello=1+1,hey=1",
        "hello1=true,name=name,admin=true",
        "hello=name",
        "hello=name|filter,id=1",
        "hello=name|filter(with_arg=true),id=1",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::kwargs, i);
    }
}

#[test]
fn lex_fn_call() {
    let inputs = vec![
        "fn(hello=1)",
        "fn(hello=1+1,hey=1)",
        "fn(hello1=true,name=name,admin=true)",
        "fn(hello=name)",
        "fn(hello=name|filter,id=1)",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::fn_call, i);
    }
}

#[test]
fn lex_filter() {
    let inputs = vec![
        "|attr",
        "|attr()",
        "|attr(key=1)",
        "|attr(key=1, more=true)",
        "|attr(key=1,more=true)",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::filter, i);
    }
}

#[test]
fn lex_macro_definition() {
    let inputs = vec![
        "hello()",
        "hello(name, admin)",
        "hello(name, admin=1)",
        "hello(name=\"bob\", admin)",
        "hello(name=\"bob\",admin=true)",
    ];
    for i in inputs {
        // The () are not counted as tokens for some reasons so can't use the macro
        assert!(TeraParser::parse_str(Rule::macro_fn, i).is_ok());
    }
}

#[test]
fn lex_test() {
    let inputs = vec![
        "a is defined",
        "a is defined()",
        "a is divisibleby(2)",
    ];
    for i in inputs {
        // The () are not counted as tokens for some reasons so can't use the macro
        assert!(TeraParser::parse_str(Rule::test, i).is_ok());
    }
}

#[test]
fn lex_include_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::include_tag,
            "{% include \"index.html\" %}"
        ).is_ok()
    );
}

#[test]
fn lex_import_macro_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::import_macro_tag,
            "{% import \"macros.html\" as macros %}"
        ).is_ok()
    );
}

#[test]
fn lex_extends_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::extends_tag,
            "{% extends \"index.html\" %}"
        ).is_ok()
    );
}

#[test]
fn lex_comment_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::comment_tag,
            "{# #comment# {{}} {%%} #}"
        ).is_ok()
    );
}

#[test]
fn lex_block_tag() {
    let inputs = vec![
        "{% block tag %}",
        "{% block my_block %}",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::block_tag, i);
    }
}

#[test]
fn lex_macro_tag() {
    let inputs = vec![
        "{%- macro tag() %}",
        "{% macro my_block(name) -%}",
        "{% macro my_block(name=42) %}",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::macro_tag, i);
    }
}

#[test]
fn lex_if_tag() {
    let inputs = vec![
        "{%- if name %}",
        "{% if true -%}",
        "{% if admin or show %}",
        "{% if 1 + 2 == 2 and true %}",
        "{% if 1 + 2 == 2 and admin is defined %}",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::if_tag, i);
    }
}

#[test]
fn lex_elif_tag() {
    let inputs = vec![
        "{%- elif name %}",
        "{% elif true -%}",
        "{% elif admin or show %}",
        "{% elif 1 + 2 == 2 and true %}",
        "{% elif 1 + 2 == 2 and admin is defined %}",
    ];
    for i in inputs {
        assert_lex_rule!(Rule::elif_tag, i);
    }
}

#[test]
fn lex_else_tag() {
    assert!(
        TeraParser::parse_str(
            Rule::else_tag,
            "{% else %}"
        ).is_ok()
    );
}

#[test]
fn lex_for_tag() {
    let inputs = vec![
        "{%- for a in array %}",
        "{% for a, b in object -%}",
        "{% for a, b in fn_call() %}",
        "{% for a in fn_call() %}",
        "{% for a,b in fn_call(with_args=true, name=name) %}",
        "{% for client in clients | slice(start=1, end=9) %}",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::for_tag, i);
    }
}

#[test]
fn lex_set_tag() {
    let inputs = vec![
        "{%- set a = true %}",
        "{% set a = object -%}",
        "{% set a = fn_call() %}",
        "{% set a = fn_call(with_args=true, name=name) %}",
        "{% set a = macros::fn_call(with_args=true, name=name) %}",
        "{% set a = var | caps %}",
        "{% set a = var +1 >= 2%}",
        "{% set_global a = var +1 >= 2%}",
        "{%- set_global a = var +1 >= 2 -%}",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::set_tag, i);
    }
}

#[test]
fn lex_variable_tag() {
    let inputs = vec![
        "{{ a }}",
        "{{ a | caps }}",
        "{{ \"hey\" }}",
        "{{ fn_call() }}",
        "{{ macros::fn() }}",
        "{{ name + 42 }}",
        "{{ loop.index + 1 }}",
        "{{ name is defined and name >= 42 }}",
        "{{ my_macros::macro1(hello=\"world\", foo=bar, hey=1+2) }}",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::variable_tag, i);
    }
}

#[test]
fn lex_content() {
    let inputs = vec![
        "some text",
        "{{ name }}",
        "{# comment #}",
        "{% filter upper %}hey{% endfilter %}",
        "{% filter upper() %}hey{% endfilter %}",
        "{% raw %}{{ hey }}{% endraw %}",
        "{% for a in b %}{{a}}{% endfor %}",
        "{% if i18n %}世界{% else %}world{% endif %}",
    ];

    for i in inputs {
        assert_lex_rule!(Rule::content, i);
    }
}

#[test]
fn lex_template() {
    assert!(
        TeraParser::parse_str(
            Rule::template,
            "{# Greeter template #}
            Hello {% if i18n %}世界{% else %}world{% endif %}
            {% for country in countries %}
                {{ loop.index }}.{{ country }}
            {% endfor %}"
        ).is_ok()
    );
}
<|endoftext|>