<commit_before>// Tifflin OS - simple_console
// - By John Hodge (thePowersGang)
//
// Simplistic console, used as a quick test case (fullscreen window)

#[macro_use]
extern crate syscalls;

use syscalls::Object;

fn main() {
	use syscalls::gui::{Group,Window};
	use syscalls::threads::S_THIS_PROCESS;

	::syscalls::threads::wait(&mut [S_THIS_PROCESS.get_wait()], !0);
	::syscalls::gui::set_group( S_THIS_PROCESS.receive_object::<Group>(0).unwrap() );

	let window = Window::new("Console").unwrap();
	window.maximise();
	window.fill_rect(0,0, !0,!0, 0x0);
	window.show();

	loop {
		// Bind to receive events relating to the window
		let mut events = [window.get_wait()];

		::syscalls::threads::wait(&mut events, !0);

		while let Some(ev) = window.pop_event()
		{
			kernel_log!("ev = {:?}", ev);
		}

		window.check_wait(&events[0]);
	}
}

<commit_msg>Usermode/simple_console - Use a deep red/ochre for test colour<commit_after>// Tifflin OS - simple_console
// - By John Hodge (thePowersGang)
//
// Simplistic console, used as a quick test case (fullscreen window)

#[macro_use]
extern crate syscalls;

use syscalls::Object;

fn main() {
	use syscalls::gui::{Group,Window};
	use syscalls::threads::S_THIS_PROCESS;

	::syscalls::threads::wait(&mut [S_THIS_PROCESS.get_wait()], !0);
	::syscalls::gui::set_group( S_THIS_PROCESS.receive_object::<Group>(0).unwrap() );

	let window = Window::new("Console").unwrap();
	window.maximise();
	window.fill_rect(0,0, !0,!0, 0x33_00_00);   // A nice rust-like red :)
	window.show();

	loop {
		// Bind to receive events relating to the window
		let mut events = [window.get_wait()];

		::syscalls::threads::wait(&mut events, !0);

		while let Some(ev) = window.pop_event()
		{
			kernel_log!("ev = {:?}", ev);
		}

		window.check_wait(&events[0]);
	}
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate crossbeam_channel;
extern crate tempdir;
extern crate languageserver_types;
extern crate serde;
extern crate serde_json;
extern crate gen_lsp_server;
extern crate flexi_logger;
extern crate m;

mod support;

use m::req::{Runnables, RunnablesParams, DidReloadWorkspace};

use support::project;

const LOG: &'static str = "";

#[test]
fn test_runnables_no_project() {
    let server = project(r"
//- lib.rs
#[test]
fn foo() {
}
");
    server.request::<Runnables>(
        RunnablesParams {
            text_document: server.doc_id("lib.rs"),
            position: None,
        },
        r#"[
          {
            "args": [ "test", "--", "foo", "--nocapture" ],
            "bin": "cargo",
            "env": { "RUST_BACKTRACE": "short" },
            "label": "test foo",
            "range": {
              "end": { "character": 1, "line": 2 },
              "start": { "character": 0, "line": 0 }
            }
          }
        ]"#
    );
}

#[test]
fn test_runnables_project() {
    let server = project(r#"
//- Cargo.toml
[package]
name = "foo"
version = "0.0.0"

//- src/lib.rs
pub fn foo() {}

//- tests/spam.rs
#[test]
fn test_eggs() {}
"#);
    server.wait_for_notification::<DidReloadWorkspace>();
    server.request::<Runnables>(
        RunnablesParams {
            text_document: server.doc_id("tests/spam.rs"),
            position: None,
        },
        r#"[
          {
            "args": [ "test", "--package", "foo", "--test", "spam", "--", "test_eggs", "--nocapture" ],
            "bin": "cargo",
            "env": { "RUST_BACKTRACE": "short" },
            "label": "test test_eggs",
            "range": {
              "end": { "character": 17, "line": 1 },
              "start": { "character": 0, "line": 0 }
            }
          }
        ]"#
    );
}

#[test]
fn test_project_model() {
    let server = project(r#"
//- Cargo.toml
[package]
name = "foo"
version = "0.0.0"

//- src/lib.rs
pub fn foo() {}
"#);
    server.notification::<DidReloadWorkspace>(r#"[
  {
    "packages": [
      {
        "manifest": "$PROJECT_ROOT$/Cargo.toml",
        "name": "foo",
        "targets": [ 0 ]
      }
    ],
    "targets": [
      { "kind": "Lib", "name": "foo", "pkg": 0, "root": "$PROJECT_ROOT$/src/lib.rs" }
    ],
    "ws_members": [ 0 ]
  }
]"#
    );
}
<commit_msg>fix the test<commit_after>#[macro_use]
extern crate crossbeam_channel;
extern crate tempdir;
extern crate languageserver_types;
extern crate serde;
extern crate serde_json;
extern crate gen_lsp_server;
extern crate flexi_logger;
extern crate m;

mod support;

use m::req::{Runnables, RunnablesParams, DidReloadWorkspace};

use support::project;

const LOG: &'static str = "";

#[test]
fn test_runnables_no_project() {
    let server = project(r"
//- lib.rs
#[test]
fn foo() {
}
");
    server.request::<Runnables>(
        RunnablesParams {
            text_document: server.doc_id("lib.rs"),
            position: None,
        },
        r#"[
          {
            "args": [ "test", "--", "foo", "--nocapture" ],
            "bin": "cargo",
            "env": { "RUST_BACKTRACE": "short" },
            "label": "test foo",
            "range": {
              "end": { "character": 1, "line": 2 },
              "start": { "character": 0, "line": 0 }
            }
          }
        ]"#
    );
}

#[test]
fn test_runnables_project() {
    let server = project(r#"
//- Cargo.toml
[package]
name = "foo"
version = "0.0.0"

//- src/lib.rs
pub fn foo() {}

//- tests/spam.rs
#[test]
fn test_eggs() {}
"#);
    server.wait_for_notification::<DidReloadWorkspace>();
    server.request::<Runnables>(
        RunnablesParams {
            text_document: server.doc_id("tests/spam.rs"),
            position: None,
        },
        r#"[
          {
            "args": [ "test", "--package", "foo", "--test", "spam", "--", "test_eggs", "--nocapture" ],
            "bin": "cargo",
            "env": { "RUST_BACKTRACE": "short" },
            "label": "test test_eggs",
            "range": {
              "end": { "character": 17, "line": 1 },
              "start": { "character": 0, "line": 0 }
            }
          }
        ]"#
    );
}

#[test]
fn test_project_model() {
    let server = project(r#"
//- Cargo.toml
[package]
name = "foo"
version = "0.0.0"

//- src/lib.rs
pub fn foo() {}
"#);
    server.notification::<DidReloadWorkspace>(r#"[
  {
    "packages": [
      {
        "is_member": true,
        "manifest": "$PROJECT_ROOT$/Cargo.toml",
        "name": "foo",
        "targets": [ 0 ]
      }
    ],
    "targets": [
      { "kind": "Lib", "name": "foo", "pkg": 0, "root": "$PROJECT_ROOT$/src/lib.rs" }
    ]
  }
]"#
    );
}
<|endoftext|>


<commit_before>//! The integration suite helpers.

use regex::Regex;
use std::process::Command;
use std::path::Path;
use std::collections::HashMap;
use std::str::FromStr;

/// List windows will give details about the active sessions in testing.
/// target: A string represented by the {named_session}:{named_window}
pub fn list_windows(target: &String) -> String {
    let output = Command::new("tmux")
                     .arg("list-windows")
                     .arg("-t")
                     .arg(target)
                     .output()
                     .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });

    String::from_utf8_lossy(&output.stdout).into_owned()
}

pub fn open_muxed(project: &String, project_root: &Path) -> () {
    println!("root: {}", project_root.display());
    let output = Command::new("./target/debug/muxed")
        .arg("-d")
        .arg("-p")
        .arg(format!("{}", project_root.display()))
        .arg(project)
        .output()
        .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });

    println!("status: {}", output.status);
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
}

pub fn kill_session(target: &String) -> () {
    Command::new("tmux")
        .arg("kill-session")
        .arg("-t")
        .arg(target)
        .output()
        .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
}

#[derive(Debug)]
pub struct TmuxSession {
    pub num_of_windows: usize,
    pub windows: HashMap<String, HashMap<String, usize>>
}

impl TmuxSession {
    pub fn from_string(results: &String) -> TmuxSession {
        let window_name = Regex::new(r": (\w*)[$\*-]? \(").unwrap();

        let lines: Vec<&str> = results.split("\n").collect();
        let (_, window_lines) = lines.split_last().unwrap();

        let mut windows: HashMap<String, HashMap<String, usize>> = HashMap::new();
        let mut h = HashMap::new();

        for line in window_lines {
            for cap in window_name.captures_iter(line) {
                let name = cap.at(1).unwrap();
                h.insert("Panes".to_string(), TmuxSession::count_panes(line));
                windows.insert(name.to_string(), h.clone());
            }
        }

        TmuxSession {
          num_of_windows: window_lines.len(),
          windows: windows
        }
    }

    pub fn count_panes(line: &str) -> usize {
        let panes = Regex::new(r"\((\d*) panes\)").unwrap();
        let mut num: &str = "";

        for cap in panes.captures_iter(line) {
            num = cap.at(1).unwrap_or("0");
        }

        usize::from_str(num).unwrap()
    }
}
<commit_msg>Add testing for pane counter<commit_after>//! The integration suite helpers.

use regex::Regex;
use std::process::Command;
use std::path::Path;
use std::collections::HashMap;
use std::str::FromStr;

