<commit_before><commit_msg>Port tests for TcpStream from Gaea<commit_after>use std::io::{self, IoSlice, IoSliceMut, Read, Write};
use std::net::{self, Shutdown, SocketAddr};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
use std::sync::mpsc::channel;
use std::sync::{Arc, Barrier};
use std::thread;

use mio::net::TcpStream;
use mio::{Interests, Token};

mod util;

use util::{
    any_local_address, any_local_ipv6_address, assert_send, assert_sync, assert_would_block,
    expect_events, expect_no_events, init, init_with_poll, ExpectEvent,
};

const DATA1: &[u8] = b"Hello world!";
const DATA2: &[u8] = b"Hello mars!";
// TODO: replace with `DATA1.len()` once `const_slice_len` is stable.
const DATA1_LEN: usize = 12;
const DATA2_LEN: usize = 11;

const ID1: Token = Token(0);
const ID2: Token = Token(1);

#[test]
fn is_send_and_sync() {
    assert_send::<TcpStream>();
    assert_sync::<TcpStream>();
}

#[test]
fn tcp_stream_ipv4() {
    smoke_test_tcp_stream(any_local_address());
}

#[test]
fn tcp_stream_ipv6() {
    smoke_test_tcp_stream(any_local_ipv6_address());
}

fn smoke_test_tcp_stream(addr: SocketAddr) {
    let (mut poll, mut events) = init_with_poll();

    let (thread_handle, addr) = echo_listener(addr, 1);
    let mut stream = TcpStream::connect(addr).unwrap();

    poll.registry()
        .register(&stream, ID1, Interests::WRITABLE.add(Interests::READABLE))
        .expect("unable to register TCP stream");

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::WRITABLE)],
    );

    let mut buf = [0; 16];
    assert_would_block(stream.peek(&mut buf));
    assert_would_block(stream.read(&mut buf));

    // NOTE: the call to `peer_addr` must happen after we received a writable
    // event as the stream might not yet be connected.
    assert_eq!(stream.peer_addr().unwrap(), addr);
    assert!(stream.local_addr().unwrap().ip().is_loopback());

    let n = stream.write(&DATA1).expect("unable to write to stream");
    assert_eq!(n, DATA1.len());

    stream.flush().unwrap();

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::READABLE)],
    );

    let n = stream.peek(&mut buf).expect("unable to peek from stream");
    assert_eq!(n, DATA1.len());
    assert_eq!(&buf[..n], DATA1);

    let n = stream.read(&mut buf).expect("unable to read from stream");
    assert_eq!(n, DATA1.len());
    assert_eq!(&buf[..n], DATA1);

    assert!(stream.take_error().unwrap().is_none());

    let bufs = [IoSlice::new(&DATA1), IoSlice::new(&DATA2)];
    let n = stream
        .write_vectored(&bufs)
        .expect("unable to write vectored to stream");
    assert_eq!(n, DATA1.len() + DATA2.len());

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::READABLE)],
    );

    let mut buf1 = [1; DATA1_LEN];
    let mut buf2 = [2; DATA2_LEN + 1];
    let mut bufs = [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)];
    let n = stream
        .read_vectored(&mut bufs)
        .expect("unable to read vectored from stream");
    assert_eq!(n, DATA1.len() + DATA2.len());
    assert_eq!(&buf1, DATA1);
    assert_eq!(&buf2[..DATA2.len()], DATA2);
    assert_eq!(buf2[DATA2.len()], 2); // Last byte should be unchanged.

    // Close the connection to allow the listener to shutdown.
    drop(stream);

    thread_handle.join().expect("unable to join thread");
}

#[test]
fn try_clone() {
    let (mut poll, mut events) = init_with_poll();

    let (thread_handle, address) = echo_listener(any_local_address(), 1);

    let mut stream1 = TcpStream::connect(address).unwrap();

    poll.registry()
        .register(&stream1, ID1, Interests::WRITABLE)
        .expect("unable to register TCP stream");

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::WRITABLE)],
    );

    let n = stream1.write(DATA1).unwrap();
    assert_eq!(n, DATA1.len());

    let mut stream2 = stream1.try_clone().unwrap();

    // When using `try_clone` the `TcpStream` needs to be deregistered!
    poll.registry().deregister(&stream1).unwrap();
    drop(stream1);

    poll.registry()
        .register(&stream2, ID2, Interests::READABLE)
        .expect("unable to register TCP stream");

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID2, Interests::READABLE)],
    );

    let mut buf = [0; 20];
    let n = stream2.read(&mut buf).unwrap();
    assert_eq!(n, DATA1.len());
    assert_eq!(&buf[..n], DATA1);

    drop(stream2);
    thread_handle.join().expect("unable to join thread");
}

#[test]
fn ttl() {
    init();

    let barrier = Arc::new(Barrier::new(2));
    let (thread_handle, address) = start_listener(1, Some(barrier.clone()));

    let stream = TcpStream::connect(address).unwrap();

    const TTL: u32 = 10;
    stream.set_ttl(TTL).unwrap();
    assert_eq!(stream.ttl().unwrap(), TTL);
    assert!(stream.take_error().unwrap().is_none());

    barrier.wait();
    thread_handle.join().expect("unable to join thread");
}

#[test]
fn nodelay() {
    init();

    let barrier = Arc::new(Barrier::new(2));
    let (thread_handle, address) = start_listener(1, Some(barrier.clone()));

    let stream = TcpStream::connect(address).unwrap();

    const NO_DELAY: bool = true;
    stream.set_nodelay(NO_DELAY).unwrap();
    assert_eq!(stream.nodelay().unwrap(), NO_DELAY);
    assert!(stream.take_error().unwrap().is_none());

    barrier.wait();
    thread_handle.join().expect("unable to join thread");
}

#[test]
fn shutdown_read() {
    let (mut poll, mut events) = init_with_poll();

    let (thread_handle, address) = echo_listener(any_local_address(), 1);

    let mut stream = TcpStream::connect(address).unwrap();

    poll.registry()
        .register(&stream, ID1, Interests::WRITABLE.add(Interests::READABLE))
        .expect("unable to register TCP stream");

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::WRITABLE)],
    );

    let n = stream.write(DATA2).unwrap();
    assert_eq!(n, DATA2.len());

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::READABLE)],
    );

    stream.shutdown(Shutdown::Read).unwrap();

    let mut buf = [0; 20];
    let n = stream.read(&mut buf).unwrap();
    assert_eq!(n, 0);

    drop(stream);
    thread_handle.join().expect("unable to join thread");
}

#[test]
fn shutdown_write() {
    let (mut poll, mut events) = init_with_poll();

    let (thread_handle, address) = echo_listener(any_local_address(), 1);

    let mut stream = TcpStream::connect(address).unwrap();

    poll.registry()
        .register(&stream, ID1, Interests::WRITABLE.add(Interests::READABLE))
        .expect("unable to register TCP stream");

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::WRITABLE)],
    );

    let n = stream.write(DATA1).unwrap();
    assert_eq!(n, DATA1.len());

    stream.shutdown(Shutdown::Write).unwrap();

    let err = stream.write(DATA2).unwrap_err();
    assert_eq!(err.kind(), io::ErrorKind::BrokenPipe);

    // TODO: this can be flaky, fix that.
    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::READABLE)],
    );

    // Read should be ok.
    let mut buf = [0; 20];
    let n = stream.read(&mut buf).unwrap();
    assert_eq!(n, DATA1.len());
    assert_eq!(&buf[..n], DATA1);

    drop(stream);
    thread_handle.join().expect("unable to join thread");
}

#[test]
fn shutdown_both() {
    let (mut poll, mut events) = init_with_poll();

    let (thread_handle, address) = echo_listener(any_local_address(), 1);

    let mut stream = TcpStream::connect(address).unwrap();

    poll.registry()
        .register(&stream, ID1, Interests::WRITABLE.add(Interests::READABLE))
        .expect("unable to register TCP stream");

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::WRITABLE)],
    );

    let n = stream.write(DATA1).unwrap();
    assert_eq!(n, DATA1.len());

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID1, Interests::READABLE)],
    );

    stream.shutdown(Shutdown::Both).unwrap();

    let mut buf = [0; 20];
    let n = stream.read(&mut buf).unwrap();
    assert_eq!(n, 0);

    let err = stream.write(DATA2).unwrap_err();
    assert_eq!(err.kind(), io::ErrorKind::BrokenPipe);

    drop(stream);
    thread_handle.join().expect("unable to join thread");
}

#[test]
#[cfg(unix)]
fn raw_fd() {
    init();

    let (thread_handle, address) = start_listener(1, None);

    let stream = TcpStream::connect(address).unwrap();
    let address = stream.local_addr().unwrap();

    let raw_fd1 = stream.as_raw_fd();
    let raw_fd2 = stream.into_raw_fd();
    assert_eq!(raw_fd1, raw_fd2);

    let stream = unsafe { TcpStream::from_raw_fd(raw_fd2) };
    assert_eq!(stream.as_raw_fd(), raw_fd1);
    assert_eq!(stream.local_addr().unwrap(), address);

    thread_handle.join().expect("unable to join thread");
}

#[test]
fn registering() {
    let (mut poll, mut events) = init_with_poll();

    let (thread_handle, address) = echo_listener(any_local_address(), 1);

    let stream = TcpStream::connect(address).unwrap();

    poll.registry()
        .register(&stream, ID1, Interests::READABLE)
        .expect("unable to register TCP stream");

    expect_no_events(&mut poll, &mut events);

    // NOTE: more tests are done in the smoke tests above.

    drop(stream);
    thread_handle.join().expect("unable to join thread");
}

#[test]
fn reregistering() {
    let (mut poll, mut events) = init_with_poll();

    let (thread_handle, address) = echo_listener(any_local_address(), 1);

    let stream = TcpStream::connect(address).unwrap();

    poll.registry()
        .register(&stream, ID1, Interests::READABLE)
        .expect("unable to register TCP stream");

    poll.registry()
        .reregister(&stream, ID2, Interests::WRITABLE)
        .expect("unable to reregister TCP stream");

    expect_events(
        &mut poll,
        &mut events,
        vec![ExpectEvent::new(ID2, Interests::WRITABLE)],
    );

    assert_eq!(stream.peer_addr().unwrap(), address);

    drop(stream);
    thread_handle.join().expect("unable to join thread");
}

