<commit_before>use std::fs::File;
use std::io;
use std::io::Write;
use std::mem;
use std::ptr;

use super::{ReadAt, WriteAt};

use std::os::windows::io::AsRawHandle;

extern crate winapi;
use self::winapi::shared::minwindef::{BOOL, DWORD, LPVOID};
use self::winapi::um::fileapi::ReadFile;
use self::winapi::um::minwinbase::{OVERLAPPED_u, OVERLAPPED_u_s, OVERLAPPED};
use self::winapi::um::winnt::HANDLE;

fn result(e: BOOL) -> Result<()> {
    if e == 0 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}

fn overlapped(pos: u64) -> OVERLAPPED {
    OVERLAPPED {
        Internal: 0,
        InternalHigh: 0,
        u: unsafe {
            let mut u: OVERLAPPED_u = mem::zeroed();
            *u.s_mut() = OVERLAPPED_u_s {
                Offset: pos as u32,
                OffsetHigh: (pos >> 32) as u32,
            };
            u
        },
        hEvent: ptr::null_mut(),
    }
}

impl ReadAt for File {
    fn read_at(&self, pos: u64, buf: &mut [u8]) -> io::Result<usize> {
        let mut bytes: DWORD = 0;
        let mut ov = overlapped(pos);
        result(unsafe {
            ReadFile(
                self.as_raw_handle() as HANDLE,
                buf.as_mut_ptr() as LPVOID,
                buf.len() as DWORD,
                &mut bytes,
                &mut ov,
            )
        })?;
        Ok(bytes as usize)
    }
}

impl WriteAt for File {
    fn write_at(&mut self, pos: u64, buf: &[u8]) -> io::Result<usize> {
        let mut bytes: DWORD = 0;
        let mut ov = overlapped(pos);
        result(unsafe {
            ReadFile(
                self.as_raw_handle() as HANDLE,
                buf.as_ptr() as LPVOID,
                buf.len() as DWORD,
                &mut bytes,
                &mut ov,
            )
        })?;
        Ok(bytes as usize)
    }

    fn flush(&mut self) -> io::Result<()> {
        Write::flush(self)
    }
}
<commit_msg>another blind fix for windows.rs<commit_after>use std::fs::File;
use std::io;
use std::io::Write;
use std::mem;
use std::ptr;

use super::{ReadAt, WriteAt};

use std::os::windows::io::AsRawHandle;

extern crate winapi;
use self::winapi::shared::minwindef::{BOOL, DWORD, LPVOID};
use self::winapi::um::fileapi::ReadFile;
use self::winapi::um::minwinbase::{OVERLAPPED_u, OVERLAPPED_u_s, OVERLAPPED};
use self::winapi::um::winnt::HANDLE;

fn result(e: BOOL) -> io::Result<()> {
    if e == 0 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}

fn overlapped(pos: u64) -> OVERLAPPED {
    OVERLAPPED {
        Internal: 0,
        InternalHigh: 0,
        u: unsafe {
            let mut u: OVERLAPPED_u = mem::zeroed();
            *u.s_mut() = OVERLAPPED_u_s {
                Offset: pos as u32,
                OffsetHigh: (pos >> 32) as u32,
            };
            u
        },
        hEvent: ptr::null_mut(),
    }
}

impl ReadAt for File {
    fn read_at(&self, pos: u64, buf: &mut [u8]) -> io::Result<usize> {
        let mut bytes: DWORD = 0;
        let mut ov = overlapped(pos);
        result(unsafe {
            ReadFile(
                self.as_raw_handle() as HANDLE,
                buf.as_mut_ptr() as LPVOID,
                buf.len() as DWORD,
                &mut bytes,
                &mut ov,
            )
        })?;
        Ok(bytes as usize)
    }
}

impl WriteAt for File {
    fn write_at(&mut self, pos: u64, buf: &[u8]) -> io::Result<usize> {
        let mut bytes: DWORD = 0;
        let mut ov = overlapped(pos);
        result(unsafe {
            ReadFile(
                self.as_raw_handle() as HANDLE,
                buf.as_ptr() as LPVOID,
                buf.len() as DWORD,
                &mut bytes,
                &mut ov,
            )
        })?;
        Ok(bytes as usize)
    }

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


<commit_before>//! Functions and data-structures to load descriptor tables.
use core::fmt;
use core::mem::size_of;

/// A struct describing a pointer to a descriptor table (GDT / IDT).
/// This is in a format suitable for giving to 'lgdt' or 'lidt'.
#[repr(C, packed)]
pub struct DescriptorTablePointer<Entry> {
    /// Size of the DT.
    pub limit: u16,
    /// Pointer to the memory region containing the DT.
    pub base: *const Entry,
}

impl<T> Default for DescriptorTablePointer<T> {
    fn default() -> DescriptorTablePointer<T> {
        DescriptorTablePointer {
            limit: 0,
            base: core::ptr::null(),
        }
    }
}

impl<T> DescriptorTablePointer<T> {
    pub fn new(tbl: &T) -> Self {
        // GDT, LDT, and IDT all expect the limit to be set to "one less".
        // See Intel 3a, Section 3.5.1 "Segment Descriptor Tables" and
        // Section 6.10 "Interrupt Descriptor Table (IDT)".
        let len = size_of::<T>() - 1;
        assert!(len < 0x10000);
        DescriptorTablePointer {
            base: tbl as *const T,
            limit: len as u16,
        }
    }

    pub fn new_from_slice(slice: &[T]) -> Self {
        // GDT, LDT, and IDT all expect the limit to be set to "one less".
        // See Intel 3a, Section 3.5.1 "Segment Descriptor Tables" and
        // Section 6.10 "Interrupt Descriptor Table (IDT)".
        let len = slice.len() * size_of::<T>() - 1;
        assert!(len < 0x10000);
        DescriptorTablePointer {
            base: slice.as_ptr(),
            limit: len as u16,
        }
    }
}

impl<T> fmt::Debug for DescriptorTablePointer<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe { write!(f, "DescriptorTablePointer ({} {:?})", self.limit, self.base) }
    }
}

/// Load GDT table with 32bit descriptors
pub unsafe fn lgdt<T>(gdt: &DescriptorTablePointer<T>) {
    asm!("lgdt ($0)" :: "r" (gdt) : "memory");
}

/// Load LDT table with 32bit descriptors.
pub unsafe fn lldt<T>(ldt: &DescriptorTablePointer<T>) {
    asm!("lldt ($0)" :: "r" (ldt) : "memory");
}

/// Load IDT table with 32bit descriptors.
pub unsafe fn lidt<T>(idt: &DescriptorTablePointer<T>) {
    asm!("lidt ($0)" :: "r" (idt) : "memory");
}

/// Retrive IDT table with 32bit descriptors.
pub unsafe fn sidt<T>(idt: &mut DescriptorTablePointer<T>) {
    asm!("sidt ($0)" : "=r" (idt as *mut DescriptorTablePointer<T>) :: "memory");
}
<commit_msg>Replaced old and added new functions for working with the LDTR<commit_after>//! Functions and data-structures to load descriptor tables.
use core::fmt;
use core::mem::size_of;
use crate::segmentation::SegmentSelector;

/// A struct describing a pointer to a descriptor table (GDT / IDT).
/// This is in a format suitable for giving to 'lgdt' or 'lidt'.
#[repr(C, packed)]
pub struct DescriptorTablePointer<Entry> {
    /// Size of the DT.
    pub limit: u16,
    /// Pointer to the memory region containing the DT.
    pub base: *const Entry,
}

impl<T> Default for DescriptorTablePointer<T> {
    fn default() -> DescriptorTablePointer<T> {
        DescriptorTablePointer {
            limit: 0,
            base: core::ptr::null(),
        }
    }
}

impl<T> DescriptorTablePointer<T> {
    pub fn new(tbl: &T) -> Self {
        // GDT, LDT, and IDT all expect the limit to be set to "one less".
        // See Intel 3a, Section 3.5.1 "Segment Descriptor Tables" and
        // Section 6.10 "Interrupt Descriptor Table (IDT)".
        let len = size_of::<T>() - 1;
        assert!(len < 0x10000);
        DescriptorTablePointer {
            base: tbl as *const T,
            limit: len as u16,
        }
    }

    pub fn new_from_slice(slice: &[T]) -> Self {
        // GDT, LDT, and IDT all expect the limit to be set to "one less".
        // See Intel 3a, Section 3.5.1 "Segment Descriptor Tables" and
        // Section 6.10 "Interrupt Descriptor Table (IDT)".
        let len = slice.len() * size_of::<T>() - 1;
        assert!(len < 0x10000);
        DescriptorTablePointer {
            base: slice.as_ptr(),
            limit: len as u16,
        }
    }
}

impl<T> fmt::Debug for DescriptorTablePointer<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe { write!(f, "DescriptorTablePointer ({} {:?})", self.limit, self.base) }
    }
}

/// Load GDT table with 32bit descriptors
pub unsafe fn lgdt<T>(gdt: &DescriptorTablePointer<T>) {
    asm!("lgdt ($0)" :: "r" (gdt) : "memory");
}

/// Loads the segment selector into the selector field of the local
/// descriptor table register (LDTR).
///
/// After the segment selector is loaded in the LDTR,
/// the processor uses the segment selector to locate
/// the segment descriptor for the LDT in the global
/// descriptor table (GDT).
pub unsafe fn load_ldtr(selector: SegmentSelector) {
    asm!("lldt $0" :: "r" (selector.bits()) : "memory");
}

/// Returns the segment selector from the local descriptor table register (LDTR).
///
/// The returned segment selector points to the segment descriptor
/// (located in the GDT) for the current LDT.
pub unsafe fn ldtr() -> SegmentSelector {
    let selector: u16;
    asm!("sldt $0" : "=r"(selector));
    SegmentSelector::from_raw(selector)
}

/// Load IDT table with 32bit descriptors.
pub unsafe fn lidt<T>(idt: &DescriptorTablePointer<T>) {
    asm!("lidt ($0)" :: "r" (idt) : "memory");
}

/// Retrive IDT table with 32bit descriptors.
pub unsafe fn sidt<T>(idt: &mut DescriptorTablePointer<T>) {
    asm!("sidt ($0)" : "=r" (idt as *mut DescriptorTablePointer<T>) :: "memory");
}
<|endoftext|>


<commit_before>//! Interval-based annotation features.

use bio::utils::{Interval, IntervalError};

pub trait NamedInterval: Sized {

    /// Underlying interval struct.
    fn interval(&self) -> &Interval<u64>;  // TODO: Generalize over interval types.