/// List windows will give details about the active sessions in testing.
/// target: A string represented by the {named_session}:{named_window}
pub fn list_windows(target: &String) -> String {
    let output = Command::new("tmux")
                     .arg("list-windows")
                     .arg("-t")
                     .arg(target)
                     .output()
                     .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });

    String::from_utf8_lossy(&output.stdout).into_owned()
}

pub fn open_muxed(project: &String, project_root: &Path) -> () {
    println!("root: {}", project_root.display());
    let output = Command::new("./target/debug/muxed")
        .arg("-d")
        .arg("-p")
        .arg(format!("{}", project_root.display()))
        .arg(project)
        .output()
        .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });

    println!("status: {}", output.status);
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
}

pub fn kill_session(target: &String) -> () {
    Command::new("tmux")
        .arg("kill-session")
        .arg("-t")
        .arg(target)
        .output()
        .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
}

#[derive(Debug)]
pub struct TmuxSession {
    pub num_of_windows: usize,
    pub windows: HashMap<String, HashMap<String, usize>>
}

impl TmuxSession {
    pub fn from_string(results: &String) -> TmuxSession {
        let window_name = Regex::new(r": (\w*)[$\*-]? \(").unwrap();

        let lines: Vec<&str> = results.split("\n").collect();
        let (_, window_lines) = lines.split_last().unwrap();

        let mut windows: HashMap<String, HashMap<String, usize>> = HashMap::new();
        let mut h = HashMap::new();

        for line in window_lines {
            for cap in window_name.captures_iter(line) {
                let name = cap.at(1).unwrap();
                h.insert("Panes".to_string(), TmuxSession::count_panes(line));
                windows.insert(name.to_string(), h.clone());
            }
        }

        TmuxSession {
          num_of_windows: window_lines.len(),
          windows: windows
        }
    }

    pub fn count_panes(line: &str) -> usize {
        let panes = Regex::new(r"\((\d*) panes\)").unwrap();
        let mut num: &str = "";

        for cap in panes.captures_iter(line) {
            num = cap.at(1).unwrap_or("0");
        }

        usize::from_str(num).unwrap()
    }
}

#[test]
fn count_panes_returns_two() {
  let num = TmuxSession::count_panes("1: ssh (2 panes) [173x42] [layout b5bd,173x42,0,0,0] @0");
  assert_eq!(num, 2)
}

#[test]
fn count_panes_returns_one() {
  let num = TmuxSession::count_panes("1: ssh (1 panes) [173x42] [layout b5bd,173x42,0,0,0] @0");
  assert_eq!(num, 1)
}

#[test]
fn counts_with_active_previous_flag() {
  let num = TmuxSession::count_panes("1: ssh- (2 panes) [173x42] [layout b5bd,173x42,0,0,0] @0");
  assert_eq!(num, 2)
}

#[test]
fn count_with_active_dollar_sign_flag() {
  let num = TmuxSession::count_panes("1: ssh$ (2 panes) [173x42] [layout b5bd,173x42,0,0,0] @0");
  assert_eq!(num, 2)
}

#[test]
fn count_with_active_window_flag() {
  let num = TmuxSession::count_panes("1: ssh* (2 panes) [173x42] [layout b5bd,173x42,0,0,0] @0");
  assert_eq!(num, 2)
}
<|endoftext|>


<commit_before>//! An asynchronous RabbitMQ client for proxy engine
//!

use std::io;

use amq_protocol::uri::{AMQPUri};
use futures::{IntoFuture};
use futures::future::{Future};
use lapin_futures_rustls::{AMQPConnectionRustlsExt};
use lapin_futures_rustls::lapin::channel::{Channel, ConfirmSelectOptions};
use lapin_futures_rustls::lapin::client::{Client, ConnectionOptions};
use tokio::executor::{spawn};
use tokio_tcp::{TcpStream};

use super::super::cli::{CliOptions};
use super::super::error::{PathfinderError};

/// Alias for the lapin client with TLS.
pub type LapinClient = Client<TcpStream>;
/// Alias for the lapin channel.
pub type LapinChannel = Channel<TcpStream>;
/// Alias for generic future for pathfinder and RabbitMQ.
pub type RabbitMQFuture = Box<Future<Item=(), Error=PathfinderError> + Send + Sync + 'static>;

/// A future-based asynchronous RabbitMQ client.
pub struct RabbitMQClient
{
    uri: AMQPUri,
    client: Option<Box<Future<Item=Client<TcpStream>, Error=io::Error> + Sync + Send + 'static>>,
}

impl RabbitMQClient {
    /// Returns a new instance of `RabbitMQClient`.
    pub fn new(cli: &CliOptions) -> RabbitMQClient {
        let schema = match cli.rabbitmq_secured {
            true => "amqps",
            false => "amqp",
        };

        let uri = format!(
            "{}://{}:{}@{}:{}/{}",
            schema.to_string(),
            cli.rabbitmq_username.clone(),
            cli.rabbitmq_password.clone(),
            cli.rabbitmq_host.clone(),
            cli.rabbitmq_port,
            cli.rabbitmq_virtual_host.clone()
        );

        RabbitMQClient {
            uri: uri.parse().unwrap(),
            client: None
        }
    }

    pub fn init(&mut self) {
        self.client = self.get_client();
    }

    pub fn get_channel(&self) -> Box<Future<Item=LapinChannel, Error=io::Error> + Sync + Send + 'static> {
        Box::new(
            self.client.unwrap().and_then(|client| {
                client.create_confirm_channel(ConfirmSelectOptions::default())
            })
        )
    }

    fn get_client(&mut self) -> Option<Box<Future<Item=LapinClient, Error=io::Error> + Sync + Send + 'static>> {
        match self.client {
            Some(client) => Some(client),
            None => {
                self.client = Some(Box::new(self.create_client()));
                self.client
            }
        }
    }

    fn create_client(&self) -> impl Future<Item=LapinClient, Error=io::Error> + Sync + Send + 'static {
        let address = self.get_address_to_rabbitmq().parse().unwrap();
        let uri = self.uri.clone();

        TcpStream::connect(&address).and_then(|stream| {
            Client::connect(stream, ConnectionOptions::from_uri(uri))
        })
        .and_then(|(client, heartbeat)| {
            spawn(heartbeat.map_err(|err| eprintln!("Heartbeat error: {:?}", err)))
                .into_future()
                .map(|_| client)
                .map_err(|_| io::Error::new(io::ErrorKind::Other, "Spawn error."))
        })
    }

    /// Generates a connection URL to RabbitMQ broker.
    fn get_address_to_rabbitmq(&self) -> String {
        format!("{}:{}", self.uri.authority.host, self.uri.authority.port)
    }
}
<commit_msg>Removed unused imports for RabbitMQ client<commit_after>//! An asynchronous RabbitMQ client for proxy engine
//!

use std::io;

use amq_protocol::uri::{AMQPUri};
use futures::{IntoFuture};
use futures::future::{Future};
use lapin_futures_rustls::lapin::channel::{Channel, ConfirmSelectOptions};
use lapin_futures_rustls::lapin::client::{Client, ConnectionOptions};
use tokio::executor::{spawn};
use tokio_tcp::{TcpStream};

use super::super::cli::{CliOptions};
use super::super::error::{PathfinderError};

/// Alias for the lapin client with TLS.
pub type LapinClient = Client<TcpStream>;
/// Alias for the lapin channel.
pub type LapinChannel = Channel<TcpStream>;
/// Alias for generic future for pathfinder and RabbitMQ.
pub type RabbitMQFuture = Box<Future<Item=(), Error=PathfinderError> + Send + Sync + 'static>;

/// A future-based asynchronous RabbitMQ client.
pub struct RabbitMQClient
{
    uri: AMQPUri,
    client: Option<Box<Future<Item=Client<TcpStream>, Error=io::Error> + Sync + Send + 'static>>,
}

impl RabbitMQClient {
    /// Returns a new instance of `RabbitMQClient`.
    pub fn new(cli: &CliOptions) -> RabbitMQClient {
        let schema = match cli.rabbitmq_secured {
            true => "amqps",
            false => "amqp",
        };

        let uri = format!(
            "{}://{}:{}@{}:{}/{}",
            schema.to_string(),
            cli.rabbitmq_username.clone(),
            cli.rabbitmq_password.clone(),
            cli.rabbitmq_host.clone(),
            cli.rabbitmq_port,
            cli.rabbitmq_virtual_host.clone()
        );

        RabbitMQClient {
            uri: uri.parse().unwrap(),
            client: None
        }
    }

    pub fn init(&mut self) {
        self.client = self.get_client();
    }

    pub fn get_channel(&self) -> Box<Future<Item=LapinChannel, Error=io::Error> + Sync + Send + 'static> {
        Box::new(
            self.client.unwrap().and_then(|client| {
                client.create_confirm_channel(ConfirmSelectOptions::default())
            })
        )
    }

    fn get_client(&mut self) -> Option<Box<Future<Item=LapinClient, Error=io::Error> + Sync + Send + 'static>> {
        match self.client {
            Some(client) => Some(client),
            None => {
                self.client = Some(Box::new(self.create_client()));
                self.client
            }
        }
    }

    fn create_client(&self) -> impl Future<Item=LapinClient, Error=io::Error> + Sync + Send + 'static {
        let address = self.get_address_to_rabbitmq().parse().unwrap();
        let uri = self.uri.clone();

        TcpStream::connect(&address).and_then(|stream| {
            Client::connect(stream, ConnectionOptions::from_uri(uri))
        })
        .and_then(|(client, heartbeat)| {
            spawn(heartbeat.map_err(|err| eprintln!("Heartbeat error: {:?}", err)))
                .into_future()
                .map(|_| client)
                .map_err(|_| io::Error::new(io::ErrorKind::Other, "Spawn error."))
        })
    }

    /// Generates a connection URL to RabbitMQ broker.
    fn get_address_to_rabbitmq(&self) -> String {
        format!("{}:{}", self.uri.authority.host, self.uri.authority.port)
    }
}
<|endoftext|>


