<commit_before>use std::cell::RefCell;
use std::cmp;
use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender};

use item::Item;
use key::Key;
use query::{Query, QueryEditor};
use screen::Screen;
use screen_data::ScreenData;

pub struct State {
    highlighted_row: usize,
    item_index: usize,
    last_items: RefCell<Arc<Vec<Item>>>,
    last_query_string: RefCell<Option<String>>,
    line_storage: LineStorage,
    query_editor: QueryEditor,
    screen: Screen,
}

pub enum StateInput {
    PutChunk(Vec<Arc<String>>),
    PutKey(Key),
}

pub enum StateReply {
    Complete(Option<Vec<Arc<String>>>),
}

impl State {
    pub fn new(screen: Screen) -> Self {
        State {
            highlighted_row: 0,
            item_index: 0,
            last_items: RefCell::new(Arc::new(Vec::new())),
            last_query_string: RefCell::new(None),
            line_storage: LineStorage::new(),
            query_editor: QueryEditor::new(),
            screen: screen,
        }
    }

    pub fn start(mut self, input_rx: Receiver<StateInput>, reply_tx: Sender<StateReply>) {
        loop {
            match input_rx.recv() {
                Ok(input) => {
                    let reply = self.process_input(input);
                    if let Some(reply) = reply {
                        reply_tx.send(reply).is_ok() || break;
                    }
                }
                Err(_) => break,
            }
        }
    }

    fn process_input(&mut self, input: StateInput) -> Option<StateReply> {
        use key::Key;
        use self::StateInput::*;
        use self::StateReply::*;
        match input {
            PutKey(Key::CtrlM) => {
                let sd = self.get_screen_data();
                return Some(Complete(sd.items.get(self.item_index+self.highlighted_row).and_then(|i| Some(vec![i.string.clone()]))));
            }
            PutKey(Key::CtrlN) => {
                self.move_highlight_forward();
                self.screen.update(self.get_screen_data());
            }
            PutKey(Key::CtrlP) => {
                self.move_highlight_backward();
                self.screen.update(self.get_screen_data());
            }
            PutKey(key) => {
                self.query_editor.put_key(key);
                let num_items = self.get_screen_data().items.len();
                self.highlighted_row = cmp::min(self.highlighted_row, cmp::max(num_items, 1) - 1);
                self.screen.update(self.get_screen_data());
            }
            PutChunk(chunk) => {
                self.line_storage.put_chunk(chunk);
                self.screen.update(self.get_screen_data());
            }
        }
        None
    }

    fn move_highlight_backward(&mut self) {
        let num_items = self.get_items().len();
        if num_items == 0 {
            self.highlighted_row = 0;
            return;
        }
        if self.highlighted_row == 0 {
            self.scroll_item_list_backward();
            return;
        }
        self.highlighted_row -= 1;
    }

    fn move_highlight_forward(&mut self) {
        let num_items = self.get_items().len();
        if num_items == 0 {
            self.highlighted_row = 0;
            return;
        }
        if self.highlighted_row >= self.screen.list_view_height() - 1 {
            self.scroll_item_list_forward();
            return;
        }
        self.highlighted_row += 1;
    }

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

    fn scroll_item_list_forward(&mut self) {
        let num_items = self.get_items().len();
        if self.item_index + self.screen.list_view_height() < num_items {
            self.item_index += 1;
        }
    }

    fn get_screen_data(&self) -> ScreenData {
        ScreenData {
            cursor_index: self.query_editor.cursor_position(),
            highlighted_row: self.highlighted_row,
            item_index: self.item_index,
            items: self.get_items(),
            query_string: Arc::new(self.query_editor.as_ref().to_string()),
            total_lines: self.line_storage.lines.len(),
        }
    }

    fn get_items(&self) -> Arc<Vec<Item>> {
        let last_qs = self.last_query_string.borrow();
        if last_qs.is_some() && last_qs.as_ref().unwrap() == self.query_editor.as_ref() {
            return self.last_items.borrow().clone();
        }
        drop(last_qs);
        let query = self.query_editor.query();
        let items = Arc::new(self.line_storage.find(&query));
        *self.last_items.borrow_mut() = items.clone();
        *self.last_query_string.borrow_mut() = Some(self.query_editor.as_ref().to_string());
        items
    }
}

pub struct LineStorage {
    lines: Vec<Arc<String>>,
}

impl LineStorage {
    pub fn new() -> Self {
        LineStorage {
            lines: Vec::new(),
        }
    }

    pub fn find(&self, query: &Query) -> Vec<Item> {
        self.lines.iter()
            .filter_map(|line| {
                if query.test(line) {
                    Some(Item::new(line.clone()))
                } else {
                    None
                }
            })
            .collect()
    }

    pub fn put_chunk(&mut self, chunk: Vec<Arc<String>>) {
        self.lines.extend(chunk);
    }
}
<commit_msg>Don't move highlight beyond end of list<commit_after>use std::cell::RefCell;
use std::cmp;
use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender};

use item::Item;
use key::Key;
use query::{Query, QueryEditor};
use screen::Screen;
use screen_data::ScreenData;

pub struct State {
    highlighted_row: usize,
    item_index: usize,
    last_items: RefCell<Arc<Vec<Item>>>,
    last_query_string: RefCell<Option<String>>,
    line_storage: LineStorage,
    query_editor: QueryEditor,
    screen: Screen,
}

pub enum StateInput {
    PutChunk(Vec<Arc<String>>),
    PutKey(Key),
}

pub enum StateReply {
    Complete(Option<Vec<Arc<String>>>),
}

impl State {
    pub fn new(screen: Screen) -> Self {
        State {
            highlighted_row: 0,
            item_index: 0,
            last_items: RefCell::new(Arc::new(Vec::new())),
            last_query_string: RefCell::new(None),
            line_storage: LineStorage::new(),
            query_editor: QueryEditor::new(),
            screen: screen,
        }
    }

    pub fn start(mut self, input_rx: Receiver<StateInput>, reply_tx: Sender<StateReply>) {
        loop {
            match input_rx.recv() {
                Ok(input) => {
                    let reply = self.process_input(input);
                    if let Some(reply) = reply {
                        reply_tx.send(reply).is_ok() || break;
                    }
                }
                Err(_) => break,
            }
        }
    }

    fn process_input(&mut self, input: StateInput) -> Option<StateReply> {
        use key::Key;
        use self::StateInput::*;
        use self::StateReply::*;
        match input {
            PutKey(Key::CtrlM) => {
                let sd = self.get_screen_data();
                return Some(Complete(sd.items.get(self.item_index+self.highlighted_row).and_then(|i| Some(vec![i.string.clone()]))));
            }
            PutKey(Key::CtrlN) => {
                self.move_highlight_forward();
                self.screen.update(self.get_screen_data());
            }
            PutKey(Key::CtrlP) => {
                self.move_highlight_backward();
                self.screen.update(self.get_screen_data());
            }
            PutKey(key) => {
                self.query_editor.put_key(key);
                let num_items = self.get_screen_data().items.len();
                self.highlighted_row = cmp::min(self.highlighted_row, cmp::max(num_items, 1) - 1);
                self.screen.update(self.get_screen_data());
            }
            PutChunk(chunk) => {
                self.line_storage.put_chunk(chunk);
                self.screen.update(self.get_screen_data());
            }
        }
        None
    }

    fn move_highlight_backward(&mut self) {
        let num_items = self.get_items().len();
        if num_items == 0 {
            self.highlighted_row = 0;
            return;
        }
        if self.highlighted_row == 0 {
            self.scroll_item_list_backward();
            return;
        }
        self.highlighted_row -= 1;
    }

    fn move_highlight_forward(&mut self) {
        let num_items = self.get_items().len();
        if num_items == 0 {
            self.highlighted_row = 0;
            return;
        }
        if self.highlighted_row >= num_items - 1 {
            return;
        }
        if self.highlighted_row >= self.screen.list_view_height() - 1 {
            self.scroll_item_list_forward();
            return;
        }
        self.highlighted_row += 1;
    }

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

    fn scroll_item_list_forward(&mut self) {
        let num_items = self.get_items().len();
        if self.item_index + self.screen.list_view_height() < num_items {
            self.item_index += 1;
        }
    }

    fn get_screen_data(&self) -> ScreenData {
        ScreenData {
            cursor_index: self.query_editor.cursor_position(),
            highlighted_row: self.highlighted_row,
            item_index: self.item_index,
            items: self.get_items(),
            query_string: Arc::new(self.query_editor.as_ref().to_string()),
            total_lines: self.line_storage.lines.len(),
        }
    }

    fn get_items(&self) -> Arc<Vec<Item>> {
        let last_qs = self.last_query_string.borrow();
        if last_qs.is_some() && last_qs.as_ref().unwrap() == self.query_editor.as_ref() {
            return self.last_items.borrow().clone();
        }
        drop(last_qs);
        let query = self.query_editor.query();
        let items = Arc::new(self.line_storage.find(&query));
        *self.last_items.borrow_mut() = items.clone();
        *self.last_query_string.borrow_mut() = Some(self.query_editor.as_ref().to_string());
        items
    }
}

pub struct LineStorage {
    lines: Vec<Arc<String>>,
}

impl LineStorage {
    pub fn new() -> Self {
        LineStorage {
            lines: Vec::new(),
        }
    }

    pub fn find(&self, query: &Query) -> Vec<Item> {
        self.lines.iter()
            .filter_map(|line| {
                if query.test(line) {
                    Some(Item::new(line.clone()))
                } else {
                    None
                }
            })
            .collect()
    }

    pub fn put_chunk(&mut self, chunk: Vec<Arc<String>>) {
        self.lines.extend(chunk);
    }
}
<|endoftext|>


<commit_before>use anymap::AnyMap;
use std::any::Any;
use std::collections::HashMap;

use Entity;
use EntityIterator;
use components::{ Parent, Children };

/// Keeps track of entities and their components.
pub struct World {
    next_idx: usize,
    next_uuid: usize,
    /// Lists every entity with it's uuid.
    /// A uuid of `0` means an inactive entity.
    active: Vec<usize>,
    reusable_idxs: Vec<usize>,
    /// List of all the components.
    components: Vec<AnyMap>,

    ent_remove: HashMap<usize, usize>,
    ent_changed: HashMap<usize, usize>,
}

impl World {
    pub fn new() -> World {
        World {
            next_idx: 0,
            next_uuid: 1,
            active: Vec::new(),
            reusable_idxs: Vec::new(),
            components: Vec::new(),

            ent_remove: HashMap::new(),
            ent_changed: HashMap::new(),
        }
    }

    /// Adds a new entity.
    /// Will reuse an idx if available, if not it will increment the idx counter and allocate
    /// space for the components.
    pub fn add_entity(&mut self) -> Entity {
        // Get the idx.
        let idx = match self.reusable_idxs.pop() {
            None => {
                // No reusable idxs, so make a new one.
                let idx = self.next_idx;
                self.next_idx += 1;
                // And add a new entry to the components vector.
                self.components.push(AnyMap::new());
                idx
            },
            Some(idx) => idx,
        };

        // Get the uuid.
        let uuid = self.next_uuid;
        self.next_uuid += 1;

        // Register the entity as active.
        if self.active.len() <= uuid {
            self.active.resize(uuid + 1, 0);
        }
        self.active[idx] = uuid;

        // Register the entity as recently changed.
        self.ent_changed.insert(idx, uuid);

        Entity { idx: idx, uuid: uuid }
    }

