<commit_before>use std::default::Default;
use std::collections::BTreeMap;

use quire::validate as V;
use quire::ast::Ast as A;
use quire::ast::Ast;
use quire::ast::Tag::{NonSpecific};
use quire::ast::ScalarKind::{Plain};

type PortNumValidator = V::Numeric<u16>;

#[derive(Decodable, Clone, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum Pid1Mode {
    exec = 0,
    wait = 1,
    wait_all_children = 2,
}

#[derive(Decodable, Show, Clone, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum SuperviseMode {
    wait_all,
    stop_on_failure,
    restart,
}

#[derive(Decodable, Show, Clone, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum WriteMode {
    read_only,
    transient_reflink_copy,
    transient_hardlink_copy,
}

#[derive(Decodable, Clone, PartialEq, Eq)]
pub struct Network {
    pub ip: String,
    pub hostname: Option<String>,
    pub ports: BTreeMap<u16, u16>,
}

#[derive(Decodable, Clone, PartialEq, Eq)]
pub struct CommandInfo {
    // Common for toplevel commands
    pub description: Option<String>,
    pub banner: Option<String>,
    pub banner_delay: Option<u32>,
    pub epilog: Option<String>,

    // Command
    pub network: Option<Network>, // Only for top-levels
    pub pid1mode: Pid1Mode,
    pub work_dir: Option<String>,
    pub container: String,
    pub accepts_arguments: Option<bool>,
    pub environ: BTreeMap<String, String>,
    pub inherit_environ: Vec<String>,
    pub write_mode: WriteMode,
    pub run: Vec<String>,
}

#[derive(Decodable, Clone, PartialEq, Eq)]
pub struct SuperviseInfo {
    // Common
    pub description: Option<String>,
    pub banner: Option<String>,
    pub banner_delay: Option<u32>,
    pub epilog: Option<String>,

    // Supervise
    pub mode: SuperviseMode,
    pub children: BTreeMap<String, ChildCommand>,
}

#[derive(Decodable, PartialEq, Eq, Clone)]
pub enum MainCommand {
    Command(CommandInfo),
    Supervise(SuperviseInfo),
}

impl MainCommand {
    pub fn description<'x>(&'x self) -> Option<&'x String> {
        match *self {
            MainCommand::Command(ref cmd) => cmd.description.as_ref(),
            MainCommand::Supervise(ref cmd) => cmd.description.as_ref(),
        }
    }
}

#[derive(Decodable, PartialEq, Eq, Clone)]
pub enum ChildCommand {
    Command(CommandInfo),
    BridgeCommand(CommandInfo),
}

impl ChildCommand {
    pub fn get_container<'x>(&'x self) -> &String {
        match *self {
            ChildCommand::Command(ref info) => &info.container,
            ChildCommand::BridgeCommand(ref info) => &info.container,
        }
    }
}

fn shell_command(ast: Ast) -> Vec<Ast> {
    match ast {
        A::Scalar(pos, _, style, value) => {
            return vec!(
                A::Scalar(pos.clone(), NonSpecific, Plain,
                          "/bin/sh".to_string()),
                A::Scalar(pos.clone(), NonSpecific, Plain,
                          "-c".to_string()),
                A::Scalar(pos.clone(), NonSpecific, style,
                          value),
                );
        }
        _ => unreachable!(),
    }
}

fn run_fields<'a>(network: bool) -> Vec<(String, Box<V::Validator + 'a>)> {
    let mut res = vec!(
        ("pid1mode".to_string(), box V::Scalar {
            default: Some("wait".to_string()),
            .. Default::default()} as Box<V::Validator>),
        ("work_dir".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("container".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("accepts_arguments".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("environ".to_string(), box V::Mapping {
            key_element: box V::Scalar {
                .. Default::default()} as Box<V::Validator>,
            value_element: box V::Scalar {
                .. Default::default()} as Box<V::Validator>,
            .. Default::default()} as Box<V::Validator>),
        ("inherit_environ".to_string(), box V::Sequence {
            element: box V::Scalar {
                .. Default::default()} as Box<V::Validator>,
            .. Default::default()} as Box<V::Validator>),
        ("write_mode".to_string(), box V::Scalar {
            default: Some("read-only".to_string()),
            .. Default::default()} as Box<V::Validator>),
        ("run".to_string(), box V::Sequence {
            from_scalar: Some(shell_command as fn(Ast) -> Vec<Ast>),
            element: box V::Scalar {
                .. Default::default()} as Box<V::Validator>,
            .. Default::default()} as Box<V::Validator>),
    );
    if network {
        res.push(
            ("network".to_string(), box V::Structure { members: vec!(
                ("ip".to_string(), box V::Scalar {
                    optional: true,
                    .. Default::default()} as Box<V::Validator>),
                ("hostname".to_string(), box V::Scalar {
                    optional: true,
                    .. Default::default()} as Box<V::Validator>),
                ("ports".to_string(), box V::Mapping {
                    key_element: box V::Numeric {
                        default: None::<u16>,
                        .. Default::default()} as Box<V::Validator>,
                    value_element: box V::Numeric {
                        default: None::<u16>,
                        .. Default::default()} as Box<V::Validator>,
                    .. Default::default()} as Box<V::Validator>),
                ),.. Default::default()} as Box<V::Validator>),
        );
    }
    return res;
}

fn command_fields<'a>() -> Vec<(String, Box<V::Validator + 'a>)> {
    return vec!(
        ("description".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("banner".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("banner_delay".to_string(), box V::Numeric {
            optional: true,
            min: Some(0u32),
            .. Default::default()} as Box<V::Validator>),
        ("epilog".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        );
}

fn subcommand_validator<'a>() -> Box<V::Validator + 'a> {
    return box V::Enum { options: vec!(
        ("Command".to_string(), box V::Structure {
            members: run_fields(true),
            .. Default::default()} as Box<V::Validator>),
        ("BridgeCommand".to_string(), box V::Structure {
            members: run_fields(false),
            .. Default::default()} as Box<V::Validator>),
    ), .. Default::default()} as Box<V::Validator>;
}

pub fn command_validator<'a>() -> Box<V::Validator + 'a> {
    let mut command_members = vec!();
    command_members.extend(command_fields().into_iter());
    command_members.extend(run_fields(false).into_iter());

    let mut supervise_members = vec!(
        ("mode".to_string(), box V::Scalar {
            default: Some("stop-on-failure".to_string()),
            .. Default::default()} as Box<V::Validator>),
        ("children".to_string(), box V::Mapping {
            key_element: box V::Scalar {
                ..Default::default()} as Box<V::Validator>,
            value_element: subcommand_validator(),
            .. Default::default()} as Box<V::Validator>),
        );
    supervise_members.extend(command_fields().into_iter());

    return box V::Enum { options: vec!(
        ("Command".to_string(), box V::Structure {
            members: command_members,
            .. Default::default()} as Box<V::Validator>),
        ("Supervise".to_string(), box V::Structure {
            members: supervise_members,
            .. Default::default()} as Box<V::Validator>),
    ), .. Default::default()} as Box<V::Validator>;
}

pub trait Networking {
    fn network<'x>(&'x self) -> Option<&'x Network>;
}

impl Networking for ChildCommand {
    fn network<'x>(&'x self) -> Option<&'x Network> {
        match self {
            &ChildCommand::Command(ref cmd) => cmd.network.as_ref(),
            &ChildCommand::BridgeCommand(_) => None,
        }
    }
}
<commit_msg>Made `network` optional for supervise commands (was bug)<commit_after>use std::default::Default;
use std::collections::BTreeMap;

use quire::validate as V;
use quire::ast::Ast as A;
use quire::ast::Ast;
use quire::ast::Tag::{NonSpecific};
use quire::ast::ScalarKind::{Plain};

type PortNumValidator = V::Numeric<u16>;

#[derive(Decodable, Clone, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum Pid1Mode {
    exec = 0,
    wait = 1,
    wait_all_children = 2,
}

#[derive(Decodable, Show, Clone, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum SuperviseMode {
    wait_all,
    stop_on_failure,
    restart,
}

#[derive(Decodable, Show, Clone, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum WriteMode {
    read_only,
    transient_reflink_copy,
    transient_hardlink_copy,
}

#[derive(Decodable, Clone, PartialEq, Eq)]
pub struct Network {
    pub ip: String,
    pub hostname: Option<String>,
    pub ports: BTreeMap<u16, u16>,
}

#[derive(Decodable, Clone, PartialEq, Eq)]
pub struct CommandInfo {
    // Common for toplevel commands
    pub description: Option<String>,
    pub banner: Option<String>,
    pub banner_delay: Option<u32>,
    pub epilog: Option<String>,

    // Command
    pub network: Option<Network>, // Only for top-levels
    pub pid1mode: Pid1Mode,
    pub work_dir: Option<String>,
    pub container: String,
    pub accepts_arguments: Option<bool>,
    pub environ: BTreeMap<String, String>,
    pub inherit_environ: Vec<String>,
    pub write_mode: WriteMode,
    pub run: Vec<String>,
}

#[derive(Decodable, Clone, PartialEq, Eq)]
pub struct SuperviseInfo {
    // Common
    pub description: Option<String>,
    pub banner: Option<String>,
    pub banner_delay: Option<u32>,
    pub epilog: Option<String>,

    // Supervise
    pub mode: SuperviseMode,
    pub children: BTreeMap<String, ChildCommand>,
}

#[derive(Decodable, PartialEq, Eq, Clone)]
pub enum MainCommand {
    Command(CommandInfo),
    Supervise(SuperviseInfo),
}

impl MainCommand {
    pub fn description<'x>(&'x self) -> Option<&'x String> {
        match *self {
            MainCommand::Command(ref cmd) => cmd.description.as_ref(),
            MainCommand::Supervise(ref cmd) => cmd.description.as_ref(),
        }
    }
}

#[derive(Decodable, PartialEq, Eq, Clone)]
pub enum ChildCommand {
    Command(CommandInfo),
    BridgeCommand(CommandInfo),
}

impl ChildCommand {
    pub fn get_container<'x>(&'x self) -> &String {
        match *self {
            ChildCommand::Command(ref info) => &info.container,
            ChildCommand::BridgeCommand(ref info) => &info.container,
        }
    }
}

fn shell_command(ast: Ast) -> Vec<Ast> {
    match ast {
        A::Scalar(pos, _, style, value) => {
            return vec!(
                A::Scalar(pos.clone(), NonSpecific, Plain,
                          "/bin/sh".to_string()),
                A::Scalar(pos.clone(), NonSpecific, Plain,
                          "-c".to_string()),
                A::Scalar(pos.clone(), NonSpecific, style,
                          value),
                );
        }
        _ => unreachable!(),
    }
}