<commit_before>use super::XPathEvaluationContext;
use super::nodeset::Nodeset;
use super::nodeset::Node::{AttributeNode,ElementNode,TextNode};

pub trait XPathNodeTest {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>);
}

pub type SubNodeTest = Box<XPathNodeTest + 'static>;

pub struct NodeTestAttribute {
    pub name: String,
}

impl XPathNodeTest for NodeTestAttribute {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>) {
        if let AttributeNode(ref a) = context.node {
            if self.name.as_slice() == "*" || a.name() == self.name.as_slice() {
                result.add(context.node);
            }
        }
    }
}

pub struct NodeTestElement {
    pub name: String,
}

impl XPathNodeTest for NodeTestElement {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>) {
        if let ElementNode(ref e) = context.node {
            // TODO: redo namespaces!
            // if (_name.has_prefix() != e->qname().has_namespace()) return;

            // if (_name.has_prefix()) {
            //     let prefix_uri = context.find_namespace_for_prefix(_name.prefix());

            //     if (! prefix_uri) return;
            //     if (*prefix_uri != e->qname().namespace_uri()) return;
            // }

            if self.name.as_slice() == "*" || e.name() == self.name.as_slice() {
                result.add(context.node);
            }
        }
    }
}

#[allow(missing_copy_implementations)]
pub struct NodeTestNode;

impl XPathNodeTest for NodeTestNode {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>) {
        result.add(context.node);
    }
}

#[allow(missing_copy_implementations)]
pub struct NodeTestText;

impl XPathNodeTest for NodeTestText {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>) {
        if let TextNode(_) = context.node {
            result.add(context.node);
        }
    }
}
<commit_msg>Updates to handle QNames<commit_after>use super::XPathEvaluationContext;
use super::nodeset::Nodeset;
use super::nodeset::Node::{AttributeNode,ElementNode,TextNode};

pub trait XPathNodeTest {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>);
}

pub type SubNodeTest = Box<XPathNodeTest + 'static>;

pub struct NodeTestAttribute {
    pub name: String,
}

impl XPathNodeTest for NodeTestAttribute {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>) {
        if let AttributeNode(ref a) = context.node {
            if self.name == "*" || a.name().local_part() == self.name {
                result.add(context.node);
            }
        }
    }
}

pub struct NodeTestElement {
    pub name: String,
}

impl XPathNodeTest for NodeTestElement {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>) {
        if let ElementNode(ref e) = context.node {
            // TODO: redo namespaces!
            // if (_name.has_prefix() != e->qname().has_namespace()) return;

            // if (_name.has_prefix()) {
            //     let prefix_uri = context.find_namespace_for_prefix(_name.prefix());

            //     if (! prefix_uri) return;
            //     if (*prefix_uri != e->qname().namespace_uri()) return;
            // }

            if self.name == "*" || e.name().local_part() == self.name {
                result.add(context.node);
            }
        }
    }
}

#[allow(missing_copy_implementations)]
pub struct NodeTestNode;

impl XPathNodeTest for NodeTestNode {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>) {
        result.add(context.node);
    }
}

#[allow(missing_copy_implementations)]
pub struct NodeTestText;

impl XPathNodeTest for NodeTestText {
    fn test<'a, 'd>(&self, context: &XPathEvaluationContext<'a, 'd>, result: &mut Nodeset<'d>) {
        if let TextNode(_) = context.node {
            result.add(context.node);
        }
    }
}
<|endoftext|>


<commit_before>//! [`MessageBody`] trait and foreign implementations.

use std::{
    mem,
    pin::Pin,
    task::{Context, Poll},
};

use bytes::{Bytes, BytesMut};

use crate::error::Error;

use super::BodySize;

/// Type that implement this trait can be streamed to a peer.
pub trait MessageBody {
    fn size(&self) -> BodySize;

    fn poll_next(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>>;

    downcast_get_type_id!();
}

downcast!(MessageBody);

impl MessageBody for () {
    fn size(&self) -> BodySize {
        BodySize::Empty
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        Poll::Ready(None)
    }
}

impl<T: MessageBody + Unpin> MessageBody for Box<T> {
    fn size(&self) -> BodySize {
        self.as_ref().size()
    }

    fn poll_next(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        Pin::new(self.get_mut().as_mut()).poll_next(cx)
    }
}

impl<T: MessageBody> MessageBody for Pin<Box<T>> {
    fn size(&self) -> BodySize {
        self.as_ref().size()
    }

    fn poll_next(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        self.as_mut().poll_next(cx)
    }
}

impl MessageBody for Bytes {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(mem::take(self.get_mut()))))
        }
    }
}

impl MessageBody for BytesMut {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(mem::take(self.get_mut()).freeze())))
        }
    }
}

impl MessageBody for &'static str {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(Bytes::from_static(
                mem::take(self.get_mut()).as_ref(),
            ))))
        }
    }
}

impl MessageBody for Vec<u8> {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(Bytes::from(mem::take(self.get_mut())))))
        }
    }
}

impl MessageBody for String {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(Bytes::from(
                mem::take(self.get_mut()).into_bytes(),
            ))))
        }
    }
}
<commit_msg>document messagebody trait items<commit_after>//! [`MessageBody`] trait and foreign implementations.

use std::{
    mem,
    pin::Pin,
    task::{Context, Poll},
};

use bytes::{Bytes, BytesMut};

use crate::error::Error;

use super::BodySize;

/// An interface for response bodies.
pub trait MessageBody {
    /// Body size hint.
    fn size(&self) -> BodySize;

    /// Attempt to pull out the next chunk of body bytes.
    fn poll_next(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>>;

    downcast_get_type_id!();
}

downcast!(MessageBody);

impl MessageBody for () {
    fn size(&self) -> BodySize {
        BodySize::Empty
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        Poll::Ready(None)
    }
}

impl<T: MessageBody + Unpin> MessageBody for Box<T> {
    fn size(&self) -> BodySize {
        self.as_ref().size()
    }

    fn poll_next(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        Pin::new(self.get_mut().as_mut()).poll_next(cx)
    }
}

impl<T: MessageBody> MessageBody for Pin<Box<T>> {
    fn size(&self) -> BodySize {
        self.as_ref().size()
    }

    fn poll_next(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        self.as_mut().poll_next(cx)
    }
}

impl MessageBody for Bytes {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(mem::take(self.get_mut()))))
        }
    }
}

impl MessageBody for BytesMut {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(mem::take(self.get_mut()).freeze())))
        }
    }
}

impl MessageBody for &'static str {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(Bytes::from_static(
                mem::take(self.get_mut()).as_ref(),
            ))))
        }
    }
}

impl MessageBody for Vec<u8> {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(Bytes::from(mem::take(self.get_mut())))))
        }
    }
}

impl MessageBody for String {
    fn size(&self) -> BodySize {
        BodySize::Sized(self.len() as u64)
    }

    fn poll_next(
        self: Pin<&mut Self>,
        _: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, Error>>> {
        if self.is_empty() {
            Poll::Ready(None)
        } else {
            Poll::Ready(Some(Ok(Bytes::from(
                mem::take(self.get_mut()).into_bytes(),
            ))))
        }
    }
}
<|endoftext|>


<commit_before>//! This module contains a trait representing the (real-valued) objective associated with a
//! discrete optimization problem. The greedy algorithm contained in this crate is implemented for
//! any struct implementing `Objective`.
use std::fmt::Debug;
use std::hash::Hash;
use rand::{Rng, thread_rng};
use rand::distributions::{Range, IndependentSample};
use errors::*;
use fnv::FnvHashSet;

#[derive(Copy, Clone, Debug)]
pub enum SampleElement<E> {
    Dependent(E),
    NonDependent,
}

use self::SampleElement::*;

pub type Set<E> = FnvHashSet<E>;

pub type ElementIterator<'a, O> = Box<Iterator<Item = <O as Objective>::Element> + 'a>;

pub mod curvature {
    //! Marker traits for Curvature bounds.
    //! These allow compile-time verification that an algorithm called on an `Objective` has its
    //! curvature constraints satisfied.
    //!
    //! As a concrete example, the `greedy::lazier_greedy` method requires a `Submodular`
    //! objective. Previously, this was done by checking an enum and panicking if it failed. Marker
    //! traits move the error from runtime to compilation.

    /// An objective with fixed bounds that are not the (0, 1) of `Submodular` or (1, ∞) of
    /// `Supermodular`.
    ///
    /// Ideally, this trait would be implemented automatically for any `Submodular` or
    /// `Supermodular` type. This may be done with an `avarice-derive` crate in the future.
    pub trait Bounded: super::Objective {
        fn bounds() -> (Option<f64>, Option<f64>);
    }

    /// A submodular objective, which satisfies `∀ S ⊆ T: f(S ∪ {e}) - f(S) ≥ f(T ∪ {e}) - f(T)` or (equivalently) has curvature bounded above by `1`.
    ///
    /// The `Bounded` implementation should return a fixed `(None, Some(1.0))`.
    pub trait Submodular: Bounded {}

    /// A supermodular objective, which satisfies `∀ S ⊆ T: f(S ∪ {e}) - f(S) ≤ f(T ∪ {e}) - f(T)` or (equivalently) has curvature bounded below by `1`.
    ///
    /// The `Bounded` implementation should return a fixed `(Some(1.0), None)`.
    pub trait Supermodular: Bounded {}