    /// Slates an entity for removal.
    /// The removal won't actually be done until `confirm_changes()` is called.
    pub fn remove_entity(&mut self, entity: Entity) {
        self.ent_remove.insert(entity.idx, entity.uuid);
    }

    /// Removes all entities currently slated for removal.
    /// Also clears the list of removed and changed entities.
    pub fn confirm_changes(&mut self) {
        // Remove all entities in the `remove` list.
        for (&idx, &uuid) in self.ent_remove.iter() {
            if self.is_valid_entity(&Entity{ idx: idx, uuid: uuid }) {
                self.active[idx] = 0;
                self.reusable_idxs.push(idx);
                // Clear the components associated with the entity.
                self.components[idx].clear();
            }
        }

        self.ent_remove.clear();
        self.ent_changed.clear();
    }

    /// Checks if an `Entity` reference is valid.
    pub fn is_valid_entity(&self, entity: &Entity) -> bool {
        match self.active.get(entity.idx) {
            Some(&uuid) => {
                uuid != 0 && entity.uuid == uuid
            },
            None => false,
        }
    }

    /// Returns the uuid currently associated with an entity index.
    /// Returns 0 for nonexistent entities.
    pub fn get_uuid(&self, idx: usize) -> usize {
        match self.active.get(idx) {
            Some(&uuid) => uuid,
            None => 0,
        }
    }

    /// Adds a new component to an entity.
    /// If the entity already had that component, that component is returned.
    /// Otherwise, `None` is returned.
    pub fn add_component<T: Any>(&mut self, entity: &Entity, component: T) -> Option<T> {
        if self.is_valid_entity(entity) {
            self.ent_changed.insert(entity.idx, entity.uuid);
            return self.components[entity.idx].insert(component);
        }
        None
    }

    /// Returns whether an entity has a specific component or not.
    pub fn has_component<T: Any>(&self, entity: &Entity) -> bool {
        if self.is_valid_entity(entity) {
            return self.components[entity.idx].contains::<T>();
        }
        false
    }

    /// Returns a reference to a component.
    /// If a component does not exist, but it does in the parent,
    /// the parent's component will be returned.
    pub fn get_component<T: Any>(&self, entity: &Entity) -> Option<&T> {
        if self.is_valid_entity(entity) {
            // See if the component is there, if so: return it.
            match self.components[entity.idx].get::<T>() {
                Some(T) => return Some(T),
                None => {
                    // This entity doesn't have the component.
                    // See if has inherited it from a parent.
                    let mut cur_ent = entity;
                    println!("start: {}, {}", cur_ent.idx, cur_ent.uuid);
                    loop  {
                        if self.is_valid_entity(cur_ent) {
                            if let Some(comp) = self.components[cur_ent.idx].get::<T>() {
                                return Some(comp);
                            }
                            if let Some(parent) = self.components[cur_ent.idx].get::<Parent>() {
                                let Parent(cur_ent) = *parent;
                                println!("parent: {}, {}", cur_ent.idx, cur_ent.uuid);
                            } else {
                                // No parents left.
                                break;
                            }
                        } else {
                            // Parent not valid.
                            break;
                        }
                    }
                }
            }
        }
        None
    }

    /// Returns a mutable reference to a component, if it exists.
    /// Mutable references won't be retreived from an entities parent,
    /// as this will easily lead to bugs that are very hard to debug.
    pub fn get_mut_component<T: Any>(&mut self, entity: &Entity) -> Option<&mut T> {
        if self.is_valid_entity(entity) {
            let comp = self.components[entity.idx].get_mut::<T>();

            return match comp {
                Some(val) => {
                    self.ent_changed.insert(entity.idx, entity.uuid);
                    Some(val)
                },
                None => None,
            }
        }
        None
    }

    /// Removes a component from an entity.
    /// Returning the component if it existed, or `None` if it didn't.
    pub fn remove_component<T: Any>(&mut self, entity: &Entity) -> Option<T> {
        if self.is_valid_entity(entity) {
            let res = self.components[entity.idx].remove::<T>();

            return match res {
                Some(res) => {
                    self.ent_changed.insert(entity.idx, entity.uuid);
                    Some(res)
                },
                None => None,
            }
        }
        None
    }

    /// Returns a lazy iterator for immutable acces to the entities.
    pub fn iterator(&self) -> EntityIterator {
        EntityIterator {
            active: &self.active,
            curr: 0,
        }
    }

    /// Returns a vector listing all the currently active entities.
    /// Can be used to iterate over all active entities while making changes to the world.
    pub fn list_entities(&self) -> Vec<Entity> {
        self.active.iter().enumerate()
            .filter(|&(_, &uuid)| uuid != 0)
            .map(|(idx, &uuid)| Entity{ idx: idx, uuid: uuid })
            .collect::<Vec<Entity>>()
    }

    /// Returns a vector listing all the entities currently slated for removal.
    pub fn list_removals(&self) -> Vec<Entity> {
        self.ent_remove.iter()
            .map(|(&idx, &uuid)| Entity{ idx: idx, uuid: uuid })
            .collect::<Vec<Entity>>()
    }

    /// Returns a vector listing all the entities that have changed since the last call of.
    /// `confirm_changes`.
    pub fn list_changes(&self) -> Vec<Entity> {
        self.ent_changed.iter()
            .map(|(&idx, &uuid)| Entity{ idx: idx, uuid: uuid })
            .collect::<Vec<Entity>>()
    }
}
<commit_msg>The `get_component()` now works properly with parenting.<commit_after>use anymap::AnyMap;
use std::any::Any;
use std::collections::HashMap;

use Entity;
use EntityIterator;
use components::{ Parent, Children };

/// Keeps track of entities and their components.
pub struct World {
    next_idx: usize,
    next_uuid: usize,
    /// Lists every entity with it's uuid.
    /// A uuid of `0` means an inactive entity.
    active: Vec<usize>,
    reusable_idxs: Vec<usize>,
    /// List of all the components.
    components: Vec<AnyMap>,

    ent_remove: HashMap<usize, usize>,
    ent_changed: HashMap<usize, usize>,
}

impl World {
    pub fn new() -> World {
        World {
            next_idx: 0,
            next_uuid: 1,
            active: Vec::new(),
            reusable_idxs: Vec::new(),
            components: Vec::new(),

            ent_remove: HashMap::new(),
            ent_changed: HashMap::new(),
        }
    }

    /// Adds a new entity.
    /// Will reuse an idx if available, if not it will increment the idx counter and allocate
    /// space for the components.
    pub fn add_entity(&mut self) -> Entity {
        // Get the idx.
        let idx = match self.reusable_idxs.pop() {
            None => {
                // No reusable idxs, so make a new one.
                let idx = self.next_idx;
                self.next_idx += 1;
                // And add a new entry to the components vector.
                self.components.push(AnyMap::new());
                idx
            },
            Some(idx) => idx,
        };

        // Get the uuid.
        let uuid = self.next_uuid;
        self.next_uuid += 1;

        // Register the entity as active.
        if self.active.len() <= uuid {
            self.active.resize(uuid + 1, 0);
        }
        self.active[idx] = uuid;

        // Register the entity as recently changed.
        self.ent_changed.insert(idx, uuid);

        Entity { idx: idx, uuid: uuid }
    }

    /// Slates an entity for removal.
    /// The removal won't actually be done until `confirm_changes()` is called.
    pub fn remove_entity(&mut self, entity: Entity) {
        self.ent_remove.insert(entity.idx, entity.uuid);
    }

    /// Removes all entities currently slated for removal.
    /// Also clears the list of removed and changed entities.
    pub fn confirm_changes(&mut self) {
        // Remove all entities in the `remove` list.
        for (&idx, &uuid) in self.ent_remove.iter() {
            if self.is_valid_entity(&Entity{ idx: idx, uuid: uuid }) {
                self.active[idx] = 0;
                self.reusable_idxs.push(idx);
                // Clear the components associated with the entity.
                self.components[idx].clear();
            }
        }

        self.ent_remove.clear();
        self.ent_changed.clear();
    }

    /// Checks if an `Entity` reference is valid.
    pub fn is_valid_entity(&self, entity: &Entity) -> bool {
        match self.active.get(entity.idx) {
            Some(&uuid) => {
                uuid != 0 && entity.uuid == uuid
            },
            None => false,
        }
    }

    /// Returns the uuid currently associated with an entity index.
    /// Returns 0 for nonexistent entities.
    pub fn get_uuid(&self, idx: usize) -> usize {
        match self.active.get(idx) {
            Some(&uuid) => uuid,
            None => 0,
        }
    }

    /// Adds a new component to an entity.
    /// If the entity already had that component, that component is returned.
    /// Otherwise, `None` is returned.
    pub fn add_component<T: Any>(&mut self, entity: &Entity, component: T) -> Option<T> {
        if self.is_valid_entity(entity) {
            self.ent_changed.insert(entity.idx, entity.uuid);
            return self.components[entity.idx].insert(component);
        }
        None
    }

    /// Returns whether an entity has a specific component or not.
    pub fn has_component<T: Any>(&self, entity: &Entity) -> bool {
        if self.is_valid_entity(entity) {
            return self.components[entity.idx].contains::<T>();
        }
        false
    }

    /// Returns a reference to a component.
    /// If a component does not exist, but it does in the parent,
    /// the parent's component will be returned.
    pub fn get_component<T: Any>(&self, entity: &Entity) -> Option<&T> {
        if self.is_valid_entity(entity) {
            // See if the component is there, if so: return it.
            match self.components[entity.idx].get::<T>() {
                Some(comp) => return Some(comp),
                None => {
                    // This entity doesn't have the component.
                    // See if has inherited it from a parent.
                    let mut cur_ent = *entity;
                    println!("start: {}, {}", cur_ent.idx, cur_ent.uuid);
                    loop  {
                        if self.is_valid_entity(&cur_ent) {
                            if let Some(comp) = self.components[cur_ent.idx].get::<T>() {
                                return Some(comp);
                            }
                            if let Some(&Parent(parent)) =
                                    self.components[cur_ent.idx].get::<Parent>() {
                                cur_ent = parent;
                                println!("parent: {}, {}", cur_ent.idx, cur_ent.uuid);
                            } else {
                                // No parents left.
                                break;
                            }
                        } else {
                            // Parent not valid.
                            break;
                        }
                    }
                }
            }
        }
        None
    }

    /// Returns a mutable reference to a component, if it exists.
    /// Mutable references won't be retreived from an entities parent,
    /// as this will easily lead to bugs that are very hard to debug.
    pub fn get_mut_component<T: Any>(&mut self, entity: &Entity) -> Option<&mut T> {
        if self.is_valid_entity(entity) {
            let comp = self.components[entity.idx].get_mut::<T>();

            return match comp {
                Some(val) => {
                    self.ent_changed.insert(entity.idx, entity.uuid);
                    Some(val)
                },
                None => None,
            }
        }
        None
    }

    /// Removes a component from an entity.
    /// Returning the component if it existed, or `None` if it didn't.
    pub fn remove_component<T: Any>(&mut self, entity: &Entity) -> Option<T> {
        if self.is_valid_entity(entity) {
            let res = self.components[entity.idx].remove::<T>();

            return match res {
                Some(res) => {
                    self.ent_changed.insert(entity.idx, entity.uuid);
                    Some(res)
                },
                None => None,
            }
        }
        None
    }

    /// Returns a lazy iterator for immutable acces to the entities.
    pub fn iterator(&self) -> EntityIterator {
        EntityIterator {
            active: &self.active,
            curr: 0,
        }
    }