fn run_fields<'a>(network: bool) -> Vec<(String, Box<V::Validator + 'a>)> {
    let mut res = vec!(
        ("pid1mode".to_string(), box V::Scalar {
            default: Some("wait".to_string()),
            .. Default::default()} as Box<V::Validator>),
        ("work_dir".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("container".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("accepts_arguments".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("environ".to_string(), box V::Mapping {
            key_element: box V::Scalar {
                .. Default::default()} as Box<V::Validator>,
            value_element: box V::Scalar {
                .. Default::default()} as Box<V::Validator>,
            .. Default::default()} as Box<V::Validator>),
        ("inherit_environ".to_string(), box V::Sequence {
            element: box V::Scalar {
                .. Default::default()} as Box<V::Validator>,
            .. Default::default()} as Box<V::Validator>),
        ("write_mode".to_string(), box V::Scalar {
            default: Some("read-only".to_string()),
            .. Default::default()} as Box<V::Validator>),
        ("run".to_string(), box V::Sequence {
            from_scalar: Some(shell_command as fn(Ast) -> Vec<Ast>),
            element: box V::Scalar {
                .. Default::default()} as Box<V::Validator>,
            .. Default::default()} as Box<V::Validator>),
    );
    if network {
        res.push(
            ("network".to_string(), box V::Structure {
                optional: true,
                members: vec!(
                ("ip".to_string(), box V::Scalar {
                    optional: true,
                    .. Default::default()} as Box<V::Validator>),
                ("hostname".to_string(), box V::Scalar {
                    optional: true,
                    .. Default::default()} as Box<V::Validator>),
                ("ports".to_string(), box V::Mapping {
                    key_element: box V::Numeric {
                        default: None::<u16>,
                        .. Default::default()} as Box<V::Validator>,
                    value_element: box V::Numeric {
                        default: None::<u16>,
                        .. Default::default()} as Box<V::Validator>,
                    .. Default::default()} as Box<V::Validator>),
                ),.. Default::default()} as Box<V::Validator>),
        );
    }
    return res;
}

fn command_fields<'a>() -> Vec<(String, Box<V::Validator + 'a>)> {
    return vec!(
        ("description".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("banner".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        ("banner_delay".to_string(), box V::Numeric {
            optional: true,
            min: Some(0u32),
            .. Default::default()} as Box<V::Validator>),
        ("epilog".to_string(), box V::Scalar {
            optional: true,
            .. Default::default()} as Box<V::Validator>),
        );
}

fn subcommand_validator<'a>() -> Box<V::Validator + 'a> {
    return box V::Enum { options: vec!(
        ("Command".to_string(), box V::Structure {
            members: run_fields(true),
            .. Default::default()} as Box<V::Validator>),
        ("BridgeCommand".to_string(), box V::Structure {
            members: run_fields(false),
            .. Default::default()} as Box<V::Validator>),
    ), .. Default::default()} as Box<V::Validator>;
}

pub fn command_validator<'a>() -> Box<V::Validator + 'a> {
    let mut command_members = vec!();
    command_members.extend(command_fields().into_iter());
    command_members.extend(run_fields(false).into_iter());

    let mut supervise_members = vec!(
        ("mode".to_string(), box V::Scalar {
            default: Some("stop-on-failure".to_string()),
            .. Default::default()} as Box<V::Validator>),
        ("children".to_string(), box V::Mapping {
            key_element: box V::Scalar {
                ..Default::default()} as Box<V::Validator>,
            value_element: subcommand_validator(),
            .. Default::default()} as Box<V::Validator>),
        );
    supervise_members.extend(command_fields().into_iter());

    return box V::Enum { options: vec!(
        ("Command".to_string(), box V::Structure {
            members: command_members,
            .. Default::default()} as Box<V::Validator>),
        ("Supervise".to_string(), box V::Structure {
            members: supervise_members,
            .. Default::default()} as Box<V::Validator>),
    ), .. Default::default()} as Box<V::Validator>;
}

pub trait Networking {
    fn network<'x>(&'x self) -> Option<&'x Network>;
}

impl Networking for ChildCommand {
    fn network<'x>(&'x self) -> Option<&'x Network> {
        match self {
            &ChildCommand::Command(ref cmd) => cmd.network.as_ref(),
            &ChildCommand::BridgeCommand(_) => None,
        }
    }
}
<|endoftext|>


<commit_before>pub mod tcp_connection;
pub mod tcp_pump;

pub mod tcp {
	pub use super::tcp_pump;
	pub use super::tcp_connection;
}

use std::sync::Arc;
use std::sync::mpsc::{ Sender };

/// The low-level message that a connection on the event loop will accept
pub enum SerialisedConnectionMessage {
	Request(
		Sender<Arc<Vec<u8>>>,
		Arc<Vec<u8>>
	),
	Execute(Vec<u8>),
	Response(Arc<Vec<u8>>)
}<commit_msg>Working on connection ideas<commit_after>pub mod tcp_connection;
pub mod tcp_pump;

pub mod tcp {
	pub use super::tcp_pump;
	pub use super::tcp_connection;
}

use std::marker::PhantomData;
use std::sync::Arc;
use std::sync::mpsc::{ Sender, Receiver };

use ::protocol::messages::ApiMessage;

/// The low-level message that a connection on the event loop will accept
enum SerialisedConnectionMessage {
	Request(
		Sender<Arc<Vec<u8>>>,
		Arc<Vec<u8>>
	),
	Execute(Arc<Vec<u8>>),
	Response(Arc<Vec<u8>>)
}

/// Wraps up a receiver in a strongly typed bundle
/// Used by the client to block on responses. Type arg ensures we don't try to receive unexpected messages
/// This type also takes ownership of the receiver, and so it will be disposed of once the handle falls out of scope
pub struct ResponseHandle<T: ApiMessage> {
	handle: Receiver<Arc<Vec<u8>>>,
	response_type: PhantomData<T>
}

impl <T: ApiMessage> ResponseHandle<T> {
	pub fn new(rx: Receiver<Arc<Vec<u8>>>) -> ResponseHandle<T> {
		ResponseHandle {
			handle: rx,
			response_type: PhantomData
		}
	}

	pub fn get_response(&self) -> T {
		//let res = self.handle.recv();
		//deserialise res as T
		panic!("implement")
	}
}<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use flow::Flow;
use flow_ref::{self, FlowRef};

use std::collections::{linked_list, LinkedList};

// This needs to be reworked now that we have dynamically-sized types in Rust.
// Until then, it's just a wrapper around LinkedList.

pub struct FlowList {
    flows: LinkedList<FlowRef>,
}

pub struct FlowListIterator<'a> {
    it: linked_list::Iter<'a, FlowRef>,
}

pub struct MutFlowListIterator<'a> {
    it: linked_list::IterMut<'a, FlowRef>,
}

impl FlowList {
    /// Provide a reference to the front element, or None if the list is empty
    #[inline]
    pub fn front(&self) -> Option<&Flow> {
        self.flows.front().map(|head| &**head)
    }

    /// Provide a mutable reference to the front element, or None if the list is empty
    #[inline]
    #[allow(unsafe_code)]
    pub unsafe fn front_mut(&mut self) -> Option<&mut Flow> {
        self.flows.front_mut().map(flow_ref::deref_mut)
    }

    /// Provide a reference to the back element, or None if the list is empty
    #[inline]
    pub fn back(&self) -> Option<&Flow> {
        self.flows.back().map(|tail| &**tail)
    }

    /// Provide a mutable reference to the back element, or None if the list is empty
    #[inline]
    #[allow(unsafe_code)]
    pub unsafe fn back_mut(&mut self) -> Option<&mut Flow> {
        self.flows.back_mut().map(flow_ref::deref_mut)
    }

    /// Add an element first in the list
    ///
    /// O(1)
    pub fn push_front(&mut self, new_head: FlowRef) {
        self.flows.push_front(new_head);
    }

    /// Remove the first element and return it, or None if the list is empty
    ///
    /// O(1)
    pub fn pop_front(&mut self) -> Option<FlowRef> {
        self.flows.pop_front()
    }

    /// Add an element last in the list
    ///
    /// O(1)
    pub fn push_back(&mut self, new_tail: FlowRef) {
        self.flows.push_back(new_tail);
    }

    /// Create an empty list
    #[inline]
    pub fn new() -> FlowList {
        FlowList {
            flows: LinkedList::new(),
        }
    }

    /// Provide a forward iterator
    #[inline]
    pub fn iter(&self) -> FlowListIterator {
        FlowListIterator {
            it: self.flows.iter(),
        }
    }

    /// Provide a forward iterator with mutable references
    #[inline]
    pub fn iter_mut(&mut self) -> MutFlowListIterator {
        MutFlowListIterator {
            it: self.flows.iter_mut(),
        }
    }

    /// O(1)
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.flows.is_empty()
    }

    /// O(1)
    #[inline]
    pub fn len(&self) -> usize {
        self.flows.len()
    }
}

impl<'a> Iterator for FlowListIterator<'a> {
    type Item = &'a Flow;
    #[inline]
    fn next(&mut self) -> Option<&'a Flow> {
        self.it.next().map(|x| &**x)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.it.size_hint()
    }
}

impl<'a> Iterator for MutFlowListIterator<'a> {
    type Item = &'a mut Flow;
    #[inline]
    fn next(&mut self) -> Option<&'a mut Flow> {
        self.it.next().map(flow_ref::deref_mut)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.it.size_hint()
    }
}
<commit_msg>Undo elision for trait object; trait objects are strange<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use flow::Flow;
use flow_ref::{self, FlowRef};

use std::collections::{linked_list, LinkedList};

// This needs to be reworked now that we have dynamically-sized types in Rust.
// Until then, it's just a wrapper around LinkedList.

pub struct FlowList {
    flows: LinkedList<FlowRef>,
}

pub struct FlowListIterator<'a> {
    it: linked_list::Iter<'a, FlowRef>,
}

pub struct MutFlowListIterator<'a> {
    it: linked_list::IterMut<'a, FlowRef>,
}

impl FlowList {
    /// Provide a reference to the front element, or None if the list is empty
    #[inline]
    pub fn front<'a>(&'a self) -> Option<&'a Flow> {
        self.flows.front().map(|head| &**head)
    }

    /// Provide a mutable reference to the front element, or None if the list is empty
    #[inline]
    #[allow(unsafe_code)]
    pub unsafe fn front_mut<'a>(&'a mut self) -> Option<&'a mut Flow> {
        self.flows.front_mut().map(flow_ref::deref_mut)
    }

    /// Provide a reference to the back element, or None if the list is empty
    #[inline]
    pub fn back<'a>(&'a self) -> Option<&'a Flow> {
        self.flows.back().map(|tail| &**tail)
    }

    /// Provide a mutable reference to the back element, or None if the list is empty
    #[inline]
    #[allow(unsafe_code)]
    pub unsafe fn back_mut<'a>(&'a mut self) -> Option<&'a mut Flow> {
        self.flows.back_mut().map(flow_ref::deref_mut)
    }

    /// Add an element first in the list
    ///
    /// O(1)
    pub fn push_front(&mut self, new_head: FlowRef) {
        self.flows.push_front(new_head);
    }

    /// Remove the first element and return it, or None if the list is empty
    ///
    /// O(1)
    pub fn pop_front(&mut self) -> Option<FlowRef> {
        self.flows.pop_front()
    }

    /// Add an element last in the list
    ///
    /// O(1)
    pub fn push_back(&mut self, new_tail: FlowRef) {
        self.flows.push_back(new_tail);
    }

    /// Create an empty list
    #[inline]
    pub fn new() -> FlowList {
        FlowList {
            flows: LinkedList::new(),
        }
    }

    /// Provide a forward iterator
    #[inline]
    pub fn iter(&self) -> FlowListIterator {
        FlowListIterator {
            it: self.flows.iter(),
        }
    }

    /// Provide a forward iterator with mutable references
    #[inline]
    pub fn iter_mut(&mut self) -> MutFlowListIterator {
        MutFlowListIterator {
            it: self.flows.iter_mut(),
        }
    }

    /// O(1)
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.flows.is_empty()
    }

    /// O(1)
    #[inline]
    pub fn len(&self) -> usize {
        self.flows.len()
    }
}