    /// A modular objective. The `Bounded` implementation should return a fixed `(Some(1.0),
    /// Some(1.0))`.
    ///
    /// This trait is the least common. The semantics of this type of objective are best understood
    /// by the equation `f(S) = Σf(e)`. That is, the objective is exactly the sum of the weights of
    /// the elements of the set `S`.
    pub trait Modular: Bounded {}
}

/// An objective to be optimized.
///
/// The functions are assumed to be 'internally-stateless'. That is, they do not modify the problem
/// instance, and instead track any relevant information on the associated `State` type. This
/// allows snapshotting of the state and allows safe parallel computation.
///
/// Any implementation must at a minimum implement `elements`, `benefit`, and `insert_mut`, though
/// at least implementing `delta` is strongly encouraged.  `nabla` may be omitted if your
/// application does not need it.
pub trait Objective: Sized {
    type Element: Eq + Hash + Clone + Copy + Debug;
    /// Holds any state that is tracked either to assist in correctness or to provide e.g.
    /// cacheing.
    type State: Default + Clone;

    /// The domain of the solution.
    fn elements(&self) -> ElementIterator<Self>;

    /// The implementation of the function `f`. This is the eponymous `Objective`.
    fn benefit(&self, s: &Set<Self::Element>, state: &Self::State) -> Result<f64>;

    /// The marginal gain $\delta(u \mid S) = f(S \cup u) - f(S)$
    ///
    /// Should return `0` for $u \in S$.
    ///
    /// The default implementation is incredibly inefficient (two calls to `benefit`), so
    /// overriding this is *strongly* encouraged.
    fn delta(&self, u: Self::Element, s: &Set<Self::Element>, state: &Self::State) -> Result<f64> {
        let next_state = self.insert(u, state)?;
        let mut next_set = s.clone();
        next_set.insert(u);

        Ok(self.benefit(&next_set, &next_state)? - self.benefit(s, state)?)
    }

    /// The primal curvature $\nabla(u, v\mid S) = \frac{\delta(u \mid S \cup v)}{\delta(u \mid
    /// S)}$.
    ///
    /// Should return `1` for $u \in S$ or when `depends(u, S)` does not contain `v`.
    ///
    /// The default implementation should be avoided, as it computes this result directly by
    /// calling `delta` twice.
    fn nabla(&self,
             u: Self::Element,
             v: Self::Element,
             s: &Set<Self::Element>,
             state: &Self::State)
             -> Result<f64> {
        let next_state = self.insert(v, state)?;
        let mut next_set = s.clone();
        next_set.insert(v);

        let lower = self.delta(u, s, state)?;
        let upper = self.delta(u, &next_set, &next_state)?;
        if lower == 0.0 && upper == 0.0 {
            Ok(1.0)
        } else if lower == 0.0 {
            Err(ErrorKind::DivideByZero(upper, lower).into())
        } else {
            Ok(upper / lower)
        }
    }

    /// The elements on which the marginal gain of `u` depends. The technical definition I have
    /// been using is based on the primal curvature (`nabla`): if `u` depends on `v`, then
    /// `nabla(u, v, sol, state) == 1`.
    fn depends(&self, u: Self::Element, state: &Self::State) -> Result<ElementIterator<Self>>;

    /// Update the state tracked in `s` to reflect the insertion of `u` into the solution.
    fn insert_mut(&self, u: Self::Element, s: &mut Self::State) -> Result<()>;

    /// Produce a new state reflecting the insertion of `u` into the solution.
    fn insert(&self, u: Self::Element, s: &Self::State) -> Result<Self::State> {
        let mut state = s.clone();
        self.insert_mut(u, &mut state)?;
        Ok(state)
    }

    /// Uniformly sample a sequence of `k` elements from about element `u` consistent with initial
    /// state `state`. *The state is not updated, so if the dependent set is state-dependent,
    /// future elements may not be valid selections.*
    fn sample_sequence(&self,
                       u: Self::Element,
                       k: usize,
                       bias: Option<f64>,
                       sol: &Set<Self::Element>,
                       state: &Self::State)
                       -> Result<Vec<SampleElement<Self::Element>>> {
        let mut sample = Vec::with_capacity(k);
        let mut deps = self.depends(u, state)?
            .filter(|&v| !sol.contains(&v))
            .collect::<Vec<_>>();
        let mut rng = thread_rng();
        rng.shuffle(&mut deps);

        let bias = bias.unwrap_or_else(|| {
            deps.len() as f64 / (self.elements().count() - sol.len()) as f64
        });

        let uniform = Range::new(0.0, 1.0);

        for _ in 0..k {
            if uniform.ind_sample(&mut rng) <= bias && !deps.is_empty() {
                // take a dependent element
                sample.push(Dependent(deps.pop().unwrap()));
            } else {
                sample.push(NonDependent);
            }
        }

        Ok(sample)
    }

    /// Compute the total primal curvature of an element `u` after the first `k` elements of
    /// `sequence` have been added. If the `sequence` does not have at least `k` elements,
    /// `ErrorKind::SampleTooSmall` is returned.
    fn gamma(&self,
             u: Self::Element,
             k: usize,
             mut sol: Set<Self::Element>,
             sequence: Vec<SampleElement<Self::Element>>,
             mut state: Self::State)
             -> Result<(f64, Set<Self::Element>, Self::State)> {
        if sequence.len() < k {
            return Err(ErrorKind::SampleTooSmall(sequence.len(), k).into());
        }
        let mut prod = 1f64;
        for e in sequence.iter().take(k) {
            prod *= match e {
                &Dependent(v) => self.nabla(u, v, &sol, &state)?,
                // proof of this relation is in the 2017 notebook, pg. 8-9
                //
                // the gist of it is that the non-dependence of x implies a pair of f_u(S \cup {x})
                // = f_u(S)-style relations, which are used to show ∇(u, v | S) = ∇(u, v | S \cup
                // {x}).
                &NonDependent => 1f64,
            };

            if let &Dependent(v) = e {
                self.insert_mut(v, &mut state)?;
                sol.insert(v);
            }
        }

        Ok((prod, sol, state))
    }

    /// Compute the sequence of total primal curvature values for `1..k` elements of `sequence`.
    /// Unlike `gamma`, this does not return the final solution or state. `gamma(0|S)` is omitted
    /// as it is constant `1`.
    fn gamma_seq(&self,
                 u: Self::Element,
                 k: usize,
                 mut sol: Set<Self::Element>,
                 sequence: Vec<SampleElement<Self::Element>>,
                 mut state: Self::State)
                 -> Result<Vec<f64>> {
        if sequence.len() < k {
            return Err(ErrorKind::SampleTooSmall(sequence.len(), k).into());
        }
        let mut prod = 1f64;
        let mut seq = Vec::with_capacity(k);
        for e in sequence.iter().take(k) {
            prod *= match e {
                &Dependent(v) => self.nabla(u, v, &sol, &state)?,
                // proof of this relation is in the 2017 notebook, pg. 8-9
                //
                // the gist of it is that the non-dependence of x implies a pair of f_u(S \cup {x})
                // = f_u(S)-style relations, which are used to show ∇(u, v | S) = ∇(u, v | S \cup
                // {x}).
                &NonDependent => 1f64,
            };

            seq.push(prod);

            if let &Dependent(v) = e {
                self.insert_mut(v, &mut state)?;
                sol.insert(v);
            }
        }
        Ok(seq)
    }
}

/// Lazy extension of `Objective`. While the same state type is used, state updates are handled
/// independently. If you need two different kinds of state for each kind of update, consider using
/// an enum-struct. For example:
///
/// ```
/// #[derive(Clone, Debug)]
/// pub enum State {
///     Empty,
///     Strict {
///         foo: usize,
///         bar: Vec<usize>,
///     },
///     Lazy {
///         baz: f64,
///     }
/// }
///
/// impl Default for State {
///     fn default() -> Self {
///         State::Empty
///     }
/// }
/// ```
pub trait LazyObjective: Objective {
    /// Updates the marginal gain of `element`, returning it value after updating the state to
    /// reflect the insertion of `previous` elements.
    ///
    /// Returns `Ok(None)` if the marginal gain does not need to be updated.
    fn update_lazy_mut(&self,
                       element: Self::Element,
                       previous: &Set<Self::Element>,
                       state: &mut Self::State)
                       -> Result<Option<f64>>;

    /// Update the state to preserve invariants upon insertion of `element`.
    ///
    /// This should do the least amount of work possible without making `update_lazy_mut` too
    /// complex.
    fn insert_lazy_mut(&self, element: Self::Element, state: &mut Self::State) -> Result<()>;
}
<commit_msg>Modular objective now implies both super- and sub-modularity.<commit_after>//! This module contains a trait representing the (real-valued) objective associated with a
//! discrete optimization problem. The greedy algorithm contained in this crate is implemented for
//! any struct implementing `Objective`.
use std::fmt::Debug;
use std::hash::Hash;
use rand::{Rng, thread_rng};
use rand::distributions::{Range, IndependentSample};
use errors::*;
use fnv::FnvHashSet;

#[derive(Copy, Clone, Debug)]
pub enum SampleElement<E> {
    Dependent(E),
    NonDependent,
}

use self::SampleElement::*;

pub type Set<E> = FnvHashSet<E>;

pub type ElementIterator<'a, O> = Box<Iterator<Item = <O as Objective>::Element> + 'a>;

pub mod curvature {
    //! Marker traits for Curvature bounds.
    //! These allow compile-time verification that an algorithm called on an `Objective` has its
    //! curvature constraints satisfied.
    //!
    //! As a concrete example, the `greedy::lazier_greedy` method requires a `Submodular`
    //! objective. Previously, this was done by checking an enum and panicking if it failed. Marker
    //! traits move the error from runtime to compilation.