    /// Returns a vector listing all the currently active entities.
    /// Can be used to iterate over all active entities while making changes to the world.
    pub fn list_entities(&self) -> Vec<Entity> {
        self.active.iter().enumerate()
            .filter(|&(_, &uuid)| uuid != 0)
            .map(|(idx, &uuid)| Entity{ idx: idx, uuid: uuid })
            .collect::<Vec<Entity>>()
    }

    /// Returns a vector listing all the entities currently slated for removal.
    pub fn list_removals(&self) -> Vec<Entity> {
        self.ent_remove.iter()
            .map(|(&idx, &uuid)| Entity{ idx: idx, uuid: uuid })
            .collect::<Vec<Entity>>()
    }

    /// Returns a vector listing all the entities that have changed since the last call of.
    /// `confirm_changes`.
    pub fn list_changes(&self) -> Vec<Entity> {
        self.ent_changed.iter()
            .map(|(&idx, &uuid)| Entity{ idx: idx, uuid: uuid })
            .collect::<Vec<Entity>>()
    }
}
<|endoftext|>


<commit_before>
use std::f32;
use std::num::Float;

use math::{LineSeg, Vec2, V2_ORIGIN};

pub struct World {
    _walls: Vec<Wall>,
}

#[derive(Copy)]
pub struct Wall {
    pub seg: LineSeg,
    pub height :f32,
}

pub struct RayCastResult {
    pub dist: f32,
    pub pos: Vec2,
    pub along: f32,
    pub height: f32,
}

pub fn temp() -> World {
    World {
        _walls: vec![
            Wall::new(-40.0, -40.0,  40.0, -40.0, 10.0),
            Wall::new( 40.0, -40.0,  40.0,  40.0, 10.0),
            Wall::new( 40.0,  40.0, -40.0,  40.0, 10.0),
            Wall::new(-40.0,  40.0, -40.0, -40.0, 10.0),
            Wall::new(-15.0, -15.0, -10.0, -15.0, 20.0),
            Wall::new(-10.0, -15.0, -10.0, -10.0, 20.0),
            Wall::new(-10.0, -10.0, -15.0, -10.0, 20.0),
            Wall::new(-15.0, -10.0, -15.0, -15.0, 20.0),
            Wall::new( 15.0,  15.0,  10.0,  15.0, 20.0),
            Wall::new( 10.0,  15.0,  10.0,  10.0, 20.0),
            Wall::new( 10.0,  10.0,  15.0,  10.0, 20.0),
            Wall::new( 15.0,  10.0,  15.0,  15.0, 20.0)
        ]
    }
}

pub static W_ZERO: Wall = Wall {
    seg: LineSeg {
        a: Vec2 { x: 0.0, y: 0.0 },
        b: Vec2 { x: 0.0, y: 0.0 },
    },
    height: 0.0,
};

impl Wall {
    pub fn new(x0: f32, y0: f32, x1: f32, y1: f32, height: f32) -> Wall {
        Wall {
            seg: LineSeg::new(x0, y0, x1, y1),
            height: height,
        }
    }
}

impl World {
    pub fn get_walls(&self) -> &[Wall] {
        self._walls.as_slice()
    }

    pub fn cast_ray(&self, pos: Vec2, angle: f32) -> Option<RayCastResult> {
        let ray = LineSeg::new(
            pos.x, pos.y,
            pos.x + 1000.0*Float::sin(angle),
            pos.y - 1000.0*Float::cos(angle)
        );

        let (d2, wall, t) = self._walls.iter()
            .filter_map(|&wall| ray.intersects_at(wall.seg).map(|t| (wall, t)))
            .fold((f32::MAX, W_ZERO, 0.0), |(s_d2, s_wall, s_t), (wall, t)| {
                let d2 = (pos - wall.seg.at(t)).get_length_sqr();
                if d2 < s_d2 { (d2, wall, t) } else { (s_d2, s_wall, s_t) }
            });

        if d2 < f32::MAX {
            Some(RayCastResult {
                dist: (pos - wall.seg.at(t)).get_length(),
                pos: wall.seg.at(t),
                along: wall.seg.get_length()*t,
                height: wall.height
            })
        } else {
            None
        }
    }
}
<commit_msg>Updated World struct to use wall in different sectors<commit_after>
use std::f32;
use std::num::Float;

use math::{LineSeg, Vec2, V2_ORIGIN};

pub struct World {
    _sectors: Vec<Sector>,
}

pub struct Sector {
    pub info: SectorInfo,
    pub walls: Vec<Wall>,
}

#[derive(Copy)]
pub struct SectorInfo {
    pub floor_elev: f32,
    pub ceiling_elev: f32,
}

#[derive(Copy)]
pub struct Wall {
    pub seg: LineSeg,
    pub portal: Option<(usize,usize)>, // (sector index, wall index) for matching wall in another sector.
}

pub struct RayCastResult {
    pub dist: f32,
    pub pos: Vec2,
    pub along: f32,
    pub height: f32,
}

#[derive(Copy)]
pub struct NewRayCastResult {
    pub dist: f32,
    pub along: f32,
    pub info: SectorInfo,
}

pub fn temp() -> World {
    World {
        _sectors: vec![
            Sector {
                info: SectorInfo {
                    floor_elev: 0.0,
                    ceiling_elev: 20.0,
                },
                walls: vec![
                    Wall::new(-40.0, -40.0,  40.0, -40.0, None),
                    Wall::new( 40.0, -40.0,  40.0,  40.0, None),
                    Wall::new( 40.0,  40.0, -40.0,  40.0, None),
                    Wall::new(-40.0,  40.0, -40.0, -40.0, None),
                    Wall::new(-15.0, -15.0, -10.0, -15.0, Some((1,0))),
                    Wall::new(-10.0, -15.0, -10.0, -10.0, Some((1,1))),
                    Wall::new(-10.0, -10.0, -15.0, -10.0, Some((1,2))),
                    Wall::new(-15.0, -10.0, -15.0, -15.0, Some((1,3))),
                    Wall::new( 15.0,  15.0,  10.0,  15.0, Some((2,0))),
                    Wall::new( 10.0,  15.0,  10.0,  10.0, Some((2,1))),
                    Wall::new( 10.0,  10.0,  15.0,  10.0, Some((2,2))),
                    Wall::new( 15.0,  10.0,  15.0,  15.0, Some((2,3)))
                ]
            },
            Sector {
                info: SectorInfo {
                    floor_elev: 5.0,
                    ceiling_elev: 20.0,
                },
                walls: vec![
                    Wall::new(-15.0, -15.0, -10.0, -15.0, Some((0,4))),
                    Wall::new(-10.0, -15.0, -10.0, -10.0, Some((0,5))),
                    Wall::new(-10.0, -10.0, -15.0, -10.0, Some((0,6))),
                    Wall::new(-15.0, -10.0, -15.0, -15.0, Some((0,7))),
                ]
            },
            Sector {
                info: SectorInfo {
                    floor_elev: 5.0,
                    ceiling_elev: 20.0,
                },
                walls: vec![
                    Wall::new(-15.0, -15.0, -10.0, -15.0, Some((0,8))),
                    Wall::new(-10.0, -15.0, -10.0, -10.0, Some((0,9))),
                    Wall::new(-10.0, -10.0, -15.0, -10.0, Some((0,10))),
                    Wall::new(-15.0, -10.0, -15.0, -15.0, Some((0,11))),
                ]
            }
        ]
    }
}

pub static W_ZERO: Wall = Wall {
    seg: LineSeg {
        a: Vec2 { x: 0.0, y: 0.0 },
        b: Vec2 { x: 0.0, y: 0.0 },
    },
    portal: None
};

impl Wall {
    pub fn new(x0: f32, y0: f32, x1: f32, y1: f32, portal: Option<(usize,usize)>) -> Wall {
        Wall {
            seg: LineSeg::new(x0, y0, x1, y1),
            portal: portal,
        }
    }
}

impl World {
    pub fn get_walls(&self) -> &[Wall] {
        self._sectors[0].walls.as_slice()
    }

    pub fn cast_ray(&self, pos: Vec2, angle: f32) -> Option<RayCastResult> {
        let ray = LineSeg::new(
            pos.x, pos.y,
            pos.x + 1000.0*Float::sin(angle),
            pos.y - 1000.0*Float::cos(angle)
        );

        let (d2, wall, t) = self._sectors[0].walls.iter()
            .filter_map(|&wall| ray.intersects_at(wall.seg).map(|t| (wall, t)))
            .fold((f32::MAX, W_ZERO, 0.0), |(s_d2, s_wall, s_t), (wall, t)| {
                let d2 = (pos - wall.seg.at(t)).get_length_sqr();
                if d2 < s_d2 { (d2, wall, t) } else { (s_d2, s_wall, s_t) }
            });

        if d2 < f32::MAX {
            Some(RayCastResult {
                dist: (pos - wall.seg.at(t)).get_length(),
                pos: wall.seg.at(t),
                along: wall.seg.get_length()*t,
                height: self._sectors[0].info.ceiling_elev
            })
        } else {
            None
        }
    }

    pub fn new_cast_ray(&self, pos: Vec2, angle: f32) -> Vec<NewRayCastResult> {
        vec![]
    }
}
<|endoftext|>


<commit_before>use std::fmt;

use crate::error::EncryptedCryptEncodingError;
use crate::error::ParseError;

use lazy_static::lazy_static;
use regex::Regex;
use rmp_serde;
use serde::{Deserialize, Serialize};

const BASE64_CONFIG: base64::Config = base64::STANDARD_NO_PAD;

const BEGIN_CRYPT_STR: &'static str = "BEGIN CRYPT";
const BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_STR: &'static str = ".e.";
const END_CRYPT_STR: &'static str = "END CRYPT";
const BEGIN_CRYPT_LEN: usize = BEGIN_CRYPT_STR.len();
const BEGIN_ENCRYPTED_CRYPT_LEN: usize =
    BEGIN_CRYPT_STR.len() + BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_STR.len();
const END_CRYPT_LEN: usize = END_CRYPT_STR.len();

lazy_static! {
    static ref IS_CRYPT_FILE_RE: Regex = Regex::new(r"(?i)BEGIN[\s\W\p{Punct}]*CRYPT").unwrap();
}

#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct EncryptedCryptBlock {
    pub algorithm: String,
    pub nonce: Vec<u8>,
    pub ciphertext: Vec<u8>,
}

impl EncryptedCryptBlock {
    pub fn from_str(input: &str) -> Result<Self, ParseError> {
        let input: String = input.chars().filter(|c| !c.is_whitespace()).collect();
        let trimmed_input = if input[..BEGIN_CRYPT_LEN]
            .to_uppercase()
            .starts_with(BEGIN_CRYPT_STR)
        {
            &input[BEGIN_ENCRYPTED_CRYPT_LEN..(input.len() - END_CRYPT_LEN)]
        } else {
            &input
        };
        let input_bytes = base64::decode_config(trimmed_input, BASE64_CONFIG)
            .map_err(|e| ParseError::Base64Decode(e))?;
        let block: EncryptedCryptBlock =
            rmp_serde::from_read(&*input_bytes).map_err(|e| ParseError::MessagePackDecode(e))?;

        Ok(block)
    }

    pub fn to_ascii_armor(&self) -> Result<String, EncryptedCryptEncodingError> {
        let mut buf = Vec::new();
        // TODO: extract to `fn to_msg_pack()`?
        self.serialize(&mut rmp_serde::Serializer::new(&mut buf))
            .map_err(|e| EncryptedCryptEncodingError::MessagePackEncode(e))?;

        let encoded = base64::encode_config(buf, BASE64_CONFIG);
        Ok(format!(
            "{}{}{}{}",
            BEGIN_CRYPT_STR, BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_STR, encoded, END_CRYPT_STR
        ))
    }
}