    /// Name of the interval.
    fn name(&self) -> Option<&str>;

    /// Name setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_name<T: Into<String>>(self, name: T) -> Self;

    /// Coordinate setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_coords(self, start: u64, end: u64) -> Result<Self, IntervalError>;

    /// Start coordinate of the interval.
    fn start(&self) -> u64 {
        self.interval().start
    }

    /// End coordinate of the interval.
    fn end(&self) -> u64 {
        self.interval().end
    }

    /// The number of bases covered by the interval.
    fn span(&self) -> u64 {
        self.end() - self.start()
    }

    /// Whether two intervals have an overlap or not.
    fn overlaps(&self, other: &Self) -> bool {
        self.start() < other.end() && other.start() < self.end()
    }

    /// Whether one interval completely contains the other.
    fn envelops(&self, other: &Self) -> bool {
        self.start() <= other.start() && self.end() >= other.end()
    }

    /// Whether two intervals cover a contiguous region without any overlaps.
    fn adjacent(&self, other: &Self) -> bool {
        self.end() == other.start() || self.start() == other.end()
    }
}

/// Macro for default function implementations of interval types.
macro_rules! impl_ninterval {
    ($struct_ty:ty) => (

        impl NamedInterval for $struct_ty {

            /// Name of the interval.
            fn name(&self) -> Option<&str> {
                self.name.as_ref().map(|n| n.as_str())
            }

            fn with_name<T>(mut self, name: T) -> $struct_ty
                where T: Into<String>
            {
                self.name = Some(name.into());
                self
            }

            fn interval(&self) -> &Interval<u64> {
                &self.interval
            }

            fn with_coords(mut self, start: u64, end: u64) -> Result<$struct_ty, IntervalError> {
                Interval::new(start..end)
                    .map(|iv| {
                        self.interval = iv;
                        self
                    })
            }
        }

    );
}

/// Default implementation of the `Interval` trait.
///
/// This struct also provides static methods for creating exons, transcripts, and genes.
#[derive(Debug)]
pub struct Feature {
    interval: Interval<u64>,
    name: Option<String>,
}

impl Default for Feature {

    fn default() -> Feature {
        Feature { interval: Interval::new(0..0).unwrap(), name: None }
    }
}

impl_ninterval!(Feature);

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

    #[test]
    fn default() {
        let fx = Feature::default();
        assert_eq!(fx.start(), 0);
        assert_eq!(fx.end(), 0);
        assert_eq!(fx.name(), None);
    }

    #[test]
    fn with_name() {
        let fx1 = Feature::default()
            .with_name("fx1");
        assert_eq!(fx1.start(), 0);
        assert_eq!(fx1.end(), 0);
        assert_eq!(fx1.name(), Some("fx1"));

        let fx2 = Feature::default()
            .with_name("fx2".to_owned());
        assert_eq!(fx2.start(), 0);
        assert_eq!(fx2.end(), 0);
        assert_eq!(fx2.name(), Some("fx2"));
    }

    #[test]
    fn with_coords() {
        let fxm = Feature::default()
            .with_coords(1, 3);
        assert!(fxm.is_ok());
        let fx = fxm.unwrap();
        assert_eq!(fx.start(), 1);
        assert_eq!(fx.end(), 3);
        assert_eq!(fx.name(), None);
    }

    #[test]
    fn with_coords_err() {
        let fxm = Feature::default()
            .with_coords(3, 1);
        assert!(fxm.is_err());
    }

    #[test]
    fn with_multiples() {
        let fxm = Feature::default()
            .with_coords(20, 30)
            .map(|f| f.with_name("fx"));
        assert!(fxm.is_ok());
        let fx = fxm.unwrap();
        assert_eq!(fx.start(), 20);
        assert_eq!(fx.end(), 30);
        assert_eq!(fx.name(), Some("fx"));
    }

    fn make_feature(start: u64, end: u64) -> Feature {
        Feature::default().with_coords(start, end).unwrap()
    }

    #[test]
    fn span() {
        let fx = make_feature(0, 15);
        assert_eq!(fx.span(), 15);
    }

    #[test]
    fn overlaps() {
        let fx1 = make_feature(100, 115);

        let fx2 = make_feature(110, 120);
        assert!(fx1.overlaps(&fx2));
        assert!(fx1.overlaps(&fx2));

        let fx3 = make_feature(115, 120);
        assert!(!fx1.overlaps(&fx3));
        assert!(!fx3.overlaps(&fx1));

        let fx4 = make_feature(90, 100);
        assert!(!fx1.overlaps(&fx4));
        assert!(!fx4.overlaps(&fx1));

        let fx5 = make_feature(200, 300);
        assert!(!fx1.overlaps(&fx5));
        assert!(!fx5.overlaps(&fx1));
    }
}
<commit_msg>Add test for envelops and is_adjacent<commit_after>//! Interval-based annotation features.

use bio::utils::{Interval, IntervalError};

pub trait NamedInterval: Sized {

    /// Underlying interval struct.
    fn interval(&self) -> &Interval<u64>;  // TODO: Generalize over interval types.

    /// Name of the interval.
    fn name(&self) -> Option<&str>;

    /// Name setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_name<T: Into<String>>(self, name: T) -> Self;

    /// Coordinate setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_coords(self, start: u64, end: u64) -> Result<Self, IntervalError>;

    /// Start coordinate of the interval.
    fn start(&self) -> u64 {
        self.interval().start
    }

    /// End coordinate of the interval.
    fn end(&self) -> u64 {
        self.interval().end
    }

    /// The number of bases covered by the interval.
    fn span(&self) -> u64 {
        self.end() - self.start()
    }

    /// Whether two intervals have an overlap or not.
    fn overlaps(&self, other: &Self) -> bool {
        self.start() < other.end() && other.start() < self.end()
    }

    /// Whether one interval completely contains the other.
    fn envelops(&self, other: &Self) -> bool {
        self.start() <= other.start() && self.end() >= other.end()
    }

    /// Whether two intervals cover a contiguous region without any overlaps.
    fn is_adjacent(&self, other: &Self) -> bool {
        self.end() == other.start() || self.start() == other.end()
    }
}

/// Macro for default function implementations of interval types.
macro_rules! impl_ninterval {
    ($struct_ty:ty) => (

        impl NamedInterval for $struct_ty {

            /// Name of the interval.
            fn name(&self) -> Option<&str> {
                self.name.as_ref().map(|n| n.as_str())
            }

            fn with_name<T>(mut self, name: T) -> $struct_ty
                where T: Into<String>
            {
                self.name = Some(name.into());
                self
            }

            fn interval(&self) -> &Interval<u64> {
                &self.interval
            }

            fn with_coords(mut self, start: u64, end: u64) -> Result<$struct_ty, IntervalError> {
                Interval::new(start..end)
                    .map(|iv| {
                        self.interval = iv;
                        self
                    })
            }
        }

    );
}

/// Default implementation of the `Interval` trait.
///
/// This struct also provides static methods for creating exons, transcripts, and genes.
#[derive(Debug)]
pub struct Feature {
    interval: Interval<u64>,
    name: Option<String>,
}

impl Default for Feature {

    fn default() -> Feature {
        Feature { interval: Interval::new(0..0).unwrap(), name: None }
    }
}

impl_ninterval!(Feature);

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

    #[test]
    fn default() {
        let fx = Feature::default();
        assert_eq!(fx.start(), 0);
        assert_eq!(fx.end(), 0);
        assert_eq!(fx.name(), None);
    }

    #[test]
    fn with_name() {
        let fx1 = Feature::default()
            .with_name("fx1");
        assert_eq!(fx1.start(), 0);
        assert_eq!(fx1.end(), 0);
        assert_eq!(fx1.name(), Some("fx1"));

        let fx2 = Feature::default()
            .with_name("fx2".to_owned());
        assert_eq!(fx2.start(), 0);
        assert_eq!(fx2.end(), 0);
        assert_eq!(fx2.name(), Some("fx2"));
    }

    #[test]
    fn with_coords() {
        let fxm = Feature::default()
            .with_coords(1, 3);
        assert!(fxm.is_ok());
        let fx = fxm.unwrap();
        assert_eq!(fx.start(), 1);
        assert_eq!(fx.end(), 3);
        assert_eq!(fx.name(), None);
    }

    #[test]
    fn with_coords_err() {
        let fxm = Feature::default()
            .with_coords(3, 1);
        assert!(fxm.is_err());
    }

    #[test]
    fn with_multiples() {
        let fxm = Feature::default()
            .with_coords(20, 30)
            .map(|f| f.with_name("fx"));
        assert!(fxm.is_ok());
        let fx = fxm.unwrap();
        assert_eq!(fx.start(), 20);
        assert_eq!(fx.end(), 30);
        assert_eq!(fx.name(), Some("fx"));
    }

    fn make_feature(start: u64, end: u64) -> Feature {
        Feature::default().with_coords(start, end).unwrap()
    }

    #[test]
    fn span() {
        let fx = make_feature(0, 15);
        assert_eq!(fx.span(), 15);
    }

    #[test]
    fn overlaps() {
        let fx1 = make_feature(100, 115);

        let fx2 = make_feature(110, 120);
        assert!(fx1.overlaps(&fx2));
        assert!(fx1.overlaps(&fx2));

        let fx3 = make_feature(115, 120);
        assert!(!fx1.overlaps(&fx3));
        assert!(!fx3.overlaps(&fx1));

        let fx4 = make_feature(90, 100);
        assert!(!fx1.overlaps(&fx4));
        assert!(!fx4.overlaps(&fx1));

        let fx5 = make_feature(200, 300);
        assert!(!fx1.overlaps(&fx5));
        assert!(!fx5.overlaps(&fx1));
    }

    #[test]
    fn envelops() {
        let fx1 = make_feature(100, 120);

        let fx2 = make_feature(105, 115);
        assert!(fx1.envelops(&fx2));
        assert!(!fx2.envelops(&fx1));

        let fx3 = make_feature(100, 105);
        assert!(fx1.envelops(&fx3));
        assert!(!fx3.envelops(&fx1));

        let fx4 = make_feature(115, 120);
        assert!(fx1.envelops(&fx4));
        assert!(!fx4.envelops(&fx1));

        let fx5 = make_feature(90, 105);
        assert!(!fx1.envelops(&fx5));
        assert!(!fx5.envelops(&fx1));

        let fx6 = make_feature(115, 130);
        assert!(!fx1.envelops(&fx5));
        assert!(!fx6.envelops(&fx1));

        let fx7 = make_feature(80, 90);
        assert!(!fx1.envelops(&fx7));
        assert!(!fx7.envelops(&fx1));
    }

    #[test]
    fn is_adjacent() {
        let fx1 = make_feature(100, 120);

        let fx2 = make_feature(90, 100);
        assert!(fx1.is_adjacent(&fx2));
        assert!(fx2.is_adjacent(&fx1));

        let fx3 = make_feature(120, 130);
        assert!(fx1.is_adjacent(&fx3));
        assert!(fx3.is_adjacent(&fx1));

        let fx4 = make_feature(90, 99);
        assert!(!fx1.is_adjacent(&fx4));
        assert!(!fx4.is_adjacent(&fx1));

        let fx5 = make_feature(119, 130);
        assert!(!fx1.is_adjacent(&fx5));
        assert!(!fx5.is_adjacent(&fx1));

        let fx6 = make_feature(100, 110);
        assert!(!fx1.is_adjacent(&fx6));
        assert!(!fx6.is_adjacent(&fx1));

        let fx7 = make_feature(110, 120);
        assert!(!fx1.is_adjacent(&fx7));
        assert!(!fx7.is_adjacent(&fx1));
    }
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2016 Antoine Wacheux

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