    /// An objective with fixed bounds that are not the (0, 1) of `Submodular` or (1, ∞) of
    /// `Supermodular`.
    ///
    /// Ideally, this trait would be implemented automatically for any `Submodular` or
    /// `Supermodular` type. This may be done with an `avarice-derive` crate in the future.
    pub trait Bounded: super::Objective {
        fn bounds() -> (Option<f64>, Option<f64>);
    }

    /// A submodular objective, which satisfies `∀ S ⊆ T: f(S ∪ {e}) - f(S) ≥ f(T ∪ {e}) - f(T)` or (equivalently) has curvature bounded above by `1`.
    ///
    /// The `Bounded` implementation should return a fixed `(None, Some(1.0))`.
    pub trait Submodular: Bounded {}

    /// A supermodular objective, which satisfies `∀ S ⊆ T: f(S ∪ {e}) - f(S) ≤ f(T ∪ {e}) - f(T)` or (equivalently) has curvature bounded below by `1`.
    ///
    /// The `Bounded` implementation should return a fixed `(Some(1.0), None)`.
    pub trait Supermodular: Bounded {}

    /// A modular objective. The `Bounded` implementation should return a fixed `(Some(1.0),
    /// Some(1.0))`.
    ///
    /// This trait is the least common. The semantics of this type of objective are best understood
    /// by the equation `f(S) = Σf(e)`. That is, the objective is exactly the sum of the weights of
    /// the elements of the set `S`.
    pub trait Modular: Bounded {}
    impl<T: Modular> Submodular for T {}
    impl<T: Modular> Supermodular for T {}
}

/// An objective to be optimized.
///
/// The functions are assumed to be 'internally-stateless'. That is, they do not modify the problem
/// instance, and instead track any relevant information on the associated `State` type. This
/// allows snapshotting of the state and allows safe parallel computation.
///
/// Any implementation must at a minimum implement `elements`, `benefit`, and `insert_mut`, though
/// at least implementing `delta` is strongly encouraged.  `nabla` may be omitted if your
/// application does not need it.
pub trait Objective: Sized {
    type Element: Eq + Hash + Clone + Copy + Debug;
    /// Holds any state that is tracked either to assist in correctness or to provide e.g.
    /// cacheing.
    type State: Default + Clone;

    /// The domain of the solution.
    fn elements(&self) -> ElementIterator<Self>;

    /// The implementation of the function `f`. This is the eponymous `Objective`.
    fn benefit(&self, s: &Set<Self::Element>, state: &Self::State) -> Result<f64>;

    /// The marginal gain $\delta(u \mid S) = f(S \cup u) - f(S)$
    ///
    /// Should return `0` for $u \in S$.
    ///
    /// The default implementation is incredibly inefficient (two calls to `benefit`), so
    /// overriding this is *strongly* encouraged.
    fn delta(&self, u: Self::Element, s: &Set<Self::Element>, state: &Self::State) -> Result<f64> {
        let next_state = self.insert(u, state)?;
        let mut next_set = s.clone();
        next_set.insert(u);

        Ok(self.benefit(&next_set, &next_state)? - self.benefit(s, state)?)
    }

    /// The primal curvature $\nabla(u, v\mid S) = \frac{\delta(u \mid S \cup v)}{\delta(u \mid
    /// S)}$.
    ///
    /// Should return `1` for $u \in S$ or when `depends(u, S)` does not contain `v`.
    ///
    /// The default implementation should be avoided, as it computes this result directly by
    /// calling `delta` twice.
    fn nabla(&self,
             u: Self::Element,
             v: Self::Element,
             s: &Set<Self::Element>,
             state: &Self::State)
             -> Result<f64> {
        let next_state = self.insert(v, state)?;
        let mut next_set = s.clone();
        next_set.insert(v);

        let lower = self.delta(u, s, state)?;
        let upper = self.delta(u, &next_set, &next_state)?;
        if lower == 0.0 && upper == 0.0 {
            Ok(1.0)
        } else if lower == 0.0 {
            Err(ErrorKind::DivideByZero(upper, lower).into())
        } else {
            Ok(upper / lower)
        }
    }

    /// The elements on which the marginal gain of `u` depends. The technical definition I have
    /// been using is based on the primal curvature (`nabla`): if `u` depends on `v`, then
    /// `nabla(u, v, sol, state) == 1`.
    fn depends(&self, u: Self::Element, state: &Self::State) -> Result<ElementIterator<Self>>;

    /// Update the state tracked in `s` to reflect the insertion of `u` into the solution.
    fn insert_mut(&self, u: Self::Element, s: &mut Self::State) -> Result<()>;

    /// Produce a new state reflecting the insertion of `u` into the solution.
    fn insert(&self, u: Self::Element, s: &Self::State) -> Result<Self::State> {
        let mut state = s.clone();
        self.insert_mut(u, &mut state)?;
        Ok(state)
    }

    /// Uniformly sample a sequence of `k` elements from about element `u` consistent with initial
    /// state `state`. *The state is not updated, so if the dependent set is state-dependent,
    /// future elements may not be valid selections.*
    fn sample_sequence(&self,
                       u: Self::Element,
                       k: usize,
                       bias: Option<f64>,
                       sol: &Set<Self::Element>,
                       state: &Self::State)
                       -> Result<Vec<SampleElement<Self::Element>>> {
        let mut sample = Vec::with_capacity(k);
        let mut deps = self.depends(u, state)?
            .filter(|&v| !sol.contains(&v))
            .collect::<Vec<_>>();
        let mut rng = thread_rng();
        rng.shuffle(&mut deps);

        let bias = bias.unwrap_or_else(|| {
            deps.len() as f64 / (self.elements().count() - sol.len()) as f64
        });

        let uniform = Range::new(0.0, 1.0);

        for _ in 0..k {
            if uniform.ind_sample(&mut rng) <= bias && !deps.is_empty() {
                // take a dependent element
                sample.push(Dependent(deps.pop().unwrap()));
            } else {
                sample.push(NonDependent);
            }
        }

        Ok(sample)
    }

    /// Compute the total primal curvature of an element `u` after the first `k` elements of
    /// `sequence` have been added. If the `sequence` does not have at least `k` elements,
    /// `ErrorKind::SampleTooSmall` is returned.
    fn gamma(&self,
             u: Self::Element,
             k: usize,
             mut sol: Set<Self::Element>,
             sequence: Vec<SampleElement<Self::Element>>,
             mut state: Self::State)
             -> Result<(f64, Set<Self::Element>, Self::State)> {
        if sequence.len() < k {
            return Err(ErrorKind::SampleTooSmall(sequence.len(), k).into());
        }
        let mut prod = 1f64;
        for e in sequence.iter().take(k) {
            prod *= match e {
                &Dependent(v) => self.nabla(u, v, &sol, &state)?,
                // proof of this relation is in the 2017 notebook, pg. 8-9
                //
                // the gist of it is that the non-dependence of x implies a pair of f_u(S \cup {x})
                // = f_u(S)-style relations, which are used to show ∇(u, v | S) = ∇(u, v | S \cup
                // {x}).
                &NonDependent => 1f64,
            };

            if let &Dependent(v) = e {
                self.insert_mut(v, &mut state)?;
                sol.insert(v);
            }
        }

        Ok((prod, sol, state))
    }

    /// Compute the sequence of total primal curvature values for `1..k` elements of `sequence`.
    /// Unlike `gamma`, this does not return the final solution or state. `gamma(0|S)` is omitted
    /// as it is constant `1`.
    fn gamma_seq(&self,
                 u: Self::Element,
                 k: usize,
                 mut sol: Set<Self::Element>,
                 sequence: Vec<SampleElement<Self::Element>>,
                 mut state: Self::State)
                 -> Result<Vec<f64>> {
        if sequence.len() < k {
            return Err(ErrorKind::SampleTooSmall(sequence.len(), k).into());
        }
        let mut prod = 1f64;
        let mut seq = Vec::with_capacity(k);
        for e in sequence.iter().take(k) {
            prod *= match e {
                &Dependent(v) => self.nabla(u, v, &sol, &state)?,
                // proof of this relation is in the 2017 notebook, pg. 8-9
                //
                // the gist of it is that the non-dependence of x implies a pair of f_u(S \cup {x})
                // = f_u(S)-style relations, which are used to show ∇(u, v | S) = ∇(u, v | S \cup
                // {x}).
                &NonDependent => 1f64,
            };

            seq.push(prod);

            if let &Dependent(v) = e {
                self.insert_mut(v, &mut state)?;
                sol.insert(v);
            }
        }
        Ok(seq)
    }
}

/// Lazy extension of `Objective`. While the same state type is used, state updates are handled
/// independently. If you need two different kinds of state for each kind of update, consider using
/// an enum-struct. For example:
///
/// ```
/// #[derive(Clone, Debug)]
/// pub enum State {
///     Empty,
///     Strict {
///         foo: usize,
///         bar: Vec<usize>,
///     },
///     Lazy {
///         baz: f64,
///     }
/// }
///
/// impl Default for State {
///     fn default() -> Self {
///         State::Empty
///     }
/// }
/// ```
pub trait LazyObjective: Objective {
    /// Updates the marginal gain of `element`, returning it value after updating the state to
    /// reflect the insertion of `previous` elements.
    ///
    /// Returns `Ok(None)` if the marginal gain does not need to be updated.
    fn update_lazy_mut(&self,
                       element: Self::Element,
                       previous: &Set<Self::Element>,
                       state: &mut Self::State)
                       -> Result<Option<f64>>;