#[test]
fn test_parsing_encrypted_crypt_block() {
    let block = EncryptedCryptBlock {
        algorithm: "test_algo".to_string(),
        nonce: b"nonce".to_vec(),
        ciphertext: b"this is some good ciphertext".to_vec(),
    };
    let armored = block.to_ascii_armor().unwrap();

    let parsed = EncryptedCryptBlock::from_str(&armored).unwrap();

    assert_eq!(parsed, block);
}

#[derive(Debug, PartialEq)]
pub enum Block {
    Plaintext(String),
    UnencryptedCryptBlock(String),
    EncryptedCryptBlock(EncryptedCryptBlock),
}

impl Block {
    pub fn is_encrypted(&self) -> bool {
        match self {
            Block::Plaintext(_) | Block::UnencryptedCryptBlock(_) => false,
            Block::EncryptedCryptBlock(_) => true,
        }
    }
}

#[derive(Debug)]
pub struct CryptFile {
    pub blocks: Vec<Block>,
}

impl fmt::Display for CryptFile {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.blocks
            .iter()
            .map(|block| match block {
                Block::Plaintext(text) => write!(f, "{}", text),
                Block::UnencryptedCryptBlock(text) => {
                    write!(f, "{}\n{}\n{}", BEGIN_CRYPT_STR, text, END_CRYPT_STR)
                }
                Block::EncryptedCryptBlock(block) => {
                    let ascii_armored = block.to_ascii_armor().map_err(|e| fmt::Error)?;
                    write!(f, "{}", ascii_armored)
                }
            })
            .collect()
    }
}

impl CryptFile {
    pub fn is_crypt_file(contents: &str) -> bool {
        IS_CRYPT_FILE_RE.is_match(contents)
    }

    pub fn has_unencrypted_crypt_blocks(&self) -> bool {
        self.blocks.iter().any(|block| match block {
            Block::UnencryptedCryptBlock(_) => true,
            _ => false,
        })
    }

    pub fn from_str(contents: &str) -> Result<CryptFile, ParseError> {
        let mut blocks = Vec::new();

        // Replace with Regexes with case insensitive matching
        let crypt_block_starts: Vec<_> = contents.match_indices(BEGIN_CRYPT_STR).collect();
        let crypt_block_ends: Vec<_> = contents.match_indices(END_CRYPT_STR).collect();
        if crypt_block_starts.len() != crypt_block_ends.len() {
            return Err(ParseError::MismatchNumStartEndCryptBlocks);
        }

        if !crypt_block_starts.is_empty() && crypt_block_starts[0].0 != 0 {
            let first_crypt_block = crypt_block_starts[0].0;
            let plaintext = contents[0..first_crypt_block].to_string();
            blocks.push(Block::Plaintext(plaintext));
        }

        let mut prev_end = 0;
        for ((start_idx, _), (end_idx, _)) in crypt_block_starts
            .into_iter()
            .zip(crypt_block_ends.into_iter())
        {
            if end_idx < start_idx {
                return Err(ParseError::EndBeforeBegin(0));
            }
            if prev_end != 0 && prev_end > start_idx {
                return Err(ParseError::BeginBeforeEnd(0));
            }
            if prev_end != 0 {
                let plaintext = contents[(prev_end + END_CRYPT_STR.len())..start_idx].to_string();
                blocks.push(Block::Plaintext(plaintext));
            }

            let matching_contents = &contents[(start_idx + BEGIN_CRYPT_STR.len())..end_idx];
            let block =
                if matching_contents.starts_with(BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_STR) {
                    Block::EncryptedCryptBlock(EncryptedCryptBlock::from_str(
                        &matching_contents[BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_STR.len()..],
                    )?)
                } else {
                    Block::UnencryptedCryptBlock(matching_contents.trim().to_string())
                };
            blocks.push(block);
            prev_end = end_idx;
        }

        Ok(CryptFile { blocks })
    }
}

#[test]
fn test_from_str_unencrypted() {
    let contents = r#"hello worldBEGIN CRYPThelloworldencryptedEND CRYPTBEGIN CRYPTthisis a test\n\nEND CRYPT
"#;
    let parsed = CryptFile::from_str(contents).unwrap();
    dbg!(parsed);
}

// TODO: Add more test cases for errors
<commit_msg>text-crypt: some updates to parsing<commit_after>use std::fmt;

use crate::error::EncryptedCryptEncodingError;
use crate::error::ParseError;

use lazy_static::lazy_static;
use regex::Regex;
use rmp_serde;
use serde::{Deserialize, Serialize};

const BASE64_CONFIG: base64::Config = base64::STANDARD_NO_PAD;

const BEGIN_CRYPT_STR: &'static str = "BEGIN CRYPT";
const BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_STR: &'static str = ".e.";
const END_CRYPT_STR: &'static str = "END CRYPT";

const BEGIN_CRYPT_LEN: usize = BEGIN_CRYPT_STR.len();
const BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_LEN: usize =
    BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_STR.len();
const BEGIN_ENCRYPTED_CRYPT_LEN: usize =
    BEGIN_CRYPT_LEN + BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_LEN;
const END_CRYPT_LEN: usize = END_CRYPT_STR.len();

lazy_static! {
    static ref IS_CRYPT_FILE_RE: Regex = Regex::new(r"(?i)BEGIN[\s\W\p{Punct}]*CRYPT").unwrap();
}

#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct EncryptedCryptBlock {
    pub algorithm: String,
    pub nonce: Vec<u8>,
    pub ciphertext: Vec<u8>,
}

impl EncryptedCryptBlock {
    pub fn from_str(input: &str) -> Result<Self, ParseError> {
        let trimmed_input = if input[..BEGIN_CRYPT_LEN]
            .to_uppercase()
            .starts_with(BEGIN_CRYPT_STR)
        {
            &input[BEGIN_ENCRYPTED_CRYPT_LEN..(input.len() - END_CRYPT_LEN)]
        } else {
            &input
        };
        let trimmed_input: String = trimmed_input
            .chars()
            .filter(|c| !c.is_whitespace())
            .collect();
        let input_bytes = base64::decode_config(trimmed_input, BASE64_CONFIG)
            .map_err(|e| ParseError::Base64Decode(e))?;
        let block: EncryptedCryptBlock =
            rmp_serde::from_read(&*input_bytes).map_err(|e| ParseError::MessagePackDecode(e))?;

        Ok(block)
    }

    pub fn to_ascii_armor(&self) -> Result<String, EncryptedCryptEncodingError> {
        let mut buf = Vec::new();
        // TODO: extract to `fn to_msg_pack()`?
        self.serialize(&mut rmp_serde::Serializer::new(&mut buf))
            .map_err(|e| EncryptedCryptEncodingError::MessagePackEncode(e))?;

        let encoded = base64::encode_config(buf, BASE64_CONFIG);
        Ok(format!(
            "{}{}{}{}",
            BEGIN_CRYPT_STR, BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_STR, encoded, END_CRYPT_STR
        ))
    }
}

#[test]
fn test_parsing_encrypted_crypt_block() {
    let block = EncryptedCryptBlock {
        algorithm: "test_algo".to_string(),
        nonce: b"nonce".to_vec(),
        ciphertext: b"this is some good ciphertext".to_vec(),
    };
    let armored = block.to_ascii_armor().unwrap();

    let parsed = EncryptedCryptBlock::from_str(&armored).unwrap();

    assert_eq!(parsed, block);
}

#[derive(Debug, PartialEq)]
pub enum Block {
    Plaintext(String),
    UnencryptedCryptBlock(String),
    EncryptedCryptBlock(EncryptedCryptBlock),
}

impl Block {
    pub fn is_encrypted(&self) -> bool {
        match self {
            Block::Plaintext(_) | Block::UnencryptedCryptBlock(_) => false,
            Block::EncryptedCryptBlock(_) => true,
        }
    }
}

#[derive(Debug)]
pub struct CryptFile {
    pub blocks: Vec<Block>,
}

impl fmt::Display for CryptFile {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.blocks
            .iter()
            .map(|block| match block {
                Block::Plaintext(text) => write!(f, "{}", text),
                Block::UnencryptedCryptBlock(text) => {
                    write!(f, "{}\n{}\n{}", BEGIN_CRYPT_STR, text, END_CRYPT_STR)
                }
                Block::EncryptedCryptBlock(block) => {
                    let ascii_armored = block.to_ascii_armor().map_err(|e| fmt::Error)?;
                    write!(f, "{}", ascii_armored)
                }
            })
            .collect::<fmt::Result>()?;
        if let Some(Block::Plaintext(text)) = self.blocks.last() {
            if !text.ends_with('\n') {
                write!(f, "\n")?;
            }
        }
        Ok(())
    }
}

impl CryptFile {
    pub fn is_crypt_file(contents: &str) -> bool {
        IS_CRYPT_FILE_RE.is_match(contents)
    }

    pub fn has_unencrypted_crypt_blocks(&self) -> bool {
        self.blocks.iter().any(|block| match block {
            Block::UnencryptedCryptBlock(_) => true,
            _ => false,
        })
    }

    pub fn from_str(contents: &str) -> Result<CryptFile, ParseError> {
        let mut blocks = Vec::new();

        // Replace with Regexes with case insensitive matching
        let crypt_block_starts: Vec<_> = contents.match_indices(BEGIN_CRYPT_STR).collect();
        let crypt_block_ends: Vec<_> = contents.match_indices(END_CRYPT_STR).collect();
        if crypt_block_starts.len() != crypt_block_ends.len() {
            return Err(ParseError::MismatchNumStartEndCryptBlocks);
        }

        if !crypt_block_starts.is_empty() && crypt_block_starts[0].0 != 0 {
            let first_crypt_block = crypt_block_starts[0].0;
            let plaintext = contents[0..first_crypt_block].to_string();
            blocks.push(Block::Plaintext(plaintext));
        }

        let mut prev_end = 0;
        for ((start_idx, _), (end_idx, _)) in crypt_block_starts
            .into_iter()
            .zip(crypt_block_ends.into_iter())
        {
            if end_idx < start_idx {
                return Err(ParseError::EndBeforeBegin(0));
            }
            if prev_end != 0 && prev_end > start_idx {
                return Err(ParseError::BeginBeforeEnd(0));
            }
            if prev_end != 0 && (prev_end + END_CRYPT_LEN) < start_idx {
                let plaintext = contents[(prev_end + END_CRYPT_LEN)..start_idx].to_string();
                blocks.push(Block::Plaintext(plaintext));
            }

            let matching_contents = &contents[(start_idx + BEGIN_CRYPT_LEN)..end_idx];
            let block =
                if matching_contents.starts_with(BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_STR) {
                    Block::EncryptedCryptBlock(EncryptedCryptBlock::from_str(
                        &matching_contents[BEGIN_ENCRYPTED_CRYPT_ENCRYPTION_MARKER_LEN..],
                    )?)
                } else {
                    Block::UnencryptedCryptBlock(matching_contents.trim().to_string())
                };
            blocks.push(block);
            prev_end = end_idx;
        }

        if prev_end != contents.len() - 1 {
            let plaintext = &contents[(prev_end + END_CRYPT_LEN)..];
            blocks.push(Block::Plaintext(plaintext.to_string()));
        }

        Ok(CryptFile { blocks })
    }
}