extern crate liquid;
extern crate regex_syntax;
extern crate core;

use liquidobject::LiquidObject;
use self::liquid::Value;
use std::collections::HashMap;
use std::collections::HashSet;
use self::regex_syntax::Expr;
use self::core::iter::FromIterator;

pub struct LexicalUnit {
    name : String,
    regex : String,
}

impl LiquidObject for LexicalUnit {
    fn to_liquid_object(&self) -> Value {
        let mut result = HashMap::new();
        result.insert("name".to_owned(), liquid::Value::Str(self.name.clone()));
        result.insert("regex".to_owned(), liquid::Value::Str(self.regex.clone()));
        Value::Object(result)
    }
}

pub struct ProductionRule {
    name: String,
    rule: Vec<RuleComponent>
}

pub enum RuleComponent {
    ProductionRule(String),
    LexicalUnit(String),
    Epsilon
}

#[derive(PartialEq, Eq, Hash, Clone)]
pub enum FirstElement { //Elements that appear in the first sets
    LexicalUnit(String),
    Epsilon
}

pub struct Grammar {
    lexical_units : Vec<LexicalUnit>,
    production_rules: Vec<ProductionRule>,
    axiom : String
}

impl Grammar {
    fn new() -> Grammar {
        Grammar {
            lexical_units: Vec::new(),
            production_rules: Vec::new(),
            axiom: String::new(),
        }
    }

    fn get_production_rule(&self, name: &String) -> Vec<&ProductionRule> {
        self.production_rules.iter().filter(|x| x.name == *name).collect()
    }

    pub fn get_all_production_rules_name(&self) -> Vec<String> {
        let uniq_filter = {
            let mut found : Vec<String> = Vec::new();

            move |x:&String| {
                if found.iter().find(|elem| *elem == x).is_some() {
                    false
                }
                else {
                    found.push(x.clone());
                    true
                }
            }
        };

        self.production_rules.iter().map(|x| x.name.clone()).filter(uniq_filter).collect()
    }

    pub fn get_all_lexical_units(&self) -> &Vec<LexicalUnit> {
        &self.lexical_units
    }

    pub fn first(&self) -> HashMap<String, HashSet<FirstElement> > {
        let mut result : HashMap<String, HashSet<FirstElement> > = HashMap::new();

        for rule in self.get_all_production_rules_name() {
            result.insert(rule, HashSet::new());
        }

        let mut modified = true;

        while modified {
            modified = false;
            //println!("Iteration because of modified");

            for rule in &self.production_rules {
                let mut epsilon_found = true;
                let mut rule_node_iter = rule.rule.iter();
                let mut new_first_set : HashSet<FirstElement> = {
                    let mut set = HashSet::new();
                    let first_set = result.get(&rule.name).unwrap();
                    set = set.union(&first_set).map(|x| x.clone()).collect();
                    set
                };

                while epsilon_found {
                    //println!("Iteration because of epsilon_found");
                    epsilon_found = false;

                    if let Some(rule_node) = rule_node_iter.next() {
                        match rule_node {
                            &RuleComponent::LexicalUnit(ref name) => {
                                modified = modified || new_first_set.insert(FirstElement::LexicalUnit(name.clone()));
                            },
                            &RuleComponent::Epsilon => {
                                modified = modified || new_first_set.insert(FirstElement::Epsilon);
                            }
                            &RuleComponent::ProductionRule(ref name) => {
                                let first_set = result.get(name).unwrap();
                                //Check if we have an epsilon
                                epsilon_found = first_set.iter().any(|x| match x {
                                    &FirstElement::Epsilon => true,
                                    _ => false,
                                });

                                for elem in first_set {
                                    if let &FirstElement::LexicalUnit(ref name) = elem {
                                        //println!("Inserting {}", name);
                                        modified = modified || new_first_set.insert(elem.clone());
                                    }
                                }
                            }
                        };
                    }
                    result.insert(rule.name.clone(), new_first_set.clone());
                }
            }
        }

        result
    }
}

//Methods
//get_rule(name: String&) -> Vec<ProductionRule>&

struct ParserContext {
    src: String,
    row: u32,
    col: u32,
    str_pos: usize,
}

impl ParserContext {
    fn new(src : String) -> ParserContext {
        ParserContext {
            src: src,
            row: 1,
            col: 0,
            str_pos: 0
        }
    }

    fn next_word(&mut self) -> Option<String> {
        let mut iter = self.src.chars();
        let mut ch = iter.nth(self.str_pos);
        let mut c : char;
        let mut read_word = String::new();

        match ch {
            None => { return None },
            Some(chr) => { c = chr}
        }

        macro_rules! next_char {
            ($err:stmt) => ({
                self.str_pos += 1;
                ch = iter.next();

                match ch {
                    None => { $err },
                    Some(chr) => { c = chr }
                }

                match c { //TODO : Implement a better line/column tracking and forward this information in the word
                    ' ' | '\t' => self.col += 1,
                    '\n' => self.row += 1,
                    _ => {}
                }
            });
        }

        while (c == ' ') || (c == '\n') || (c == '\t') { //We skip leading whitespaces
            next_char! { return None }
        }

        while !((c == ' ') || (c == '\n') || (c == '\t')) {
            read_word.push(c);
            next_char! { return Some(read_word) }
        }

        Some(read_word)
    }

    pub fn read_line(&mut self) -> Option<String> {
        let mut iter = self.src.chars();
        let mut ch = iter.nth(self.str_pos);
        let mut c : char;
        let mut read_word = String::new();

        match ch {
            None => { return None },
            Some(chr) => { c = chr}
        }

        macro_rules! next_char {
            ($err:stmt) => ({
                self.str_pos += 1;
                ch = iter.next();

                match ch {
                    None => { $err },
                    Some(chr) => { c = chr }
                }

                match c {
                    ' ' | '\t' => self.col += 1,
                    '\n' => self.row += 1,
                    _ => {}
                }
            });
        }

        while (c == ' ') || (c == '\n') || (c == '\t') { //We skip leading whitespaces
            next_char! { return None }
        }

        while c != '\n' {
            read_word.push(c);
            next_char! { return Some(read_word) }
        }

        Some(read_word)
    }
}

struct GrammarParser {
    ctx: ParserContext,
    grammar: Grammar,
    auto_counter: u32, //Counter for generating automatic lexical unit name
}

impl GrammarParser {
    fn new(src: String) -> GrammarParser {
        GrammarParser {
            ctx : ParserContext::new(src),
            grammar: Grammar::new(),
            auto_counter: 1,
        }
    }

    fn get_resulting_grammar(self) -> Grammar {
        self.grammar
    }

    fn parse(&mut self) -> Result<(), String> {
        while let Some(str_word) = self.ctx.next_word() {
            match str_word.chars().next().unwrap() {
                'A'...'Z' => {
                    match self.parse_grammar_rule(str_word) {
                        Ok(()) => {},
                        Err(msg) => {return Err(msg)},
                    }
                },
                'a'...'z' => {
                    match self.parse_lexical_unit(str_word) {
                        Ok(()) => {},
                        Err(msg) => {return Err(msg)},
                    }
                }
                _ => { return Err(String::from("Unknown token : ") + str_word.as_str())}
            }
        }

        Ok(())
    }

    fn parse_grammar_rule(&mut self, name : String) -> Result<(), String> {
        match self.ctx.next_word() {
            None => {return Err(format!("line {} : Expected '->'", self.ctx.row))},
            Some(token) => {
                if token != "->" {
                    return Err(format!("line {} : Expected '->' found '{}'", self.ctx.row, token));
                }
            }
        }

        if let Some(rule_str) = self.ctx.read_line() {
            let mut production_rule = ProductionRule{
                name: name,
                rule: Vec::new()
            };

            for comp_str in rule_str.split_whitespace() {
                let component_str = String::from(comp_str);
                let component = match component_str.chars().next().unwrap() {
                    'a'...'z' => if component_str == "epsilon" {
                        RuleComponent::Epsilon
                    } else {
                        RuleComponent::LexicalUnit(component_str.to_owned())
                    },
                    'A'...'Z' => {RuleComponent::ProductionRule(component_str.to_owned())},
                    '\'' => {
                        let s = component_str.len();
                        if s < 3 {
                            return Err(format!("line {} : The regex in a production rule cannot be empty.", self.ctx.row));
                        }

                        let regex : String = component_str.chars()
                                                    .enumerate()
                                                    .filter(|&(i, _)| 0 < i && i < s-1)
                                                    .map(|(_, c)| c)
                                                    .collect();

                        let name = format!("auto_{}", self.auto_counter);
                        self.auto_counter += 1;

                        if self.grammar.lexical_units.iter().find(|rule| rule.name == name).is_none() {
                            self.grammar.lexical_units.push(LexicalUnit{name:name.clone(), regex:String::from(regex)});
                        }

                        RuleComponent::LexicalUnit(name)
                    },
                    _ => {return Err(format!("line {}: '{}' is unexpected", self.ctx.row, component_str))}
                };

                production_rule.rule.push(component);
            }
            self.grammar.production_rules.push(production_rule);
            Ok(())
        }
        else {
            Err(format!("A production rule cannot be empty"))
        }
    }