    /// Update the state to preserve invariants upon insertion of `element`.
    ///
    /// This should do the least amount of work possible without making `update_lazy_mut` too
    /// complex.
    fn insert_lazy_mut(&self, element: Self::Element, state: &mut Self::State) -> Result<()>;
}
<|endoftext|>


<commit_before>#![deny(unreachable_code)]

use futures::{try_join, executor::block_on};

#[test]
fn try_join_never_error() {
    block_on(async {
        let future1 = async { Ok::<(), !>(()) };
        let future2 = async { Ok::<(), !>(()) };
        try_join!(future1, future2)
    })
    .unwrap();
}

#[test]
fn try_join_never_ok() {
    block_on(async {
        let future1 = async { Err::<!, ()>(()) };
        let future2 = async { Err::<!, ()>(()) };
        try_join!(future1, future2)
    })
    .unwrap_err();
}
<commit_msg>Workaround ! being unstablilized again<commit_after>#![deny(unreachable_code)]

use futures::{try_join, executor::block_on};

// TODO: This abuses https://github.com/rust-lang/rust/issues/58733 in order to
// test behaviour of the `try_join!` macro with the never type before it is
// stabilized. Once `!` is again stabilized this can be removed and replaced
// with direct use of `!` below where `Never` is used.
trait MyTrait {
    type Output;
}
impl<T> MyTrait for fn() -> T {
    type Output = T;
}
type Never = <fn() -> ! as MyTrait>::Output;

#[test]
fn try_join_never_error() {
    block_on(async {
        let future1 = async { Ok::<(), Never>(()) };
        let future2 = async { Ok::<(), Never>(()) };
        try_join!(future1, future2)
    })
    .unwrap();
}

#[test]
fn try_join_never_ok() {
    block_on(async {
        let future1 = async { Err::<Never, ()>(()) };
        let future2 = async { Err::<Never, ()>(()) };
        try_join!(future1, future2)
    })
    .unwrap_err();
}
<|endoftext|>


<commit_before>use std;
use std::mem;
use libc::*;

use ctxt::{Context, ctxt_ptr};
use mem::ptr::Ptr;
use os_cpu::*;

pub fn register_signals(ctxt: &Context) {
    unsafe {
        let ptr = Ptr::new(ctxt as *const Context as *const c_void);
        unsafe { ctxt_ptr = Some(ptr); }

        let mut sa: sigaction = std::mem::uninitialized();

        sa.sa_sigaction = handler as usize;
        sigemptyset(&mut sa.sa_mask as *mut sigset_t);
        sa.sa_flags = SA_SIGINFO;

        if sigaction(SIGSEGV, &sa as *const sigaction, 0 as *mut sigaction) == -1 {
            perror("sigaction failed".as_ptr() as *const i8);
        }
    }
}

fn handler(signo: c_int, _: *const c_void, ucontext: *const c_void) {
    let es = read_execstate(ucontext);

    if let Some(trap) = detect_trap(signo as i32, &es) {
        use cpu::trap::COMPILER;

        match trap {
            COMPILER => {
                let ctxt: &Context = unsafe {
                    &*(ctxt_ptr.unwrap().raw_mut_ptr() as *const Context)
                };

                let ptr = Ptr::new(es.pc as *const c_void);
                let code_map = ctxt.code_map.lock().unwrap();

                println!("stub = {:?}", code_map.get(ptr));
                unsafe { _exit(2); }
            }

            _ => unsafe { _exit(1); }
        }

    // could not recognize trap -> crash vm
    } else {
        println!("error: trap not detected (signal {}).", signo);
        unsafe { _exit(1); }
    }
}
<commit_msg>renamed variable<commit_after>use std;
use std::mem;
use libc::*;

use ctxt::{Context, ctxt_ptr};
use jit;
use mem::ptr::Ptr;
use os_cpu::*;

pub fn register_signals(ctxt: &Context) {
    unsafe {
        let ptr = Ptr::new(ctxt as *const Context as *const c_void);
        unsafe { ctxt_ptr = Some(ptr); }

        let mut sa: sigaction = std::mem::uninitialized();

        sa.sa_sigaction = handler as usize;
        sigemptyset(&mut sa.sa_mask as *mut sigset_t);
        sa.sa_flags = SA_SIGINFO;

        if sigaction(SIGSEGV, &sa as *const sigaction, 0 as *mut sigaction) == -1 {
            perror("sigaction failed".as_ptr() as *const i8);
        }
    }
}

fn handler(signo: c_int, _: *const c_void, ucontext: *const c_void) {
    let es = read_execstate(ucontext);

    if let Some(trap) = detect_trap(signo as i32, &es) {
        use cpu::trap::COMPILER;

        match trap {
            COMPILER => {
                let ctxt: &Context = unsafe {
                    &*(ctxt_ptr.unwrap().raw_mut_ptr() as *const Context)
                };

                let ptr = Ptr::new(es.pc as *const c_void);
                let code_map = ctxt.code_map.lock().unwrap();

                if let Some(fct_id) = code_map.get(ptr) {
                    let jit_fct = jit::generate(ctxt, fct_id);
                    println!("{:?}", jit_fct);
                }

                unsafe { _exit(2); }
            }

            _ => unsafe { _exit(1); }
        }

    // could not recognize trap -> crash vm
    } else {
        println!("error: trap not detected (signal {}).", signo);
        unsafe { _exit(1); }
    }
}
<|endoftext|>


<commit_before>//! Reminisce is a lightweight library intended to be used for detecting and
//! reading from joysticks at a low level across many different operting
//! systems.
extern crate libc;
#[cfg(target_os = "windows")]
#[macro_use] extern crate rustc_bitflags;

#[cfg(feature = "sdl")]
extern crate sdl2;

extern crate glob;

/// Someday, somehow
#[cfg(all(feature = "emscripten", not(feature = "sdl")))]
pub mod emscripten;

#[cfg(all(feature = "emscripten", not(feature = "sdl")))]
pub use emscripten as native;

#[cfg(all(target_os = "linux", not(feature = "sdl")))]
pub mod linux;

#[cfg(all(target_os = "linux", not(feature = "sdl")))]
pub use linux as native;

#[cfg(all(target_os = "windows", not(feature = "sdl")))]
pub mod windows;

#[cfg(all(target_os = "windows", not(feature = "sdl")))]
pub use windows as native;

#[cfg(feature = "sdl")]
pub mod sdl;

#[cfg(feature = "sdl")]
pub use sdl as native;

pub use native::{NativeJoystick, NativeContext};

/// The maximum axis value
pub static MAX_AXIS_VALUE:i16 = 32767;
/// The minimum axis value
pub static MIN_AXIS_VALUE:i16 = -32767;

use std::borrow::Cow;
use std::fmt::Debug;

/// A direction on a joystick.
pub type Axis = u8;

/// A button on a joystick.
pub type Button = u8;

/// A joystick index.

pub type JoystickIndex = u8;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// An event emitted by a joystick
pub enum Event {
    /// Fired when a joystick is connected with the index of the joystick
    /// that was connected.
    Connected(JoystickIndex),
    /// Fired when a joystick is disconnected with the index of the joystick
    /// that was disconnected.
    Disconnected(JoystickIndex),
    /// Fired when a button is pressed with the joystick's index and the
    /// button's index.
    ButtonPressed(JoystickIndex, Button),
    /// Fired when a button is released with the joystick's index and the
    /// button's index.
    ButtonReleased(JoystickIndex, Button),
    /// Fired when a axis is moved with the joystick index, axis index
    /// and its value, which is between `MIN_JOYSTICK_VALUE` and
    /// `MAX_JOYSTICK_VALUE`
    AxisMoved(JoystickIndex, Axis, i16)
}

/// A lightweight context that tracks and polls all the available joysticks.
///
/// Each `Context` has its own event queue tied to the events of the joysticks.
///
/// ``` rust
/// use reminisce::*;
/// let mut context = NativeContext::new();
/// let mut dir = 0;
/// let mut left = 30;
/// for event in &mut context {
///     left -= 1;
///     if(left <= 0) { break }
///     match event {
///         Event::AxisMoved(_, 0, nx) =>
///             dir = -1,
///         Event::AxisMoved(_, 1, ny) =>
///             dir = 1,
///         _ => ()
///     }
/// }
/// ```
pub trait Context: Sized {
    /// The kind of joystick this context tracks.
    type Joystick : Joystick;

    /// Create a new context.
    fn new() -> Self;

    /// Returns the number of joysticks connected.
    fn num_joysticks(&self) -> usize;

    /// Return a reference to the joysticks connected.
    fn get_joysticks(&self) -> &[Self::Joystick];

    /// Poll this context for events.
    fn poll(&mut self) -> Option<Event>;

    /// Iterate through the events that haven't been processed yet
    fn iter(&mut self) -> Poller<Self> {
        Poller { context: self }
    }
}

impl<'a> IntoIterator for &'a mut NativeContext {
    type Item = Event;
    type IntoIter = Poller<'a, NativeContext>;
    fn into_iter(self) -> Poller<'a, NativeContext> {
        self.iter()
    }
}

/// A joystick or gamepad.
pub trait Joystick : Sized {
    /// The error that could be thrown while trying to open the joystick
    type OpenError: Debug;

    /// Attempts to open a joystick from its index
    ///
    /// If an error occurs, this will return the textual representation of that error.
    ///
    /// ``` rust
    /// use reminisce::*;
    /// if let Ok(joystick) = NativeJoystick::open(0) {
    ///     println!("{}", joystick.id())
    /// } else {
    ///     println!("No joystick plugged in")
    /// }
    /// ```
    fn open(index: JoystickIndex) -> Result<Self, Self::OpenError>;