#[test]
fn deregistering() {
    let (mut poll, mut events) = init_with_poll();

    let (thread_handle, address) = echo_listener(any_local_address(), 1);

    let stream = TcpStream::connect(address).unwrap();

    poll.registry()
        .register(&stream, ID1, Interests::READABLE)
        .expect("unable to register TCP stream");

    poll.registry()
        .deregister(&stream)
        .expect("unable to deregister TCP stream");

    expect_no_events(&mut poll, &mut events);

    // We do expect to be connected.
    assert_eq!(stream.peer_addr().unwrap(), address);

    drop(stream);
    thread_handle.join().expect("unable to join thread");
}

/// Start a listener that accepts `n_connections` connections on the returned
/// address. It echos back any data it reads from the connection before
/// accepting another one.
fn echo_listener(addr: SocketAddr, n_connections: usize) -> (thread::JoinHandle<()>, SocketAddr) {
    let (sender, receiver) = channel();
    let thread_handle = thread::spawn(move || {
        let listener = net::TcpListener::bind(addr).unwrap();
        let local_address = listener.local_addr().unwrap();
        sender.send(local_address).unwrap();

        let mut buf = [0; 128];
        for _ in 0..n_connections {
            let (mut stream, _) = listener.accept().unwrap();

            loop {
                let n = stream.read(&mut buf).expect("error reading");
                if n == 0 {
                    break;
                }
                let written = stream.write(&buf[..n]).expect("error writing");
                assert_eq!(written, n, "short write");
            }
        }
    });
    (thread_handle, receiver.recv().unwrap())
}

/// Start a listener that accepts `n_connections` connections on the returned
/// address. If a barrier is provided it will wait on it before closing the
/// connection.
fn start_listener(
    n_connections: usize,
    barrier: Option<Arc<Barrier>>,
) -> (thread::JoinHandle<()>, SocketAddr) {
    let (sender, receiver) = channel();
    let thread_handle = thread::spawn(move || {
        let listener = net::TcpListener::bind(any_local_address()).unwrap();
        let local_address = listener.local_addr().unwrap();
        sender.send(local_address).unwrap();

        for _ in 0..n_connections {
            let (stream, _) = listener.accept().unwrap();
            if let Some(ref barrier) = barrier {
                barrier.wait();
            }
            drop(stream);
        }
    });
    (thread_handle, receiver.recv().unwrap())
}
<|endoftext|>


<commit_before><commit_msg>Renaming a module<commit_after>//! Image worker submodule
//!
//! This module can be run in two different states. `local` and `remote`
//!
//! If in `remote` mode, all request calls will be routed to the external (remote) worker server
//! whereas in `local` mode sans will do all computations locally.

/// A trait that describes a piece of work to be done
///
/// It can be locally initialised, then sent to a remote work server, returning
/// a `Result` type for the processing that was done.
pub trait Work {
    fn add_workload(&self);
    fn work(&self) -> Result<()>;
}

pub struct Workers {

}
<|endoftext|>


<commit_before><commit_msg>Beginning of the Asn1Data trait implementation<commit_after>type Asn1Tag = u64;

type Asn1Data = Vec<u8>;
type Asn1Slice = &[u8];

enum Asn1Type {
  // Universal types here ...
  AplicationTag(Asn1Tag, String),
  PrivateTag(Asn1Tag, String),
}

trait Asn1Data {
  fn get_asn1_type() -> Asn1Type;

  /// Create ASN.1 data from this struct.
  // FIXME: Should this use &self?
  fn into_asn1(&self) -> Result<Asn1Data, Asn1Error>;

  /// Create this struct from ASN.1 data.
  fn from_asn1(slice: Asn1Slice) -> Result<Self, Asn1Error>;
}

/// A macro to generate a generic Asn1Data trait implementation for a struct.
macro_rules! asn1_impl {
  ( $impl_type:ident, $asn1_type:extr,
    $( $name:ident, $rusttype:ident, $asn1type:expr ),*
  ) =>
(

impl Asn1Data for $impl_type {
  fn get_asn1_type() -> Asn1Type {
    $asn1_type
  }

  fn into_asn1(&self) -> Result<Asn1Data, Asn1Error> {
    Err(Asn1Error::EncodingError)
  }

  fn from_asn1(slice: Asn1Slice) -> Result<Self, Asn1Error> {
    Err(Asn1Error::InvalidAsn1)
  }
}

)
}

/// A list of errors that can occur decoding or encoding Asn1 data.
enum Asn1Error {
  /// Invalid Asn1 data.
  InvalidAsn1
  /// An error occured while encoding Asn1 data.
  ENcodingError
}
<|endoftext|>


<commit_before><commit_msg>Add example from blog post<commit_after><|endoftext|>


<commit_before><commit_msg>Get started with importing the icmp scheme to userspace<commit_after>use redox::Box;
use redox::cell::UnsafeCell;
use redox::console::ConsoleWindow;
use redox::fs::file::File;
use redox::rc::Rc;
use redox::str;
use redox::string::*;
use redox::io::SeekFrom;

pub struct Scheme;

impl Scheme {
    fn scheme(&self) -> Box<Self> {
        box Scheme
    }

    pub fn reply_loop() {
        while let Some(mut ip) = File::open("ip:///1") {
            let mut bytes: Vec<u8> = Vec::new();
            match ip.read_to_end(&mut bytes) {
                Some(_) => {
                    if let Some(message) = ICMP::from_bytes(bytes) {
                        if message.header._type == 0x08 {
                            let mut response = ICMP {
                                header: message.header,
                                data: message.data,
                            };

                            response.header._type = 0x00;

                            unsafe {
                                response.header.checksum.data = 0;

                                let header_ptr: *const ICMPHeader = &response.header;
                                response.header.checksum.data = Checksum::compile(
                                    Checksum::sum(header_ptr as usize, mem::size_of::<ICMPHeader>()) +
                                    Checksum::sum(response.data.as_ptr() as usize, response.data.len())
                                );
                            }

                            ip.write(&response.to_bytes().as_slice());
                        }
                    }
                }
                None => unsafe { context_switch(false) },
            }
        }
    }

    /*
    fn open(&mut self, url: &URL) -> Option<Box<Resource>> {
    }
    */
}
<|endoftext|>


<commit_before><commit_msg>rust any-all exp<commit_after>let id = "Iterator";

// This is straightforward, because we need to find just first occurence of true predicate calculation
assert!(id.chars().any(char::is_uppercase));

// Do we need to iterate through hall collection? Or Rust compiler can optimize this case? If not, it should.
assert!(!id.chars().any(char::is_uppercase));
<|endoftext|>


<commit_before><commit_msg>build: fix build,package,clean<commit_after><|endoftext|>


<commit_before><commit_msg>Implement regeneration<commit_after><|endoftext|>


<commit_before><commit_msg>Avoid re-parsing config-cli toml<commit_after><|endoftext|>


<commit_before>use super::{Error, Result, raw};
use std::collections::HashMap;
use std;

/// Handle to an ODBC Environment
///
/// Creating an instance of this type is the first thing you do then using ODBC. The environment
/// must outlive all connections created with it
pub struct Environment {
    handle: raw::SQLHENV,
}

/// Struct holding information available on a driver.
///
/// Can be obtained via `Environment::drivers`
#[derive(Clone, Debug)]
pub struct DriverInfo {
    pub description: String,
    pub attributes: HashMap<String, String>,
}

impl Environment {
    /// Allocates a new ODBC Environment
    ///
    /// Declares the Application's ODBC Version to be 3
    pub fn new() -> Result<Environment> {
        unsafe {
            let mut env = std::ptr::null_mut();
            let mut result =
                match raw::SQLAllocHandle(raw::SQL_HANDLE_ENV, std::ptr::null_mut(), &mut env) {
                    raw::SQL_SUCCESS => Environment { handle: env },
                    raw::SQL_SUCCESS_WITH_INFO => Environment { handle: env },
                    // Driver Manager failed to allocate environment
                    raw::SQL_ERROR => return Err(Error {}),
                    _ => unreachable!(),
                };
            // no leak if we return an error here, env handle is already wrapped and would be
            // dropped
            result.set_attribute(raw::SQL_ATTR_ODBC_VERSION,
                               raw::SQL_OV_ODBC3 as *mut std::os::raw::c_void,
                               0)?;

            Ok(result)
        }
    }

    /// Stores all driver description and attributes in a Vec
    pub fn drivers(&self) -> Result<Vec<DriverInfo>> {
        // Iterate twice, once for reading the maximum required buffer lengths so we can read
        // everything without truncating and a second time for actually storing the values
        let string_buf = std::ptr::null_mut();
        let mut desc_length_out: raw::SQLSMALLINT = 0;
        let mut attr_length_out: raw::SQLSMALLINT = 0;
        let mut max_desc = 0;
        let mut max_attr = 0;
        let mut count = 0;
        let mut result;
        unsafe {
            // Although the rather lengthy function call kind of blows the code, let's do the first
            // one using SQL_FETCH_FIRST, so we list all drivers independent from environment state
            result = raw::SQLDrivers(self.handle,
                                     raw::SQL_FETCH_FIRST,
                                     string_buf,
                                     0,
                                     &mut desc_length_out as *mut raw::SQLSMALLINT,
                                     string_buf,
                                     0,
                                     &mut attr_length_out as *mut raw::SQLSMALLINT);
        }
        loop {
            match result {
                raw::SQL_SUCCESS |
                raw::SQL_SUCCESS_WITH_INFO => {
                    count += 1;
                    max_desc = std::cmp::max(max_desc, desc_length_out);
                    max_attr = std::cmp::max(max_attr, attr_length_out);
                }
                raw::SQL_NO_DATA => break,
                raw::SQL_ERROR => return Err(Error {}),
                _ => unreachable!(),
            }
            unsafe {
                result = raw::SQLDrivers(self.handle,
                                         raw::SQL_FETCH_NEXT,
                                         string_buf,
                                         0,
                                         &mut desc_length_out as *mut raw::SQLSMALLINT,
                                         string_buf,
                                         0,
                                         &mut attr_length_out as *mut raw::SQLSMALLINT);
            }
        }

        let mut driver_list = Vec::with_capacity(count);
        loop {
            let mut description_buffer: Vec<_> = (0..(max_desc + 1)).map(|_| 0u8).collect();
            let mut attribute_buffer: Vec<_> = (0..(max_attr + 1)).map(|_| 0u8).collect();
            unsafe {
                result = raw::SQLDrivers(self.handle,
                                         // Its ok to use fetch next here, since we know
                                         // last state has been SQL_NO_DATA
                                         raw::SQL_FETCH_NEXT,
                                         &mut description_buffer[0] as *mut u8,
                                         max_desc + 1,
                                         &mut desc_length_out as *mut raw::SQLSMALLINT,
                                         &mut attribute_buffer[0] as *mut u8,
                                         max_attr + 1,
                                         &mut attr_length_out as *mut raw::SQLSMALLINT);
            }
            match result {
                raw::SQL_SUCCESS |
                raw::SQL_SUCCESS_WITH_INFO => {
                    description_buffer.resize(desc_length_out as usize, 0);
                    driver_list.push(DriverInfo {
                        description: String::from_utf8(description_buffer)
                            .expect("String returned by Driver Manager should be utf8 encoded"),
                        attributes: Self::parse_attributes(attribute_buffer),
                    })
                }
                raw::SQL_ERROR => return Err(Error {}),
                raw::SQL_NO_DATA => break,
                /// The only other value allowed by ODBC here is SQL_INVALID_HANDLE. We protect the
                /// validity of this handle with our invariant. In save code the user should not be
                /// able to reach this code path.
                _ => panic!("Environment invariant violated"),
            }
        }
        Ok(driver_list)
    }