    fn parse_lexical_unit(&mut self, name : String) -> Result<(), String> {
        //Let's read the ':'
        match self.ctx.next_word() {
            None => {return Err(format!("line {} : Expected ':'", self.ctx.row))},
            Some(token) => {
                if token != ":" {
                    return Err(format!("line {} : Expected ':' found '{}'", self.ctx.row, token));
                }
            }
        }

        //Ok, now the regex
        if let Some(regex) = self.ctx.read_line() {
            let lexical_rule = LexicalUnit {
                name: name,
                regex: regex,
            };

            if self.grammar.lexical_units.iter().find(|rule| rule.name == lexical_rule.name).is_some() {
                return Err(format!("line {} : the lexical unit {} has already been declared", self.ctx.row, lexical_rule.name));
            }

            //TODO : Implement a check by regex too
            //TODO : Check that the regex is syntacticly corret (https://crates.io/crates/regex-syntax)
            self.grammar.lexical_units.push(lexical_rule);
            Ok(())
        }
        else {
            Err(format!("line {} : The regex is expected after ':' but nothing was found", self.ctx.row))
        }
    }

    fn check_consistency(& self) -> Result<(), String> {
        for production_rule in &self.grammar.production_rules {
            for rule_component in &production_rule.rule {
                match rule_component {
                    &RuleComponent::ProductionRule(ref name) => {
                        if self.grammar.production_rules.iter().find(|r| *name == r.name).is_none() {
                            return Err(format!("The production rule '{}' does not exist", name));
                        }
                    },
                    &RuleComponent::LexicalUnit(ref name) => {
                        if self.grammar.lexical_units.iter().find(|lu| *name  == lu.name).is_none() {
                            return Err(format!("The lexical unit '{}' does not exist", name));
                        }
                    },
                    &RuleComponent::Epsilon => {},
                }
            }
        }

        Ok(())
    }

    fn check_for_left_recursion(& self) -> Result<(), String> {
        self.grammar.production_rules.iter()
            .map(|p| self.begin_with_production_rule(&p.name, &p.name))
            .fold(Ok(()), |acc, x| acc.and(x))
    }

    fn check_regexs(&self) -> Result<(), String> {
        let regex_check_job = |regex: &LexicalUnit| match Expr::parse(&regex.regex) {
                Ok(_) => Ok(()),
                Err(err) => Err(format!("Error in regex {} : {}", regex.name, err)),
            };

        self.grammar.lexical_units.iter().map(regex_check_job).fold(Ok(()), |acc, x| acc.and(x))
    }

    fn begin_with_production_rule(& self, name: &String, production_to_look_in: &String) -> Result<(), String> {
        for p in self.grammar.get_production_rule(production_to_look_in) {
            let first_component = &p.rule.iter().next().unwrap();
            if let &RuleComponent::ProductionRule(ref p_name) = *first_component {
                if name == p_name {
                    return Err(format!("Left recursion for the production rule {}", name));
                }
                else {
                    return self.begin_with_production_rule(name, p_name);
                }
            }
        }

        Ok(())
    }
}

pub fn parse_grammar(src : String) -> Result<Grammar, String> {
    let mut parser = GrammarParser::new(src);

    if let Err(msg) = parser.parse() {
        return Err(msg);
    }

    if let Err(msg) = parser.check_consistency() {
        return Err(msg);
    }

    if let Err(msg) = parser.check_for_left_recursion() {
        return Err(msg);
    }

    if let Err(msg) = parser.check_regexs() {
        return Err(msg);
    }

    Ok(parser.get_resulting_grammar())
}

#[test]
fn test_next_word() {
    let mut ctx = ParserContext::new("test and run".to_owned());

    assert_eq!(ctx.next_word().unwrap(), "test");
    assert_eq!(ctx.next_word().unwrap(), "and");
    assert_eq!(ctx.next_word().unwrap(), "run");
}