#[test]
fn test_from_str_unencrypted() {
    let contents = r#"hello worldBEGIN CRYPThelloworldencryptedEND CRYPTBEGIN CRYPTthisis a test

END CRYPT
"#;
    let parsed = CryptFile::from_str(contents).unwrap();

    assert_eq!(
        parsed.blocks,
        vec![
            Block::Plaintext("hello world".to_string()),
            Block::UnencryptedCryptBlock("helloworldencrypted".to_string()),
            Block::UnencryptedCryptBlock("thisis a test".to_string()),
            Block::Plaintext("\n".to_string()),
        ]
    );
}

#[test]
fn test_plaintext_after_crypt() {
    let contents = r"hello worldBEGIN CRYPTthis is a crypt END CRYPT plaintext
BEGIN CRYPT
encrypted text
END CRYPT
ending plaintext";

    let parsed = CryptFile::from_str(contents).unwrap();

    assert_eq!(
        parsed.blocks,
        vec![
            Block::Plaintext("hello world".to_string()),
            Block::UnencryptedCryptBlock("this is a crypt".to_string()),
            Block::Plaintext(" plaintext\n".to_string()),
            Block::UnencryptedCryptBlock("encrypted text".to_string()),
            Block::Plaintext("\nending plaintext".to_string())
        ]
    );
}

// TODO: Add more test cases for errors
<|endoftext|>


<commit_before>use crate::error::ParseError;
use crate::Block;
use crate::CryptBlock;
use crate::END_DELIMITER_CONTAINS_REGEX;
use crate::END_DELIMITER_WHOLE_REGEX;
use crate::END_HEADER_CONTAINS_REGEX;
use crate::END_HEADER_WHOLE_REGEX;
use crate::START_DELIMITER_CONTAINS_REGEX;
use crate::START_DELIMITER_WHOLE_REGEX;
use crate::{CryptFile, START_DELIMITER};

use lazy_static::lazy_static;
use regex::Regex;
use regex::RegexSet;

lazy_static! {
    static ref START_RE: Regex = Regex::new(START_DELIMITER_WHOLE_REGEX).unwrap();
    static ref HEADER_RE: Regex = Regex::new(END_HEADER_WHOLE_REGEX).unwrap();
    static ref END_RE: Regex = Regex::new(END_DELIMITER_WHOLE_REGEX).unwrap();
    static ref ALL_DELIMITERS_CONTAINS_RE: RegexSet = RegexSet::new(&[
        START_DELIMITER_CONTAINS_REGEX,
        END_HEADER_CONTAINS_REGEX,
        END_DELIMITER_CONTAINS_REGEX
    ])
    .unwrap();
}

impl CryptFile {
    pub fn is_crypt_file(contents: &str) -> bool {
        contents.contains(START_DELIMITER.trim_matches('-'))
    }

    pub fn from_str(contents: &str) -> Result<CryptFile, ParseError> {
        let mut current = String::new();
        let mut current_crypt_block = None;
        let mut blocks = Vec::new();

        for (line_idx, line) in contents.lines().enumerate() {
            let line_num = line_idx + 1;
            if START_RE.is_match(line) {
                blocks.push(Block::Plaintext(current));
                current = String::new();
                current_crypt_block = Some(CryptBlock::default());
            } else if HEADER_RE.is_match(line) {
                let header: Vec<_> = current.split(";").collect();
                if header.len() != 2 {
                    return Err(ParseError::InvalidHeader(line_num));
                }
                if let Some(current_crypt_block) = current_crypt_block.as_mut() {
                    if current_crypt_block.algorithm.is_some()
                        || current_crypt_block.nonce.is_some()
                    {
                        return Err(ParseError::MultipleHeaders(line_num));
                    }
                    current_crypt_block.algorithm = Some(header[0].to_string());
                    current_crypt_block.nonce = Some(header[1].trim().to_string());
                } else {
                    return Err(ParseError::EndHeaderWithNoStart(line_num));
                }
                current = String::new();
            } else if END_RE.is_match(line) {
                if current.trim().is_empty() {
                    return Err(ParseError::EmptyCryptBlock(line_num));
                }
                if let Some(mut current_crypt_block) = current_crypt_block {
                    current_crypt_block.ciphertext = current.trim_end().to_string();
                    blocks.push(Block::Crypt(current_crypt_block));
                } else {
                    return Err(ParseError::EndWithNoStart(line_num));
                }
                current = String::new();
                current_crypt_block = None;
            } else if ALL_DELIMITERS_CONTAINS_RE.is_match(line) {
                return Err(ParseError::DelimiterWithAdditionalText(line_num));
            } else {
                current.push_str(line);
                current.push('\n');
            }
        }

        if current_crypt_block.is_some() {
            return Err(ParseError::StartWithNoEnd);
        }
        if !current.trim().is_empty() {
            blocks.push(Block::Plaintext(current));
        }

        Ok(CryptFile { blocks })
    }
}

#[test]
fn test_parse_file() {
    let contents = r#"hello this is a test
test
testing
    ---BEGIN CRYPT---
hello
    ---END CRYPT---
blahblahblah
"#;

    let crypt_file = CryptFile::from_str(&contents).unwrap();
    assert_eq!(crypt_file.blocks.len(), 3);
    assert_eq!(
        crypt_file.blocks,
        vec![
            Block::Plaintext("hello this is a test\ntest\ntesting\n".to_string()),
            Block::Crypt(CryptBlock {
                algorithm: None,
                nonce: None,
                ciphertext: "hello\n".to_string()
            }),
            Block::Plaintext("blahblahblah\n".to_string())
        ]
    );
}
<commit_msg>text-crypt: Fixed parsing bugs<commit_after>use crate::error::ParseError;
use crate::Block;
use crate::CryptBlock;
use crate::CryptFile;
use crate::END_DELIMITER_CONTAINS_REGEX;
use crate::END_DELIMITER_WHOLE_REGEX;
use crate::END_HEADER_CONTAINS_REGEX;
use crate::END_HEADER_WHOLE_REGEX;
use crate::START_DELIMITER_CONTAINS_REGEX;
use crate::START_DELIMITER_WHOLE_REGEX;

use lazy_static::lazy_static;
use regex::Regex;
use regex::RegexSet;

lazy_static! {
    static ref START_RE: Regex = Regex::new(START_DELIMITER_WHOLE_REGEX).unwrap();
    static ref HEADER_RE: Regex = Regex::new(END_HEADER_WHOLE_REGEX).unwrap();
    static ref END_RE: Regex = Regex::new(END_DELIMITER_WHOLE_REGEX).unwrap();
    static ref ALL_DELIMITERS_CONTAINS_RE: RegexSet = RegexSet::new(&[
        START_DELIMITER_CONTAINS_REGEX,
        END_HEADER_CONTAINS_REGEX,
        END_DELIMITER_CONTAINS_REGEX
    ])
    .unwrap();
}

impl CryptFile {
    pub fn is_crypt_file(contents: &str) -> bool {
        ALL_DELIMITERS_CONTAINS_RE.is_match(contents)
    }

    pub fn from_str(contents: &str) -> Result<CryptFile, ParseError> {
        let mut current = String::new();
        let mut current_crypt_block = None;
        let mut blocks = Vec::new();

        for (line_idx, line) in contents.lines().enumerate() {
            let line_num = line_idx + 1;
            if START_RE.is_match(line.trim()) {
                if !current.is_empty() {
                    blocks.push(Block::Plaintext(current));
                }
                current = String::new();
                current_crypt_block = Some(CryptBlock::default());
            } else if HEADER_RE.is_match(line.trim()) {
                let header: Vec<_> = current.split(";").collect();
                if header.len() != 2 {
                    return Err(ParseError::InvalidHeader(line_num));
                }
                if let Some(current_crypt_block) = current_crypt_block.as_mut() {
                    if current_crypt_block.algorithm.is_some()
                        || current_crypt_block.nonce.is_some()
                    {
                        return Err(ParseError::MultipleHeaders(line_num));
                    }
                    current_crypt_block.algorithm = Some(header[0].to_string());
                    current_crypt_block.nonce = Some(header[1].trim().to_string());
                } else {
                    return Err(ParseError::EndHeaderWithNoStart(line_num));
                }
                current = String::new();
            } else if END_RE.is_match(line.trim()) {
                if current.trim().is_empty() {
                    return Err(ParseError::EmptyCryptBlock(line_num));
                }
                if let Some(mut current_crypt_block) = current_crypt_block {
                    current_crypt_block.ciphertext = current.trim_end().to_string();
                    blocks.push(Block::Crypt(current_crypt_block));
                } else {
                    return Err(ParseError::EndWithNoStart(line_num));
                }
                current = String::new();
                current_crypt_block = None;
            } else if ALL_DELIMITERS_CONTAINS_RE.is_match(line) {
                return Err(ParseError::DelimiterWithAdditionalText(line_num));
            } else {
                current.push_str(line);
                current.push('\n');
            }
        }

        if current_crypt_block.is_some() {
            return Err(ParseError::StartWithNoEnd);
        }
        if !current.trim().is_empty() {
            blocks.push(Block::Plaintext(current));
        }

        Ok(CryptFile { blocks })
    }
}

#[test]
fn test_parse_file() {
    let contents = r#"hello this is a test
test
testing
    ---BEGIN CRYPT---
hello
    ---END CRYPT---
blahblahblah
"#;

    let crypt_file = CryptFile::from_str(&contents).unwrap();
    assert_eq!(crypt_file.blocks.len(), 3);
    assert_eq!(
        crypt_file.blocks,
        vec![
            Block::Plaintext("hello this is a test\ntest\ntesting\n".to_string()),
            Block::Crypt(CryptBlock {
                algorithm: None,
                nonce: None,
                ciphertext: "hello".to_string()
            }),
            Block::Plaintext("blahblahblah\n".to_string())
        ]
    );
}

#[test]
fn test_parse_file2() {
    let contents = r"---BEGIN_CRYPT--
testhello
---END CRYPT---
";
    let crypt_file = CryptFile::from_str(contents).unwrap();
    assert_eq!(crypt_file.blocks.len(), 1);
    assert_eq!(
        crypt_file.blocks,
        vec![Block::Crypt(CryptBlock {
            ciphertext: "testhello".to_string(),
            ..Default::default()
        })]
    );
}
<|endoftext|>


<commit_before>// print_vec takes an immutable_slice. The elements in the slice are not changeable.
fn print_vec(slice: &[i32]) {
    // Won't compile.
    // slice[0] = 20;

    for (idx, elem) in slice.iter().enumerate() {
        println!("vec[{}] = {}", idx, elem);
    }
}

// We can also get a mutable slice, where we can change the elements.
fn pass_mutable_slice(slice: &mut [i32]) {
    slice[0] *= 100;
}