    /// Check if the joystick is still connected.
    fn connected(&self) -> bool;

    /// Get the identifier of this joystick.
    ///
    /// This is copy-on-write because it can be a borrowed or owned String,
    /// depending on the implementation.
    fn id(&self) -> Cow<str>;

    /// Get the index of this joystick.
    fn index(&self) -> JoystickIndex;

    /// Get the number of axes this joystick has
    ///
    /// This is capped at 6 axes for now.
    fn num_axes(&self) -> Axis;

    /// Get the number of buttons this joystick has
    ///
    /// This is capped at 16 buttons currently.
    fn num_buttons(&self) -> Button;

    /// Get the battery level of this joystick
    ///
    /// Returns none if the joystick is wired or this operation is not supported
    /// by the backend
    fn battery(&self) -> Option<f32>;
}

/// A joystick that tracks its state.
pub struct StatefulJoystick<J> where J: Joystick {
    joystick: J,
    buttons: i32,
    axes: Vec<i16>
}
impl<J> StatefulJoystick<J> where J: Joystick {
    /// Get the position of the axis.
    pub fn get_axis(&self, axis: Axis) -> Option<i16> {
        self.axes.get(axis as usize).cloned()
    }
    /// Check if the button given is down.
    pub fn get_button(&self, button: Button) -> Option<bool> {
        if button < self.joystick.num_buttons() {
            Some(self.buttons & (1 << button) > 0)
        } else {
            None
        }
    }
    /// Update this joystick with the event given.
    pub fn process(&mut self, event: Event) {
        let index = self.joystick.index();
        match event {
            Event::ButtonPressed(i, b) if i == index => {
                self.buttons |= (i as i32) << b;
            },
            Event::ButtonReleased(i, b) if i == index => {
                self.buttons &= !((i as i32) << b);
            },
            Event::AxisMoved(i, a, v) if i == index => {
                self.axes[a as usize] = v;
            },
            _ => ()
        }
    }
}
impl<J> Joystick for StatefulJoystick<J> where J: Joystick {
    type OpenError = J::OpenError;
    fn open(index: JoystickIndex) -> Result<Self, Self::OpenError> {
        let joystick = try!(J::open(index));
        let axes = (0..joystick.num_axes()).map(|_| 0).collect();
        Ok(StatefulJoystick {
            joystick: joystick,
            buttons: 0,
            axes: axes
        })
    }
    fn connected(&self) -> bool {
        self.joystick.connected()
    }
    fn id(&self) -> Cow<str> {
        self.joystick.id()
    }
    fn index(&self) -> JoystickIndex {
        self.joystick.index()
    }
    fn num_axes(&self) -> Axis {
        self.joystick.num_axes()
    }
    fn num_buttons(&self) -> Button {
        self.joystick.num_buttons()
    }
    fn battery(&self) -> Option<f32> {
        self.joystick.battery()
    }
}

/// An iterator over a context's event queue
pub struct Poller<'a, J> where J:Context+'a {
    context: &'a mut J
}

impl<'a, C> Iterator for Poller<'a, C> where C:Context {
    type Item = Event;
    /// This calls the `context.poll()` method to poll for the next event
    fn next(&mut self) -> Option<Event> {
        self.context.poll()
    }
}
<commit_msg>Add more useful documentation<commit_after>//! Reminisce is a lightweight library intended to be used for detecting and
//! reading from joysticks at a low level across many different operating
//! systems.
//!
//! Scanning for joysticks
//! ----------------------
//! To scan for joysticks, a `Context` must be created.
//! ``` rust
//! use reminisce::*;
//! let context = NativeContext::new();
//! println!("{} joysticks connected", context.num_joysticks());
//! ```
//!
//! Scanning for events
//! -------------------
//! To scan events, a `Context` must be created and polled.
//! ``` rust
//! use reminisce::*;
//! let context = NativeContext::new();
//! while let Some(event) = context.poll() {
//!     println!("{:?}", event);
//! }
//! ```
extern crate libc;
#[cfg(target_os = "windows")]
#[macro_use] extern crate rustc_bitflags;

#[cfg(feature = "sdl")]
extern crate sdl2;

extern crate glob;

/// Someday, somehow
#[cfg(all(feature = "emscripten", not(feature = "sdl")))]
pub mod emscripten;

#[cfg(all(feature = "emscripten", not(feature = "sdl")))]
pub use emscripten as native;

#[cfg(all(target_os = "linux", not(feature = "sdl")))]
pub mod linux;

#[cfg(all(target_os = "linux", not(feature = "sdl")))]
pub use linux as native;

#[cfg(all(target_os = "windows", not(feature = "sdl")))]
pub mod windows;

#[cfg(all(target_os = "windows", not(feature = "sdl")))]
pub use windows as native;

#[cfg(feature = "sdl")]
pub mod sdl;

#[cfg(feature = "sdl")]
pub use sdl as native;

pub use native::{NativeJoystick, NativeContext};

/// The maximum axis value
pub static MAX_AXIS_VALUE:i16 = 32767;
/// The minimum axis value
pub static MIN_AXIS_VALUE:i16 = -32767;

use std::borrow::Cow;
use std::fmt::Debug;

/// A direction on a joystick.
pub type Axis = u8;

/// A button on a joystick.
pub type Button = u8;

/// A joystick index.

pub type JoystickIndex = u8;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// An event emitted by a joystick
pub enum Event {
    /// Fired when a joystick is connected with the index of the joystick
    /// that was connected.
    Connected(JoystickIndex),
    /// Fired when a joystick is disconnected with the index of the joystick
    /// that was disconnected.
    Disconnected(JoystickIndex),
    /// Fired when a button is pressed with the joystick's index and the
    /// button's index.
    ButtonPressed(JoystickIndex, Button),
    /// Fired when a button is released with the joystick's index and the
    /// button's index.
    ButtonReleased(JoystickIndex, Button),
    /// Fired when a axis is moved with the joystick index, axis index
    /// and its value, which is between `MIN_JOYSTICK_VALUE` and
    /// `MAX_JOYSTICK_VALUE`
    AxisMoved(JoystickIndex, Axis, i16)
}

/// A lightweight context that tracks and polls all the available joysticks.
///
/// Each `Context` has its own event queue tied to the events of the joysticks.
///
/// ``` rust
/// use reminisce::*;
/// let mut context = NativeContext::new();
/// let mut dir = 0;
/// let mut left = 30;
/// for event in &mut context {
///     left -= 1;
///     if(left <= 0) { break }
///     match event {
///         Event::AxisMoved(_, 0, nx) =>
///             dir = -1,
///         Event::AxisMoved(_, 1, ny) =>
///             dir = 1,
///         _ => ()
///     }
/// }
/// ```
pub trait Context: Sized {
    /// The kind of joystick this context tracks.
    type Joystick : Joystick;

    /// Create a new context.
    fn new() -> Self;

    /// Returns the number of joysticks connected.
    fn num_joysticks(&self) -> usize;

    /// Return a reference to the joysticks connected.
    fn get_joysticks(&self) -> &[Self::Joystick];

    /// Poll this context for events.
    fn poll(&mut self) -> Option<Event>;

    /// Iterate through the events that haven't been processed yet
    fn iter(&mut self) -> Poller<Self> {
        Poller { context: self }
    }
}

impl<'a> IntoIterator for &'a mut NativeContext {
    type Item = Event;
    type IntoIter = Poller<'a, NativeContext>;
    fn into_iter(self) -> Poller<'a, NativeContext> {
        self.iter()
    }
}

/// A joystick or gamepad.
pub trait Joystick : Sized {
    /// The error that could be thrown while trying to open the joystick
    type OpenError: Debug;

    /// Attempts to open a joystick from its index
    ///
    /// If an error occurs, this will return the textual representation of that error.
    ///
    /// ``` rust
    /// use reminisce::*;
    /// if let Ok(joystick) = NativeJoystick::open(0) {
    ///     println!("{}", joystick.id())
    /// } else {
    ///     println!("No joystick plugged in")
    /// }
    /// ```
    fn open(index: JoystickIndex) -> Result<Self, Self::OpenError>;

    /// Check if the joystick is still connected.
    fn connected(&self) -> bool;

    /// Get the identifier of this joystick.
    ///
    /// This is copy-on-write because it can be a borrowed or owned String,
    /// depending on the implementation.
    fn id(&self) -> Cow<str>;

    /// Get the index of this joystick.
    fn index(&self) -> JoystickIndex;

    /// Get the number of axes this joystick has
    ///
    /// This is capped at 6 axes for now.
    fn num_axes(&self) -> Axis;

    /// Get the number of buttons this joystick has
    ///
    /// This is capped at 16 buttons currently.
    fn num_buttons(&self) -> Button;

    /// Get the battery level of this joystick
    ///
    /// Returns none if the joystick is wired or this operation is not supported
    /// by the backend
    fn battery(&self) -> Option<f32>;
}