impl<'a> Iterator for FlowListIterator<'a> {
    type Item = &'a Flow;
    #[inline]
    fn next(&mut self) -> Option<&'a Flow> {
        self.it.next().map(|x| &**x)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.it.size_hint()
    }
}

impl<'a> Iterator for MutFlowListIterator<'a> {
    type Item = &'a mut Flow;
    #[inline]
    fn next(&mut self) -> Option<&'a mut Flow> {
        self.it.next().map(flow_ref::deref_mut)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.it.size_hint()
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Count_in_octal

use std::uint;

fn main() {
	for i in range(uint::MIN, uint::MAX) {
		println!("{:o}", i);
	}
}
<commit_msg>Commented count in octal<commit_after>// Implements http://rosettacode.org/wiki/Count_in_octal

use std::u8;
use std::iter::range_inclusive;

fn main() {
    // We count from 0 to 255 (377 in octal)
	for i in range_inclusive(0, u8::MAX) {
		println!("{:o}", i);
	}
}
<|endoftext|>


<commit_before>use std::cmp::{Ordering, PartialOrd};
use std::fmt;
use std::marker::PhantomData;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign};

use num::{Num, One, Zero};

use num_complex::Complex;

use approx::{AbsDiffEq, RelativeEq, UlpsEq};

use general::{
    AbstractGroup, AbstractGroupAbelian, AbstractLoop, AbstractMagma, AbstractMonoid,
    AbstractQuasigroup, AbstractSemigroup, Additive, Inverse, JoinSemilattice, Lattice,
    MeetSemilattice, Multiplicative, Operator, SubsetOf,
};

/// A type that is equipped with identity.
pub trait Identity<O: Operator> {
    /// The identity element.
    fn identity() -> Self;

    /// Specific identity.
    #[inline]
    fn id(_: O) -> Self
    where
        Self: Sized,
    {
        Self::identity()
    }
}

impl_ident!(Additive; 0; u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
impl_ident!(Additive; 0.; f32, f64);
#[cfg(decimal)]
impl_ident!(Additive; 0.; decimal::d128);
impl_ident!(Multiplicative; 1; u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
impl_ident!(Multiplicative; 1.; f32, f64);
#[cfg(decimal)]
impl_ident!(Multiplicative; 1.; decimal::d128);

impl<N: Identity<Additive>> Identity<Additive> for Complex<N> {
    #[inline]
    fn identity() -> Self {
        Complex {
            re: N::identity(),
            im: N::identity(),
        }
    }
}

impl<N: Num + Clone> Identity<Multiplicative> for Complex<N> {
    #[inline]
    fn identity() -> Self {
        Complex::new(N::one(), N::zero())
    }
}

/// The universal identity element wrt. a given operator, usually noted `Id` with a
/// context-dependent subscript.
///
/// By default, it is the multiplicative identity element. It represents the degenerate set
/// containing only the identity element of any group-like structure.  It has no dimension known at
/// compile-time. All its operations are no-ops.
#[repr(C)]
#[derive(Debug)]
pub struct Id<O: Operator = Multiplicative> {
    _op: PhantomData<O>,
}

impl<O: Operator> Id<O> {
    /// Creates a new identity element.
    #[inline]
    pub fn new() -> Id<O> {
        Id { _op: PhantomData }
    }
}

impl<O: Operator> Copy for Id<O> {}

impl<O: Operator> Clone for Id<O> {
    #[inline]
    fn clone(&self) -> Id<O> {
        Id::new()
    }
}

impl<O: Operator> fmt::Display for Id<O> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Identity element")
    }
}

impl<O: Operator> PartialEq for Id<O> {
    #[inline]
    fn eq(&self, _: &Id<O>) -> bool {
        true
    }
}

impl<O: Operator> Eq for Id<O> {}

impl<O: Operator> PartialOrd for Id<O> {
    #[inline]
    fn partial_cmp(&self, _: &Id<O>) -> Option<Ordering> {
        Some(Ordering::Equal)
    }
}

impl<O: Operator> Identity<O> for Id<O> {
    #[inline]
    fn identity() -> Id<O> {
        Id::new()
    }
}

impl<O: Operator> AbsDiffEq for Id<O> {
    type Epsilon = Id<O>;

    #[inline]
    fn default_epsilon() -> Self::Epsilon {
        Id::new()
    }

    #[inline]
    fn abs_diff_eq(&self, _: &Self, _: Self::Epsilon) -> bool {
        true
    }
}

impl<O: Operator> RelativeEq for Id<O> {
    #[inline]
    fn default_max_relative() -> Self::Epsilon {
        Id::new()
    }

    #[inline]
    fn relative_eq(&self, _: &Self, _: Self::Epsilon, _: Self::Epsilon) -> bool {
        true
    }
}

impl<O: Operator> UlpsEq for Id<O> {
    #[inline]
    fn default_max_ulps() -> u32 {
        0
    }

    #[inline]
    fn ulps_eq(&self, _: &Self, _: Self::Epsilon, _: u32) -> bool {
        true
    }
}

/*
 *
 * Algebraic structures.
 *
 */
impl Mul<Id> for Id {
    type Output = Id;

    fn mul(self, _: Id) -> Id {
        self
    }
}

impl MulAssign<Id> for Id {
    fn mul_assign(&mut self, _: Id) {
        // no-op
    }
}

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

    fn div(self, _: Id) -> Id {
        self
    }
}

impl DivAssign<Id> for Id {
    fn div_assign(&mut self, _: Id) {
        // no-op
    }
}

impl Add<Id> for Id {
    type Output = Id;

    fn add(self, _: Id) -> Id {
        self
    }
}

impl AddAssign<Id> for Id {
    fn add_assign(&mut self, _: Id) {
        // no-op
    }
}

impl<O: Operator> AbstractMagma<O> for Id<O> {
    #[inline]
    fn operate(&self, _: &Self) -> Id<O> {
        Id::new()
    }
}

impl<O: Operator> Inverse<O> for Id<O> {
    #[inline]
    fn inverse(&self) -> Self {
        Id::new()
    }

    #[inline]
    fn inverse_mut(&mut self) {
        // no-op
    }
}

impl<O: Operator> AbstractSemigroup<O> for Id<O> {}
impl<O: Operator> AbstractQuasigroup<O> for Id<O> {}
impl<O: Operator> AbstractMonoid<O> for Id<O> {}
impl<O: Operator> AbstractLoop<O> for Id<O> {}
impl<O: Operator> AbstractGroup<O> for Id<O> {}
impl<O: Operator> AbstractGroupAbelian<O> for Id<O> {}

impl One for Id {
    #[inline]
    fn one() -> Id {
        Id::new()
    }
}

impl Zero for Id {
    #[inline]
    fn zero() -> Id {
        Id::new()
    }

    #[inline]
    fn is_zero(&self) -> bool {
        true
    }
}

/*
 *
 * Conversions.
 *
 */
impl<O: Operator, T: PartialEq + Identity<O>> SubsetOf<T> for Id<O> {
    #[inline]
    fn to_superset(&self) -> T {
        T::identity()
    }

    #[inline]
    fn is_in_subset(t: &T) -> bool {
        *t == T::identity()
    }

    #[inline]
    unsafe fn from_superset_unchecked(_: &T) -> Self {
        Id::new()
    }
}

impl<O: Operator> MeetSemilattice for Id<O> {
    #[inline]
    fn meet(&self, _: &Self) -> Self {
        Id::new()
    }
}

impl<O: Operator> JoinSemilattice for Id<O> {
    #[inline]
    fn join(&self, _: &Self) -> Self {
        Id::new()
    }
}

impl<O: Operator> Lattice for Id<O> {}
<commit_msg>impl Add for Id<Additive>, not Id<commit_after>use std::cmp::{Ordering, PartialOrd};
use std::fmt;
use std::marker::PhantomData;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign};

use num::{Num, One, Zero};

use num_complex::Complex;

use approx::{AbsDiffEq, RelativeEq, UlpsEq};

use general::{
    AbstractGroup, AbstractGroupAbelian, AbstractLoop, AbstractMagma, AbstractMonoid,
    AbstractQuasigroup, AbstractSemigroup, Additive, Inverse, JoinSemilattice, Lattice,
    MeetSemilattice, Multiplicative, Operator, SubsetOf,
};

/// A type that is equipped with identity.
pub trait Identity<O: Operator> {
    /// The identity element.
    fn identity() -> Self;

    /// Specific identity.
    #[inline]
    fn id(_: O) -> Self
    where
        Self: Sized,
    {
        Self::identity()
    }
}

impl_ident!(Additive; 0; u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
impl_ident!(Additive; 0.; f32, f64);
#[cfg(decimal)]
impl_ident!(Additive; 0.; decimal::d128);
impl_ident!(Multiplicative; 1; u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
impl_ident!(Multiplicative; 1.; f32, f64);
#[cfg(decimal)]
impl_ident!(Multiplicative; 1.; decimal::d128);

impl<N: Identity<Additive>> Identity<Additive> for Complex<N> {
    #[inline]
    fn identity() -> Self {
        Complex {
            re: N::identity(),
            im: N::identity(),
        }
    }
}

impl<N: Num + Clone> Identity<Multiplicative> for Complex<N> {
    #[inline]
    fn identity() -> Self {
        Complex::new(N::one(), N::zero())
    }
}

/// The universal identity element wrt. a given operator, usually noted `Id` with a
/// context-dependent subscript.
///
/// By default, it is the multiplicative identity element. It represents the degenerate set
/// containing only the identity element of any group-like structure.  It has no dimension known at
/// compile-time. All its operations are no-ops.
#[repr(C)]
#[derive(Debug)]
pub struct Id<O: Operator = Multiplicative> {
    _op: PhantomData<O>,
}

impl<O: Operator> Id<O> {
    /// Creates a new identity element.
    #[inline]
    pub fn new() -> Id<O> {
        Id { _op: PhantomData }
    }
}

impl<O: Operator> Copy for Id<O> {}

impl<O: Operator> Clone for Id<O> {
    #[inline]
    fn clone(&self) -> Id<O> {
        Id::new()
    }
}

impl<O: Operator> fmt::Display for Id<O> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Identity element")
    }
}

impl<O: Operator> PartialEq for Id<O> {
    #[inline]
    fn eq(&self, _: &Id<O>) -> bool {
        true
    }
}

impl<O: Operator> Eq for Id<O> {}

impl<O: Operator> PartialOrd for Id<O> {
    #[inline]
    fn partial_cmp(&self, _: &Id<O>) -> Option<Ordering> {
        Some(Ordering::Equal)
    }
}

impl<O: Operator> Identity<O> for Id<O> {
    #[inline]
    fn identity() -> Id<O> {
        Id::new()
    }
}