    /// Allows access to the raw ODBC handle
    pub unsafe fn raw(&mut self) -> raw::SQLHENV {
        self.handle
    }

    /// Allows setting attributes to Environment
    pub unsafe fn set_attribute(&mut self,
                                attribute: raw::SQLINTEGER,
                                value: raw::SQLPOINTER,
                                length: raw::SQLINTEGER)
                                -> Result<()> {
        match raw::SQLSetEnvAttr(self.handle, attribute, value, length) {
            raw::SQL_SUCCESS => Ok(()),
            raw::SQL_SUCCESS_WITH_INFO => Ok(()),
            _ => Err(Error {}),
        }
    }

    /// Called by drivers to pares list of attributes
    ///
    /// Key value pairs are seperated by `\0`. Key and value are seperated by `=`
    fn parse_attributes(attribute_buffer: Vec<u8>) -> HashMap<String, String> {
        String::from_utf8(attribute_buffer)
            .expect("String returned by Driver Manager should be utf8 encoded")
            .split('\0')
            .take_while(|kv_str| *kv_str != String::new())
            .map(|kv_str| {
                let mut iter = kv_str.split('=');
                let key = iter.next().unwrap();
                let value = iter.next().unwrap();
                (key.to_string(), value.to_string())
            })
            .collect()
    }
}

impl Drop for Environment {
    fn drop(&mut self) {
        unsafe {
            raw::SQLFreeEnv(self.handle);
        }
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn parse_attributes() {
        let buffer = "APILevel=2\0ConnectFunctions=YYY\0CPTimeout=60\0DriverODBCVer=03.\
                      50\0FileUsage=0\0SQLLevel=1\0UsageCount=1\0\0"
            .as_bytes()
            .iter()
            .cloned()
            .collect();
        let attributes = Environment::parse_attributes(buffer);
        assert_eq!(attributes["APILevel"], "2");
        assert_eq!(attributes["ConnectFunctions"], "YYY");
        assert_eq!(attributes["CPTimeout"], "60");
        assert_eq!(attributes["DriverODBCVer"], "03.50");
        assert_eq!(attributes["FileUsage"], "0");
        assert_eq!(attributes["SQLLevel"], "1");
        assert_eq!(attributes["UsageCount"], "1");
    }
}<commit_msg>replaced unreachable with panic<commit_after>use super::{Error, Result, raw};
use std::collections::HashMap;
use std;

/// Handle to an ODBC Environment
///
/// Creating an instance of this type is the first thing you do then using ODBC. The environment
/// must outlive all connections created with it
pub struct Environment {
    handle: raw::SQLHENV,
}

/// Struct holding information available on a driver.
///
/// Can be obtained via `Environment::drivers`
#[derive(Clone, Debug)]
pub struct DriverInfo {
    pub description: String,
    pub attributes: HashMap<String, String>,
}

impl Environment {
    /// Allocates a new ODBC Environment
    ///
    /// Declares the Application's ODBC Version to be 3
    pub fn new() -> Result<Environment> {
        unsafe {
            let mut env = std::ptr::null_mut();
            let mut result =
                match raw::SQLAllocHandle(raw::SQL_HANDLE_ENV, std::ptr::null_mut(), &mut env) {
                    raw::SQL_SUCCESS => Environment { handle: env },
                    raw::SQL_SUCCESS_WITH_INFO => Environment { handle: env },
                    // Driver Manager failed to allocate environment
                    raw::SQL_ERROR => return Err(Error {}),
                    _ => unreachable!(),
                };
            // no leak if we return an error here, env handle is already wrapped and would be
            // dropped
            result.set_attribute(raw::SQL_ATTR_ODBC_VERSION,
                               raw::SQL_OV_ODBC3 as *mut std::os::raw::c_void,
                               0)?;

            Ok(result)
        }
    }

    /// Stores all driver description and attributes in a Vec
    pub fn drivers(&self) -> Result<Vec<DriverInfo>> {
        // Iterate twice, once for reading the maximum required buffer lengths so we can read
        // everything without truncating and a second time for actually storing the values
        let string_buf = std::ptr::null_mut();
        let mut desc_length_out: raw::SQLSMALLINT = 0;
        let mut attr_length_out: raw::SQLSMALLINT = 0;
        let mut max_desc = 0;
        let mut max_attr = 0;
        let mut count = 0;
        let mut result;
        unsafe {
            // Although the rather lengthy function call kind of blows the code, let's do the first
            // one using SQL_FETCH_FIRST, so we list all drivers independent from environment state
            result = raw::SQLDrivers(self.handle,
                                     raw::SQL_FETCH_FIRST,
                                     string_buf,
                                     0,
                                     &mut desc_length_out as *mut raw::SQLSMALLINT,
                                     string_buf,
                                     0,
                                     &mut attr_length_out as *mut raw::SQLSMALLINT);
        }
        loop {
            match result {
                raw::SQL_SUCCESS |
                raw::SQL_SUCCESS_WITH_INFO => {
                    count += 1;
                    max_desc = std::cmp::max(max_desc, desc_length_out);
                    max_attr = std::cmp::max(max_attr, attr_length_out);
                }
                raw::SQL_NO_DATA => break,
                raw::SQL_ERROR => return Err(Error {}),
                /// The only other value allowed by ODBC here is SQL_INVALID_HANDLE. We protect the
                /// validity of this handle with our invariant. In save code the user should not be
                /// able to reach this code path.
                _ => panic!("Environment invariant violated"),
            }
            unsafe {
                result = raw::SQLDrivers(self.handle,
                                         raw::SQL_FETCH_NEXT,
                                         string_buf,
                                         0,
                                         &mut desc_length_out as *mut raw::SQLSMALLINT,
                                         string_buf,
                                         0,
                                         &mut attr_length_out as *mut raw::SQLSMALLINT);
            }
        }

        let mut driver_list = Vec::with_capacity(count);
        loop {
            let mut description_buffer: Vec<_> = (0..(max_desc + 1)).map(|_| 0u8).collect();
            let mut attribute_buffer: Vec<_> = (0..(max_attr + 1)).map(|_| 0u8).collect();
            unsafe {
                result = raw::SQLDrivers(self.handle,
                                         // Its ok to use fetch next here, since we know
                                         // last state has been SQL_NO_DATA
                                         raw::SQL_FETCH_NEXT,
                                         &mut description_buffer[0] as *mut u8,
                                         max_desc + 1,
                                         &mut desc_length_out as *mut raw::SQLSMALLINT,
                                         &mut attribute_buffer[0] as *mut u8,
                                         max_attr + 1,
                                         &mut attr_length_out as *mut raw::SQLSMALLINT);
            }
            match result {
                raw::SQL_SUCCESS |
                raw::SQL_SUCCESS_WITH_INFO => {
                    description_buffer.resize(desc_length_out as usize, 0);
                    driver_list.push(DriverInfo {
                        description: String::from_utf8(description_buffer)
                            .expect("String returned by Driver Manager should be utf8 encoded"),
                        attributes: Self::parse_attributes(attribute_buffer),
                    })
                }
                raw::SQL_ERROR => return Err(Error {}),
                raw::SQL_NO_DATA => break,
                /// The only other value allowed by ODBC here is SQL_INVALID_HANDLE. We protect the
                /// validity of this handle with our invariant. In save code the user should not be
                /// able to reach this code path.
                _ => panic!("Environment invariant violated"),
            }
        }
        Ok(driver_list)
    }

    /// Allows access to the raw ODBC handle
    pub unsafe fn raw(&mut self) -> raw::SQLHENV {
        self.handle
    }

    /// Allows setting attributes to Environment
    pub unsafe fn set_attribute(&mut self,
                                attribute: raw::SQLINTEGER,
                                value: raw::SQLPOINTER,
                                length: raw::SQLINTEGER)
                                -> Result<()> {
        match raw::SQLSetEnvAttr(self.handle, attribute, value, length) {
            raw::SQL_SUCCESS => Ok(()),
            raw::SQL_SUCCESS_WITH_INFO => Ok(()),
            _ => Err(Error {}),
        }
    }