/// A joystick that tracks its state.
pub struct StatefulJoystick<J> where J: Joystick {
    joystick: J,
    buttons: i32,
    axes: Vec<i16>
}
impl<J> StatefulJoystick<J> where J: Joystick {
    /// Get the position of the axis.
    pub fn get_axis(&self, axis: Axis) -> Option<i16> {
        self.axes.get(axis as usize).cloned()
    }
    /// Check if the button given is down.
    pub fn get_button(&self, button: Button) -> Option<bool> {
        if button < self.joystick.num_buttons() {
            Some(self.buttons & (1 << button) > 0)
        } else {
            None
        }
    }
    /// Update this joystick with the event given.
    pub fn process(&mut self, event: Event) {
        let index = self.joystick.index();
        match event {
            Event::ButtonPressed(i, b) if i == index => {
                self.buttons |= (i as i32) << b;
            },
            Event::ButtonReleased(i, b) if i == index => {
                self.buttons &= !((i as i32) << b);
            },
            Event::AxisMoved(i, a, v) if i == index => {
                self.axes[a as usize] = v;
            },
            _ => ()
        }
    }
}
impl<J> Joystick for StatefulJoystick<J> where J: Joystick {
    type OpenError = J::OpenError;
    fn open(index: JoystickIndex) -> Result<Self, Self::OpenError> {
        let joystick = try!(J::open(index));
        let axes = (0..joystick.num_axes()).map(|_| 0).collect();
        Ok(StatefulJoystick {
            joystick: joystick,
            buttons: 0,
            axes: axes
        })
    }
    fn connected(&self) -> bool {
        self.joystick.connected()
    }
    fn id(&self) -> Cow<str> {
        self.joystick.id()
    }
    fn index(&self) -> JoystickIndex {
        self.joystick.index()
    }
    fn num_axes(&self) -> Axis {
        self.joystick.num_axes()
    }
    fn num_buttons(&self) -> Button {
        self.joystick.num_buttons()
    }
    fn battery(&self) -> Option<f32> {
        self.joystick.battery()
    }
}

/// An iterator over a context's event queue
pub struct Poller<'a, J> where J:Context+'a {
    context: &'a mut J
}

impl<'a, C> Iterator for Poller<'a, C> where C:Context {
    type Item = Event;
    /// This calls the `context.poll()` method to poll for the next event
    fn next(&mut self) -> Option<Event> {
        self.context.poll()
    }
}
<|endoftext|>


<commit_before>use std::convert;
use std::ops::{Add, Sub};
use std::default::Default;
use internals::Node;

pub trait Semigroup {
    /// The sum operation of the semigroup
    fn sum(self, other: Self) -> Self;
}

/// The class of monoids
///
/// The class of monoids (types with an accumulative binary operation that has
/// an default).
///
/// An instance _M_ should satisfy the following laws:
///
///  + _x_`.sum(`_M_`::default())` = _x_
///  + _M_`::default().sum(`_x_`)` = _x_
///  + _x_`.sum(`_y_`.sum(`_z_`))` = _z_`.sum(`_x_`.sum(`_y_`))`
///  + _M_`::accumulate(`_a_`)` = _a_`.fold(`_M_`::default,`_M_`::sum)`
///
pub trait Monoid: Semigroup + Default + Sized {

    #[inline]
    fn accumulate<F>(xs: F) -> Self
    where F: Iterator<Item=Self>
        , Self: Sized {
        xs.fold(Self::default(), Self::sum)
    }
}

/// A monoid that can be applied to a `Node` as a measurement
pub trait Metric: Monoid + Eq + Add<usize, Output=Self>
                              + Sub<usize, Output=Self>
                              + Sized {
    /// Apply this `Metric` to the given `Node`
    ///
    /// Although we aren't currently enforcing this, `measure`ing a `Node` with
    /// two children should produce the same result as `measure`ing both
    /// children and `Monoid::sum`ming the result. That is to say, `measure`
    /// should be a [_monoid homomorphism_]
    /// (https://en.wikipedia.org/wiki/Monoid#Monoid_homomorphisms).
    fn measure(node: &Node) -> Self;

    /// Convert the `Metric` into a byte index into the given `Node`
    ///
    /// # Returns
    /// - `Some` with the byte index of the beginning of the `n`th  element
    ///    in `node` measured by this `Metric`, if there is an `n`th element
    /// - `None` if there is no `n`th element in `node`
    fn to_byte_index(&self, node: &Node) -> Option<usize>;

    /// Returns the byte index of the next element of this metric in `Node`
    #[inline] fn next(self, node: &Node) -> Option<usize> {
        (self + 1).to_byte_index(node)
    }

    /// Returns the byte index of the previous element of this metric in `Node`
    #[inline] fn back(self, node: &Node) -> Option<usize> {
        (self - 1).to_byte_index(node)
    }

    /// Returns true if index `i` in `node` is a boundary along this `Metric`
    // TODO: should this be a method on `Node`s instead?
    fn is_boundary(node: &Node, i: usize) -> bool;
}

#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Grapheme(usize);
impl Default for Grapheme {
    #[inline] fn default() -> Self { Grapheme(0) }
}
impl Semigroup for Grapheme {
    #[inline] fn sum(self, other: Self) -> Self { Grapheme(self.0 + other.0) }
}
impl convert::From<usize> for Grapheme {
    #[inline] fn from(u: usize) -> Self { Grapheme(u) }
}
impl Add<usize> for Grapheme {
    type Output = Self;
    #[inline] fn add(self, rhs: usize) -> Self { Grapheme(self.0 + rhs) }
}
impl Sub<usize> for Grapheme {
    type Output = Self;
    #[inline] fn sub(self, rhs: usize) -> Self { Grapheme(self.0 - rhs) }
}

#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Line(usize);
impl Default for Line {
    #[inline] fn default() -> Self { Line(0) }
}
impl Semigroup for Line {
    #[inline] fn sum(self, other: Self) -> Self { Line(self.0 + other.0) }
}

impl convert::From<usize> for Line {
    #[inline] fn from(u: usize) -> Self { Line(u) }
}
impl Add<usize> for Line {
    type Output = Self;
    #[inline] fn add(self, rhs: usize) -> Self { Line(self.0 + rhs) }
}
impl Sub<usize> for Line {
    type Output = Self;
    #[inline] fn sub(self, rhs: usize) -> Self { Line(self.0 - rhs) }
}
<commit_msg>feat(rope metrics): replace semigroup with ops::Add<commit_after>use std::convert;
use std::ops::{Add, Sub};
use std::default::Default;
use internals::Node;

/// The class of monoids
///
/// The class of monoids (types with an accumulative binary operation that has
/// an identity).
///
/// Technically, `Add<Self, Output=Self>` is standing in for "semigroup" here,
/// while `Default` is standing in for "identity".
///
/// An instance _M_ should satisfy the following laws:
///
///  + _x_`.add(`_M_`::default())` = _x_
///  + _M_`::default().add(`_x_`)` = _x_
///  + _x_`.add(`_y_`.add(`_z_`))` = _z_`.add(`_x_`.add(`_y_`))`
///  + _M_`::accumulate(`_a_`)` = _a_`.fold(`_M_`::default,`_M_`::sum)`
///
pub trait Monoid: Add<Self, Output=Self> + Default + Sized {
    #[inline]
    fn accumulate<F>(xs: F) -> Self
    where F: Iterator<Item=Self>
        , Self: Sized {
        xs.fold(Self::default(), Self::add)
    }
}

/// A monoid that can be applied to a `Node` as a measurement
pub trait Metric: Monoid + Eq + Add<usize, Output=Self>
                              + Sub<usize, Output=Self>
                              + Sized {
    /// Apply this `Metric` to the given `Node`
    ///
    /// Although we aren't currently enforcing this, `measure`ing a `Node` with
    /// two children should produce the same result as `measure`ing both
    /// children and `Monoid::sum`ming the result. That is to say, `measure`
    /// should be a [_monoid homomorphism_]
    /// (https://en.wikipedia.org/wiki/Monoid#Monoid_homomorphisms).
    fn measure(node: &Node) -> Self;

    /// Convert the `Metric` into a byte index into the given `Node`
    ///
    /// # Returns
    /// - `Some` with the byte index of the beginning of the `n`th  element
    ///    in `node` measured by this `Metric`, if there is an `n`th element
    /// - `None` if there is no `n`th element in `node`
    fn to_byte_index(&self, node: &Node) -> Option<usize>;

    /// Returns the byte index of the next element of this metric in `Node`
    #[inline] fn next(self, node: &Node) -> Option<usize> {
        (self + 1).to_byte_index(node)
    }

    /// Returns the byte index of the previous element of this metric in `Node`
    #[inline] fn back(self, node: &Node) -> Option<usize> {
        (self - 1).to_byte_index(node)
    }

    /// Returns true if index `i` in `node` is a boundary along this `Metric`
    // TODO: should this be a method on `Node`s instead?
    fn is_boundary(node: &Node, i: usize) -> bool;
}

#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Grapheme(usize);
impl Default for Grapheme {
    #[inline] fn default() -> Self { Grapheme(0) }
}
impl convert::From<usize> for Grapheme {
    #[inline] fn from(u: usize) -> Self { Grapheme(u) }
}
impl Add<usize> for Grapheme {
    type Output = Self;
    #[inline] fn add(self, rhs: usize) -> Self { Grapheme(self.0 + rhs) }
}
impl Add<Grapheme> for Grapheme {
    type Output = Self;
    #[inline] fn add(self, rhs: Self) -> Self { Grapheme(self.0 + rhs.0) }
}
impl Sub<usize> for Grapheme {
    type Output = Self;
    #[inline] fn sub(self, rhs: usize) -> Self { Grapheme(self.0 - rhs) }
}

#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Line(usize);
impl Default for Line {
    #[inline] fn default() -> Self { Line(0) }
}
impl Add<Line> for Line {
    type Output = Self;
    #[inline] fn add(self, rhs: Self) -> Self { Line(self.0 + rhs.0) }
}
impl convert::From<usize> for Line {
    #[inline] fn from(u: usize) -> Self { Line(u) }
}
impl Add<usize> for Line {
    type Output = Self;
    #[inline] fn add(self, rhs: usize) -> Self { Line(self.0 + rhs) }
}
impl Sub<usize> for Line {
    type Output = Self;
    #[inline] fn sub(self, rhs: usize) -> Self { Line(self.0 - rhs) }
}
<|endoftext|>