impl<O: Operator> AbsDiffEq for Id<O> {
    type Epsilon = Id<O>;

    #[inline]
    fn default_epsilon() -> Self::Epsilon {
        Id::new()
    }

    #[inline]
    fn abs_diff_eq(&self, _: &Self, _: Self::Epsilon) -> bool {
        true
    }
}

impl<O: Operator> RelativeEq for Id<O> {
    #[inline]
    fn default_max_relative() -> Self::Epsilon {
        Id::new()
    }

    #[inline]
    fn relative_eq(&self, _: &Self, _: Self::Epsilon, _: Self::Epsilon) -> bool {
        true
    }
}

impl<O: Operator> UlpsEq for Id<O> {
    #[inline]
    fn default_max_ulps() -> u32 {
        0
    }

    #[inline]
    fn ulps_eq(&self, _: &Self, _: Self::Epsilon, _: u32) -> bool {
        true
    }
}

/*
 *
 * Algebraic structures.
 *
 */
impl Mul<Id> for Id {
    type Output = Id;

    fn mul(self, _: Id) -> Id {
        self
    }
}

impl MulAssign<Id> for Id {
    fn mul_assign(&mut self, _: Id) {
        // no-op
    }
}

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

    fn div(self, _: Id) -> Id {
        self
    }
}

impl DivAssign<Id> for Id {
    fn div_assign(&mut self, _: Id) {
        // no-op
    }
}

impl Add<Id<Additive>> for Id<Additive> {
    type Output = Id<Additive>;

    fn add(self, _: Id<Additive>) -> Id<Additive> {
        self
    }
}

impl AddAssign<Id<Additive>> for Id<Additive> {
    fn add_assign(&mut self, _: Id<Additive>) {
        // no-op
    }
}

impl<O: Operator> AbstractMagma<O> for Id<O> {
    #[inline]
    fn operate(&self, _: &Self) -> Id<O> {
        Id::new()
    }
}

impl<O: Operator> Inverse<O> for Id<O> {
    #[inline]
    fn inverse(&self) -> Self {
        Id::new()
    }

    #[inline]
    fn inverse_mut(&mut self) {
        // no-op
    }
}

impl<O: Operator> AbstractSemigroup<O> for Id<O> {}
impl<O: Operator> AbstractQuasigroup<O> for Id<O> {}
impl<O: Operator> AbstractMonoid<O> for Id<O> {}
impl<O: Operator> AbstractLoop<O> for Id<O> {}
impl<O: Operator> AbstractGroup<O> for Id<O> {}
impl<O: Operator> AbstractGroupAbelian<O> for Id<O> {}

impl One for Id {
    #[inline]
    fn one() -> Id {
        Id::new()
    }
}

impl Zero for Id<Additive> {
    #[inline]
    fn zero() -> Id<Additive> {
        Id::new()
    }

    #[inline]
    fn is_zero(&self) -> bool {
        true
    }
}

/*
 *
 * Conversions.
 *
 */
impl<O: Operator, T: PartialEq + Identity<O>> SubsetOf<T> for Id<O> {
    #[inline]
    fn to_superset(&self) -> T {
        T::identity()
    }

    #[inline]
    fn is_in_subset(t: &T) -> bool {
        *t == T::identity()
    }

    #[inline]
    unsafe fn from_superset_unchecked(_: &T) -> Self {
        Id::new()
    }
}

impl<O: Operator> MeetSemilattice for Id<O> {
    #[inline]
    fn meet(&self, _: &Self) -> Self {
        Id::new()
    }
}

impl<O: Operator> JoinSemilattice for Id<O> {
    #[inline]
    fn join(&self, _: &Self) -> Self {
        Id::new()
    }
}

impl<O: Operator> Lattice for Id<O> {}
<|endoftext|>


<commit_before>use std::env;

fn is_palindrome(input: &str) -> bool {

    return true;
}

fn main() {
    let args: Vec<_> = env::args().collect();
    let input = &args[1];
    let is_pal = is_palindrome(input);
    println!("Is {} a palindrome? {}", input, is_pal);
}
<commit_msg>Rust: messing with vectors<commit_after>use std::env;

fn is_palindrome(input: &str) -> bool {
    let ch_vec: Vec<&str> = input.split("").collect();

    let mut front_vec: Vec<&str> = vec![];
    let mut back_vec: Vec<&str> = vec![];
    return true;
}

fn main() {
    let args: Vec<_> = env::args().collect();
    let input = &args[1];
    let is_pal = is_palindrome(input);
    println!("Is {} a palindrome? {}", input, is_pal);
}
<|endoftext|>


<commit_before>extern crate core;

use self::core::fmt::Show;
use matchers::matcher::Matcher;

pub struct Expect<T> {
    value: T
}

impl<T: Show + Clone> Expect<T> {
    pub fn to(&self, other: Box<Matcher<T>>) {
        if !other.assert_check(self.value.clone()) {
            self.fail(other)
        }
    }

    pub fn not_to(&self, other: Box<Matcher<T>>) {
        if other.assert_check(self.value.clone()) {
            self.fail(other)
        }
    }

    fn fail(&self, other: Box<Matcher<T>>) {
        // let mut t = term::stdout().unwrap();
        // t.fg(term::color::RED).unwrap();
        fail!(other.negated_msg(self.value.clone()));
    }
}

pub fn expect<T: Eq + Ord + Show>(value: T) -> Expect<T> {
    Expect { value: value }
}
<commit_msg>oops messages were always negated<commit_after>extern crate core;

use self::core::fmt::Show;
use matchers::matcher::Matcher;

pub struct Expect<T> {
    value: T,
    negated: bool
}

impl<T: Show + Clone> Expect<T> {
    pub fn to(&self, other: Box<Matcher<T>>) {
        let mut cond = !other.assert_check(self.value.clone());

        if self.negated {
            cond = !cond;
        }

        if cond {
            self.fail(other)
        }
    }

    pub fn not_to(&mut self, other: Box<Matcher<T>>) {
        self.negated = true;
        self.to(other);
    }

    fn fail(&self, other: Box<Matcher<T>>) {
        let mut msg;

        if self.negated {
            msg = other.negated_msg(self.value.clone());
        } else {
            msg = other.msg(self.value.clone());
        }

        fail!(msg);
    }
}

pub fn expect<T: Eq + Ord + Show>(value: T) -> Expect<T> {
    Expect { value: value, negated: false }
}
<|endoftext|>


<commit_before>use std::path::{PathBuf, Path};
use std::collections::HashMap;

use perlin_core::index::Index;
use perlin_core::index::vocabulary::SharedVocabulary;
use perlin_core::index::posting::DocId;
use perlin_core::page_manager::{RamPageCache, FsPageManager};

use field::{RawField, FieldId, FieldDefinition, FieldType, FieldResolver};

use document::Document;

/// `DocumentIndex` takes some of the basic building blocks in `perlin_core`
/// and provides an abstraction that can be used to index and query documents
/// using fields, metadata, taxonomies etc
pub struct DocumentIndex {
    // We need to overwrite perlin_core's default DocIds as some Documents might contain
    // other fields than others. This counter acts as DocumentIndex global document counter.
    doc_id_counter: DocId,
    // The base path of this index.
    base_path: PathBuf,
    // A, possible shared between many DocumentIndices, vocabulary for string-terms
    vocabulary: SharedVocabulary<String>,
    // Indices for fields that contain strings
    text_fields: Vec<(FieldId, Index<String>)>,
    // Indices for fields that contain numbers
    number_fields: Vec<(FieldId, Index<u64>)>,
}

impl DocumentIndex {
    /// Create a new index.
    pub fn new(path: &Path, vocab: SharedVocabulary<String>) -> Self {
        DocumentIndex {
            vocabulary: vocab,
            doc_id_counter: DocId::none(),
            base_path: path.to_path_buf(),
            text_fields: Vec::new(),
            number_fields: Vec::new(),
        }
    }

    /// Adds a document to this index by indexing every field in its index
    pub fn add_document(&mut self, document: Document) -> DocId {
        self.doc_id_counter.inc();
        let doc_id = self.doc_id_counter;
        for field in document.0 {
            self.index_field(doc_id, field);
        }
        doc_id
    }

    /// Indexes a field. Might create a new index!
    fn index_field(&mut self, doc_id: DocId, field: RawField) {
        match field {
            RawField(FieldDefinition(field_id, FieldType::Text), content) => {
                // Find index for field_id
                if let Ok(pos) = self.text_fields
                    .binary_search_by_key(&field_id, |&(f_id, _)| f_id) {
                    self.text_fields[pos].1.index(doc_id, content);
                } else {
                    panic!("Something is seriously wrong!");
                }
            }
            RawField(FieldDefinition(field_id, FieldType::Number), content) => {
                // Find index for field_id
                if let Ok(pos) = self.number_fields
                    .binary_search_by_key(&field_id, |&(f_id, _)| f_id) {
                    self.number_fields[pos].1.index(doc_id, content);
                } else {
                    panic!("Something is seriously wrong!");
                }
            }
        }
    }

    /// Commits this index
    pub fn commit(&mut self) {
        self.text_fields.iter_mut().map(|&mut (_, ref mut index)| index.commit()).count();
        self.number_fields.iter_mut().map(|&mut (_, ref mut index)| index.commit()).count();
    }

    /// Runs an atom_query on a certain field
    pub fn query_field(&self, query: &RawField) -> Vec<DocId> {
        vec![]
    }
}

trait Indexer<'a> {
    fn index(&mut self, DocId, &'a str);
}

impl<'a> Indexer<'a> for Index<String> {
    fn index(&mut self, doc_id: DocId, data: &'a str) {
        self.index_document(data.split_whitespace().map(|s| s.to_string()), Some(doc_id));
    }
}