pub fn run() {
    println!("********* vec<i32> examples *********");

    // Create using ctor and type inference.
    let mut vec = Vec::new();
    vec.push(1);

    // Create using a macro.
    let mut vec = vec![10, 20, 30, 40, 50];

    // If a function does not need to add, remove or change elements, then pass an immutable slice.
    println!("Slicing the entire vector...");
    print_vec(&vec);
    println!("Slicing the first four elements...");
    print_vec(&vec[0..4]);

    vec.truncate(2);
    println!("Truncating to length of 2...");
    print_vec(&vec);

    // These two calls are equivalent.
    pass_mutable_slice(&mut vec);
    pass_mutable_slice(vec.as_mut_slice());

    println!("After mutating a slice...");
    print_vec(&vec);

    // Summary
    //     &vec is equivalent to vec.as_slice() and yields an immutable slice
    //     &mut vec is equivalent to vec.as_mut_slice() and yields a mutable slice.

    vec.insert(0, 50);              // Insert an element at index = 0.
    let elem = vec.remove(1);       // Remove the element at index = 1.
    println!("After insert and remove...");
    print_vec(&vec);

    // Reinitialize.
    let mut vec = vec![10, 20, 30, 40, 50];

    println!("After retaining only elements matching a predicate...");
    vec.retain(|&elem| elem == 20 || elem == 40);
    print_vec(&vec);

    // Try that again, using a lambda for the predicate.
    // The two predicates are the same. Not sure why.
    let mut vec = vec![10, 20, 30, 40, 50];
    let pred = |elem: &i32| *elem == 20 || *elem == 40;
    let pred = |&elem: &i32| elem == 20 || elem == 40;
    vec.retain(&pred);
    println!("After retaining only elements matching a predicate (lambda)...");
    print_vec(&vec);

    // Negating the predicate, not sure if this is the best way.
    vec.retain(|&elem| !pred(&elem));

    // Add an element to the end.
    vec.push(555);

    // Remove the last element. Returns Option<T>: None if the vec is empty.
    let elem = vec.pop().unwrap();

    // We can append a vec, but it does a 'move' of all the elements from the vec2 we are appending.
    let mut vec = vec![10, 20, 30, 40, 50];
    println!("vec before append of vec2...");
    print_vec(&vec);

    let mut vec2 = vec![-10, -20, -30];
    vec.append(&mut vec2);

    println!("vec after append of vec2...");
    print_vec(&vec);

    println!("vec2 after append to vec (it's empty)...");
    print_vec(&vec2);
    println!("See!");

    // We have a lot of methods from come from slices, because vectors implement "Deref<Target = [T]>"
    vec.reverse();
    vec.reverse();

    // drain allows us to remove slices of vectors.
    let removed: Vec<_> = vec.drain(2..5).collect();
    println!("vec after draining 2..5 ...");
    print_vec(&vec);
    println!("The items drained...");
    print_vec(&removed);

    // Clear is easy enough.
    vec.clear();

    // split_off allows us to split a vector into two. Half-empty range, as usual.
    let mut vec = vec![10, 20, 30, 40, 50];
    let vec2 = vec.split_off(2);
    assert_eq!(vec, [10, 20]);
    assert_eq!(vec2, [30, 40, 50]);

    // Change length to 5, fill with value of 4.
    vec.resize(5, 4);
    println!("vec after resizing and filling with a value of 4 ...");
    print_vec(&vec);

    vec.extend_from_slice(&[100, 200]);
    println!("vec after extend_from_slice ...");
    print_vec(&vec);

    let mut vec = vec![1, 2, 2, 3, 2];
    println!("vec before dedup ...");
    print_vec(&vec);
    vec.dedup();
    println!("vec after dedup (note there is dedup_by_key as well)...");
    print_vec(&vec);

    println!("vec = {:?}", &vec);;
}
<commit_msg>Rust: print out the vector using its built in debug format trait.<commit_after>// print_vec takes an immutable_slice. The elements in the slice are not changeable.
fn pass_immutable_slice(slice: &[i32]) {
    // Won't compile.
    // slice[0] = 20;
}

// We can also get a mutable slice, where we can change the elements.
fn pass_mutable_slice(slice: &mut [i32]) {
    slice[0] *= 100;
}

pub fn run() {
    println!("********* vec<i32> examples *********");

    // Create using ctor and type inference.
    let mut vec = Vec::new();
    vec.push(1);
    // Remove the last element. Returns Option<T>: None if the vec is empty.
    let elem = vec.pop().unwrap();

    // Create using a macro.
    let mut vec = vec![10, 20, 30, 40, 50];

    // If a function does not need to add, remove or change elements, then pass an immutable slice.
    pass_immutable_slice(&vec);
    pass_immutable_slice(&vec[0..4]);

    vec.truncate(2);
    println!("vec after truncating to length of 2: {:?}", &vec);

    // These two calls are equivalent.
    pass_mutable_slice(&mut vec);
    pass_mutable_slice(vec.as_mut_slice());

    println!("vec after mutating a slice: {:?}", &vec);

    // Summary
    //     &vec is equivalent to vec.as_slice() and yields an immutable slice
    //     &mut vec is equivalent to vec.as_mut_slice() and yields a mutable slice.

    vec.insert(0, 50);              // Insert an element at index = 0.
    let elem = vec.remove(1);       // Remove the element at index = 1.
    println!("After insert and remove: {:?}", &vec);

    // Reinitialize.
    let mut vec = vec![10, 20, 30, 40, 50];
    vec.retain(|&elem| elem == 20 || elem == 40);

    println!("After retaining only elements matching a predicate: {:?}", &vec);

    // Try that again, using a lambda for the predicate.
    // The two predicates are the same. Not sure why.
    let mut vec = vec![10, 20, 30, 40, 50];
    let pred = |elem: &i32| *elem == 20 || *elem == 40;
    let pred = |&elem: &i32| elem == 20 || elem == 40;
    vec.retain(&pred);
    println!("After retaining only elements matching a predicate (lambda): {:?}", &vec);

    // Negating the predicate, not sure if this is the best way.
    vec.retain(|&elem| !pred(&elem));

    // We can append a vec, but it does a 'move' of all the elements from the vec2 we are appending.
    let mut vec = vec![10, 20, 30, 40, 50];
    println!("vec before append of vec2: {:?}", &vec);
    let mut vec2 = vec![-10, -20, -30];
    vec.append(&mut vec2);
    println!("vec after append of vec2: {:?}", &vec);

    println!("vec2 after append to vec (it's empty): {:?}", &vec2);

    // We have a lot of methods from come from slices, because vectors implement "Deref<Target = [T]>"
    vec.reverse();
    vec.reverse();

    // drain allows us to remove slices of vectors.
    let removed: Vec<_> = vec.drain(2..5).collect();
    println!("vec after draining elements 2..5: {:?}", &vec);
    println!("The items drained: {:?}", &removed);

    // Clear is easy enough.
    vec.clear();

    // split_off allows us to split a vector into two. Half-empty range, as usual.
    let mut vec = vec![10, 20, 30, 40, 50];
    let vec2 = vec.split_off(2);
    assert_eq!(vec, [10, 20]);
    assert_eq!(vec2, [30, 40, 50]);

    // Change length to 5, fill with value of 4.
    vec.resize(5, 4);
    println!("vec after resizing and filling with a value of 4: {:?}", &vec);

    vec.extend_from_slice(&[100, 200]);
    println!("vec after extend_from_slice: {:?}", &vec);

    let mut vec = vec![1, 2, 2, 3, 2];
    println!("vec before dedup: {:?}", &vec);
    vec.dedup();
    println!("vec after dedup (note there is dedup_by_key as well): {:?}", &vec);
}
<|endoftext|>


<commit_before>use context::Context;
use get;
use std::default::Default;
use types::Type;
use types::kind::*;
macro_rules! test_compile(
    ($ty:ty, $test_name:ident, $kind:expr) => (
        #[test]
        fn $test_name() {
            let default_value:$ty = Default::default();
            Context::new().build_func(get::<fn() -> $ty>(), |func| {
                let ref val = func.insn_of(&default_value);
                assert!(val.get_type().get_kind() == $kind);
                func.insn_return(val);
            }).with(|func: extern fn(()) -> $ty| {
                assert_eq!(func(()), default_value);
            });
        }
    );
)
type SQRT = extern fn(uint) -> uint;
#[test]
fn test_sqrt() {
    println!("Square root");
    Context::new().build_func(get::<SQRT>(), |func| {
        let ref arg = func[0];
        assert_eq!(arg.get_type(), get::<uint>());
        let sqrt_arg = func.insn_sqrt(arg);
        let sqrt_arg_ui = func.insn_convert(&sqrt_arg, get::<uint>(), false);
        func.insn_return(&sqrt_arg_ui);
    }).with(|sqrt: SQRT| {
        assert_eq!(sqrt(64), 8);
        assert_eq!(sqrt(16), 4);
        assert_eq!(sqrt(9), 3);
        assert_eq!(sqrt(4), 2);
        assert_eq!(sqrt(1), 1);
    });
}
#[test]
fn test_struct() {
     println!("Struct");
    ::init();
    let pos_t = jit!(struct {
        "x": f64,
        "y": f64
    });
    for (i, field) in pos_t.fields().enumerate() {
        assert_eq!(field.get_type(), get::<f64>());
        assert_eq!(field.get_name().unwrap()[], match i {
            0 => "x",
            1 => "y",
            _ => unimplemented!()
        })
    }
}

test_compile!((), test_compile_void, Void)
test_compile!(f64, test_compile_f64, Float64)
test_compile!(f32, test_compile_f32, Float32)
test_compile!(int, test_compile_int, NInt)
test_compile!(uint, test_compile_uint, NUInt)
test_compile!(i32, test_compile_i32, Int)
test_compile!(u32, test_compile_u32, UInt)
test_compile!(i16, test_compile_i16, Short)
test_compile!(u16, test_compile_u16, UShort)
test_compile!(i8, test_compile_i8, SByte)
test_compile!(u8, test_compile_u8, UByte)
<commit_msg>Use `assert_eq` instead of `assert`<commit_after>use context::Context;
use get;
use std::default::Default;
use types::Type;
use types::kind::*;
use Function;
macro_rules! test_compile(
    ($ty:ty, $test_name:ident, $kind:expr) => (
        #[test]
        fn $test_name() {
            let default_value:$ty = Default::default();
            Context::new().build_func(get::<fn() -> $ty>(), |func| {
                let ref val = func.insn_of(&default_value);
                assert_eq!(val.get_type().get_kind(), $kind);
                func.insn_return(val);
            }).with(|func: extern fn(()) -> $ty| {
                assert_eq!(func(()), default_value);
            });
        }
    );
)
type SQRT = extern fn(uint) -> uint;
#[test]
fn test_sqrt() {
    Context::new().build_func(get::<SQRT>(), |func| {
        let ref arg = func[0];
        assert_eq!(arg.get_type(), get::<uint>());
        let sqrt_arg = func.insn_sqrt(arg);
        let sqrt_arg_ui = func.insn_convert(&sqrt_arg, get::<uint>(), false);
        func.insn_return(&sqrt_arg_ui);
    }).with(|sqrt: SQRT| {
        assert_eq!(sqrt(64), 8);
        assert_eq!(sqrt(16), 4);
        assert_eq!(sqrt(9), 3);
        assert_eq!(sqrt(4), 2);
        assert_eq!(sqrt(1), 1);
    });
}
#[test]
fn test_struct() {
    let pos_t = jit!(struct {
        "x": f64,
        "y": f64
    });
    for (i, field) in pos_t.fields().enumerate() {
        assert_eq!(field.get_type(), get::<f64>());
        assert_eq!(field.get_name().unwrap()[], match i {
            0 => "x",
            1 => "y",
            _ => unimplemented!()
        })
    }
}

test_compile!((), test_compile_void, Void)
test_compile!(f64, test_compile_f64, Float64)
test_compile!(f32, test_compile_f32, Float32)
test_compile!(int, test_compile_int, NInt)
test_compile!(uint, test_compile_uint, NUInt)
test_compile!(i32, test_compile_i32, Int)
test_compile!(u32, test_compile_u32, UInt)
test_compile!(i16, test_compile_i16, Short)
test_compile!(u16, test_compile_u16, UShort)
test_compile!(i8, test_compile_i8, SByte)
test_compile!(u8, test_compile_u8, UByte)
<|endoftext|>


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

#[derive(PartialEq,Eq,Debug,Hash,Clone)]
pub enum BasicValue {
    Byte(u8),
    Boolean(bool),
    Int16(i16),
    Uint16(u16),
    Int32(i32),
    Uint32(u32),
    Int64(i64),
    Uint64(u64),
    String(String),
    ObjectPath(Path),
    Signature(Signature),
}