    /// Called by drivers to pares list of attributes
    ///
    /// Key value pairs are seperated by `\0`. Key and value are seperated by `=`
    fn parse_attributes(attribute_buffer: Vec<u8>) -> HashMap<String, String> {
        String::from_utf8(attribute_buffer)
            .expect("String returned by Driver Manager should be utf8 encoded")
            .split('\0')
            .take_while(|kv_str| *kv_str != String::new())
            .map(|kv_str| {
                let mut iter = kv_str.split('=');
                let key = iter.next().unwrap();
                let value = iter.next().unwrap();
                (key.to_string(), value.to_string())
            })
            .collect()
    }
}

impl Drop for Environment {
    fn drop(&mut self) {
        unsafe {
            raw::SQLFreeEnv(self.handle);
        }
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn parse_attributes() {
        let buffer = "APILevel=2\0ConnectFunctions=YYY\0CPTimeout=60\0DriverODBCVer=03.\
                      50\0FileUsage=0\0SQLLevel=1\0UsageCount=1\0\0"
            .as_bytes()
            .iter()
            .cloned()
            .collect();
        let attributes = Environment::parse_attributes(buffer);
        assert_eq!(attributes["APILevel"], "2");
        assert_eq!(attributes["ConnectFunctions"], "YYY");
        assert_eq!(attributes["CPTimeout"], "60");
        assert_eq!(attributes["DriverODBCVer"], "03.50");
        assert_eq!(attributes["FileUsage"], "0");
        assert_eq!(attributes["SQLLevel"], "1");
        assert_eq!(attributes["UsageCount"], "1");
    }
}<|endoftext|>


<commit_before>/*
Module: list

A standard linked list
*/

import core::option;
import option::*;
import option::{some, none};

/* Section: Types */

/*
Tag: list
*/
tag list<T> {
    /* Variant: cons */
    cons(T, @list<T>);
    /* Variant: nil */
    nil;
}

/*Section: Operations */

/*
Function: from_vec

Create a list from a vector
*/
fn from_vec<copy T>(v: [const T]) -> list<T> {
    *vec::foldr(v, @nil::<T>, { |h, t| @cons(h, t) })
}

/*
Function: foldl

Left fold

Applies `f` to `u` and the first element in the list, then applies
`f` to the result of the previous call and the second element,
and so on, returning the accumulated result.

Parameters:

ls - The list to fold
z - The initial value
f - The function to apply
*/
fn foldl<copy T, copy U>(ls: list<U>, z: T, f: block(T, U) -> T) -> T {
    let accum: T = z;
    let ls = ls;
    while true {
        alt ls {
          cons(hd, tl) { accum = f(accum, hd); ls = *tl; }
          nil. { break; }
        }
    }
    ret accum;
}

/*
Function: find

Search for an element that matches a given predicate

Apply function `f` to each element of `v`, starting from the first.
When function `f` returns true then an option containing the element
is returned. If `f` matches no elements then none is returned.
*/
fn find<copy T, copy U>(ls: list<T>, f: block(T) -> option::t<U>)
    -> option::t<U> {
    let ls = ls;
    while true {
        alt ls {
          cons(hd, tl) {
            alt f(hd) { none. { ls = *tl; } some(rs) { ret some(rs); } }
          }
          nil. { break; }
        }
    }
    ret none;
}

/*
Function: has

Returns true if a list contains an element with the given value
*/
fn has<copy T>(ls: list<T>, elt: T) -> bool {
    let ls = ls;
    while true {
        alt ls {
          cons(hd, tl) { if elt == hd { ret true; } else { ls = *tl; } }
          nil. { break; }
        }
    }
    ret false;
}

/*
Function: is_empty

Returns true if the list is empty.
*/
pure fn is_empty<copy T>(ls: list<T>) -> bool {
    alt ls {
        nil. { true }
        _ { false }
    }
}

/*
Function: is_not_empty

Returns true if the list is not empty.
*/
pure fn is_not_empty<copy T>(ls: list<T>) -> bool {
    ret !is_empty(ls);
}

/*
Function: len

Returns the length of a list
*/
fn len<copy T>(ls: list<T>) -> uint {
    fn count<T>(&&u: uint, _t: T) -> uint { ret u + 1u; }
    ret foldl(ls, 0u, bind count(_, _));
}

/*
Function: tail

Returns all but the first element of a list
*/
pure fn tail<copy T>(ls: list<T>) : is_not_empty(ls) -> list<T> {
    alt ls {
        cons(_, tl) { ret *tl; }
        nil. { fail "list empty" }
    }
}

/*
Function: head

Returns the first element of a list
*/
pure fn head<copy T>(ls: list<T>) : is_not_empty(ls) -> T {
    alt ls {
        cons(hd, _) { ret hd; }
        nil. { fail "list empty" }
    }
}

/*
Function: append

Appends one list to another
*/
pure fn append<copy T>(l: list<T>, m: list<T>) -> list<T> {
    alt l {
      nil. { ret m; }
      cons(x, xs) { let rest = append(*xs, m); ret cons(x, @rest); }
    }
}

/*
Function: iter

Iterate over a list
*/
fn iter<copy T>(l: list<T>, f: block(T)) {
    let cur = l;
    while cur != nil {
        alt cur {
          cons(hd, tl) {
            f(hd);
            cur = *tl;
          }
        }
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>Express some list primitives in a way that doesn't copy<commit_after>/*
Module: list

A standard linked list
*/

import core::option;
import option::*;
import option::{some, none};

/* Section: Types */

/*
Tag: list
*/
tag list<T> {
    /* Variant: cons */
    cons(T, @list<T>);
    /* Variant: nil */
    nil;
}

/*Section: Operations */

/*
Function: from_vec

Create a list from a vector
*/
fn from_vec<copy T>(v: [const T]) -> list<T> {
    *vec::foldr(v, @nil::<T>, { |h, t| @cons(h, t) })
}

/*
Function: foldl

Left fold

Applies `f` to `u` and the first element in the list, then applies
`f` to the result of the previous call and the second element,
and so on, returning the accumulated result.

Parameters:

ls - The list to fold
z - The initial value
f - The function to apply
*/
fn foldl<copy T, U>(ls: list<U>, z: T, f: block(T, U) -> T) -> T {
    let accum: T = z;
    iter(ls) {|elt| accum = f(accum, elt);}
    accum
}

/*
Function: find

Search for an element that matches a given predicate

Apply function `f` to each element of `v`, starting from the first.
When function `f` returns true then an option containing the element
is returned. If `f` matches no elements then none is returned.
*/
fn find<copy T, copy U>(ls: list<T>, f: block(T) -> option::t<U>)
    -> option::t<U> {
    let ls = ls;
    while true {
        alt ls {
          cons(hd, tl) {
            alt f(hd) { none. { ls = *tl; } some(rs) { ret some(rs); } }
          }
          nil. { break; }
        }
    }
    ret none;
}

/*
Function: has

Returns true if a list contains an element with the given value
*/
fn has<copy T>(ls: list<T>, elt: T) -> bool {
    let ls = ls;
    while true {
        alt ls {
          cons(hd, tl) { if elt == hd { ret true; } else { ls = *tl; } }
          nil. { break; }
        }
    }
    ret false;
}

/*
Function: is_empty

Returns true if the list is empty.
*/
pure fn is_empty<copy T>(ls: list<T>) -> bool {
    alt ls {
        nil. { true }
        _ { false }
    }
}

/*
Function: is_not_empty

Returns true if the list is not empty.
*/
pure fn is_not_empty<copy T>(ls: list<T>) -> bool {
    ret !is_empty(ls);
}

/*
Function: len

Returns the length of a list
*/
fn len<T>(ls: list<T>) -> uint {
    let count = 0u;
    iter(ls) {|_e| count += 1u;}
    count
}

/*
Function: tail

Returns all but the first element of a list
*/
pure fn tail<copy T>(ls: list<T>) : is_not_empty(ls) -> list<T> {
    alt ls {
        cons(_, tl) { ret *tl; }
        nil. { fail "list empty" }
    }
}

/*
Function: head

Returns the first element of a list
*/
pure fn head<copy T>(ls: list<T>) : is_not_empty(ls) -> T {
    alt ls {
        cons(hd, _) { ret hd; }
        nil. { fail "list empty" }
    }
}

/*
Function: append

Appends one list to another
*/
pure fn append<copy T>(l: list<T>, m: list<T>) -> list<T> {
    alt l {
      nil. { ret m; }
      cons(x, xs) { let rest = append(*xs, m); ret cons(x, @rest); }
    }
}

/*
Function: iter

Iterate over a list
*/
fn iter<T>(l: list<T>, f: block(T)) {
    alt l {
      cons(hd, tl) {
        f(hd);
        let cur = tl;
        while true {
            alt *cur {
              cons(hd, tl) {
                f(hd);
                cur = tl;
              }
              nil. { break; }
            }
        }
      }
      nil. {}
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before>/*
Module: term

Simple ANSI color library
*/

import core::option;

// TODO: Windows support.

/* Const: color_black */
const color_black: u8 = 0u8;
/* Const: color_red */
const color_red: u8 = 1u8;
/* Const: color_green */
const color_green: u8 = 2u8;
/* Const: color_yellow */
const color_yellow: u8 = 3u8;
/* Const: color_blue */
const color_blue: u8 = 4u8;
/* Const: color_magenta */
const color_magenta: u8 = 5u8;
/* Const: color_cyan */
const color_cyan: u8 = 6u8;
/* Const: color_light_gray */
const color_light_gray: u8 = 7u8;
/* Const: color_light_grey */
const color_light_grey: u8 = 7u8;
/* Const: color_dark_gray */
const color_dark_gray: u8 = 8u8;
/* Const: color_dark_grey */
const color_dark_grey: u8 = 8u8;
/* Const: color_bright_red */
const color_bright_red: u8 = 9u8;
/* Const: color_bright_green */
const color_bright_green: u8 = 10u8;
/* Const: color_bright_yellow */
const color_bright_yellow: u8 = 11u8;
/* Const: color_bright_blue */
const color_bright_blue: u8 = 12u8;
/* Const: color_bright_magenta */
const color_bright_magenta: u8 = 13u8;
/* Const: color_bright_cyan */
const color_bright_cyan: u8 = 14u8;
/* Const: color_bright_white */
const color_bright_white: u8 = 15u8;

fn esc(writer: io::buf_writer) { writer.write([0x1bu8, '[' as u8]); }

/*
Function: reset

Reset the foreground and background colors to default
*/
fn reset(writer: io::buf_writer) {
    esc(writer);
    writer.write(['0' as u8, 'm' as u8]);
}

/*
Function: color_supported

Returns true if the terminal supports color
*/
fn color_supported() -> bool {
    let supported_terms = ["xterm-color", "xterm", "screen-bce", "xterm-256color"];
    ret alt generic_os::getenv("TERM") {
          option::some(env) {
            for term: str in supported_terms {
                if str::eq(term, env) { ret true; }
            }
            false
          }
          option::none. { false }
        };
}

fn set_color(writer: io::buf_writer, first_char: u8, color: u8) {
    assert (color < 16u8);
    esc(writer);
    let color = color;
    if color >= 8u8 { writer.write(['1' as u8, ';' as u8]); color -= 8u8; }
    writer.write([first_char, ('0' as u8) + color, 'm' as u8]);
}

/*
Function: fg

Set the foreground color
*/
fn fg(writer: io::buf_writer, color: u8) {
    ret set_color(writer, '3' as u8, color);
}

/*
Function: fg

Set the background color
*/
fn bg(writer: io::buf_writer, color: u8) {
    ret set_color(writer, '4' as u8, color);
}

// Local Variables:
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>libstd: Long lines<commit_after>/*
Module: term

Simple ANSI color library
*/

import core::option;

// TODO: Windows support.

/* Const: color_black */
const color_black: u8 = 0u8;
/* Const: color_red */
const color_red: u8 = 1u8;
/* Const: color_green */
const color_green: u8 = 2u8;
/* Const: color_yellow */
const color_yellow: u8 = 3u8;
/* Const: color_blue */
const color_blue: u8 = 4u8;
/* Const: color_magenta */
const color_magenta: u8 = 5u8;
/* Const: color_cyan */
const color_cyan: u8 = 6u8;
/* Const: color_light_gray */
const color_light_gray: u8 = 7u8;
/* Const: color_light_grey */
const color_light_grey: u8 = 7u8;
/* Const: color_dark_gray */
const color_dark_gray: u8 = 8u8;
/* Const: color_dark_grey */
const color_dark_grey: u8 = 8u8;
/* Const: color_bright_red */
const color_bright_red: u8 = 9u8;
/* Const: color_bright_green */
const color_bright_green: u8 = 10u8;
/* Const: color_bright_yellow */
const color_bright_yellow: u8 = 11u8;
/* Const: color_bright_blue */
const color_bright_blue: u8 = 12u8;
/* Const: color_bright_magenta */
const color_bright_magenta: u8 = 13u8;
/* Const: color_bright_cyan */
const color_bright_cyan: u8 = 14u8;
/* Const: color_bright_white */
const color_bright_white: u8 = 15u8;

fn esc(writer: io::buf_writer) { writer.write([0x1bu8, '[' as u8]); }

/*
Function: reset

Reset the foreground and background colors to default
*/
fn reset(writer: io::buf_writer) {
    esc(writer);
    writer.write(['0' as u8, 'm' as u8]);
}

/*
Function: color_supported

Returns true if the terminal supports color
*/
fn color_supported() -> bool {
    let supported_terms = ["xterm-color", "xterm",
                           "screen-bce", "xterm-256color"];
    ret alt generic_os::getenv("TERM") {
          option::some(env) {
            for term: str in supported_terms {
                if str::eq(term, env) { ret true; }
            }
            false
          }
          option::none. { false }
        };
}

fn set_color(writer: io::buf_writer, first_char: u8, color: u8) {
    assert (color < 16u8);
    esc(writer);
    let color = color;
    if color >= 8u8 { writer.write(['1' as u8, ';' as u8]); color -= 8u8; }
    writer.write([first_char, ('0' as u8) + color, 'm' as u8]);
}

/*
Function: fg

Set the foreground color
*/
fn fg(writer: io::buf_writer, color: u8) {
    ret set_color(writer, '3' as u8, color);
}

/*
Function: fg

Set the background color
*/
fn bg(writer: io::buf_writer, color: u8) {
    ret set_color(writer, '4' as u8, color);
}

// Local Variables:
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before><commit_msg>add regression test<commit_after>// run-pass
// edition:2021
// compile-flags: -Zunstable-options

// regression test for https://github.com/rust-lang/rust/pull/85678

#![feature(assert_matches)]

fn main() {
    assert!(matches!((), ()));
    assert_matches!((), ());
}
<|endoftext|>


<commit_before><commit_msg>add benchmarks for orthogonal_nmf<commit_after>#![feature(test)]
extern crate test;

extern crate onmf;

extern crate nalgebra;
use self::nalgebra::{DMat};

extern crate rand;
use rand::{StdRng, SeedableRng};

extern crate num;
use num::{Float};

macro_rules! bench_ortho_nmf {
    ($bencher:expr, $float:ty, $nhidden:expr, $nobserved:expr, $nsamples:expr) => {{
        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng: StdRng = SeedableRng::from_seed(seed);

        let mut ortho_nmf = onmf::OrthogonalNMF::<$float>::init_random01(
            $nhidden, $nobserved, $nsamples, &mut rng);

        let samples = DMat::<$float>::new_ones($nsamples, $nobserved);

        let alpha: $float = 0.1 * 1.01.powi(0);
        $bencher.iter(|| {
            ortho_nmf.iterate(alpha, &samples);
        });
    }}
}

#[bench]
fn bench_ortho_nmf_f64_10_256_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 256, 11);
}

#[bench]
fn bench_ortho_nmf_f32_10_256_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 256, 11);
}

#[bench]
fn bench_ortho_nmf_f64_10_512_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 10, 512, 11);
}