impl<'a> Indexer<'a> for Index<u64> {
    fn index(&mut self, doc_id: DocId, data: &'a str) {
        use std::str::FromStr;
        let num = u64::from_str(data).unwrap();
        self.index_document(vec![num].into_iter(), Some(doc_id));
    }
}

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

    use test_utils::create_test_dir;
    use document::DocumentBuilder;
    use field::{FieldId, FieldQuery};

    use perlin_core::index::vocabulary::SharedVocabulary;
    use perlin_core::index::posting::DocId;

    fn new_index(name: &str) -> DocumentIndex {
        DocumentIndex::new(&create_test_dir(format!("perlin_index/{}", name).as_str()),
                           SharedVocabulary::new())
    }

    #[test]
    fn one_document() {
        let mut index = new_index("one_document");
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .build());
        index.commit();
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "test".to_string())),
                   vec![DocId(0)]);
    }

    #[test]
    fn multiple_documents() {
        let mut index = new_index("multiple_documents");
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .build());
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .build());
        index.commit();
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "test".to_string())),
                   vec![DocId(0), DocId(1)]);
    }

    #[test]
    fn multiple_fields() {
        let mut index = new_index("multiple_fields");
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .add_string_field(FieldId(1), "This is a test content".to_string())
            .build());
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .add_string_field(FieldId(1), "This is a test content".to_string())
            .build());
        index.commit();
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "content".to_string())),
                   vec![]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "title".to_string())),
                   vec![DocId(0), DocId(1)]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(1), "content".to_string())),
                   vec![DocId(0), DocId(1)]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(1), "title".to_string())),
                   vec![])
    }

    #[test]
    fn multiple_fieldtypes() {
        let mut index = new_index("multiple_fieldtypes");
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "Mars".to_string())
            .add_string_field(FieldId(1),
                              "Mars is the fourth planet from the Sun and the second-smallest \
                               planet in the Solar System, after Mercury."
                              .to_string())
             //Planet Number in solar system
            .add_number_field(FieldId(2), 4)
             //Object type. 1=star 2=planet 3=moon
            .add_number_field(FieldId(3), 2)
                           .build());
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "Sun".to_string())
            .add_string_field(FieldId(1),
                              "The Sun is the star at the center of the Solar System."
                                  .to_string())
            .add_number_field(FieldId(3), 1)
            .build());
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "Moon".to_string())
            .add_string_field(FieldId(1),
                              "The Moon is an astronomical body that orbits planet Earth, being \
                               Earth's only permanent natural satellite."
                                  .to_string())
            .add_number_field(FieldId(3), 3)
            .build());
        index.commit();
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "Moon".to_string())),
                   vec![DocId(2)]);
        assert_eq!(index.query_field(FieldQuery::new_number(FieldId(2), 4)),
                   vec![DocId(0)]);
        assert_eq!(index.query_field(FieldQuery::new_number(FieldId(3), 1)),
                   vec![DocId(1)]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "is".to_string())),
                   vec![]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(1), "is".to_string())),
                   vec![DocId(0), DocId(1), DocId(2)]);

    }
}
<commit_msg>possibility to add indices<commit_after>use std::path::{PathBuf, Path};

use perlin_core::index::Index;
use perlin_core::index::vocabulary::SharedVocabulary;
use perlin_core::index::posting::DocId;
use perlin_core::page_manager::{RamPageCache, FsPageManager};

use field::{RawField, FieldId, FieldDefinition, FieldType, FieldResolver};

use document::Document;

/// `DocumentIndex` takes some of the basic building blocks in `perlin_core`
/// and provides an abstraction that can be used to index and query documents
/// using fields, metadata, taxonomies etc
pub struct DocumentIndex {
    // We need to overwrite perlin_core's default DocIds as some Documents might contain
    // other fields than others. This counter acts as DocumentIndex global document counter.
    doc_id_counter: DocId,
    // The base path of this index.
    base_path: PathBuf,
    // A, possible shared between many DocumentIndices, vocabulary for string-terms
    vocabulary: SharedVocabulary<String>,
    // Indices for fields that contain strings
    text_fields: Vec<(FieldId, Index<String>)>,
    // Indices for fields that contain numbers
    number_fields: Vec<(FieldId, Index<u64>)>,
}

impl DocumentIndex {
    /// Create a new index.
    pub fn new(path: &Path, vocab: SharedVocabulary<String>) -> Self {
        DocumentIndex {
            vocabulary: vocab,
            doc_id_counter: DocId::none(),
            base_path: path.to_path_buf(),
            text_fields: Vec::new(),
            number_fields: Vec::new(),
        }
    }

    /// Adds a document to this index by indexing every field in its index
    pub fn add_document(&mut self, document: Document) -> DocId {
        self.doc_id_counter.inc();
        let doc_id = self.doc_id_counter;
        for field in document.0 {
            self.index_field(doc_id, field);
        }
        doc_id
    }

    pub fn add_index(&mut self, field_def: FieldDefinition) -> Result<(), ()>{
        let FieldDefinition(field_id, field_type) = field_def;
        let page_cache = RamPageCache::new(FsPageManager::new(&self.base_path.join(format!("{}_pages.bin", field_id.0).to_string())));
        match field_type {
            FieldType::Text => {
                if let Err(pos) = self.text_fields.binary_search_by_key(&field_id, |&(f_id, _)| f_id) {
                    self.text_fields.insert(pos, (field_id, Index::new(page_cache, self.vocabulary.clone())));
                }
            },
            FieldType::Number => {
                if let Err(pos) = self.number_fields.binary_search_by_key(&field_id, |&(f_id, _)| f_id) {
                    self.number_fields.insert(pos, (field_id, Index::new(page_cache, SharedVocabulary::new())));
                }
            }
        };
        Ok(())
    }

    /// Indexes a field. Might create a new index!
    fn index_field(&mut self, doc_id: DocId, field: RawField) {
        match field {
            RawField(FieldDefinition(field_id, FieldType::Text), content) => {
                // Find index for field_id
                if let Ok(pos) = self.text_fields
                    .binary_search_by_key(&field_id, |&(f_id, _)| f_id) {
                    self.text_fields[pos].1.index(doc_id, content);
                } else {
                    panic!("Something is seriously wrong!");
                }
            }
            RawField(FieldDefinition(field_id, FieldType::Number), content) => {
                // Find index for field_id
                if let Ok(pos) = self.number_fields
                    .binary_search_by_key(&field_id, |&(f_id, _)| f_id) {
                    self.number_fields[pos].1.index(doc_id, content);
                } else {
                    panic!("Something is seriously wrong!");
                }
            }
        }
    }

    /// Commits this index
    pub fn commit(&mut self) {
        self.text_fields.iter_mut().map(|&mut (_, ref mut index)| index.commit()).count();
        self.number_fields.iter_mut().map(|&mut (_, ref mut index)| index.commit()).count();
    }

    /// Runs an atom_query on a certain field
    pub fn query_field(&self, query: &RawField) -> Vec<DocId> {
        vec![]
    }
}

trait Indexer<'a> {
    fn index(&mut self, DocId, &'a str);
}

impl<'a> Indexer<'a> for Index<String> {
    fn index(&mut self, doc_id: DocId, data: &'a str) {
        self.index_document(data.split_whitespace().map(|s| s.to_string()), Some(doc_id));
    }
}

impl<'a> Indexer<'a> for Index<u64> {
    fn index(&mut self, doc_id: DocId, data: &'a str) {
        use std::str::FromStr;
        let num = u64::from_str(data).unwrap();
        self.index_document(vec![num].into_iter(), Some(doc_id));
    }
}

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

    use test_utils::create_test_dir;
    use document::DocumentBuilder;
    use field::{FieldId, FieldQuery};

    use perlin_core::index::vocabulary::SharedVocabulary;
    use perlin_core::index::posting::DocId;

    fn new_index(name: &str) -> DocumentIndex {
        DocumentIndex::new(&create_test_dir(format!("perlin_index/{}", name).as_str()),
                           SharedVocabulary::new())
    }

    #[test]
    fn one_document() {
        let mut index = new_index("one_document");
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .build());
        index.commit();
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "test".to_string())),
                   vec![DocId(0)]);
    }

    #[test]
    fn multiple_documents() {
        let mut index = new_index("multiple_documents");
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .build());
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .build());
        index.commit();
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "test".to_string())),
                   vec![DocId(0), DocId(1)]);
    }

    #[test]
    fn multiple_fields() {
        let mut index = new_index("multiple_fields");
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .add_string_field(FieldId(1), "This is a test content".to_string())
            .build());
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "This is a test title".to_string())
            .add_string_field(FieldId(1), "This is a test content".to_string())
            .build());
        index.commit();
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "content".to_string())),
                   vec![]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "title".to_string())),
                   vec![DocId(0), DocId(1)]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(1), "content".to_string())),
                   vec![DocId(0), DocId(1)]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(1), "title".to_string())),
                   vec![])
    }

    #[test]
    fn multiple_fieldtypes() {
        let mut index = new_index("multiple_fieldtypes");
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "Mars".to_string())
            .add_string_field(FieldId(1),
                              "Mars is the fourth planet from the Sun and the second-smallest \
                               planet in the Solar System, after Mercury."
                              .to_string())
             //Planet Number in solar system
            .add_number_field(FieldId(2), 4)
             //Object type. 1=star 2=planet 3=moon
            .add_number_field(FieldId(3), 2)
                           .build());
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "Sun".to_string())
            .add_string_field(FieldId(1),
                              "The Sun is the star at the center of the Solar System."
                                  .to_string())
            .add_number_field(FieldId(3), 1)
            .build());
        index.add_document(DocumentBuilder::new()
            .add_string_field(FieldId(0), "Moon".to_string())
            .add_string_field(FieldId(1),
                              "The Moon is an astronomical body that orbits planet Earth, being \
                               Earth's only permanent natural satellite."
                                  .to_string())
            .add_number_field(FieldId(3), 3)
            .build());
        index.commit();
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "Moon".to_string())),
                   vec![DocId(2)]);
        assert_eq!(index.query_field(FieldQuery::new_number(FieldId(2), 4)),
                   vec![DocId(0)]);
        assert_eq!(index.query_field(FieldQuery::new_number(FieldId(3), 1)),
                   vec![DocId(1)]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(0), "is".to_string())),
                   vec![]);
        assert_eq!(index.query_field(FieldQuery::new_string(FieldId(1), "is".to_string())),
                   vec![DocId(0), DocId(1), DocId(2)]);

    }
}
<|endoftext|>


<commit_before>extern crate bson;
extern crate mongodb;

use std::error::Error as ErrorTrait;
use std::ops::Deref;
use linear_map::LinearMap;
use self::bson::{Bson, Document};
use self::mongodb::{Client, ThreadedClient, Error as MongoDBError};
use self::mongodb::connstring;
use self::mongodb::db::{Database, ThreadedDatabase};
use schema::{Definition, Schema};
use driver::Driver;
use error::{Error, ErrorCode};
use patch::Patch;
use query::{Query, Selection};
use value::Value;

struct MongoDBDriver {
  db: Database
}

impl Driver for MongoDriver {
  fn connect(uri: &str) -> Result<Box<Self>, Error> {
    let config = try!(connstring::parse(uri));
    if let Some(db_name) = config.clone().database {
      Ok(Box::new(MongoDBDriver {
        db: try!(Client::with_config(config, None, None)).db(&db_name)
      }))
    } else {
      Err(Error::validation(
        format!("Database name not provided in connection path '{}'.", uri),
        "Include the database name you are connecting to as the connection URI path."
      ))
    }
  }

  fn validate_definition(definition: &Definition) -> Result<(), Error> {
    match &definition.data {
      &Schema::Object{ref properties,..} => {
        for (key, value) in properties {
          match value {
            &Schema::Array{ref items} => {
              match items.deref() {
                &Schema::Object{..} => (),
                _ => return Err(Error::validation(
                  format!("Items for collection '{}' must be an object.", key),
                  format!("The MongoDB driver only supports inserting objects into collections, try changing the schema type of the '{}' collection to reflect this.", key)
                ))
              }
            },
            _ => return Err(Error::validation(
              format!("Schema type for the '{}' property must be an array.", key),
              format!("The MongoDB driver only supports array collections as the first level data types, try changing the '{}' property in your schema to reflect this.", key)
            ))
          }
        }
      },
      _ => return Err(Error::validation(
        "Root data schema is not object.",
        "The MongoDB driver only supports an object as the root data type, try changing your schema to reflect this."
      ))
    }
    Ok(())
  }