#[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub struct Path(pub String);

#[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub struct Signature(pub String);

impl BasicValue {
    fn get_signature(&self) -> &str {
        match self {
            &BasicValue::Byte(_) => "y",
            &BasicValue::Boolean(_) => "b",
            &BasicValue::Int16(_) => "n",
            &BasicValue::Uint16(_) => "q",
            &BasicValue::Int32(_) => "i",
            &BasicValue::Uint32(_) => "u",
            &BasicValue::Int64(_) => "x",
            &BasicValue::Uint64(_) => "t",
            &BasicValue::String(_) => "s",
            &BasicValue::ObjectPath(_) => "o",
            &BasicValue::Signature(_) => "g",
        }
    }
}

#[derive(PartialEq,Debug,Clone)]
pub struct Struct {
    pub objects: Vec<Value>,
    pub signature: Signature
}

#[derive(PartialEq,Debug,Clone)]
pub struct Variant {
    pub object: Box<Value>,
    pub signature: Signature
}

impl Variant {
    pub fn new (v: Value, s: &str) -> Variant {
        Variant {
            object: Box::new(v),
            signature: Signature(s.to_string())
        }
    }
}

#[derive(Clone,Debug,PartialEq)]
pub struct Array {
    pub objects: Vec<Value>,
    signature: Signature
}

impl Array {
    // This function can only be used if it is never possible for the
    // input vector to be empty.  If it is empty, this function will
    // panic.  The reason is that it is impossible to determine the type
    // signature for an empty vector.  Use new_with_sig instead.
    pub fn new(objects: Vec<Value>) -> Array {
        let sig = objects.iter().next().unwrap().get_signature().to_string();
        Array {
            objects: objects,
            signature: Signature(sig)
        }
    }

    pub fn new_with_sig(objects: Vec<Value>, sig: String) -> Array {
        Array {
            objects: objects,
            signature: Signature(sig)
        }
    }
}

#[derive(Clone,Debug,PartialEq)]
pub struct Dictionary {
    pub map: HashMap<BasicValue,Value>,
    signature: Signature
}

impl Dictionary {
    // This function can only be used if it is never possible for the
    // input map to be empty.  If it is empty, this function will
    // panic.  The reason is that it is impossible to determine the type
    // signature for an empty map.  Use new_with_sig instead.
    pub fn new(map: HashMap<BasicValue,Value>) -> Dictionary {
        let key_type = map.keys().next().unwrap().get_signature().to_string();
        let val_type = map.values().next().unwrap().get_signature().to_string();
        let sig = "a{".to_string() + &key_type + &val_type + "}";
        Dictionary {
            map: map,
            signature: Signature(sig)
        }
    }

    pub fn new_with_sig(map: HashMap<BasicValue,Value>, sig: String) -> Dictionary {
        Dictionary {
            map: map,
            signature: Signature(sig)
        }
    }
}

#[derive(PartialEq,Debug,Clone)]
pub enum Value {
    BasicValue(BasicValue),
    Double(f64),
    Array(Array),
    Variant(Variant),
    Struct(Struct),
    Dictionary(Dictionary)
}

impl Value {
    fn get_signature(&self) -> &str {
        match self {
            &Value::BasicValue(ref x) => x.get_signature(),
            &Value::Double(_) => "d",
            &Value::Array(ref x) => &x.signature.0,
            &Value::Variant(_) => "v",
            &Value::Struct(ref x) => &x.signature.0,
            &Value::Dictionary(ref x) => &x.signature.0
        }
    }
}

#[test]
fn test_from () {
    let x = Value::from(12);
    assert_eq!(x, Value::BasicValue(BasicValue::Int32(12)));
    let y = Value::from("foobar");
    assert_eq!(y, Value::BasicValue(BasicValue::String("foobar".to_string())));
}
<commit_msg>types.rs: get_signature should be public<commit_after>use std::collections::HashMap;

#[derive(PartialEq,Eq,Debug,Hash,Clone)]
pub enum BasicValue {
    Byte(u8),
    Boolean(bool),
    Int16(i16),
    Uint16(u16),
    Int32(i32),
    Uint32(u32),
    Int64(i64),
    Uint64(u64),
    String(String),
    ObjectPath(Path),
    Signature(Signature),
}

#[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub struct Path(pub String);

#[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub struct Signature(pub String);

impl BasicValue {
    pub fn get_signature(&self) -> &str {
        match self {
            &BasicValue::Byte(_) => "y",
            &BasicValue::Boolean(_) => "b",
            &BasicValue::Int16(_) => "n",
            &BasicValue::Uint16(_) => "q",
            &BasicValue::Int32(_) => "i",
            &BasicValue::Uint32(_) => "u",
            &BasicValue::Int64(_) => "x",
            &BasicValue::Uint64(_) => "t",
            &BasicValue::String(_) => "s",
            &BasicValue::ObjectPath(_) => "o",
            &BasicValue::Signature(_) => "g",
        }
    }
}

#[derive(PartialEq,Debug,Clone)]
pub struct Struct {
    pub objects: Vec<Value>,
    pub signature: Signature
}

#[derive(PartialEq,Debug,Clone)]
pub struct Variant {
    pub object: Box<Value>,
    pub signature: Signature
}

impl Variant {
    pub fn new (v: Value, s: &str) -> Variant {
        Variant {
            object: Box::new(v),
            signature: Signature(s.to_string())
        }
    }
}

#[derive(Clone,Debug,PartialEq)]
pub struct Array {
    pub objects: Vec<Value>,
    signature: Signature
}

impl Array {
    // This function can only be used if it is never possible for the
    // input vector to be empty.  If it is empty, this function will
    // panic.  The reason is that it is impossible to determine the type
    // signature for an empty vector.  Use new_with_sig instead.
    pub fn new(objects: Vec<Value>) -> Array {
        let sig = objects.iter().next().unwrap().get_signature().to_string();
        Array {
            objects: objects,
            signature: Signature(sig)
        }
    }

    pub fn new_with_sig(objects: Vec<Value>, sig: String) -> Array {
        Array {
            objects: objects,
            signature: Signature(sig)
        }
    }
}

#[derive(Clone,Debug,PartialEq)]
pub struct Dictionary {
    pub map: HashMap<BasicValue,Value>,
    signature: Signature
}

impl Dictionary {
    // This function can only be used if it is never possible for the
    // input map to be empty.  If it is empty, this function will
    // panic.  The reason is that it is impossible to determine the type
    // signature for an empty map.  Use new_with_sig instead.
    pub fn new(map: HashMap<BasicValue,Value>) -> Dictionary {
        let key_type = map.keys().next().unwrap().get_signature().to_string();
        let val_type = map.values().next().unwrap().get_signature().to_string();
        let sig = "a{".to_string() + &key_type + &val_type + "}";
        Dictionary {
            map: map,
            signature: Signature(sig)
        }
    }

    pub fn new_with_sig(map: HashMap<BasicValue,Value>, sig: String) -> Dictionary {
        Dictionary {
            map: map,
            signature: Signature(sig)
        }
    }
}

#[derive(PartialEq,Debug,Clone)]
pub enum Value {
    BasicValue(BasicValue),
    Double(f64),
    Array(Array),
    Variant(Variant),
    Struct(Struct),
    Dictionary(Dictionary)
}

impl Value {
    pub fn get_signature(&self) -> &str {
        match self {
            &Value::BasicValue(ref x) => x.get_signature(),
            &Value::Double(_) => "d",
            &Value::Array(ref x) => &x.signature.0,
            &Value::Variant(_) => "v",
            &Value::Struct(ref x) => &x.signature.0,
            &Value::Dictionary(ref x) => &x.signature.0
        }
    }
}

#[test]
fn test_from () {
    let x = Value::from(12);
    assert_eq!(x, Value::BasicValue(BasicValue::Int32(12)));
    let y = Value::from("foobar");
    assert_eq!(y, Value::BasicValue(BasicValue::String("foobar".to_string())));
}
<|endoftext|>


<commit_before>//! Basic types and their methods for linear algebra

use ndarray::LinalgScalar;
use num_complex::Complex;
use num_traits::*;
use rand::Rng;
use rand::distributions::*;
use std::fmt::Debug;
use std::iter::Sum;
use std::ops::Neg;

use super::lapack_traits::LapackScalar;

pub use num_complex::Complex32 as c32;
pub use num_complex::Complex64 as c64;

/// General Scalar trait. This generalizes complex and real number.
///
/// You can use the following operations with `A: Scalar`:
///
/// - [abs](trait.Absolute.html#method.abs)
/// - [abs_sqr](trait.Absolute.html#tymethod.abs_sqr)
/// - [sqrt](trait.SquareRoot.html#tymethod.sqrt)
/// - [exp](trait.Exponential.html#tymethod.exp)
/// - [ln](trait.NaturalLogarithm.html#tymethod.ln)
/// - [conj](trait.Conjugate.html#tymethod.conj)
/// - [randn](trait.RandNormal.html#tymethod.randn)
///
pub trait Scalar
    : LapackScalar
    + LinalgScalar
    + AssociatedReal
    + AssociatedComplex
    + Absolute
    + SquareRoot
    + Exponential
    + NaturalLogarithm
    + Conjugate
    + RandNormal
    + Neg<Output = Self>
    + Debug {
    fn from_f64(f64) -> Self;
}

impl Scalar for f32 {
    fn from_f64(f: f64) -> Self {
        f as f32
    }
}

impl Scalar for f64 {
    fn from_f64(f: f64) -> Self {
        f
    }
}

impl Scalar for c32 {
    fn from_f64(f: f64) -> Self {
        Self::new(f as f32, 0.0)
    }
}

impl Scalar for c64 {
    fn from_f64(f: f64) -> Self {
        Self::new(f, 0.0)
    }
}

pub trait RealScalar: Scalar + Float + Sum {}
impl RealScalar for f32 {}
impl RealScalar for f64 {}

/// Convert `f64` into `Scalar`
///
/// ```rust
/// use ndarray_linalg::*;
/// fn mult<A: Scalar>(a: A) -> A {
///     // a * 2.0  // Error!
///     a * into_scalar(2.0)
/// }
/// ```
pub fn into_scalar<T: Scalar>(f: f64) -> T {
    T::from_f64(f)
}

/// Define associating real float type
pub trait AssociatedReal: Sized {
    type Real: RealScalar;
    fn inject(Self::Real) -> Self;
    fn add_real(self, Self::Real) -> Self;
    fn sub_real(self, Self::Real) -> Self;
    fn mul_real(self, Self::Real) -> Self;
    fn div_real(self, Self::Real) -> Self;
}

/// Define associating complex type
pub trait AssociatedComplex: Sized {
    type Complex;
    fn inject(Self) -> Self::Complex;
    fn add_complex(self, Self::Complex) -> Self::Complex;
    fn sub_complex(self, Self::Complex) -> Self::Complex;
    fn mul_complex(self, Self::Complex) -> Self::Complex;
}

/// Define `abs()` more generally
pub trait Absolute: AssociatedReal {
    fn abs_sqr(&self) -> Self::Real;
    fn abs(&self) -> Self::Real {
        self.abs_sqr().sqrt()
    }
}

/// Define `sqrt()` more generally
pub trait SquareRoot {
    fn sqrt(&self) -> Self;
}

/// Define `exp()` more generally
pub trait Exponential {
    fn exp(&self) -> Self;
}