#[bench]
fn bench_ortho_nmf_f32_10_512_11(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 10, 512, 11);
}

#[bench]
fn bench_ortho_nmf_f64_20_512_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f64, 20, 512, 30);
}

#[bench]
fn bench_ortho_nmf_f32_20_512_30(bencher: &mut test::Bencher) {
    bench_ortho_nmf!(bencher, f32, 20, 512, 30);
}
<|endoftext|>


<commit_before><commit_msg>tut-03 uses inputcontroller for smoother input<commit_after><|endoftext|>


<commit_before>/*!

The iteration traits and common implementation

*/

use cmp::{Eq, Ord};

/// A function used to initialize the elements of a sequence
type InitOp<T> = &fn(uint) -> T;

trait BaseIter<A> {
    pure fn each(blk: fn(v: &A) -> bool);
    pure fn size_hint() -> Option<uint>;
}

trait ExtendedIter<A> {
    pure fn eachi(blk: fn(uint, v: &A) -> bool);
    pure fn all(blk: fn(&A) -> bool) -> bool;
    pure fn any(blk: fn(&A) -> bool) -> bool;
    pure fn foldl<B>(+b0: B, blk: fn(&B, &A) -> B) -> B;
    pure fn position(f: fn(A) -> bool) -> Option<uint>;
}

trait EqIter<A:Eq> {
    pure fn contains(x: &A) -> bool;
    pure fn count(x: &A) -> uint;
}

trait Times {
    pure fn times(it: fn() -> bool);
}
trait TimesIx{
    pure fn timesi(it: fn(uint) -> bool);
}

trait CopyableIter<A:Copy> {
    pure fn filter_to_vec(pred: fn(+a: A) -> bool) -> ~[A];
    pure fn map_to_vec<B>(op: fn(+v: A) -> B) -> ~[B];
    pure fn to_vec() -> ~[A];
    pure fn find(p: fn(A) -> bool) -> Option<A>;
}

trait CopyableOrderedIter<A:Copy Ord> {
    pure fn min() -> A;
    pure fn max() -> A;
}

// A trait for sequences that can be by imperatively pushing elements
// onto them.
trait Buildable<A> {
    /**
     * Builds a buildable sequence by calling a provided function with
     * an argument function that pushes an element onto the back of
     * the sequence.
     * This version takes an initial size for the sequence.
     *
     * # Arguments
     *
     * * size - A hint for an initial size of the sequence
     * * builder - A function that will construct the sequence. It recieves
     *             as an argument a function that will push an element
     *             onto the sequence being constructed.
     */
     static pure fn build_sized(size: uint,
                                builder: fn(push: pure fn(+v: A))) -> self;
}

pure fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: fn(uint, v: &A) -> bool) {
    let mut i = 0;
    for self.each |a| {
        if !blk(i, a) { break; }
        i += 1;
    }
}

pure fn all<A,IA:BaseIter<A>>(self: &IA, blk: fn(&A) -> bool) -> bool {
    for self.each |a| {
        if !blk(a) { return false; }
    }
    return true;
}

pure fn any<A,IA:BaseIter<A>>(self: &IA, blk: fn(&A) -> bool) -> bool {
    for self.each |a| {
        if blk(a) { return true; }
    }
    return false;
}

pure fn filter_to_vec<A:Copy,IA:BaseIter<A>>(self: &IA,
                                         prd: fn(+a: A) -> bool) -> ~[A] {
    do vec::build_sized_opt(self.size_hint()) |push| {
        for self.each |a| {
            if prd(*a) { push(*a); }
        }
    }
}

pure fn map_to_vec<A:Copy,B,IA:BaseIter<A>>(self: &IA, op: fn(+v: A) -> B)
    -> ~[B] {
    do vec::build_sized_opt(self.size_hint()) |push| {
        for self.each |a| {
            push(op(*a));
        }
    }
}

pure fn flat_map_to_vec<A:Copy,B:Copy,IA:BaseIter<A>,IB:BaseIter<B>>(
    self: &IA, op: fn(+a: A) -> IB) -> ~[B] {

    do vec::build |push| {
        for self.each |a| {
            for op(*a).each |b| {
                push(*b);
            }
        }
    }
}

pure fn foldl<A,B,IA:BaseIter<A>>(self: &IA, +b0: B, blk: fn(&B, &A) -> B)
    -> B {
    let mut b <- b0;
    for self.each |a| {
        b = blk(&b, a);
    }
    move b
}

pure fn to_vec<A:Copy,IA:BaseIter<A>>(self: &IA) -> ~[A] {
    foldl::<A,~[A],IA>(self, ~[], |r, a| vec::append(copy (*r), ~[*a]))
}

pure fn contains<A:Eq,IA:BaseIter<A>>(self: IA, x: &A) -> bool {
    for self.each |a| {
        if *a == *x { return true; }
    }
    return false;
}

pure fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
    do foldl(self, 0) |count, value| {
        if *value == *x {
            *count + 1
        } else {
            *count
        }
    }
}

pure fn position<A,IA:BaseIter<A>>(self: IA, f: fn(A) -> bool)
    -> Option<uint>
{
    let mut i = 0;
    for self.each |a| {
        if f(*a) { return Some(i); }
        i += 1;
    }
    return None;
}

// note: 'rposition' would only make sense to provide with a bidirectional
// iter interface, such as would provide "reach" in addition to "each". as is,
// it would have to be implemented with foldr, which is too inefficient.