  // TODO: Better inline documentation.
  fn query(&self, query: Query) -> Result<Value, Error> {
    match query {
      Query::Value => Err(Error::new(
        ErrorCode::Forbidden,
        "Can’t query the entire MongoDB database.",
        Some("Query something more specfic instead of the entire database.")
      )),
      Query::Object(collection_queries) => {
        // First level is the collection.
        let mut object = LinearMap::new();
        for (Selection::Key(coll_name), query) in collection_queries {
          // if let Selection::Key(coll_name) = selection {
            let collection = self.db.collection(&coll_name);
            match query {
              // TODO: Make this a range error when implementing selection by
              // range.
              Query::Value => {
                let mut cursor = try!(collection.find(None, None));
                let mut values = Vec::new();
                if let Some(Err(error)) = cursor.find(|entry| match entry {
                  &Ok(ref document) => { values.push(Value::from(document.clone())); false },
                  &Err(_) => true
                }) {
                  return Err(Error::from(error));
                } else {
                  object.insert(coll_name, Value::Array(values));
                }
              },
              // TODO: When implementing collections consider not using the
              // MongoDB `_id` property as the key.
              Query::Object(_) => {

              }
            }
          // } else {
          //   return Err(Error::new(
          //     ErrorCode::Forbidden,
          //     "Can‘t query a selection of MongoDB collections.",
          //     Some("Query specific collections instead of a range of collections.")
          //   );
          // }
        }
        Ok(Value::Object(object))
      }
    }
  }

  fn patch(&self, _: Vec<Patch>) -> Result<Value, Error> {
    Err(Error::unimplemented("Patching not implemented for MongoDB driver."))
  }
}

impl From<MongoDBError> for Error {
  fn from(error: MongoDBError) -> Self {
    Error::internal(error.description())
  }
}

impl From<Document> for Value {
  fn from(document: Document) -> Self {
    let mut map = LinearMap::new();
    for key in &document.keys {
      if let Some(value) = document.get(key) {
        map.insert(key.clone(), Value::from(value.clone()));
      }
    }
    Value::Object(map)
  }
}

impl From<Bson> for Value {
  fn from(bson: Bson) -> Self {
    match bson {
      Bson::FloatingPoint(value) => Value::F64(f64::from(value)),
      Bson::String(value) => Value::String(value),
      Bson::Array(values) => Value::Array(values.into_iter().map(|v| Value::from(v)).collect()),
      Bson::Document(document) => Value::from(document),
      Bson::Boolean(value) => Value::Boolean(value),
      Bson::Null => Value::Null,
      Bson::RegExp(value, _) => Value::String(value),
      Bson::JavaScriptCode(value) => Value::String(value),
      Bson::JavaScriptCodeWithScope(value, _) => Value::String(value),
      Bson::I32(value) => Value::I64(i64::from(value)),
      Bson::I64(value) => Value::I64(i64::from(value)),
      Bson::TimeStamp(value) => Value::I64(i64::from(value)),
      // TODO: Actual transformation of binary type.
      Bson::Binary(_, _) => Value::Null,
      Bson::ObjectId(object_id) => Value::String(object_id.to_string()),
      Bson::UtcDatetime(time) => Value::String(time.to_rfc3339())
    }
  }
}

#[cfg(test)]
mod tests {
  use super::bson::{Bson, Document};
  use super::mongodb::db::{ThreadedDatabase};
  use definition::Definition;
  use definition::schema::Schema;
  use driver::Driver;
  use driver::mongodb::MongoDBDriver;
  use query::{Query, Selection};
  use value::Value;

  #[test]
  fn test_validate_definition() {
    assert!(MongoDBDriver::validate_definition(&Definition { data: Schema::Boolean }).is_err());
    assert!(MongoDBDriver::validate_definition(&Definition {
      data: Schema::Object {
        required: vec![],
        additional_properties: false,
        properties: linear_map! {}
      }
    }).is_ok());
    assert!(MongoDBDriver::validate_definition(&Definition {
      data: Schema::Object {
        required: vec![],
        additional_properties: false,
        properties: linear_map! {
          S!("foo") => Schema::Boolean
        }
      }
    }).is_err());
    assert!(MongoDBDriver::validate_definition(&Definition {
      data: Schema::Object {
        required: vec![],
        additional_properties: false,
        properties: linear_map! {
          S!("foo") => Schema::Array {
            items: Box::new(Schema::Boolean)
          }
        }
      }
    }).is_err());
    assert!(MongoDBDriver::validate_definition(&Definition {
      data: Schema::Object {
        required: vec![],
        additional_properties: false,
        properties: linear_map! {
          S!("foo") => Schema::Array {
            items: Box::new(Schema::Object {
              required: vec![],
              additional_properties: true,
              properties: linear_map! {}
            })
          }
        }
      }
    }).is_ok());
  }

  #[test]
  fn test_database() {
    let driver = MongoDBDriver::connect("mongodb://localhost:27017/ardite_test").unwrap();
    let coll_name = "ardite_test_collection";
    driver.db.drop_collection(coll_name).unwrap();
    let collection = driver.db.collection(coll_name);
    let mut doc1 = Document::new();
    doc1.insert(S!("title"), Bson::String(S!("Back to the future!")));
    doc1.insert(S!("foo"), Bson::String(S!("bar")));
    let mut doc2 = Document::new();
    doc2.insert(S!("buz"), Bson::String(S!("baz")));
    let id1 = collection.insert_one(doc1, None).unwrap().inserted_id.unwrap();
    let id2 = collection.insert_one(doc2, None).unwrap().inserted_id.unwrap();
    assert!(driver.query(Query::Value).is_err());
    assert_eq!(driver.query(Query::Object(linear_map! {
      Selection::Key(coll_name.to_string()) => Query::Value
    })).unwrap(), vobject! {
      coll_name => varray![
        vobject! {
          "_id" => Value::from(id1),
          "title" => vstring!("Back to the future!"),
          "foo" => vstring!("bar")
        }, vobject! {
          "_id" => Value::from(id2),
          "buz" => vstring!("baz")
        }
      ]
    });
    driver.db.drop_collection(coll_name).unwrap();
  }
}
<commit_msg>fix: actually rename MongoDBDriver to MongoDriver<commit_after>extern crate bson;
extern crate mongodb;

use std::error::Error as ErrorTrait;
use std::ops::Deref;
use linear_map::LinearMap;
use self::bson::{Bson, Document};
use self::mongodb::{Client, ThreadedClient, Error as MongoDBError};
use self::mongodb::connstring;
use self::mongodb::db::{Database, ThreadedDatabase};
use schema::{Definition, Schema};
use driver::Driver;
use error::{Error, ErrorCode};
use patch::Patch;
use query::{Query, Selection};
use value::Value;

struct MongoDriver {
  db: Database
}

impl Driver for MongoDriver {
  fn connect(uri: &str) -> Result<Box<Self>, Error> {
    let config = try!(connstring::parse(uri));
    if let Some(db_name) = config.clone().database {
      Ok(Box::new(MongoDriver {
        db: try!(Client::with_config(config, None, None)).db(&db_name)
      }))
    } else {
      Err(Error::validation(
        format!("Database name not provided in connection path '{}'.", uri),
        "Include the database name you are connecting to as the connection URI path."
      ))
    }
  }

  fn validate_definition(definition: &Definition) -> Result<(), Error> {
    match &definition.data {
      &Schema::Object{ref properties,..} => {
        for (key, value) in properties {
          match value {
            &Schema::Array{ref items} => {
              match items.deref() {
                &Schema::Object{..} => (),
                _ => return Err(Error::validation(
                  format!("Items for collection '{}' must be an object.", key),
                  format!("The MongoDB driver only supports inserting objects into collections, try changing the schema type of the '{}' collection to reflect this.", key)
                ))
              }
            },
            _ => return Err(Error::validation(
              format!("Schema type for the '{}' property must be an array.", key),
              format!("The MongoDB driver only supports array collections as the first level data types, try changing the '{}' property in your schema to reflect this.", key)
            ))
          }
        }
      },
      _ => return Err(Error::validation(
        "Root data schema is not object.",
        "The MongoDB driver only supports an object as the root data type, try changing your schema to reflect this."
      ))
    }
    Ok(())
  }

  // TODO: Better inline documentation.
  fn query(&self, query: Query) -> Result<Value, Error> {
    match query {
      Query::Value => Err(Error::new(
        ErrorCode::Forbidden,
        "Can’t query the entire MongoDB database.",
        Some("Query something more specfic instead of the entire database.")
      )),
      Query::Object(collection_queries) => {
        // First level is the collection.
        let mut object = LinearMap::new();
        for (Selection::Key(coll_name), query) in collection_queries {
          // if let Selection::Key(coll_name) = selection {
            let collection = self.db.collection(&coll_name);
            match query {
              // TODO: Make this a range error when implementing selection by
              // range.
              Query::Value => {
                let mut cursor = try!(collection.find(None, None));
                let mut values = Vec::new();
                if let Some(Err(error)) = cursor.find(|entry| match entry {
                  &Ok(ref document) => { values.push(Value::from(document.clone())); false },
                  &Err(_) => true
                }) {
                  return Err(Error::from(error));
                } else {
                  object.insert(coll_name, Value::Array(values));
                }
              },
              // TODO: When implementing collections consider not using the
              // MongoDB `_id` property as the key.
              Query::Object(_) => {

              }
            }
          // } else {
          //   return Err(Error::new(
          //     ErrorCode::Forbidden,
          //     "Can‘t query a selection of MongoDB collections.",
          //     Some("Query specific collections instead of a range of collections.")
          //   );
          // }
        }
        Ok(Value::Object(object))
      }
    }
  }

  fn patch(&self, _: Vec<Patch>) -> Result<Value, Error> {
    Err(Error::unimplemented("Patching not implemented for MongoDB driver."))
  }
}

impl From<MongoDBError> for Error {
  fn from(error: MongoDBError) -> Self {
    Error::internal(error.description())
  }
}

impl From<Document> for Value {
  fn from(document: Document) -> Self {
    let mut map = LinearMap::new();
    for key in &document.keys {
      if let Some(value) = document.get(key) {
        map.insert(key.clone(), Value::from(value.clone()));
      }
    }
    Value::Object(map)
  }
}

impl From<Bson> for Value {
  fn from(bson: Bson) -> Self {
    match bson {
      Bson::FloatingPoint(value) => Value::F64(f64::from(value)),
      Bson::String(value) => Value::String(value),
      Bson::Array(values) => Value::Array(values.into_iter().map(|v| Value::from(v)).collect()),
      Bson::Document(document) => Value::from(document),
      Bson::Boolean(value) => Value::Boolean(value),
      Bson::Null => Value::Null,
      Bson::RegExp(value, _) => Value::String(value),
      Bson::JavaScriptCode(value) => Value::String(value),
      Bson::JavaScriptCodeWithScope(value, _) => Value::String(value),
      Bson::I32(value) => Value::I64(i64::from(value)),
      Bson::I64(value) => Value::I64(i64::from(value)),
      Bson::TimeStamp(value) => Value::I64(i64::from(value)),
      // TODO: Actual transformation of binary type.
      Bson::Binary(_, _) => Value::Null,
      Bson::ObjectId(object_id) => Value::String(object_id.to_string()),
      Bson::UtcDatetime(time) => Value::String(time.to_rfc3339())
    }
  }
}