/// Define `ln()` more generally
pub trait NaturalLogarithm {
    fn ln(&self) -> Self;
}

/// Complex conjugate value
pub trait Conjugate: Copy {
    fn conj(self) -> Self;
}

/// Scalars which can be initialized from Gaussian random number
pub trait RandNormal {
    fn randn<R: Rng>(&mut R) -> Self;
}

macro_rules! impl_traits {
    ($real:ty, $complex:ty) => {

impl AssociatedReal for $real {
    type Real = $real;
    fn inject(r: Self::Real) -> Self { r }
    fn add_real(self, r: Self::Real) -> Self { self + r }
    fn sub_real(self, r: Self::Real) -> Self { self - r }
    fn mul_real(self, r: Self::Real) -> Self { self * r }
    fn div_real(self, r: Self::Real) -> Self { self / r }
}

impl AssociatedReal for $complex {
    type Real = $real;
    fn inject(r: Self::Real) -> Self { Self::new(r, 0.0) }
    fn add_real(self, r: Self::Real) -> Self { self + r }
    fn sub_real(self, r: Self::Real) -> Self { self - r }
    fn mul_real(self, r: Self::Real) -> Self { self * r }
    fn div_real(self, r: Self::Real) -> Self { self / r }
}

impl AssociatedComplex for $real {
    type Complex = $complex;
    fn inject(r: Self) -> Self::Complex { Self::Complex::new(r, 0.0) }
    fn add_complex(self, c: Self::Complex) -> Self::Complex { self + c }
    fn sub_complex(self, c: Self::Complex) -> Self::Complex { self - c }
    fn mul_complex(self, c: Self::Complex) -> Self::Complex { self * c }
}

impl AssociatedComplex for $complex {
    type Complex = $complex;
    fn inject(c: Self) -> Self::Complex { c }
    fn add_complex(self, c: Self::Complex) -> Self::Complex { self + c }
    fn sub_complex(self, c: Self::Complex) -> Self::Complex { self - c }
    fn mul_complex(self, c: Self::Complex) -> Self::Complex { self * c }
}

impl Absolute for $real {
    fn abs_sqr(&self) -> Self::Real {
        *self * *self
    }
    fn abs(&self) -> Self::Real{
        Float::abs(*self)
    }
}

impl Absolute for $complex {
    fn abs_sqr(&self) -> Self::Real {
        self.norm_sqr()
    }
    fn abs(&self) -> Self::Real {
        self.norm()
    }
}

impl SquareRoot for $real {
    fn sqrt(&self) -> Self {
        Float::sqrt(*self)
    }
}

impl SquareRoot for $complex {
    fn sqrt(&self) -> Self {
        Complex::sqrt(self)
    }
}

impl Exponential for $real {
    fn exp(&self) -> Self {
        Float::exp(*self)
    }
}

impl Exponential for $complex {
    fn exp(&self) -> Self {
        Complex::exp(self)
    }
}

impl NaturalLogarithm for $real {
    fn ln(&self) -> Self {
        Float::ln(*self)
    }
}

impl NaturalLogarithm for $complex {
    fn ln(&self) -> Self {
        Complex::ln(self)
    }
}

impl Conjugate for $real {
    fn conj(self) -> Self {
        self
    }
}

impl Conjugate for $complex {
    fn conj(self) -> Self {
        Complex::conj(&self)
    }
}

impl RandNormal for $real {
    fn randn<R: Rng>(rng: &mut R) -> Self {
        let dist = Normal::new(0., 1.);
        dist.ind_sample(rng) as $real
    }
}

impl RandNormal for $complex {
    fn randn<R: Rng>(rng: &mut R) -> Self {
        let dist = Normal::new(0., 1.);
        let re = dist.ind_sample(rng) as $real;
        let im = dist.ind_sample(rng) as $real;
        Self::new(re, im)
    }
}

}} // impl_traits!

impl_traits!(f64, c64);
impl_traits!(f32, c32);
<commit_msg>Add AssociatedReal::real() and ::imag()<commit_after>//! Basic types and their methods for linear algebra

use ndarray::LinalgScalar;
use num_complex::Complex;
use num_traits::*;
use rand::Rng;
use rand::distributions::*;
use std::fmt::Debug;
use std::iter::Sum;
use std::ops::Neg;

use super::lapack_traits::LapackScalar;

pub use num_complex::Complex32 as c32;
pub use num_complex::Complex64 as c64;

/// General Scalar trait. This generalizes complex and real number.
///
/// You can use the following operations with `A: Scalar`:
///
/// - [abs](trait.Absolute.html#method.abs)
/// - [abs_sqr](trait.Absolute.html#tymethod.abs_sqr)
/// - [sqrt](trait.SquareRoot.html#tymethod.sqrt)
/// - [exp](trait.Exponential.html#tymethod.exp)
/// - [ln](trait.NaturalLogarithm.html#tymethod.ln)
/// - [conj](trait.Conjugate.html#tymethod.conj)
/// - [randn](trait.RandNormal.html#tymethod.randn)
///
pub trait Scalar
    : LapackScalar
    + LinalgScalar
    + AssociatedReal
    + AssociatedComplex
    + Absolute
    + SquareRoot
    + Exponential
    + NaturalLogarithm
    + Conjugate
    + RandNormal
    + Neg<Output = Self>
    + Debug {
    fn from_f64(f64) -> Self;
}

impl Scalar for f32 {
    fn from_f64(f: f64) -> Self {
        f as f32
    }
}

impl Scalar for f64 {
    fn from_f64(f: f64) -> Self {
        f
    }
}

impl Scalar for c32 {
    fn from_f64(f: f64) -> Self {
        Self::new(f as f32, 0.0)
    }
}

impl Scalar for c64 {
    fn from_f64(f: f64) -> Self {
        Self::new(f, 0.0)
    }
}

pub trait RealScalar: Scalar + Float + Sum {}
impl RealScalar for f32 {}
impl RealScalar for f64 {}

/// Convert `f64` into `Scalar`
///
/// ```rust
/// use ndarray_linalg::*;
/// fn mult<A: Scalar>(a: A) -> A {
///     // a * 2.0  // Error!
///     a * into_scalar(2.0)
/// }
/// ```
pub fn into_scalar<T: Scalar>(f: f64) -> T {
    T::from_f64(f)
}

/// Define associating real float type
pub trait AssociatedReal: Sized {
    type Real: RealScalar;
    fn inject(Self::Real) -> Self;
    /// Returns the real part of `self`.
    fn real(self) -> Self::Real;
    /// Returns the imaginary part of `self`.
    fn imag(self) -> Self::Real;
    fn add_real(self, Self::Real) -> Self;
    fn sub_real(self, Self::Real) -> Self;
    fn mul_real(self, Self::Real) -> Self;
    fn div_real(self, Self::Real) -> Self;
}

/// Define associating complex type
pub trait AssociatedComplex: Sized {
    type Complex;
    fn inject(Self) -> Self::Complex;
    fn add_complex(self, Self::Complex) -> Self::Complex;
    fn sub_complex(self, Self::Complex) -> Self::Complex;
    fn mul_complex(self, Self::Complex) -> Self::Complex;
}

/// Define `abs()` more generally
pub trait Absolute: AssociatedReal {
    fn abs_sqr(&self) -> Self::Real;
    fn abs(&self) -> Self::Real {
        self.abs_sqr().sqrt()
    }
}

/// Define `sqrt()` more generally
pub trait SquareRoot {
    fn sqrt(&self) -> Self;
}

/// Define `exp()` more generally
pub trait Exponential {
    fn exp(&self) -> Self;
}

/// Define `ln()` more generally
pub trait NaturalLogarithm {
    fn ln(&self) -> Self;
}

/// Complex conjugate value
pub trait Conjugate: Copy {
    fn conj(self) -> Self;
}

/// Scalars which can be initialized from Gaussian random number
pub trait RandNormal {
    fn randn<R: Rng>(&mut R) -> Self;
}

macro_rules! impl_traits {
    ($real:ty, $complex:ty) => {

impl AssociatedReal for $real {
    type Real = $real;
    fn inject(r: Self::Real) -> Self { r }
    fn real(self) -> Self::Real { self }
    fn imag(self) -> Self::Real { 0. }
    fn add_real(self, r: Self::Real) -> Self { self + r }
    fn sub_real(self, r: Self::Real) -> Self { self - r }
    fn mul_real(self, r: Self::Real) -> Self { self * r }
    fn div_real(self, r: Self::Real) -> Self { self / r }
}

impl AssociatedReal for $complex {
    type Real = $real;
    fn inject(r: Self::Real) -> Self { Self::new(r, 0.0) }
    fn real(self) -> Self::Real { self.re }
    fn imag(self) -> Self::Real { self.im }
    fn add_real(self, r: Self::Real) -> Self { self + r }
    fn sub_real(self, r: Self::Real) -> Self { self - r }
    fn mul_real(self, r: Self::Real) -> Self { self * r }
    fn div_real(self, r: Self::Real) -> Self { self / r }
}

impl AssociatedComplex for $real {
    type Complex = $complex;
    fn inject(r: Self) -> Self::Complex { Self::Complex::new(r, 0.0) }
    fn add_complex(self, c: Self::Complex) -> Self::Complex { self + c }
    fn sub_complex(self, c: Self::Complex) -> Self::Complex { self - c }
    fn mul_complex(self, c: Self::Complex) -> Self::Complex { self * c }
}

impl AssociatedComplex for $complex {
    type Complex = $complex;
    fn inject(c: Self) -> Self::Complex { c }
    fn add_complex(self, c: Self::Complex) -> Self::Complex { self + c }
    fn sub_complex(self, c: Self::Complex) -> Self::Complex { self - c }
    fn mul_complex(self, c: Self::Complex) -> Self::Complex { self * c }
}

impl Absolute for $real {
    fn abs_sqr(&self) -> Self::Real {
        *self * *self
    }
    fn abs(&self) -> Self::Real{
        Float::abs(*self)
    }
}

impl Absolute for $complex {
    fn abs_sqr(&self) -> Self::Real {
        self.norm_sqr()
    }
    fn abs(&self) -> Self::Real {
        self.norm()
    }
}

impl SquareRoot for $real {
    fn sqrt(&self) -> Self {
        Float::sqrt(*self)
    }
}

impl SquareRoot for $complex {
    fn sqrt(&self) -> Self {
        Complex::sqrt(self)
    }
}

impl Exponential for $real {
    fn exp(&self) -> Self {
        Float::exp(*self)
    }
}

impl Exponential for $complex {
    fn exp(&self) -> Self {
        Complex::exp(self)
    }
}

impl NaturalLogarithm for $real {
    fn ln(&self) -> Self {
        Float::ln(*self)
    }
}

impl NaturalLogarithm for $complex {
    fn ln(&self) -> Self {
        Complex::ln(self)
    }
}

impl Conjugate for $real {
    fn conj(self) -> Self {
        self
    }
}

impl Conjugate for $complex {
    fn conj(self) -> Self {
        Complex::conj(&self)
    }
}

impl RandNormal for $real {
    fn randn<R: Rng>(rng: &mut R) -> Self {
        let dist = Normal::new(0., 1.);
        dist.ind_sample(rng) as $real
    }
}

impl RandNormal for $complex {
    fn randn<R: Rng>(rng: &mut R) -> Self {
        let dist = Normal::new(0., 1.);
        let re = dist.ind_sample(rng) as $real;
        let im = dist.ind_sample(rng) as $real;
        Self::new(re, im)
    }
}

}} // impl_traits!

impl_traits!(f64, c64);
impl_traits!(f32, c32);
<|endoftext|>