pure fn repeat(times: uint, blk: fn() -> bool) {
    let mut i = 0u;
    while i < times {
        if !blk() { break }
        i += 1u;
    }
}

pure fn min<A:Copy Ord,IA:BaseIter<A>>(self: &IA) -> A {
    match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
        match a {
          &Some(ref a_) if *a_ < *b => {
             *(move a)
          }
          _ => Some(*b)
        }
    } {
        Some(move val) => val,
        None => fail ~"min called on empty iterator"
    }
}

pure fn max<A:Copy Ord,IA:BaseIter<A>>(self: &IA) -> A {
    match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
        match a {
          &Some(ref a_) if *a_ > *b => {
              *(move a)
          }
          _ => Some(*b)
        }
    } {
        Some(move val) => val,
        None => fail ~"max called on empty iterator"
    }
}

pure fn find<A: Copy,IA:BaseIter<A>>(self: IA,
                                     p: fn(A) -> bool) -> Option<A> {
    for self.each |i| {
        if p(*i) { return Some(*i) }
    }
    return None;
}

// Some functions for just building

/**
 * Builds a sequence by calling a provided function with an argument
 * function that pushes an element to the back of a sequence.
 *
 * # Arguments
 *
 * * builder - A function that will construct the sequence. It recieves
 *             as an argument a function that will push an element
 *             onto the sequence being constructed.
 */
#[inline(always)]
pure fn build<A,B: Buildable<A>>(builder: fn(push: pure fn(+v: A))) -> B {
    build_sized(4, builder)
}

/**
 * Builds a sequence by calling a provided function with an argument
 * function that pushes an element to the back of a sequence.
 * This version takes an initial size for the sequence.
 *
 * # Arguments
 *
 * * size - An option, maybe containing initial size of the sequence
 *          to reserve
 * * builder - A function that will construct the sequence. It recieves
 *             as an argument a function that will push an element
 *             onto the sequence being constructed.
 */
#[inline(always)]
pure fn build_sized_opt<A,B: Buildable<A>>(
    size: Option<uint>,
    builder: fn(push: pure fn(+v: A))) -> B {

    build_sized(size.get_default(4), builder)
}

// Functions that combine iteration and building

/// Apply a function to each element of an iterable and return the results
fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: IT, f: fn(T) -> U) -> BU {
    do build_sized_opt(v.size_hint()) |push| {
        for v.each() |elem| {
            push(f(*elem));
        }
    }
}

/**
 * Creates and initializes a generic sequence from a function
 *
 * Creates a generic sequence of size `n_elts` and initializes the elements
 * to the value returned by the function `op`.
 */
pure fn from_fn<T,BT: Buildable<T>>(n_elts: uint, op: InitOp<T>) -> BT {
    do build_sized(n_elts) |push| {
        let mut i: uint = 0u;
        while i < n_elts { push(op(i)); i += 1u; }
    }
}

/**
 * Creates and initializes a generic sequence with some element
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value `t`.
 */
pure fn from_elem<T: Copy,BT: Buildable<T>>(n_elts: uint, t: T) -> BT {
    do build_sized(n_elts) |push| {
        let mut i: uint = 0u;
        while i < n_elts { push(t); i += 1u; }
    }
}

/// Appending two generic sequences
#[inline(always)]
pure fn append<T: Copy,IT: BaseIter<T>,BT: Buildable<T>>(
    lhs: IT, rhs: IT) -> BT {
    let size_opt = lhs.size_hint().chain_ref(
        |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2));
    do build_sized_opt(size_opt) |push| {
        for lhs.each |x| { push(*x); }
        for rhs.each |x| { push(*x); }
    }
}

/// Copies a generic sequence, possibly converting it to a different
/// type of sequence.
#[inline(always)]
pure fn copy_seq<T: Copy,IT: BaseIter<T>,BT: Buildable<T>>(
    v: IT) -> BT {
    do build_sized_opt(v.size_hint()) |push| {
        for v.each |x| { push(*x); }
    }
}
<commit_msg>Finish demoding iter: from_elem, copy_seq, map, append<commit_after>/*!

The iteration traits and common implementation

*/

use cmp::{Eq, Ord};

/// A function used to initialize the elements of a sequence
type InitOp<T> = &fn(uint) -> T;

trait BaseIter<A> {
    pure fn each(blk: fn(v: &A) -> bool);
    pure fn size_hint() -> Option<uint>;
}

trait ExtendedIter<A> {
    pure fn eachi(blk: fn(uint, v: &A) -> bool);
    pure fn all(blk: fn(&A) -> bool) -> bool;
    pure fn any(blk: fn(&A) -> bool) -> bool;
    pure fn foldl<B>(+b0: B, blk: fn(&B, &A) -> B) -> B;
    pure fn position(f: fn(A) -> bool) -> Option<uint>;
}

trait EqIter<A:Eq> {
    pure fn contains(x: &A) -> bool;
    pure fn count(x: &A) -> uint;
}

trait Times {
    pure fn times(it: fn() -> bool);
}
trait TimesIx{
    pure fn timesi(it: fn(uint) -> bool);
}

trait CopyableIter<A:Copy> {
    pure fn filter_to_vec(pred: fn(+a: A) -> bool) -> ~[A];
    pure fn map_to_vec<B>(op: fn(+v: A) -> B) -> ~[B];
    pure fn to_vec() -> ~[A];
    pure fn find(p: fn(A) -> bool) -> Option<A>;
}

trait CopyableOrderedIter<A:Copy Ord> {
    pure fn min() -> A;
    pure fn max() -> A;
}

// A trait for sequences that can be by imperatively pushing elements
// onto them.
trait Buildable<A> {
    /**
     * Builds a buildable sequence by calling a provided function with
     * an argument function that pushes an element onto the back of
     * the sequence.
     * This version takes an initial size for the sequence.
     *
     * # Arguments
     *
     * * size - A hint for an initial size of the sequence
     * * builder - A function that will construct the sequence. It recieves
     *             as an argument a function that will push an element
     *             onto the sequence being constructed.
     */
     static pure fn build_sized(size: uint,
                                builder: fn(push: pure fn(+v: A))) -> self;
}

pure fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: fn(uint, v: &A) -> bool) {
    let mut i = 0;
    for self.each |a| {
        if !blk(i, a) { break; }
        i += 1;
    }
}

pure fn all<A,IA:BaseIter<A>>(self: &IA, blk: fn(&A) -> bool) -> bool {
    for self.each |a| {
        if !blk(a) { return false; }
    }
    return true;
}

pure fn any<A,IA:BaseIter<A>>(self: &IA, blk: fn(&A) -> bool) -> bool {
    for self.each |a| {
        if blk(a) { return true; }
    }
    return false;
}

pure fn filter_to_vec<A:Copy,IA:BaseIter<A>>(self: &IA,
                                         prd: fn(+a: A) -> bool) -> ~[A] {
    do vec::build_sized_opt(self.size_hint()) |push| {
        for self.each |a| {
            if prd(*a) { push(*a); }
        }
    }
}

pure fn map_to_vec<A:Copy,B,IA:BaseIter<A>>(self: &IA, op: fn(+v: A) -> B)
    -> ~[B] {
    do vec::build_sized_opt(self.size_hint()) |push| {
        for self.each |a| {
            push(op(*a));
        }
    }
}

pure fn flat_map_to_vec<A:Copy,B:Copy,IA:BaseIter<A>,IB:BaseIter<B>>(
    self: &IA, op: fn(+a: A) -> IB) -> ~[B] {

    do vec::build |push| {
        for self.each |a| {
            for op(*a).each |b| {
                push(*b);
            }
        }
    }
}

pure fn foldl<A,B,IA:BaseIter<A>>(self: &IA, +b0: B, blk: fn(&B, &A) -> B)
    -> B {
    let mut b <- b0;
    for self.each |a| {
        b = blk(&b, a);
    }
    move b
}

pure fn to_vec<A:Copy,IA:BaseIter<A>>(self: &IA) -> ~[A] {
    foldl::<A,~[A],IA>(self, ~[], |r, a| vec::append(copy (*r), ~[*a]))
}

pure fn contains<A:Eq,IA:BaseIter<A>>(self: IA, x: &A) -> bool {
    for self.each |a| {
        if *a == *x { return true; }
    }
    return false;
}

pure fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
    do foldl(self, 0) |count, value| {
        if *value == *x {
            *count + 1
        } else {
            *count
        }
    }
}

pure fn position<A,IA:BaseIter<A>>(self: IA, f: fn(A) -> bool)
    -> Option<uint>
{
    let mut i = 0;
    for self.each |a| {
        if f(*a) { return Some(i); }
        i += 1;
    }
    return None;
}

// note: 'rposition' would only make sense to provide with a bidirectional
// iter interface, such as would provide "reach" in addition to "each". as is,
// it would have to be implemented with foldr, which is too inefficient.

pure fn repeat(times: uint, blk: fn() -> bool) {
    let mut i = 0u;
    while i < times {
        if !blk() { break }
        i += 1u;
    }
}

pure fn min<A:Copy Ord,IA:BaseIter<A>>(self: &IA) -> A {
    match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
        match a {
          &Some(ref a_) if *a_ < *b => {
             *(move a)
          }
          _ => Some(*b)
        }
    } {
        Some(move val) => val,
        None => fail ~"min called on empty iterator"
    }
}

pure fn max<A:Copy Ord,IA:BaseIter<A>>(self: &IA) -> A {
    match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
        match a {
          &Some(ref a_) if *a_ > *b => {
              *(move a)
          }
          _ => Some(*b)
        }
    } {
        Some(move val) => val,
        None => fail ~"max called on empty iterator"
    }
}

pure fn find<A: Copy,IA:BaseIter<A>>(self: IA,
                                     p: fn(A) -> bool) -> Option<A> {
    for self.each |i| {
        if p(*i) { return Some(*i) }
    }
    return None;
}

// Some functions for just building

/**
 * Builds a sequence by calling a provided function with an argument
 * function that pushes an element to the back of a sequence.
 *
 * # Arguments
 *
 * * builder - A function that will construct the sequence. It recieves
 *             as an argument a function that will push an element
 *             onto the sequence being constructed.
 */
#[inline(always)]
pure fn build<A,B: Buildable<A>>(builder: fn(push: pure fn(+v: A))) -> B {
    build_sized(4, builder)
}