#[test]
fn test_read_line() {
    let mut ctx = ParserContext::new("line 1\nline2\nline3\nline4".to_owned());
    ctx.next_word();

    assert_eq!(ctx.read_line().unwrap(), "1");
    assert_eq!(ctx.read_line().unwrap(), "line2");
    assert_eq!(ctx.read_line().unwrap(), "line3");
    assert_eq!(ctx.read_line().unwrap(), "line4");
}
<commit_msg>Set the axiom<commit_after>/*
Copyright (c) 2016 Antoine Wacheux

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

extern crate liquid;
extern crate regex_syntax;
extern crate core;

use liquidobject::LiquidObject;
use self::liquid::Value;
use std::collections::HashMap;
use std::collections::HashSet;
use self::regex_syntax::Expr;
use self::core::iter::FromIterator;

pub struct LexicalUnit {
    name : String,
    regex : String,
}

impl LiquidObject for LexicalUnit {
    fn to_liquid_object(&self) -> Value {
        let mut result = HashMap::new();
        result.insert("name".to_owned(), liquid::Value::Str(self.name.clone()));
        result.insert("regex".to_owned(), liquid::Value::Str(self.regex.clone()));
        Value::Object(result)
    }
}

pub struct ProductionRule {
    name: String,
    rule: Vec<RuleComponent>
}

pub enum RuleComponent {
    ProductionRule(String),
    LexicalUnit(String),
    Epsilon
}

#[derive(PartialEq, Eq, Hash, Clone)]
pub enum FirstElement { //Elements that appear in the first sets
    LexicalUnit(String),
    Epsilon
}

pub struct Grammar {
    lexical_units : Vec<LexicalUnit>,
    production_rules: Vec<ProductionRule>,
    axiom : String
}

impl Grammar {
    fn new() -> Grammar {
        Grammar {
            lexical_units: Vec::new(),
            production_rules: Vec::new(),
            axiom: String::new(),
        }
    }

    fn get_production_rule(&self, name: &String) -> Vec<&ProductionRule> {
        self.production_rules.iter().filter(|x| x.name == *name).collect()
    }

    pub fn get_all_production_rules_name(&self) -> Vec<String> {
        let uniq_filter = {
            let mut found : Vec<String> = Vec::new();

            move |x:&String| {
                if found.iter().find(|elem| *elem == x).is_some() {
                    false
                }
                else {
                    found.push(x.clone());
                    true
                }
            }
        };

        self.production_rules.iter().map(|x| x.name.clone()).filter(uniq_filter).collect()
    }

    pub fn get_all_lexical_units(&self) -> &Vec<LexicalUnit> {
        &self.lexical_units
    }

    pub fn first(&self) -> HashMap<String, HashSet<FirstElement> > {
        let mut result : HashMap<String, HashSet<FirstElement> > = HashMap::new();

        for rule in self.get_all_production_rules_name() {
            result.insert(rule, HashSet::new());
        }

        let mut modified = true;

        while modified {
            modified = false;
            //println!("Iteration because of modified");

            for rule in &self.production_rules {
                let mut epsilon_found = true;
                let mut rule_node_iter = rule.rule.iter();
                let mut new_first_set : HashSet<FirstElement> = {
                    let mut set = HashSet::new();
                    let first_set = result.get(&rule.name).unwrap();
                    set = set.union(&first_set).map(|x| x.clone()).collect();
                    set
                };

                while epsilon_found {
                    //println!("Iteration because of epsilon_found");
                    epsilon_found = false;

                    if let Some(rule_node) = rule_node_iter.next() {
                        match rule_node {
                            &RuleComponent::LexicalUnit(ref name) => {
                                modified = modified || new_first_set.insert(FirstElement::LexicalUnit(name.clone()));
                            },
                            &RuleComponent::Epsilon => {
                                modified = modified || new_first_set.insert(FirstElement::Epsilon);
                            }
                            &RuleComponent::ProductionRule(ref name) => {
                                let first_set = result.get(name).unwrap();
                                //Check if we have an epsilon
                                epsilon_found = first_set.iter().any(|x| match x {
                                    &FirstElement::Epsilon => true,
                                    _ => false,
                                });

                                for elem in first_set {
                                    if let &FirstElement::LexicalUnit(ref name) = elem {
                                        //println!("Inserting {}", name);
                                        modified = modified || new_first_set.insert(elem.clone());
                                    }
                                }
                            }
                        };
                    }
                    result.insert(rule.name.clone(), new_first_set.clone());
                }
            }
        }

        result
    }
}

//Methods
//get_rule(name: String&) -> Vec<ProductionRule>&

struct ParserContext {
    src: String,
    row: u32,
    col: u32,
    str_pos: usize,
}

impl ParserContext {
    fn new(src : String) -> ParserContext {
        ParserContext {
            src: src,
            row: 1,
            col: 0,
            str_pos: 0
        }
    }

    fn next_word(&mut self) -> Option<String> {
        let mut iter = self.src.chars();
        let mut ch = iter.nth(self.str_pos);
        let mut c : char;
        let mut read_word = String::new();

        match ch {
            None => { return None },
            Some(chr) => { c = chr}
        }

        macro_rules! next_char {
            ($err:stmt) => ({
                self.str_pos += 1;
                ch = iter.next();

                match ch {
                    None => { $err },
                    Some(chr) => { c = chr }
                }

                match c { //TODO : Implement a better line/column tracking and forward this information in the word
                    ' ' | '\t' => self.col += 1,
                    '\n' => self.row += 1,
                    _ => {}
                }
            });
        }

        while (c == ' ') || (c == '\n') || (c == '\t') { //We skip leading whitespaces
            next_char! { return None }
        }

        while !((c == ' ') || (c == '\n') || (c == '\t')) {
            read_word.push(c);
            next_char! { return Some(read_word) }
        }

        Some(read_word)
    }

    pub fn read_line(&mut self) -> Option<String> {
        let mut iter = self.src.chars();
        let mut ch = iter.nth(self.str_pos);
        let mut c : char;
        let mut read_word = String::new();

        match ch {
            None => { return None },
            Some(chr) => { c = chr}
        }

        macro_rules! next_char {
            ($err:stmt) => ({
                self.str_pos += 1;
                ch = iter.next();

                match ch {
                    None => { $err },
                    Some(chr) => { c = chr }
                }

                match c {
                    ' ' | '\t' => self.col += 1,
                    '\n' => self.row += 1,
                    _ => {}
                }
            });
        }

        while (c == ' ') || (c == '\n') || (c == '\t') { //We skip leading whitespaces
            next_char! { return None }
        }

        while c != '\n' {
            read_word.push(c);
            next_char! { return Some(read_word) }
        }

        Some(read_word)
    }
}

struct GrammarParser {
    ctx: ParserContext,
    grammar: Grammar,
    auto_counter: u32, //Counter for generating automatic lexical unit name
}

impl GrammarParser {
    fn new(src: String) -> GrammarParser {
        GrammarParser {
            ctx : ParserContext::new(src),
            grammar: Grammar::new(),
            auto_counter: 1,
        }
    }

    fn get_resulting_grammar(self) -> Grammar {
        self.grammar
    }

    fn parse(&mut self) -> Result<(), String> {
        while let Some(str_word) = self.ctx.next_word() {
            match str_word.chars().next().unwrap() {
                'A'...'Z' => {
                    match self.parse_grammar_rule(str_word) {
                        Ok(()) => {},
                        Err(msg) => {return Err(msg)},
                    }
                },
                'a'...'z' => {
                    match self.parse_lexical_unit(str_word) {
                        Ok(()) => {},
                        Err(msg) => {return Err(msg)},
                    }
                }
                _ => { return Err(String::from("Unknown token : ") + str_word.as_str())}
            }
        }

        Ok(())
    }

    fn parse_grammar_rule(&mut self, name : String) -> Result<(), String> {
        match self.ctx.next_word() {
            None => {return Err(format!("line {} : Expected '->'", self.ctx.row))},
            Some(token) => {
                if token != "->" {
                    return Err(format!("line {} : Expected '->' found '{}'", self.ctx.row, token));
                }
            }
        }

        if let Some(rule_str) = self.ctx.read_line() {
            let mut production_rule = ProductionRule{
                name: name,
                rule: Vec::new()
            };

            for comp_str in rule_str.split_whitespace() {
                let component_str = String::from(comp_str);
                let component = match component_str.chars().next().unwrap() {
                    'a'...'z' => if component_str == "epsilon" {
                        RuleComponent::Epsilon
                    } else {
                        RuleComponent::LexicalUnit(component_str.to_owned())
                    },
                    'A'...'Z' => {RuleComponent::ProductionRule(component_str.to_owned())},
                    '\'' => {
                        let s = component_str.len();
                        if s < 3 {
                            return Err(format!("line {} : The regex in a production rule cannot be empty.", self.ctx.row));
                        }

                        let regex : String = component_str.chars()
                                                    .enumerate()
                                                    .filter(|&(i, _)| 0 < i && i < s-1)
                                                    .map(|(_, c)| c)
                                                    .collect();

                        let name = format!("auto_{}", self.auto_counter);
                        self.auto_counter += 1;

                        if self.grammar.lexical_units.iter().find(|rule| rule.name == name).is_none() {
                            self.grammar.lexical_units.push(LexicalUnit{name:name.clone(), regex:String::from(regex)});
                        }

                        RuleComponent::LexicalUnit(name)
                    },
                    _ => {return Err(format!("line {}: '{}' is unexpected", self.ctx.row, component_str))}
                };

                production_rule.rule.push(component);

                if self.grammar.axiom.is_empty() {
                    self.grammar.axiom = production_rule.name.clone();
                }
            }
            self.grammar.production_rules.push(production_rule);
            Ok(())
        }
        else {
            Err(format!("A production rule cannot be empty"))
        }
    }

    fn parse_lexical_unit(&mut self, name : String) -> Result<(), String> {
        //Let's read the ':'
        match self.ctx.next_word() {
            None => {return Err(format!("line {} : Expected ':'", self.ctx.row))},
            Some(token) => {
                if token != ":" {
                    return Err(format!("line {} : Expected ':' found '{}'", self.ctx.row, token));
                }
            }
        }

        //Ok, now the regex
        if let Some(regex) = self.ctx.read_line() {
            let lexical_rule = LexicalUnit {
                name: name,
                regex: regex,
            };

            if self.grammar.lexical_units.iter().find(|rule| rule.name == lexical_rule.name).is_some() {
                return Err(format!("line {} : the lexical unit {} has already been declared", self.ctx.row, lexical_rule.name));
            }

            //TODO : Implement a check by regex too
            //TODO : Check that the regex is syntacticly corret (https://crates.io/crates/regex-syntax)
            self.grammar.lexical_units.push(lexical_rule);
            Ok(())
        }
        else {
            Err(format!("line {} : The regex is expected after ':' but nothing was found", self.ctx.row))
        }
    }

    fn check_consistency(& self) -> Result<(), String> {
        for production_rule in &self.grammar.production_rules {
            for rule_component in &production_rule.rule {
                match rule_component {
                    &RuleComponent::ProductionRule(ref name) => {
                        if self.grammar.production_rules.iter().find(|r| *name == r.name).is_none() {
                            return Err(format!("The production rule '{}' does not exist", name));
                        }
                    },
                    &RuleComponent::LexicalUnit(ref name) => {
                        if self.grammar.lexical_units.iter().find(|lu| *name  == lu.name).is_none() {
                            return Err(format!("The lexical unit '{}' does not exist", name));
                        }
                    },
                    &RuleComponent::Epsilon => {},
                }
            }
        }

        Ok(())
    }

    fn check_for_left_recursion(& self) -> Result<(), String> {
        self.grammar.production_rules.iter()
            .map(|p| self.begin_with_production_rule(&p.name, &p.name))
            .fold(Ok(()), |acc, x| acc.and(x))
    }

    fn check_regexs(&self) -> Result<(), String> {
        let regex_check_job = |regex: &LexicalUnit| match Expr::parse(&regex.regex) {
                Ok(_) => Ok(()),
                Err(err) => Err(format!("Error in regex {} : {}", regex.name, err)),
            };

        self.grammar.lexical_units.iter().map(regex_check_job).fold(Ok(()), |acc, x| acc.and(x))
    }

    fn begin_with_production_rule(& self, name: &String, production_to_look_in: &String) -> Result<(), String> {
        for p in self.grammar.get_production_rule(production_to_look_in) {
            let first_component = &p.rule.iter().next().unwrap();
            if let &RuleComponent::ProductionRule(ref p_name) = *first_component {
                if name == p_name {
                    return Err(format!("Left recursion for the production rule {}", name));
                }
                else {
                    return self.begin_with_production_rule(name, p_name);
                }
            }
        }

        Ok(())
    }
}

pub fn parse_grammar(src : String) -> Result<Grammar, String> {
    let mut parser = GrammarParser::new(src);

    if let Err(msg) = parser.parse() {
        return Err(msg);
    }

    if let Err(msg) = parser.check_consistency() {
        return Err(msg);
    }

    if let Err(msg) = parser.check_for_left_recursion() {
        return Err(msg);
    }

    if let Err(msg) = parser.check_regexs() {
        return Err(msg);
    }

    Ok(parser.get_resulting_grammar())
}

#[test]
fn test_next_word() {
    let mut ctx = ParserContext::new("test and run".to_owned());

    assert_eq!(ctx.next_word().unwrap(), "test");
    assert_eq!(ctx.next_word().unwrap(), "and");
    assert_eq!(ctx.next_word().unwrap(), "run");
}

#[test]
fn test_read_line() {
    let mut ctx = ParserContext::new("line 1\nline2\nline3\nline4".to_owned());
    ctx.next_word();

    assert_eq!(ctx.read_line().unwrap(), "1");
    assert_eq!(ctx.read_line().unwrap(), "line2");
    assert_eq!(ctx.read_line().unwrap(), "line3");
    assert_eq!(ctx.read_line().unwrap(), "line4");
}
<|endoftext|>


<commit_before>use tcod;
use tcod::{BackgroundFlag, Console, Key, KeyCode};
use tcod::{KEY_PRESSED, FONT_LAYOUT_ASCII_INROW, FONT_TYPE_GREYSCALE};

use engine::Game;
use util::units::{Direction, XYPair};

#[deriving(PartialEq)]
pub enum State {
    Running,
    Exited
}

pub struct GUI {
    game: Game,
    width: int,
    height: int,
    pub console: Console,
    state: State,
}

impl GUI {
    pub fn new(game: Game) -> GUI {
        let (width, height) = (100, 50);

        tcod::system::set_fps(60);
        Console::set_custom_font(Path::new("/home/jonny/code/rslike/assets/fonts/terminal12x12_gs_ro.png"), FONT_LAYOUT_ASCII_INROW | FONT_TYPE_GREYSCALE, 0, 0);
        let console = Console::init_root(width, height, "Libtcod Rust Tutorial", false);

        GUI {
            game: game,
            width: width,
            height: height,
            console: console,
            state: State::Running,
        }
    }

    pub fn run(&mut self) {
        while !self.window_closed() && !self.exited() {
            self.render();
            self.handle_input();
        }
    }

    fn handle_input(&mut self) {
        let check_key = Console::check_for_keypress(KEY_PRESSED);

        if let Some(keypress) = check_key {
            match keypress.key {
                Key::Special(KeyCode::Up) => {
                    self.game.walk(Direction::Up);
                },
                Key::Special(KeyCode::Down) => {
                    self.game.walk(Direction::Down);
                },
                Key::Special(KeyCode::Left) => {
                    self.game.walk(Direction::Left);
                },
                Key::Special(KeyCode::Right) => {
                    self.game.walk(Direction::Right);
                },
                Key::Special(KeyCode::Escape) => {
                    self.state = State::Exited;
                },
                _ => {}
            }
        }

    }

    fn render(&mut self) {
        self.clear();

        let repr = self.game.world.player.repr();
        let pos = self.game.world.player.pos();

        self.console.put_char(pos.x, pos.y, repr, BackgroundFlag::Set);

        self.flush();
    }

    pub fn clear(&mut self) {
        self.console.clear();
    }

    pub fn flush(&mut self) {
        Console::flush();
    }

    pub fn exited(&self) -> bool {
        self.state == State::Exited
    }

    pub fn window_closed(&self) -> bool {
        Console::window_closed()
    }
}
<commit_msg>Remove unused XYPair import in GUI<commit_after>use tcod;
use tcod::{BackgroundFlag, Console, Key, KeyCode};
use tcod::{KEY_PRESSED, FONT_LAYOUT_ASCII_INROW, FONT_TYPE_GREYSCALE};

use engine::Game;
use util::units::Direction;

#[deriving(PartialEq)]
pub enum State {
    Running,
    Exited
}

pub struct GUI {
    game: Game,
    width: int,
    height: int,
    pub console: Console,
    state: State,
}

impl GUI {
    pub fn new(game: Game) -> GUI {
        let (width, height) = (100, 50);

        tcod::system::set_fps(60);
        Console::set_custom_font(Path::new("/home/jonny/code/rslike/assets/fonts/terminal12x12_gs_ro.png"), FONT_LAYOUT_ASCII_INROW | FONT_TYPE_GREYSCALE, 0, 0);
        let console = Console::init_root(width, height, "Libtcod Rust Tutorial", false);

        GUI {
            game: game,
            width: width,
            height: height,
            console: console,
            state: State::Running,
        }
    }

    pub fn run(&mut self) {
        while !self.window_closed() && !self.exited() {
            self.render();
            self.handle_input();
        }
    }

    fn handle_input(&mut self) {
        let check_key = Console::check_for_keypress(KEY_PRESSED);

        if let Some(keypress) = check_key {
            match keypress.key {
                Key::Special(KeyCode::Up) => {
                    self.game.walk(Direction::Up);
                },
                Key::Special(KeyCode::Down) => {
                    self.game.walk(Direction::Down);
                },
                Key::Special(KeyCode::Left) => {
                    self.game.walk(Direction::Left);
                },
                Key::Special(KeyCode::Right) => {
                    self.game.walk(Direction::Right);
                },
                Key::Special(KeyCode::Escape) => {
                    self.state = State::Exited;
                },
                _ => {}
            }
        }

    }

    fn render(&mut self) {
        self.clear();

        let repr = self.game.world.player.repr();
        let pos = self.game.world.player.pos();

        self.console.put_char(pos.x, pos.y, repr, BackgroundFlag::Set);

        self.flush();
    }

    pub fn clear(&mut self) {
        self.console.clear();
    }

    pub fn flush(&mut self) {
        Console::flush();
    }

    pub fn exited(&self) -> bool {
        self.state == State::Exited
    }

    pub fn window_closed(&self) -> bool {
        Console::window_closed()
    }
}
<|endoftext|>


<commit_before>extern crate ws;

use message::PeerMessage;

use std::cmp;
use std::collections::hash_map::HashMap;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};

use bincode::rustc_serialize::decode;

use ws::util::Token;

static LIB_NAME: &'static str = "ws-p2p";

const DELAYED_MESSAGE: Token = Token(1);

/// Connection handler for incoming messages.
pub struct MessageHandler {
    /// Sender that is used to communicate for the handler.
    pub ws: ws::Sender,
    /// An arc clone of my local vector clocks.
    pub clocks: Arc<Mutex<HashMap<String, u32>>>,
    /// My address/name.
    pub me: String,
    /// Buffer of messages that caused conflicts when initially received.
    pub buffer: Arc<Mutex<VecDeque<PeerMessage>>>,
    /// Delays messages received from client.
    pub demo_client: Option<String>,
    /// Holder for delayed messages.
    message_queue: VecDeque<PeerMessage>,
}

impl ws::Handler for MessageHandler {
    fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
        match msg {
            ws::Message::Binary(vector) => {
                let encoded_msg = &*vector.into_boxed_slice();
                if let Ok(message) = decode(encoded_msg) {
                    let message: PeerMessage = message;

                    debug!(target: LIB_NAME, "I am using {:?}.", self.ws.token());

                    if let Some(demo_client) = self.demo_client.clone() {
                        if message.sender.as_str() == demo_client.as_str() {
                            info!(target: LIB_NAME, "Faking delay for messages from {}!", demo_client);
                            self.message_queue.push_back(message);
                            return self.ws.timeout(4000, DELAYED_MESSAGE);
                        }
                    }

                    self.message_handler(message);
                    Ok(())
                } else {
                    Err(ws::Error::new(ws::ErrorKind::Internal,
                                    "Failed to serialize the binary message."))
                }
            }
            ws::Message::Text(string) => {
                info!(target: LIB_NAME, "Received peer's name. Adding {} to client list", string);
                if let Ok(mut clocks) = self.clocks.lock() {
                    clocks.insert(string, 0u32);
                    Ok(())
                } else {
                    Err(ws::Error::new(ws::ErrorKind::Internal,
                                    "Failed to serialize the string message."))
                }
            }
        }
    }
    fn on_timeout(&mut self, event: Token) -> ws::Result<()> {
        match event {
            DELAYED_MESSAGE => {
                if let Some(msg) = self.message_queue.pop_front() {
                    self.message_handler(msg);
                    Ok(())
                } else {
                    Err(ws::Error::new(ws::ErrorKind::Internal,
                                       "Invalid timeout token encountered!"))
                }
            }
            _ => Err(ws::Error::new(ws::ErrorKind::Internal,
                                    "Invalid timeout token encountered!")),
        }
    }
    fn on_close(&mut self, code: ws::CloseCode, reason: &str) {
        // TODO: Remove disconnected client's clock from our vclock copy.
        info!(target: LIB_NAME, "Received an on_close call");
        if reason.is_empty() {
            // This works: CloseCode::Abnormal
            info!(target: LIB_NAME, "Client disconnected with code: {:?}", code);
        } else {
            info!(target: LIB_NAME, "{} d/c with code: {:?} and reason: {}", self.me, code, reason);
        }
    }
    fn on_error(&mut self, err: ws::Error) {
        warn!(target: LIB_NAME, "Error family robinson! {:?}", err.kind);
    }
    fn on_shutdown(&mut self) {
        warn!(target: LIB_NAME, "Socket shutdown from {}", self.me);
    }
}

impl MessageHandler {
    fn buffer_check(&self) {
        let mut buffer = self.buffer.lock().unwrap();
        let buffer_clone = buffer.clone();
        for message in buffer_clone.iter() {
            let mut vclocks = self.clocks.lock().unwrap();
            for (key, val) in message.clocks.iter() {
                if key.as_str() == message.sender.as_str() {
                    if let Some(lval) = vclocks.get(&key.clone()) {
                        if *val != *lval + 1 {
                            debug!(target: LIB_NAME, "discrepency still exists");
                            return;
                        }
                    }
                } else {
                    if let Some(lval) = vclocks.get(&key.clone()) {
                        debug!(target: LIB_NAME, "key: {} val: {} and lval: {}", key, val, lval);
                        if val <= lval {
                            debug!(target: LIB_NAME, "val <= lval");
                            continue;
                        } else {
                            // There's a clock that is greater than what we have
                            debug!(target: LIB_NAME, "discrepency still exists");
                            return;
                        }
                    }
                }
            }

            // Update clocks
            for (key, val) in message.clocks.iter() {
                if vclocks.get(&key.clone()).is_some() {
                    let lval = vclocks.get(&key.clone()).unwrap().clone();
                    let max_val = cmp::max(val, &lval);
                    vclocks.insert(key.clone(), *max_val);
                }
            }
            info!(target: LIB_NAME, "buf_check: Peer {} with clocks: {:?} got message: {}",
                    message.sender, message.clocks, message.message);
            buffer.pop_front();
        }
    }
    fn message_handler(&self, message: PeerMessage) {
        {
            let mut vclocks = self.clocks.lock().unwrap();
            for (key, val) in message.clocks.iter() {
                if key.as_str() == message.sender.as_str() {
                    if let Some(lval) = vclocks.get(&key.clone()) {
                        if *val != *lval + 1 {
                            if let Ok(mut buffer) = self.buffer.lock() {
                                debug!(target: LIB_NAME, "pushing to buffer..");
                                buffer.push_back(message.clone());
                            }
                            debug!(target: LIB_NAME, "clock discrepency with from incoming peer");
                            return;
                        }
                    }
                } else {
                    if let Some(lval) = vclocks.get(&key.clone()) {
                        debug!(target: LIB_NAME, "key: {} val: {} and lval: {}", key, val, lval);
                        if val <= lval {
                            debug!(target: LIB_NAME, "val <= lval");
                            continue;
                        } else {
                            // There's a clock that is greater than what we have
                            if let Ok(mut buffer) = self.buffer.lock() {
                                debug!(target: LIB_NAME, "pushing to buffer..");
                                buffer.push_back(message.clone());
                            }
                            debug!(target: LIB_NAME, "clock discrepency from other peer clocks");
                            return;
                        }
                    }
                }
            }

            // Update clocks
            debug!(target: LIB_NAME, "Updating clocks now because no discrepency");
            info!(target: LIB_NAME, "msg_handler: Peer {} with clocks: {:?} got message: {}",
                    message.sender, message.clocks, message.message);
            for (key, val) in message.clocks.iter() {
                vclocks.insert(key.clone(), *val);
            }
        }
        self.buffer_check();
    }
}

#[derive(Clone)]
pub struct MessageFactory {
    vclocks: Arc<Mutex<HashMap<String, u32>>>,
    me: String,
    buffer: Arc<Mutex<VecDeque<PeerMessage>>>,
    demo_client: Option<String>,
}

impl MessageFactory {
    pub fn build(vclocks: Arc<Mutex<HashMap<String, u32>>>) -> MessageFactory {
        MessageFactory {
            vclocks: vclocks.clone(),
            me: String::from("undefined"),
            buffer: Arc::new(Mutex::new(VecDeque::new())),
            demo_client: None,
        }
    }
    pub fn me(&self, me: &str) -> MessageFactory {
        MessageFactory {
            vclocks: self.vclocks.clone(),
            me: String::from(me),
            buffer: self.buffer.clone(),
            demo_client: match self.demo_client.clone() {
                Some(peer) => Some(peer),
                None => None,
            },
        }
    }
    pub fn demo(&mut self, peer: &str) {
        self.demo_client = Some(String::from(peer));
    }
}

impl ws::Factory for MessageFactory {
    type Handler = MessageHandler;

    fn connection_made(&mut self, ws: ws::Sender) -> Self::Handler {
        MessageHandler {
            ws: ws,
            clocks: self.vclocks.clone(),
            me: self.me.clone(),
            buffer: self.buffer.clone(),
            demo_client: self.demo_client.clone(),
            message_queue: VecDeque::new(),
        }
    }

    fn server_connected(&mut self, ws: ws::Sender) -> Self::Handler {
        ws.send(self.me.clone()).unwrap();
        MessageHandler {
            ws: ws,
            clocks: self.vclocks.clone(),
            me: self.me.clone(),
            buffer: self.buffer.clone(),
            demo_client: self.demo_client.clone(),
            message_queue: VecDeque::new(),
        }
    }

    fn client_connected(&mut self, ws: ws::Sender) -> Self::Handler {
        ws.send(self.me.clone()).unwrap();
        MessageHandler {
            ws: ws,
            clocks: self.vclocks.clone(),
            me: self.me.clone(),
            buffer: self.buffer.clone(),
            demo_client: self.demo_client.clone(),
            message_queue: VecDeque::new(),
        }
    }
}
<commit_msg>Added a comment so I remember later<commit_after>extern crate ws;

use message::PeerMessage;

use std::cmp;
use std::collections::hash_map::HashMap;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};

use bincode::rustc_serialize::decode;

use ws::util::Token;

static LIB_NAME: &'static str = "ws-p2p";

const DELAYED_MESSAGE: Token = Token(1);

/// Connection handler for incoming messages.
pub struct MessageHandler {
    /// Sender that is used to communicate for the handler.
    pub ws: ws::Sender,
    /// An arc clone of my local vector clocks.
    pub clocks: Arc<Mutex<HashMap<String, u32>>>,
    /// My address/name.
    pub me: String,
    /// Buffer of messages that caused conflicts when initially received.
    pub buffer: Arc<Mutex<VecDeque<PeerMessage>>>,
    /// Delays messages received from client.
    pub demo_client: Option<String>,
    /// Holder for delayed messages.
    message_queue: VecDeque<PeerMessage>,
}

impl ws::Handler for MessageHandler {
    fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
        match msg {
            ws::Message::Binary(vector) => {
                let encoded_msg = &*vector.into_boxed_slice();
                if let Ok(message) = decode(encoded_msg) {
                    let message: PeerMessage = message;

                    debug!(target: LIB_NAME, "I am using {:?}.", self.ws.token());

                    if let Some(demo_client) = self.demo_client.clone() {
                        if message.sender.as_str() == demo_client.as_str() {
                            info!(target: LIB_NAME, "Faking delay for messages from {}!", demo_client);
                            self.message_queue.push_back(message);
                            return self.ws.timeout(4000, DELAYED_MESSAGE);
                        }
                    }

                    self.message_handler(message);
                    Ok(())
                } else {
                    Err(ws::Error::new(ws::ErrorKind::Internal,
                                    "Failed to serialize the binary message."))
                }
            }
            ws::Message::Text(string) => {
                info!(target: LIB_NAME, "Received peer's name. Adding {} to client list", string);
                if let Ok(mut clocks) = self.clocks.lock() {
                    clocks.insert(string, 0u32);
                    Ok(())
                } else {
                    Err(ws::Error::new(ws::ErrorKind::Internal,
                                    "Failed to serialize the string message."))
                }
            }
        }
    }
    fn on_timeout(&mut self, event: Token) -> ws::Result<()> {
        match event {
            DELAYED_MESSAGE => {
                if let Some(msg) = self.message_queue.pop_front() {
                    self.message_handler(msg);
                    Ok(())
                } else {
                    Err(ws::Error::new(ws::ErrorKind::Internal,
                                       "Invalid timeout token encountered!"))
                }
            }
            _ => Err(ws::Error::new(ws::ErrorKind::Internal,
                                    "Invalid timeout token encountered!")),
        }
    }
    fn on_close(&mut self, code: ws::CloseCode, reason: &str) {
        // TODO: Remove disconnected client's clock from our vclock copy.
        info!(target: LIB_NAME, "Received an on_close call");
        if reason.is_empty() {
            // This works: CloseCode::Abnormal
            info!(target: LIB_NAME, "Client disconnected with code: {:?}", code);
        } else {
            info!(target: LIB_NAME, "{} d/c with code: {:?} and reason: {}", self.me, code, reason);
        }
    }
    fn on_error(&mut self, err: ws::Error) {
        warn!(target: LIB_NAME, "Error family robinson! {:?}", err.kind);
    }
    fn on_shutdown(&mut self) {
        warn!(target: LIB_NAME, "Socket shutdown from {}", self.me);
    }
}

impl MessageHandler {
    fn buffer_check(&self) {
        let mut buffer = self.buffer.lock().unwrap();
        let buffer_clone = buffer.clone();
        for message in buffer_clone.iter() {
            let mut vclocks = self.clocks.lock().unwrap();
            for (key, val) in message.clocks.iter() {
                if key.as_str() == message.sender.as_str() {
                    if let Some(lval) = vclocks.get(&key.clone()) {
                        if *val != *lval + 1 {
                            debug!(target: LIB_NAME, "discrepency still exists");
                            return;
                        }
                    }
                } else {
                    if let Some(lval) = vclocks.get(&key.clone()) {
                        debug!(target: LIB_NAME, "key: {} val: {} and lval: {}", key, val, lval);
                        if val <= lval {
                            debug!(target: LIB_NAME, "val <= lval");
                            continue;
                        } else {
                            // There's a clock that is greater than what we have
                            debug!(target: LIB_NAME, "discrepency still exists");
                            return;
                        }
                    }
                }
            }

            // Update clocks
            for (key, val) in message.clocks.iter() {
                if vclocks.get(&key.clone()).is_some() {
                    let lval = vclocks.get(&key.clone()).unwrap().clone();
                    let max_val = cmp::max(val, &lval);
                    vclocks.insert(key.clone(), *max_val);
                }
            }
            info!(target: LIB_NAME, "buf_check: Peer {} with clocks: {:?} got message: {}",
                    message.sender, message.clocks, message.message);
            buffer.pop_front();
        }
    }
    fn message_handler(&self, message: PeerMessage) {
        // Finishes the lifetime of the mutex holds so buffer_check can use it without blocking
        {
            let mut vclocks = self.clocks.lock().unwrap();
            for (key, val) in message.clocks.iter() {
                if key.as_str() == message.sender.as_str() {
                    if let Some(lval) = vclocks.get(&key.clone()) {
                        if *val != *lval + 1 {
                            if let Ok(mut buffer) = self.buffer.lock() {
                                debug!(target: LIB_NAME, "pushing to buffer..");
                                buffer.push_back(message.clone());
                            }
                            debug!(target: LIB_NAME, "clock discrepency with from incoming peer");
                            return;
                        }
                    }
                } else {
                    if let Some(lval) = vclocks.get(&key.clone()) {
                        debug!(target: LIB_NAME, "key: {} val: {} and lval: {}", key, val, lval);
                        if val <= lval {
                            debug!(target: LIB_NAME, "val <= lval");
                            continue;
                        } else {
                            // There's a clock that is greater than what we have
                            if let Ok(mut buffer) = self.buffer.lock() {
                                debug!(target: LIB_NAME, "pushing to buffer..");
                                buffer.push_back(message.clone());
                            }
                            debug!(target: LIB_NAME, "clock discrepency from other peer clocks");
                            return;
                        }
                    }
                }
            }

            // Update clocks
            debug!(target: LIB_NAME, "Updating clocks now because no discrepency");
            info!(target: LIB_NAME, "msg_handler: Peer {} with clocks: {:?} got message: {}",
                    message.sender, message.clocks, message.message);
            for (key, val) in message.clocks.iter() {
                vclocks.insert(key.clone(), *val);
            }
        }
        self.buffer_check();
    }
}

#[derive(Clone)]
pub struct MessageFactory {
    vclocks: Arc<Mutex<HashMap<String, u32>>>,
    me: String,
    buffer: Arc<Mutex<VecDeque<PeerMessage>>>,
    demo_client: Option<String>,
}

impl MessageFactory {
    pub fn build(vclocks: Arc<Mutex<HashMap<String, u32>>>) -> MessageFactory {
        MessageFactory {
            vclocks: vclocks.clone(),
            me: String::from("undefined"),
            buffer: Arc::new(Mutex::new(VecDeque::new())),
            demo_client: None,
        }
    }
    pub fn me(&self, me: &str) -> MessageFactory {
        MessageFactory {
            vclocks: self.vclocks.clone(),
            me: String::from(me),
            buffer: self.buffer.clone(),
            demo_client: match self.demo_client.clone() {
                Some(peer) => Some(peer),
                None => None,
            },
        }
    }
    pub fn demo(&mut self, peer: &str) {
        self.demo_client = Some(String::from(peer));
    }
}

impl ws::Factory for MessageFactory {
    type Handler = MessageHandler;

    fn connection_made(&mut self, ws: ws::Sender) -> Self::Handler {
        MessageHandler {
            ws: ws,
            clocks: self.vclocks.clone(),
            me: self.me.clone(),
            buffer: self.buffer.clone(),
            demo_client: self.demo_client.clone(),
            message_queue: VecDeque::new(),
        }
    }

    fn server_connected(&mut self, ws: ws::Sender) -> Self::Handler {
        ws.send(self.me.clone()).unwrap();
        MessageHandler {
            ws: ws,
            clocks: self.vclocks.clone(),
            me: self.me.clone(),
            buffer: self.buffer.clone(),
            demo_client: self.demo_client.clone(),
            message_queue: VecDeque::new(),
        }
    }

    fn client_connected(&mut self, ws: ws::Sender) -> Self::Handler {
        ws.send(self.me.clone()).unwrap();
        MessageHandler {
            ws: ws,
            clocks: self.vclocks.clone(),
            me: self.me.clone(),
            buffer: self.buffer.clone(),
            demo_client: self.demo_client.clone(),
            message_queue: VecDeque::new(),
        }
    }
}
<|endoftext|>


<commit_before>//! Define trait for Hermite matrices

use ndarray::{Ix2, Array};
use lapack::c::Layout;

use matrix::{Matrix, MFloat};
use square::SquareMatrix;
use error::LinalgError;
use eigh::ImplEigh;
use cholesky::ImplCholesky;

pub trait HMFloat: ImplEigh + ImplCholesky + MFloat {}
impl<A: ImplEigh + ImplCholesky + MFloat> HMFloat for A {}

/// Methods for Hermite matrix
pub trait HermiteMatrix: SquareMatrix + Matrix {
    /// eigenvalue decomposition
    fn eigh(self) -> Result<(Self::Vector, Self), LinalgError>;
    /// symmetric square root of Hermite matrix
    fn ssqrt(self) -> Result<Self, LinalgError>;
    /// Cholesky factorization
    fn cholesky(self) -> Result<Self, LinalgError>;
    /// calc determinant using Cholesky factorization
    fn deth(self) -> Result<Self::Scalar, LinalgError>;
}

impl<A: HMFloat> HermiteMatrix for Array<A, Ix2> {
    fn eigh(self) -> Result<(Self::Vector, Self), LinalgError> {
        self.check_square()?;
        let layout = self.layout()?;
        let (rows, cols) = self.size();
        let (w, a) = ImplEigh::eigh(layout, rows, self.into_raw_vec())?;
        let ea = Array::from_vec(w);
        let va = match layout {
            Layout::ColumnMajor => Array::from_vec(a).into_shape((rows, cols)).unwrap().reversed_axes(),
            Layout::RowMajor => Array::from_vec(a).into_shape((rows, cols)).unwrap(),
        };
        Ok((ea, va))
    }
    fn ssqrt(self) -> Result<Self, LinalgError> {
        let (n, _) = self.size();
        let (e, v) = self.eigh()?;
        let mut res = Array::zeros((n, n));
        for i in 0..n {
            for j in 0..n {
                res[(i, j)] = e[i].sqrt() * v[(j, i)];
            }
        }
        Ok(v.dot(&res))
    }
    fn cholesky(self) -> Result<Self, LinalgError> {
        self.check_square()?;
        let (n, _) = self.size();
        let layout = self.layout()?;
        let a = ImplCholesky::cholesky(layout, n, self.into_raw_vec())?;
        let mut c = match layout {
            Layout::RowMajor => Array::from_vec(a).into_shape((n, n)).unwrap(),
            Layout::ColumnMajor => Array::from_vec(a).into_shape((n, n)).unwrap().reversed_axes(),
        };
        for ((i, j), val) in c.indexed_iter_mut() {
            if i > j {
                *val = A::zero();
            }
        }
        Ok(c)
    }
    fn deth(self) -> Result<Self::Scalar, LinalgError> {
        let (n, _) = self.size();
        let c = self.cholesky()?;
        let rt = (0..n).map(|i| c[(i, i)]).fold(A::one(), |det, c| det * c);
        Ok(rt * rt)
    }
}
<commit_msg>Implement HermiteMatrix for RcArray<A, Ix2><commit_after>//! Define trait for Hermite matrices

use ndarray::{Ix2, Array, RcArray};
use lapack::c::Layout;

use matrix::{Matrix, MFloat};
use square::SquareMatrix;
use error::LinalgError;
use eigh::ImplEigh;
use cholesky::ImplCholesky;

pub trait HMFloat: ImplEigh + ImplCholesky + MFloat {}
impl<A: ImplEigh + ImplCholesky + MFloat> HMFloat for A {}

/// Methods for Hermite matrix
pub trait HermiteMatrix: SquareMatrix + Matrix {
    /// eigenvalue decomposition
    fn eigh(self) -> Result<(Self::Vector, Self), LinalgError>;
    /// symmetric square root of Hermite matrix
    fn ssqrt(self) -> Result<Self, LinalgError>;
    /// Cholesky factorization
    fn cholesky(self) -> Result<Self, LinalgError>;
    /// calc determinant using Cholesky factorization
    fn deth(self) -> Result<Self::Scalar, LinalgError>;
}

impl<A: HMFloat> HermiteMatrix for Array<A, Ix2> {
    fn eigh(self) -> Result<(Self::Vector, Self), LinalgError> {
        self.check_square()?;
        let layout = self.layout()?;
        let (rows, cols) = self.size();
        let (w, a) = ImplEigh::eigh(layout, rows, self.into_raw_vec())?;
        let ea = Array::from_vec(w);
        let va = match layout {
            Layout::ColumnMajor => Array::from_vec(a).into_shape((rows, cols)).unwrap().reversed_axes(),
            Layout::RowMajor => Array::from_vec(a).into_shape((rows, cols)).unwrap(),
        };
        Ok((ea, va))
    }
    fn ssqrt(self) -> Result<Self, LinalgError> {
        let (n, _) = self.size();
        let (e, v) = self.eigh()?;
        let mut res = Array::zeros((n, n));
        for i in 0..n {
            for j in 0..n {
                res[(i, j)] = e[i].sqrt() * v[(j, i)];
            }
        }
        Ok(v.dot(&res))
    }
    fn cholesky(self) -> Result<Self, LinalgError> {
        self.check_square()?;
        let (n, _) = self.size();
        let layout = self.layout()?;
        let a = ImplCholesky::cholesky(layout, n, self.into_raw_vec())?;
        let mut c = match layout {
            Layout::RowMajor => Array::from_vec(a).into_shape((n, n)).unwrap(),
            Layout::ColumnMajor => Array::from_vec(a).into_shape((n, n)).unwrap().reversed_axes(),
        };
        for ((i, j), val) in c.indexed_iter_mut() {
            if i > j {
                *val = A::zero();
            }
        }
        Ok(c)
    }
    fn deth(self) -> Result<Self::Scalar, LinalgError> {
        let (n, _) = self.size();
        let c = self.cholesky()?;
        let rt = (0..n).map(|i| c[(i, i)]).fold(A::one(), |det, c| det * c);
        Ok(rt * rt)
    }
}

impl<A: HMFloat> HermiteMatrix for RcArray<A, Ix2> {
    fn eigh(self) -> Result<(Self::Vector, Self), LinalgError> {
        // XXX unnecessray clone (should use into_owned())
        let (e, v) = self.to_owned().eigh()?;
        Ok((e.into_shared(), v.into_shared()))
    }
    fn ssqrt(self) -> Result<Self, LinalgError> {
        // XXX unnecessray clone (should use into_owned())
        let s = self.to_owned().ssqrt()?;
        Ok(s.into_shared())
    }
    fn cholesky(self) -> Result<Self, LinalgError> {
        // XXX unnecessray clone (should use into_owned())
        let s = self.to_owned().cholesky()?;
        Ok(s.into_shared())
    }
    fn deth(self) -> Result<Self::Scalar, LinalgError> {
        // XXX unnecessray clone (should use into_owned())
        self.to_owned().deth()
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use {Command, Error, Record};

#[derive(Debug)]
struct Branch<R> {
    parent: usize,
    cursor: usize,
    commands: Box<[Box<dyn Command<R> + 'static>]>,
}

/// A history of commands.
#[derive(Debug)]
pub struct History<R> {
    id: usize,
    record: Record<R>,
    branches: Vec<Branch<R>>,
}

impl<R> History<R> {
    /// Returns a new history.
    #[inline]
    pub fn new(receiver: impl Into<R>) -> History<R> {
        History {
            id: 0,
            record: Record::new(receiver),
            branches: Vec::new(),
        }
    }

    /// Pushes the command to the top of the history and executes its [`apply`] method.
    /// The command is merged with the previous top command if they have the same [`id`].
    ///
    /// # Errors
    /// If an error occur when executing [`apply`] the error is returned together with the command.
    ///
    /// [`apply`]: trait.Command.html#tymethod.apply
    /// [`id`]: trait.Command.html#method.id
    #[inline]
    pub fn apply(&mut self, cmd: impl Command<R> + 'static) -> Result<(), Error<R>>
    where
        R: 'static,
    {
        let commands = self.record.apply(cmd)?;
        let commands: Vec<_> = commands.collect();
        if !commands.is_empty() {
            self.branches.push(Branch {
                parent: self.id,
                cursor: self.record.cursor(),
                commands: commands.into_boxed_slice(),
            });
        }
        Ok(())
    }

    /// Calls the [`undo`] method for the active command and sets the previous one as the new active one.
    ///
    /// # Errors
    /// If an error occur when executing [`undo`] the error is returned together with the command.
    ///
    /// [`undo`]: trait.Command.html#tymethod.undo
    #[inline]
    #[must_use]
    pub fn undo(&mut self) -> Option<Result<(), Error<R>>> {
        self.record.undo()
    }

    /// Calls the [`redo`] method for the active command and sets the next one as the
    /// new active one.
    ///
    /// # Errors
    /// If an error occur when executing [`redo`] the error is returned together with the command.
    ///
    /// [`redo`]: trait.Command.html#method.redo
    #[inline]
    #[must_use]
    pub fn redo(&mut self) -> Option<Result<(), Error<R>>> {
        self.record.redo()
    }
}

impl<R> From<R> for History<R> {
    #[inline]
    fn from(receiver: R) -> Self {
        History::new(receiver)
    }
}

/// Builder for a history.
#[allow(missing_debug_implementations)]
pub struct HistoryBuilder<R> {
    receiver: PhantomData<R>,
}
<commit_msg>Add path from dest to origin branch in jump_to<commit_after>use std::collections::HashMap;
use std::marker::PhantomData;
use std::ops::RangeFrom;
use {Command, Error, Record};

#[derive(Debug)]
struct Branch<R> {
    parent: usize,
    cursor: usize,
    commands: Box<[Box<dyn Command<R> + 'static>]>,
}

/// A history of commands.
#[derive(Debug)]
pub struct History<R> {
    id: usize,
    next: RangeFrom<usize>,
    record: Record<R>,
    branches: HashMap<usize, Branch<R>>,
}

impl<R> History<R> {
    /// Returns a new history.
    #[inline]
    pub fn new(receiver: impl Into<R>) -> History<R> {
        History {
            id: 0,
            next: 1..,
            record: Record::new(receiver),
            branches: HashMap::new(),
        }
    }

    /// Pushes the command to the top of the history and executes its [`apply`] method.
    /// The command is merged with the previous top command if they have the same [`id`].
    ///
    /// # Errors
    /// If an error occur when executing [`apply`] the error is returned together with the command.
    ///
    /// [`apply`]: trait.Command.html#tymethod.apply
    /// [`id`]: trait.Command.html#method.id
    #[inline]
    pub fn apply(&mut self, cmd: impl Command<R> + 'static) -> Result<Option<usize>, Error<R>>
    where
        R: 'static,
    {
        let commands = self.record.apply(cmd)?;
        let commands: Vec<_> = commands.collect();
        if !commands.is_empty() {
            let id = self.next.next().unwrap();
            self.branches.insert(
                id,
                Branch {
                    parent: self.id,
                    cursor: self.record.cursor(),
                    commands: commands.into_boxed_slice(),
                },
            );
            Ok(Some(id))
        } else {
            Ok(None)
        }
    }

    /// Calls the [`undo`] method for the active command and sets the previous one as the new active one.
    ///
    /// # Errors
    /// If an error occur when executing [`undo`] the error is returned together with the command.
    ///
    /// [`undo`]: trait.Command.html#tymethod.undo
    #[inline]
    #[must_use]
    pub fn undo(&mut self) -> Option<Result<(), Error<R>>> {
        self.record.undo()
    }

    /// Calls the [`redo`] method for the active command and sets the next one as the
    /// new active one.
    ///
    /// # Errors
    /// If an error occur when executing [`redo`] the error is returned together with the command.
    ///
    /// [`redo`]: trait.Command.html#method.redo
    #[inline]
    #[must_use]
    pub fn redo(&mut self) -> Option<Result<(), Error<R>>> {
        self.record.redo()
    }

    /// Jumps to the command in `branch` at `cursor`.
    #[inline]
    #[must_use]
    pub fn jump_to(&mut self, branch: usize, cursor: usize) -> Option<Result<(), Error<R>>> {
        if self.id == branch {
            return self.record.set_cursor(cursor);
        }

        let mut dst = &self.branches[&branch];
        let mut path = vec![dst];
        while dst.parent != self.id {
            dst = &self.branches[&dst.parent];
            path.push(dst);
        }

        while let Some(last) = path.pop() {
            let _ = last.parent;
            let _ = last.cursor;
        }

        unimplemented!()
    }
}

impl<R> From<R> for History<R> {
    #[inline]
    fn from(receiver: R) -> Self {
        History::new(receiver)
    }
}

/// Builder for a history.
#[allow(missing_debug_implementations)]
pub struct HistoryBuilder<R> {
    receiver: PhantomData<R>,
}
<|endoftext|>