#[cfg(test)]
mod tests {
  use super::bson::{Bson, Document};
  use super::mongodb::db::{ThreadedDatabase};
  use definition::Definition;
  use definition::schema::Schema;
  use driver::Driver;
  use driver::mongodb::MongoDriver;
  use query::{Query, Selection};
  use value::Value;

  #[test]
  fn test_validate_definition() {
    assert!(MongoDriver::validate_definition(&Definition { data: Schema::Boolean }).is_err());
    assert!(MongoDriver::validate_definition(&Definition {
      data: Schema::Object {
        required: vec![],
        additional_properties: false,
        properties: linear_map! {}
      }
    }).is_ok());
    assert!(MongoDriver::validate_definition(&Definition {
      data: Schema::Object {
        required: vec![],
        additional_properties: false,
        properties: linear_map! {
          S!("foo") => Schema::Boolean
        }
      }
    }).is_err());
    assert!(MongoDriver::validate_definition(&Definition {
      data: Schema::Object {
        required: vec![],
        additional_properties: false,
        properties: linear_map! {
          S!("foo") => Schema::Array {
            items: Box::new(Schema::Boolean)
          }
        }
      }
    }).is_err());
    assert!(MongoDriver::validate_definition(&Definition {
      data: Schema::Object {
        required: vec![],
        additional_properties: false,
        properties: linear_map! {
          S!("foo") => Schema::Array {
            items: Box::new(Schema::Object {
              required: vec![],
              additional_properties: true,
              properties: linear_map! {}
            })
          }
        }
      }
    }).is_ok());
  }

  #[test]
  fn test_database() {
    let driver = MongoDriver::connect("mongodb://localhost:27017/ardite_test").unwrap();
    let coll_name = "ardite_test_collection";
    driver.db.drop_collection(coll_name).unwrap();
    let collection = driver.db.collection(coll_name);
    let mut doc1 = Document::new();
    doc1.insert(S!("title"), Bson::String(S!("Back to the future!")));
    doc1.insert(S!("foo"), Bson::String(S!("bar")));
    let mut doc2 = Document::new();
    doc2.insert(S!("buz"), Bson::String(S!("baz")));
    let id1 = collection.insert_one(doc1, None).unwrap().inserted_id.unwrap();
    let id2 = collection.insert_one(doc2, None).unwrap().inserted_id.unwrap();
    assert!(driver.query(Query::Value).is_err());
    assert_eq!(driver.query(Query::Object(linear_map! {
      Selection::Key(coll_name.to_string()) => Query::Value
    })).unwrap(), vobject! {
      coll_name => varray![
        vobject! {
          "_id" => Value::from(id1),
          "title" => vstring!("Back to the future!"),
          "foo" => vstring!("bar")
        }, vobject! {
          "_id" => Value::from(id2),
          "buz" => vstring!("baz")
        }
      ]
    });
    driver.db.drop_collection(coll_name).unwrap();
  }
}
<|endoftext|>


<commit_before>use std;
import std::ivec;
import std::int;
import std::sort;

fn test_qsort() {
    auto names = ~[mutable 2, 1, 3];

    auto expected = ~[1, 2, 3];

    fn lteq(&int a, &int b) -> bool { int::le(a, b) }
    sort::ivector::quick_sort(lteq, names);

    auto pairs = ivec::zip(expected, ivec::from_mut(names));
    for (tup(int, int) p in pairs) {
        log_err #fmt("%d %d", p._0, p._1);
        assert p._0 == p._1;
    }
}

fn main() {
    test_qsort();
}
<commit_msg>xfail simple-qsort.rs test at stage0.<commit_after>// xfail-stage0

use std;
import std::ivec;
import std::int;
import std::sort;

fn test_qsort() {
    auto names = ~[mutable 2, 1, 3];

    auto expected = ~[1, 2, 3];

    fn lteq(&int a, &int b) -> bool { int::le(a, b) }
    sort::ivector::quick_sort(lteq, names);

    auto pairs = ivec::zip(expected, ivec::from_mut(names));
    for (tup(int, int) p in pairs) {
        log_err #fmt("%d %d", p._0, p._1);
        assert p._0 == p._1;
    }
}

fn main() {
    test_qsort();
}
<|endoftext|>


<commit_before>// Copyright (C) 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: MPL-2.0
//

use super::*;
use std::path::PathBuf;
use tempfile::tempdir;

pub fn create_hook(path: PathBuf, contents: &str, mode: u32) {
    use std::fs::create_dir_all;
    use std::fs::metadata;
    use std::fs::File;
    use std::io::Write;
    use std::os::unix::fs::PermissionsExt;
    use std::{thread, time};

    // ensure path exists
    create_dir_all(path.parent().unwrap()).unwrap();

    let mut file = File::create(&path).unwrap();
    file.write_all(contents.as_bytes()).unwrap();

    let mut permissions = metadata(path).unwrap().permissions();
    permissions.set_mode(mode);
    file.set_permissions(permissions).unwrap();

    // This is needed because the filesystem may report it is complete
    // before it finishes writing it.
    thread::sleep(time::Duration::from_millis(50));
}

pub fn product_uid_hook(path: &Path) -> PathBuf {
    path.join(PRODUCT_UID_HOOK)
}

pub fn version_hook(path: &Path) -> PathBuf {
    path.join(VERSION_HOOK)
}

pub fn hardware_hook(path: &Path) -> PathBuf {
    path.join(HARDWARE_HOOK)
}

pub fn device_identity_dir(path: &Path) -> PathBuf {
    path.join(DEVICE_IDENTITY_DIR).join("identity")
}

pub fn device_attributes_dir(path: &Path) -> PathBuf {
    path.join(DEVICE_ATTRIBUTES_DIR).join("attributes")
}

pub enum FakeDevice {
    NoUpdate,
    HasUpdate,
    ExtraPoll,
    InvalidHardware,
}

pub fn create_fake_metadata(device: FakeDevice) -> PathBuf {
    let tmpdir = tempdir().unwrap().path().to_path_buf();

    // create fake hooks to be used to validate the load
    create_hook(
        product_uid_hook(&tmpdir),
        "#!/bin/sh\necho 229ffd7e08721d716163fc81a2dbaf6c90d449f0a3b009b6a2defe8a0b0d7381",
        0o755,
    );
    create_hook(version_hook(&tmpdir), "#!/bin/sh\necho 1.1", 0o755);
    create_hook(
        hardware_hook(&tmpdir),
        &format!(
            "#!/bin/sh\necho {}",
            match device {
                FakeDevice::InvalidHardware => "invalid",
                _ => "board",
            }
        ),
        0o755,
    );
    create_hook(
        device_identity_dir(&tmpdir),
        &format!(
            "#!/bin/sh\necho id1=value{}\necho id2=value2",
            match device {
                FakeDevice::NoUpdate => 1,
                FakeDevice::HasUpdate => 2,
                FakeDevice::ExtraPoll => 3,
                FakeDevice::InvalidHardware => 4,
            }
        ),
        0o755,
    );
    create_hook(
        device_attributes_dir(&tmpdir),
        "#!/bin/sh\necho attr1=attrvalue1\necho attr2=attrvalue2",
        0o755,
    );

    tmpdir
}

#[test]
fn run_multiple_hooks_in_a_dir() {
    let tmpdir = tempdir().unwrap().path().to_path_buf();

    // create two scripts so we can test the parsing of output
    create_hook(
        tmpdir.join("hook1"),
        "#!/bin/sh\necho key2=val2\necho key1=val1",
        0o755,
    );
    create_hook(
        tmpdir.join("hook2"),
        "#!/bin/sh\necho key2=val4\necho key1=val3",
        0o755,
    );

    let fv = run_hooks_from_dir(&tmpdir).unwrap();

    assert_eq!(fv.keys().len(), 2);
    assert_eq!(fv.keys().collect::<Vec<_>>(), ["key1", "key2"]);
    assert_eq!(fv["key1"], ["val1", "val3"]);
    assert_eq!(fv["key2"], ["val2", "val4"]);
}

#[test]
fn check_load_metadata() {
    use std::fs::remove_file;

    {
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        // check error with a invalid product uid
        create_hook(
            product_uid_hook(&metadata_dir),
            "#!/bin/sh\necho 123",
            0o755,
        );
        let metadata = Metadata::new(&metadata_dir);
        assert!(metadata.is_err());
    }

    {
        // check error when lacks product uid
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        remove_file(product_uid_hook(&metadata_dir)).unwrap();
        let metadata = Metadata::new(&metadata_dir);
        assert!(metadata.is_err());
    }

    {
        // check error when lacks device identity
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        remove_file(device_identity_dir(&metadata_dir)).unwrap();
        let metadata = Metadata::new(&metadata_dir);
        assert!(metadata.is_err());
    }

    {
        // check if is still valid without device attributes
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        remove_file(device_attributes_dir(&metadata_dir)).unwrap();
        let metadata = Metadata::new(&metadata_dir).unwrap();
        assert_eq!(
            "229ffd7e08721d716163fc81a2dbaf6c90d449f0a3b009b6a2defe8a0b0d7381",
            metadata.product_uid
        );
        assert_eq!("1.1", metadata.version);
        assert_eq!("board", metadata.hardware);
        assert_eq!(2, metadata.device_identity.len());
        assert_eq!(0, metadata.device_attributes.len());
    }

    {
        // complete metadata
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        let metadata = Metadata::new(&metadata_dir).unwrap();
        assert_eq!(
            "229ffd7e08721d716163fc81a2dbaf6c90d449f0a3b009b6a2defe8a0b0d7381",
            metadata.product_uid
        );
        assert_eq!("1.1", metadata.version);
        assert_eq!("board", metadata.hardware);
        assert_eq!(2, metadata.device_identity.len());
        assert_eq!(2, metadata.device_attributes.len());
    }
}
<commit_msg>firmware: tests: Drop mode param from `create_hook`<commit_after>// Copyright (C) 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: MPL-2.0
//

use super::*;
use std::path::PathBuf;
use tempfile::tempdir;

pub fn create_hook(path: PathBuf, contents: &str) {
    use std::fs::create_dir_all;
    use std::fs::metadata;
    use std::fs::File;
    use std::io::Write;
    use std::os::unix::fs::PermissionsExt;
    use std::{thread, time};

    // ensure path exists
    create_dir_all(path.parent().unwrap()).unwrap();

    let mut file = File::create(&path).unwrap();
    file.write_all(contents.as_bytes()).unwrap();

    let mut permissions = metadata(path).unwrap().permissions();
    permissions.set_mode(0o755);
    file.set_permissions(permissions).unwrap();

    // This is needed because the filesystem may report it is complete
    // before it finishes writing it.
    thread::sleep(time::Duration::from_millis(50));
}

pub fn product_uid_hook(path: &Path) -> PathBuf {
    path.join(PRODUCT_UID_HOOK)
}

pub fn version_hook(path: &Path) -> PathBuf {
    path.join(VERSION_HOOK)
}

pub fn hardware_hook(path: &Path) -> PathBuf {
    path.join(HARDWARE_HOOK)
}