/**
 * Builds a sequence by calling a provided function with an argument
 * function that pushes an element to the back of a sequence.
 * This version takes an initial size for the sequence.
 *
 * # Arguments
 *
 * * size - An option, maybe containing initial size of the sequence
 *          to reserve
 * * builder - A function that will construct the sequence. It recieves
 *             as an argument a function that will push an element
 *             onto the sequence being constructed.
 */
#[inline(always)]
pure fn build_sized_opt<A,B: Buildable<A>>(
    size: Option<uint>,
    builder: fn(push: pure fn(+v: A))) -> B {

    build_sized(size.get_default(4), builder)
}

// Functions that combine iteration and building

/// Apply a function to each element of an iterable and return the results
fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: &IT, f: fn(&T) -> U) -> BU {
    do build_sized_opt(v.size_hint()) |push| {
        for v.each() |elem| {
            push(f(elem));
        }
    }
}

/**
 * Creates and initializes a generic sequence from a function
 *
 * Creates a generic sequence of size `n_elts` and initializes the elements
 * to the value returned by the function `op`.
 */
pure fn from_fn<T,BT: Buildable<T>>(n_elts: uint, op: InitOp<T>) -> BT {
    do build_sized(n_elts) |push| {
        let mut i: uint = 0u;
        while i < n_elts { push(op(i)); i += 1u; }
    }
}

/**
 * Creates and initializes a generic sequence with some element
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value `t`.
 */
pure fn from_elem<T: Copy,BT: Buildable<T>>(n_elts: uint, +t: T) -> BT {
    do build_sized(n_elts) |push| {
        let mut i: uint = 0;
        while i < n_elts { push(t); i += 1; }
    }
}

/// Appending two generic sequences
#[inline(always)]
pure fn append<T: Copy,IT: BaseIter<T>,BT: Buildable<T>>(
    lhs: &IT, rhs: &IT) -> BT {
    let size_opt = lhs.size_hint().chain_ref(
        |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2));
    do build_sized_opt(size_opt) |push| {
        for lhs.each |x| { push(*x); }
        for rhs.each |x| { push(*x); }
    }
}

/// Copies a generic sequence, possibly converting it to a different
/// type of sequence.
#[inline(always)]
pure fn copy_seq<T: Copy,IT: BaseIter<T>,BT: Buildable<T>>(
    v: &IT) -> BT {
    do build_sized_opt(v.size_hint()) |push| {
        for v.each |x| { push(*x); }
    }
}
<|endoftext|>


<commit_before>#[crate_id = "github.com/musitdev/rust-portmidi#portmidi:0.1"];
#[comment = "PortMidi binding for Rust"];
#[license = "MIT"];
#[crate_type = "lib"];
#[crate_type = "dylib"];

///  build : rustpkg build portmidi
///  test : rustpkg test portmidi

//extern mod extra;
extern mod extra;  //= "extra#0.10-pre"

pub mod midi;
pub mod time;
pub mod util;

<commit_msg>update for serialize lib change<commit_after>#[crate_id = "github.com/musitdev/rust-portmidi#portmidi:0.1"];
#[comment = "PortMidi binding for Rust"];
#[license = "MIT"];
#[crate_type = "lib"];
#[crate_type = "dylib"];

///  build : rustpkg build portmidi
///  test : rustpkg test portmidi

//extern mod extra;
extern mod extra;  //= "extra#0.10-pre"
extern mod serialize;

pub mod midi;
pub mod time;
pub mod util;

<|endoftext|>


<commit_before><commit_msg>Add the m.server_notice* message type.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix Disable/Enable in systemd::dbus I need to remember that systemd's dbus only accepts unit names rather than paths<commit_after><|endoftext|>


<commit_before><commit_msg>Added pair_of_pairs example<commit_after>/*

PAIR OF PAIRS

In this example we will try to solve the following problem:

   You are a secret MIB agent trying to detect activity of 4 criminal aliens.
   The aliens are of species that live in pairs and die if separated by 10m.
   You know that the 4 criminal aliens met each other at some point,
   but not when or where.

   A super computer is monitoring all the people in a city.
   Each person has a unique identity.
   Unfortunately, the computer's AI refuses to collaborate of ethical reasons,
   and the super computer can therefore only tell you yes/no questions.

   If the city contains N people, find all possible meetups of pairs.

   Notice that a person can not meet itself, and even if the alien species
   can time travel they always occur in the same pair.

Using this library, we can construct a discrete space that contains all
combinations of pairs. Not only can we get all pairs of up to N objects,
but we can also construct a space containing pair of pairs.

We simply create a variable of type `Pair<Of<Pair<Data>>>` and call
`Construct::new()` to create it.

The Rust compiler can now assist you solving rest of the task.

For every space, there is a dimension type and a position type.
The dimension type is needed to control the size of the space.
In our case the dimension type is a number N.
The position type is a structure that describes the data within the space.

Discrete spaces have the property that each number from 0 up to the size
corresponds to position within the space. It is the information inside
the position we are interested in, because plain numbers are meaningless.
The `ToPos` trait converts from a number to the position structure.

By computing the size of the space and iterating through every number,
we can convert it to a position and then do filtering based on some criteria.
In our case we can filter out any meetups between pairs where one person
is in both pairs.

For example, for 150 people there are 61 332 125 possible meetups.

*/

extern crate discrete;

use discrete::{ Count, Construct, Pair, Of, Data, ToPos };

fn main() {
    let pair_of_pairs: Pair<Of<Pair<Data>>> = Construct::new();
    let n = 150;
    let count = pair_of_pairs.count(n);
    println!("count {:?}", count);
    let mut pos: ((usize, usize), (usize, usize)) = ((0, 0), (0, 0));
    let mut res_count = 0;
    for x in 0..count {
        pair_of_pairs.to_pos(n, x, (&mut pos.0, &mut pos.1));
        if (pos.0).0 == (pos.1).0
        || (pos.0).0 == (pos.1).1
        || (pos.0).1 == (pos.1).0 {
            // println!("anomaly {:?}", pos)
        } else {
            // println!("{:?}", pos);
            res_count += 1;
        }
    }
    println!("{:?} results", res_count);
}
<|endoftext|>


<commit_before>// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Representation and calculation of movement within a view.

use std::cmp::max;

use selection::{Affinity, HorizPos, Selection, SelRegion};
use view::View;
use word_boundaries::WordCursor;
use xi_rope::rope::{LinesMetric, Rope};
use xi_rope::tree::Cursor;

/// The specification of a movement.
#[derive(Clone, Copy)]
pub enum Movement {
    /// Move to the left by one grapheme cluster.
    Left,
    /// Move to the right by one grapheme cluster.
    Right,
    /// Move to the left by one word.
    LeftWord,
    /// Move to the right by one word.
    RightWord,
    /// Move to left end of visible line.
    LeftOfLine,
    /// Move to right end of visible line.
    RightOfLine,
    /// Move up one visible line.
    Up,
    /// Move down one visible line.
    Down,
    /// Move up one viewport height.
    UpPage,
    /// Move down one viewport height.
    DownPage,
    /// Move to the start of the text line.
    StartOfParagraph,
    /// Move to the end of the text line.
    EndOfParagraph,
    /// Move to the start of the document.
    StartOfDocument,
    /// Move to the end of the document
    EndOfDocument,
}

/// Compute movement based on vertical motion by the given number of lines.
///
/// Note: in non-exceptional cases, this function preserves the `horiz`
/// field of the selection region.
fn vertical_motion(r: &SelRegion, view: &View, text: &Rope, line_delta: isize,
    modify: bool) -> (usize, Option<HorizPos>)
{
    // The active point of the selection
    let active = if modify {
        r.end
    } else if line_delta < 0 {
        r.min()
    } else {
        r.max()
    };
    let col = if let Some(col) = r.horiz {
        col
    } else {
        view.offset_to_line_col(text, active).1
    };
    // This code is quite careful to avoid integer overflow.
    // TODO: write tests to verify
    let line = view.line_of_offset(text, active);
    if line_delta < 0 && (-line_delta as usize) > line {
        return (0, Some(col));
    }
    let line = if line_delta < 0 {
        line - (-line_delta as usize)
    } else {
        line.saturating_add(line_delta as usize)
    };
    let n_lines = view.line_of_offset(text, text.len());
    if line > n_lines {
        return (text.len(), Some(col));
    }
    let new_offset = view.line_col_to_offset(text, line, col);
    (new_offset, Some(col))
}

/// Computes the actual desired amount of scrolling (generally slightly
/// less than the height of the viewport, to allow overlap).
fn scroll_height(view: &View) -> isize {
    max(view.scroll_height() as isize - 2, 1)
}

/// Compute the result of movement on one selection region.

fn region_movement(m: Movement, r: &SelRegion, view: &View, text: &Rope, modify: bool)
    -> (usize, Option<HorizPos>)
{
    match m {
        Movement::Left => {
            if r.is_caret() || modify {
                if let Some(offset) = text.prev_grapheme_offset(r.end) {
                    (offset, None)
                } else {
                    (0, r.horiz)
                }
            } else {
                (r.min(), None)
            }
        }
        Movement::Right => {
            if r.is_caret() || modify {
                if let Some(offset) = text.next_grapheme_offset(r.end) {
                    (offset, None)
                } else {
                    (r.end, r.horiz)
                }
            } else {
                (r.max(), None)
            }
        }
        Movement::LeftWord => {
            let mut word_cursor = WordCursor::new(text, r.end);
            let offset = word_cursor.prev_boundary().unwrap_or(0);
            (offset, None)
        }
        Movement::RightWord => {
            let mut word_cursor = WordCursor::new(text, r.end);
            let offset = word_cursor.next_boundary().unwrap_or_else(|| text.len());
            (offset, None)
        }
        Movement::LeftOfLine => {
            let line = view.line_of_offset(text, r.end);
            let offset = view.offset_of_line(text, line);
            (offset, None)
        }
        Movement::RightOfLine => {
            let line = view.line_of_offset(text, r.end);
            let mut offset = text.len();

            // calculate end of line
            let next_line_offset = view.offset_of_line(text, line + 1);
            if line < view.line_of_offset(text, offset) {
                if let Some(prev) = text.prev_grapheme_offset(next_line_offset) {
                    offset = prev;
                }
            }
            (offset, None)
        }
        Movement::Up => vertical_motion(r, view, text, -1, modify),
        Movement::Down => vertical_motion(r, view, text, 1, modify),
        Movement::StartOfParagraph => {
            // Note: TextEdit would start at modify ? r.end : r.min()
            let mut cursor = Cursor::new(&text, r.end);
            let offset = cursor.prev::<LinesMetric>().unwrap_or(0);
            (offset, None)
        }
        Movement::EndOfParagraph => {
            // Note: TextEdit would start at modify ? r.end : r.max()
            let mut offset = r.end;
            let mut cursor = Cursor::new(&text, offset);
            if let Some(next_para_offset) = cursor.next::<LinesMetric>() {
                if cursor.is_boundary::<LinesMetric>() {
                    if let Some(eol) = text.prev_grapheme_offset(next_para_offset) {
                        offset = eol;
                    }
                }
            }
            (offset, None)
        }
        Movement::UpPage => vertical_motion(r, view, text, -scroll_height(view), modify),
        Movement::DownPage => vertical_motion(r, view, text, scroll_height(view), modify),
        Movement::StartOfDocument => (0, None),
        Movement::EndOfDocument => (text.len(), None),
    }
}

/// Compute a new selection by applying a movement to an existing selection.
///
/// In a multi-region selection, this function applies the movement to each
/// region in the selection, and returns the union of the results.
///
/// If `modify` is `true`, the selections are modified, otherwise the results
/// of individual region movements become carets.
pub fn selection_movement(m: Movement, s: &Selection, view: &View, text: &Rope,
    modify: bool) -> Selection
{
    let mut result = Selection::new();
    for r in s.iter() {
        let (offset, horiz) = region_movement(m, r, view, text, modify);
        let new_region = SelRegion {
            start: if modify { r.start } else { offset },
            end: offset,
            horiz: horiz,
            affinity: Affinity::default(),
        };
        result.add_region(new_region);
    }
    result
}
<commit_msg>Address review comments<commit_after>// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Representation and calculation of movement within a view.

use std::cmp::max;

use selection::{Affinity, HorizPos, Selection, SelRegion};
use view::View;
use word_boundaries::WordCursor;
use xi_rope::rope::{LinesMetric, Rope};
use xi_rope::tree::Cursor;

/// The specification of a movement.
#[derive(Clone, Copy)]
pub enum Movement {
    /// Move to the left by one grapheme cluster.
    Left,
    /// Move to the right by one grapheme cluster.
    Right,
    /// Move to the left by one word.
    LeftWord,
    /// Move to the right by one word.
    RightWord,
    /// Move to left end of visible line.
    LeftOfLine,
    /// Move to right end of visible line.
    RightOfLine,
    /// Move up one visible line.
    Up,
    /// Move down one visible line.
    Down,
    /// Move up one viewport height.
    UpPage,
    /// Move down one viewport height.
    DownPage,
    /// Move to the start of the text line.
    StartOfParagraph,
    /// Move to the end of the text line.
    EndOfParagraph,
    /// Move to the start of the document.
    StartOfDocument,
    /// Move to the end of the document
    EndOfDocument,
}

/// Compute movement based on vertical motion by the given number of lines.
///
/// Note: in non-exceptional cases, this function preserves the `horiz`
/// field of the selection region.
fn vertical_motion(r: &SelRegion, view: &View, text: &Rope, line_delta: isize,
    modify: bool) -> (usize, Option<HorizPos>)
{
    // The active point of the selection
    let active = if modify {
        r.end
    } else if line_delta < 0 {
        r.min()
    } else {
        r.max()
    };
    let col = if let Some(col) = r.horiz {
        col
    } else {
        view.offset_to_line_col(text, active).1
    };
    // This code is quite careful to avoid integer overflow.
    // TODO: write tests to verify
    let line = view.line_of_offset(text, active);
    if line_delta < 0 && (-line_delta as usize) > line {
        return (0, Some(col));
    }
    let line = if line_delta < 0 {
        line - (-line_delta as usize)
    } else {
        line.saturating_add(line_delta as usize)
    };
    let n_lines = view.line_of_offset(text, text.len());
    if line > n_lines {
        return (text.len(), Some(col));
    }
    let new_offset = view.line_col_to_offset(text, line, col);
    (new_offset, Some(col))
}

/// When paging through a file, the number of lines from the previous page
/// that will also be visible in the next.
const SCROLL_OVERLAP: isize = 2;

/// Computes the actual desired amount of scrolling (generally slightly
/// less than the height of the viewport, to allow overlap).
fn scroll_height(view: &View) -> isize {
    max(view.scroll_height() as isize - SCROLL_OVERLAP, 1)
}

/// Compute the result of movement on one selection region.
fn region_movement(m: Movement, r: &SelRegion, view: &View, text: &Rope, modify: bool)
    -> (usize, Option<HorizPos>)
{
    match m {
        Movement::Left => {
            if r.is_caret() || modify {
                if let Some(offset) = text.prev_grapheme_offset(r.end) {
                    (offset, None)
                } else {
                    (0, r.horiz)
                }
            } else {
                (r.min(), None)
            }
        }
        Movement::Right => {
            if r.is_caret() || modify {
                if let Some(offset) = text.next_grapheme_offset(r.end) {
                    (offset, None)
                } else {
                    (r.end, r.horiz)
                }
            } else {
                (r.max(), None)
            }
        }
        Movement::LeftWord => {
            let mut word_cursor = WordCursor::new(text, r.end);
            let offset = word_cursor.prev_boundary().unwrap_or(0);
            (offset, None)
        }
        Movement::RightWord => {
            let mut word_cursor = WordCursor::new(text, r.end);
            let offset = word_cursor.next_boundary().unwrap_or_else(|| text.len());
            (offset, None)
        }
        Movement::LeftOfLine => {
            let line = view.line_of_offset(text, r.end);
            let offset = view.offset_of_line(text, line);
            (offset, None)
        }
        Movement::RightOfLine => {
            let line = view.line_of_offset(text, r.end);
            let mut offset = text.len();

            // calculate end of line
            let next_line_offset = view.offset_of_line(text, line + 1);
            if line < view.line_of_offset(text, offset) {
                if let Some(prev) = text.prev_grapheme_offset(next_line_offset) {
                    offset = prev;
                }
            }
            (offset, None)
        }
        Movement::Up => vertical_motion(r, view, text, -1, modify),
        Movement::Down => vertical_motion(r, view, text, 1, modify),
        Movement::StartOfParagraph => {
            // Note: TextEdit would start at modify ? r.end : r.min()
            let mut cursor = Cursor::new(&text, r.end);
            let offset = cursor.prev::<LinesMetric>().unwrap_or(0);
            (offset, None)
        }
        Movement::EndOfParagraph => {
            // Note: TextEdit would start at modify ? r.end : r.max()
            let mut offset = r.end;
            let mut cursor = Cursor::new(&text, offset);
            if let Some(next_para_offset) = cursor.next::<LinesMetric>() {
                if cursor.is_boundary::<LinesMetric>() {
                    if let Some(eol) = text.prev_grapheme_offset(next_para_offset) {
                        offset = eol;
                    }
                }
            }
            (offset, None)
        }
        Movement::UpPage => vertical_motion(r, view, text, -scroll_height(view), modify),
        Movement::DownPage => vertical_motion(r, view, text, scroll_height(view), modify),
        Movement::StartOfDocument => (0, None),
        Movement::EndOfDocument => (text.len(), None),
    }
}

/// Compute a new selection by applying a movement to an existing selection.
///
/// In a multi-region selection, this function applies the movement to each
/// region in the selection, and returns the union of the results.
///
/// If `modify` is `true`, the selections are modified, otherwise the results
/// of individual region movements become carets.
pub fn selection_movement(m: Movement, s: &Selection, view: &View, text: &Rope,
    modify: bool) -> Selection
{
    let mut result = Selection::new();
    for r in s.iter() {
        let (offset, horiz) = region_movement(m, r, view, text, modify);
        let new_region = SelRegion {
            start: if modify { r.start } else { offset },
            end: offset,
            horiz: horiz,
            affinity: Affinity::default(),
        };
        result.add_region(new_region);
    }
    result
}
<|endoftext|>


<commit_before><commit_msg>Added mock action (only for test configutation)<commit_after><|endoftext|>


<commit_before><commit_msg>Docs: Add code to generate #derive(AddAssign) docs<commit_after>#![allow(dead_code)]
#[macro_use]
extern crate derive_more;

#[derive(AddAssign)]
struct MyInts(i32, i32);

#[derive(AddAssign)]
struct Point2D {
    x: i32,
    y: i32,
}
<|endoftext|>


<commit_before><commit_msg>Add chain iterator test<commit_after>use anyhow::{anyhow, Error};

fn error() -> Error {
    anyhow!(0).context(1).context(2).context(3)
}

#[test]
fn test_iter() {
    let e = error();
    let mut chain = e.chain();
    assert_eq!("3", chain.next().unwrap().to_string());
    assert_eq!("2", chain.next().unwrap().to_string());
    assert_eq!("1", chain.next().unwrap().to_string());
    assert_eq!("0", chain.next().unwrap().to_string());
    assert!(chain.next().is_none());
    assert!(chain.next_back().is_none());
}

#[test]
fn test_rev() {
    let e = error();
    let mut chain = e.chain().rev();
    assert_eq!("0", chain.next().unwrap().to_string());
    assert_eq!("1", chain.next().unwrap().to_string());
    assert_eq!("2", chain.next().unwrap().to_string());
    assert_eq!("3", chain.next().unwrap().to_string());
    assert!(chain.next().is_none());
    assert!(chain.next_back().is_none());
}

#[test]
fn test_len() {
    let e = error();
    let mut chain = e.chain();
    assert_eq!(4, chain.len());
    assert_eq!("3", chain.next().unwrap().to_string());
    assert_eq!(3, chain.len());
    assert_eq!("0", chain.next_back().unwrap().to_string());
    assert_eq!(2, chain.len());
    assert_eq!("2", chain.next().unwrap().to_string());
    assert_eq!(1, chain.len());
    assert_eq!("1", chain.next_back().unwrap().to_string());
    assert_eq!(0, chain.len());
    assert!(chain.next().is_none());
}
<|endoftext|>


<commit_before><commit_msg>generics struct<commit_after><|endoftext|>