pub fn device_identity_dir(path: &Path) -> PathBuf {
    path.join(DEVICE_IDENTITY_DIR).join("identity")
}

pub fn device_attributes_dir(path: &Path) -> PathBuf {
    path.join(DEVICE_ATTRIBUTES_DIR).join("attributes")
}

pub enum FakeDevice {
    NoUpdate,
    HasUpdate,
    ExtraPoll,
    InvalidHardware,
}

pub fn create_fake_metadata(device: FakeDevice) -> PathBuf {
    let tmpdir = tempdir().unwrap().path().to_path_buf();

    // create fake hooks to be used to validate the load
    create_hook(
        product_uid_hook(&tmpdir),
        "#!/bin/sh\necho 229ffd7e08721d716163fc81a2dbaf6c90d449f0a3b009b6a2defe8a0b0d7381",
    );
    create_hook(version_hook(&tmpdir), "#!/bin/sh\necho 1.1");
    create_hook(
        hardware_hook(&tmpdir),
        &format!(
            "#!/bin/sh\necho {}",
            match device {
                FakeDevice::InvalidHardware => "invalid",
                _ => "board",
            }
        ),
    );
    create_hook(
        device_identity_dir(&tmpdir),
        &format!(
            "#!/bin/sh\necho id1=value{}\necho id2=value2",
            match device {
                FakeDevice::NoUpdate => 1,
                FakeDevice::HasUpdate => 2,
                FakeDevice::ExtraPoll => 3,
                FakeDevice::InvalidHardware => 4,
            }
        ),
    );
    create_hook(
        device_attributes_dir(&tmpdir),
        "#!/bin/sh\necho attr1=attrvalue1\necho attr2=attrvalue2",
    );

    tmpdir
}

#[test]
fn run_multiple_hooks_in_a_dir() {
    let tmpdir = tempdir().unwrap().path().to_path_buf();

    // create two scripts so we can test the parsing of output
    create_hook(
        tmpdir.join("hook1"),
        "#!/bin/sh\necho key2=val2\necho key1=val1",
    );
    create_hook(
        tmpdir.join("hook2"),
        "#!/bin/sh\necho key2=val4\necho key1=val3",
    );

    let fv = run_hooks_from_dir(&tmpdir).unwrap();

    assert_eq!(fv.keys().len(), 2);
    assert_eq!(fv.keys().collect::<Vec<_>>(), ["key1", "key2"]);
    assert_eq!(fv["key1"], ["val1", "val3"]);
    assert_eq!(fv["key2"], ["val2", "val4"]);
}

#[test]
fn check_load_metadata() {
    use std::fs::remove_file;

    {
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        // check error with a invalid product uid
        create_hook(product_uid_hook(&metadata_dir), "#!/bin/sh\necho 123");
        let metadata = Metadata::new(&metadata_dir);
        assert!(metadata.is_err());
    }

    {
        // check error when lacks product uid
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        remove_file(product_uid_hook(&metadata_dir)).unwrap();
        let metadata = Metadata::new(&metadata_dir);
        assert!(metadata.is_err());
    }

    {
        // check error when lacks device identity
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        remove_file(device_identity_dir(&metadata_dir)).unwrap();
        let metadata = Metadata::new(&metadata_dir);
        assert!(metadata.is_err());
    }

    {
        // check if is still valid without device attributes
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        remove_file(device_attributes_dir(&metadata_dir)).unwrap();
        let metadata = Metadata::new(&metadata_dir).unwrap();
        assert_eq!(
            "229ffd7e08721d716163fc81a2dbaf6c90d449f0a3b009b6a2defe8a0b0d7381",
            metadata.product_uid
        );
        assert_eq!("1.1", metadata.version);
        assert_eq!("board", metadata.hardware);
        assert_eq!(2, metadata.device_identity.len());
        assert_eq!(0, metadata.device_attributes.len());
    }

    {
        // complete metadata
        let metadata_dir = create_fake_metadata(FakeDevice::NoUpdate);
        let metadata = Metadata::new(&metadata_dir).unwrap();
        assert_eq!(
            "229ffd7e08721d716163fc81a2dbaf6c90d449f0a3b009b6a2defe8a0b0d7381",
            metadata.product_uid
        );
        assert_eq!("1.1", metadata.version);
        assert_eq!("board", metadata.hardware);
        assert_eq!(2, metadata.device_identity.len());
        assert_eq!(2, metadata.device_attributes.len());
    }
}
<|endoftext|>


<commit_before>use crate::numeric::*;

fn witness(mut a: u64, exponent: u64, m: u64) -> bool {
    if a == 0 {
        return false;
    }

    let mul = if m < 1 << 63 {
        sm_mul as fn(u64, u64, u64) -> u64
    } else {
        big_mul as fn(u64, u64, u64) -> u64
    };

    if pow(a, m - 1, m, mul) != 1 {
        return true;
    }
    a = pow(a, exponent, m, mul);
    if a == 1 {
        return false;
    }
    loop {
        if a == 1 {
            return true;
        }
        if a == m - 1 {
            return false;
        }
        a = mul(a, a, m);
    }
}

// Deterministic Miller-Rabin primality-checking algorithm, adapted to extract
// (some) dividers; it will fail to factor strong pseudoprimes.
pub(crate) fn is_prime(num: u64) -> bool {
    if num < 2 {
        return false;
    }
    if num % 2 == 0 {
        return num == 2;
    }
    let mut exponent = num - 1;
    while exponent & 1 == 0 {
        exponent >>= 1;
    }

    // These witnesses detect all composites up to at least 2^64.
    // Discovered by Jim Sinclair, according to http://miller-rabin.appspot.com
    let witnesses = [2, 325, 9_375, 28_178, 450_775, 9_780_504, 1_795_265_022];
    !witnesses
        .iter()
        .any(|&wit| witness(wit % num, exponent, num))
}
<commit_msg>factor::miller_rabbin: Refactor before extracting dividers<commit_after>use crate::numeric::*;

// Small set of bases for the Miller-Rabin prime test, valid for all 64b integers;
//  discovered by Jim Sinclair on 2011-04-20, see miller-rabin.appspot.com
const BASIS: [u64; 7] = [2, 325, 9375, 28178, 450775, 9780504, 1795265022];

// Deterministic Miller-Rabin primality-checking algorithm, adapted to extract
// (some) dividers; it will fail to factor strong pseudoprimes.
pub(crate) fn is_prime(n: u64) -> bool {
    if n < 2 {
        return false;
    }
    if n % 2 == 0 {
        return n == 2;
    }

    let d = (n - 1).trailing_zeros();
    let r = (n - 1) >> d;

    let mul = if n < 1 << 63 {
        sm_mul as fn(u64, u64, u64) -> u64
    } else {
        big_mul as fn(u64, u64, u64) -> u64
    };

    for a in BASIS.iter() {
        let mut x = a % n;
        if x == 0 {
            break;
        }

        if pow(x, n - 1, n, mul) != 1 {
            return false;
        }
        x = pow(x, r, n, mul);
        if x == 1 || x == n - 1 {
            break;
        }

        loop {
            let y = mul(x, x, n);
            if y == 1 {
                return false;
            }
            if y == n - 1 {
                // This basis element is not a witness of `n` being composite.
                // Keep looking.
                break;
            }
            x = y;
        }
    }

    true
}
<|endoftext|>


<commit_before>use decoders::Image;

pub fn gamma(img: &Image, inb: &[f32]) -> Vec<f32> {
  let mut out: Vec<f32> = vec![0.0; (img.width*img.height*3) as usize];

  let g: f32 = 0.45;
  let f: f32 = 0.099;
  let min: f32 = 0.018;
  let mul: f32 = 4.5;

  let mut pos = 0;
  for val in inb {
    out[pos] = if *val <= min {
      mul * val
    } else {
      ((1.0+f) * val).powf(g) - f
    };

    pos += 1;
  }

  out
}
<commit_msg>gamma: speedup by precomputing the powf<commit_after>use decoders::Image;

pub fn gamma(img: &Image, inb: &[f32]) -> Vec<f32> {
  let mut out: Vec<f32> = vec![0.0; (img.width*img.height*3) as usize];

  let g: f32 = 0.45;
  let f: f32 = 0.099;
  let min: f32 = 0.018;
  let mul: f32 = 4.5;

  let maxvals = 72100; // 2^16 * 1.099 plus some margin
  let mut powlookup: Vec<f32> = vec![0.0; maxvals+1];
  for i in 0..(maxvals+1) {
    let v = (i as f32) / (maxvals as f32);
    powlookup[i] = v.powf(g);
  }

  let mut pos = 0;
  for val in inb {
    out[pos] = if *val <= min {
      mul * val
    } else {
      let part = (1.0+f) * val;
      let power = powlookup[(part.max(0.0)*(maxvals as f32)).min(maxvals as f32) as usize];
      power - f
    };

    pos += 1;
  }

  out
}
<|endoftext|>


<commit_before>struct Person<'a> {
    name: &'a str,
    parent: Option<&'a Person<'a>>,
}

impl<'a> Person<'a> {
    fn new(name: &'a str, parent: Option<&'a Person<'a>>) -> Person<'a> {
        Person{name: name, parent: parent}
    }

    fn parents_name(&self) -> Option<&'a str> {
        match self.parent {
            Some(p) => Some(p.name),
            None => None,
        }
    }
}

#[test]
fn it_works() {
    let jane = Person::new("Jane", None);
    let tom = Person::new("Tom", Some(&jane));

    assert_eq!(tom.name, "Tom");
    assert_eq!(jane.name, "Jane");
    assert_eq!(tom.parent.unwrap().name, "Jane");
    assert_eq!(tom.parents_name(), Some("Jane"));
    assert_eq!(jane.parents_name(), None);
}
<commit_msg>Added some notes for blog post<commit_after>struct Person<'a> {
    name: &'a str,
    parent: Option<&'a Person<'a>>,
}

impl<'a> Person<'a> {
    fn new(name: &'a str, parent: Option<&'a Person<'a>>) -> Person<'a> {
        Person{name: name, parent: parent}
    }

    fn parents_name(&self) -> Option<&'a str> {
        match self.parent {
            Some(p) => Some(p.name),
            None => None,
        }
    }
}

#[test]
fn it_works() {
    let jane = Person::new("Jane", None);
    let tom = Person::new("Tom", Some(&jane));

    assert_eq!(tom.name, "Tom");
    assert_eq!(jane.name, "Jane");
    assert_eq!(tom.parent.unwrap().name, "Jane");
    assert_eq!(tom.parents_name(), Some("Jane"));
    assert_eq!(jane.parents_name(), None);
}

// - We are making a promise to the compiler that all of these things live for atleast the same scope.
// - We are not asking the compiler to "create a lifetime". We are just telling it to complain if we
//   don't do what we say we are doing.
// - Why? Because this allows Rust to ensure we cannot cause common memory allocation bugs. It does
//   this at compile time. It's a zero-cost abstraction because there is no runtime penalty.
// - It makes code look "uglier". But this is the wrong mindset for writing systems-level programs.
//   The emphasis here is on safety, not expressiveness.
// - Question: Why can't Rust ensure/infer/elide this scenario? Surely any reference to a Parent
//   must *always* live for the same or a bigger scope???
// -
<|endoftext|>