<commit_before>use general::{Interface, Security, ConnectionState};

/// Get a list of Network Manager connections.
///
/// # Examples
///
/// ```
/// let connections = network_manager::connection::list().unwrap();
/// println!("{:?}", connections);
/// ```
pub fn list() -> Result<Vec<Connection>, String> {
    // Get list of connections

    let connection1 = Connection {
        name: "resin_io".to_owned(),
        ssid: "resin_io".to_owned(),
        uuid: "3c8e6e8b-b895-4b07-97a5-bbc192c3b436".to_owned(),
        device: "wlp4s0".to_owned(),
        path: "/org/freedesktop/NetworkManager/ActiveConnection/187".to_owned(),
        interface: Interface::WiFi,
        security: Security::WPA2,
        state: ConnectionState::Activated,
    };

    let connection2 = Connection {
        name: "docker0".to_owned(),
        ssid: String::new(),
        uuid: "3c8e6e8b-b895-4b07-97a5-bbc192c3b436".to_owned(),
        device: "docker0".to_owned(),
        path: "/org/freedesktop/NetworkManager/ActiveConnection/180".to_owned(),
        interface: Interface::Bridge,
        security: Security::None,
        state: ConnectionState::Deactivated,
    };

    Ok(vec![connection1, connection2])
}

/// Creates a Network Manager connection.
///
/// # Examples
///
/// ```
/// let connection = network_manager::connection::create(
///     "resin_io",
///     network_manager::general::Interface::WiFi,
///     network_manager::general::Security::WPA2,
///     "super_secret_passphase"
///     ).unwrap();
/// println!("{:?}", connection);
/// ```
pub fn create(s: &str, i: Interface, sc: Security, p: &str) -> Result<Connection, String> {
    // Create a connection
    // Get the connection
    // Return the connection

    let new_connection = Connection {
        name: "resin_io".to_owned(),
        ssid: "resin_io".to_owned(),
        uuid: "3c8e6e8b-b895-4b07-97a5-bbc192c3b436".to_owned(),
        device: "wlp4s0".to_owned(),
        path: "/org/freedesktop/NetworkManager/ActiveConnection/187".to_owned(),
        interface: Interface::WiFi,
        security: Security::WPA2,
        state: ConnectionState::Activated,
    };

    Ok(new_connection)
}

/// Deletes a Network Manager connection.
///
/// # Examples
///
/// ```
/// let connections = network_manager::connection::list().unwrap();
/// let connection = &connections[0];
/// network_manager::connection::delete(connection).unwrap();
/// ```
pub fn delete(c: &Connection) -> Result<(), String> {
    // Delete connection

    Ok(())
}

/// Enables a Network Manager connection.
///
/// # Examples
///
/// ```
/// let connections = network_manager::connection::list().unwrap();
/// let connection = &connections[0];
/// let state = network_manager::connection::enable(connection, 10).unwrap();
/// println!("{:?}", state);
/// ```
pub fn enable(c: &Connection, t: i32) -> Result<ConnectionState, String> {
    // Enable connection

    if t != 0 {
        // Wait until the connection state is 'Activated' or
        // until the time has elapsed
    }

    Ok(ConnectionState::Activated)
}

/// Disables a Network Manager connection.
///
/// # Examples
///
/// ```
/// let connections = network_manager::connection::list().unwrap();
/// let connection = &connections[0];
/// let state = network_manager::connection::disable(connection, 10).unwrap();
/// println!("{:?}", state);
/// ```
pub fn disable(c: &Connection, t: i32) -> Result<ConnectionState, String> {
    // Disable connection

    if t != 0 {
        // Wait until the connection state is 'Deactivated' or
        // until the time has elapsed
    }

    Ok(ConnectionState::Deactivated)
}

#[derive(Debug)]
pub struct Connection {
    name: String,
    ssid: String,
    uuid: String,
    device: String,
    path: String,
    interface: Interface,
    security: Security,
    state: ConnectionState,
}
<commit_msg>List connections function<commit_after>extern crate dbus;

use std::str;
use general::{Interface, Security, ConnectionState};

const NM_SERVICE: &'static str = "org.freedesktop.NetworkManager";
const NM_SETTINGS_PATH: &'static str = "/org/freedesktop/NetworkManager/Settings";
const NM_SETTINGS_INTERFACE: &'static str = "org.freedesktop.NetworkManager.Settings";
const NM_CONNECTION_INTERFACE: &'static str = "org.freedesktop.NetworkManager.Settings.Connection";

/// Get a list of Network Manager connections.
///
/// # Examples
///
/// ```
/// let connections = network_manager::connection::list().unwrap();
/// println!("{:?}", connections);
/// ```
pub fn list() -> Result<Vec<Connection>, String> {
    let message = dbus_message!(NM_SERVICE,
                                NM_SETTINGS_PATH,
                                NM_SETTINGS_INTERFACE,
                                "ListConnections");
    let response = dbus_connect!(message).unwrap();
    let paths: dbus::arg::Array<dbus::Path, _> = response.get1().unwrap();
    let connections = paths.map(|p| get(p).unwrap()).collect::<Vec<Connection>>();

    Ok(connections)
}

/// Creates a Network Manager connection.
///
/// # Examples
///
/// ```
/// let connection = network_manager::connection::create(
///     "resin_io",
///     network_manager::general::Interface::WiFi,
///     network_manager::general::Security::WPA2,
///     "super_secret_passphase"
///     ).unwrap();
/// println!("{:?}", connection);
/// ```
pub fn create(s: &str, i: Interface, sc: Security, p: &str) -> Result<Connection, String> {
    // Create a connection
    // Get the connection
    // Return the connection

    let connection1 = Connection {
        path: "/org/freedesktop/NetworkManager/ActiveConnection/187".to_string(),
        id: "resin_io".to_string(),
        uuid: "3c8e6e8b-b895-4b07-97a5-bbc192c3b436".to_string(),
        ssid: "resin_io".to_string(), /* device: "wlp4s0".to_string(),
                                       * interface: Interface::WiFi,
                                       * security: Security::WPA2,
                                       * state: ConnectionState::Activated, */
    };

    Ok(connection1)
}

/// Deletes a Network Manager connection.
///
/// # Examples
///
/// ```
/// let connections = network_manager::connection::list().unwrap();
/// let connection = &connections[0];
/// network_manager::connection::delete(connection).unwrap();
/// ```
pub fn delete(c: &Connection) -> Result<(), String> {
    // Delete connection

    Ok(())
}

/// Enables a Network Manager connection.
///
/// # Examples
///
/// ```
/// let connections = network_manager::connection::list().unwrap();
/// let connection = &connections[0];
/// let state = network_manager::connection::enable(connection, 10).unwrap();
/// println!("{:?}", state);
/// ```
pub fn enable(c: &Connection, t: i32) -> Result<ConnectionState, String> {
    // Enable connection

    if t != 0 {
        // Wait until the connection state is 'Activated' or
        // until the time has elapsed
    }

    Ok(ConnectionState::Activated)
}

/// Disables a Network Manager connection.
///
/// # Examples
///
/// ```
/// let connections = network_manager::connection::list().unwrap();
/// let connection = &connections[0];
/// let state = network_manager::connection::disable(connection, 10).unwrap();
/// println!("{:?}", state);
/// ```
pub fn disable(c: &Connection, t: i32) -> Result<ConnectionState, String> {
    // Disable connection

    if t != 0 {
        // Wait until the connection state is 'Deactivated' or
        // until the time has elapsed
    }

    Ok(ConnectionState::Deactivated)
}

fn get(path: dbus::Path) -> Result<Connection, String> {
    let mut connection =
        Connection { path: path.as_cstr().to_str().unwrap().to_string(), ..Default::default() };

    let message = dbus_message!(NM_SERVICE,
                                connection.path.clone(),
                                NM_CONNECTION_INTERFACE,
                                "GetSettings");
    let response = dbus_connect!(message).unwrap();
    let dictionary: dbus::arg::Dict<&str,
                                    dbus::arg::Dict<&str, dbus::arg::Variant<dbus::arg::Iter>, _>,
                                    _> = response.get1().unwrap();

    for (_, v1) in dictionary {
        for (k2, v2) in v1 {
            match k2 {
                "id" => {
                    connection.id = v2.0.clone().get::<&str>().unwrap().to_string();
                }
                "uuid" => {
                    connection.uuid = v2.0.clone().get::<&str>().unwrap().to_string();
                }
                "ssid" => {
                    connection.ssid = str::from_utf8(&v2.0
                            .clone()
                            .get::<dbus::arg::Array<u8, _>>()
                            .unwrap()
                            .collect::<Vec<u8>>())
                        .unwrap()
                        .to_string();
                }
                _ => (),
            }
        }
    }

    Ok(connection)
}

#[derive(Default, Debug)]
pub struct Connection {
    path: String,
    id: String,
    uuid: String,
    ssid: String, /* device: String,
                   * interface: Interface,
                   * security: Security,
                   * state: ConnectionState, */
}
<|endoftext|>


<commit_before>use std::vec;
use std::slice;
use std::borrow::Borrow;
use std::default::Default;
use std::iter::FromIterator;
use std::iter::IntoIterator;
use std::ops::Index;
use std::ops::IndexMut;
use std::ops::Deref;
use std::ops::DerefMut;
use std::cmp::Ordering;
use std::fmt;

use clear::Clear;

pub struct RepeatedField<T> {
    vec: Vec<T>,
    len: usize,
}

impl<T> RepeatedField<T> {
    #[inline]
    fn len(&self) -> usize {
        self.len
    }

    #[inline]
    pub fn clear(&mut self) {
        self.len = 0;
    }
}

impl<T> Clear for RepeatedField<T> {
    #[inline]
    fn clear(&mut self) {
        self.len = 0;
    }
}

impl<T> Default for RepeatedField<T> {
    #[inline]
    fn default() -> RepeatedField<T> {
        RepeatedField {
            vec: Vec::new(),
            len: 0,
        }
    }
}

impl<T> RepeatedField<T> {
    #[inline]
    pub fn new() -> RepeatedField<T> {
        Default::default()
    }

    #[inline]
    pub fn from_vec(vec: Vec<T>) -> RepeatedField<T> {
        let len = vec.len();
        RepeatedField {
            vec: vec,
            len: len,
        }
    }

    #[inline]
    pub fn into_vec(self) -> Vec<T> {
        let mut vec = self.vec;
        vec.truncate(self.len);
        vec
    }

    #[inline]
    pub fn capacity(&self) -> usize {
        self.vec.capacity()
    }

    #[inline]
    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        &mut self.vec
    }

    #[inline]
    pub fn slice<'a>(&'a self, start: usize, end: usize) -> &'a [T] {
        &self.as_ref()[start..end]
    }

    #[inline]
    pub fn slice_mut<'a>(&'a mut self, start: usize, end: usize) -> &'a mut [T] {
        &mut self.as_mut_slice()[start..end]
    }

    #[inline]
    pub fn slice_from<'a>(&'a self, start: usize) -> &'a [T] {
        &self.as_ref()[start..]
    }

    #[inline]
    pub fn slice_from_mut<'a>(&'a mut self, start: usize) -> &'a mut [T] {
        &mut self.as_mut_slice()[start..]
    }

    #[inline]
    pub fn slice_to<'a>(&'a self, end: usize) -> &'a [T] {
        &self.as_ref()[..end]
    }

    #[inline]
    pub fn slice_to_mut<'a>(&'a mut self, end: usize) -> &'a mut [T] {
        &mut self.as_mut_slice()[..end]
    }

    #[inline]
    pub fn split_at<'a>(&'a self, mid: usize) -> (&'a [T], &'a [T]) {
        self.as_ref().split_at(mid)
    }

    #[inline]
    pub fn split_at_mut<'a>(&'a mut self, mid: usize) -> (&'a mut [T], &'a mut [T]) {
        self.as_mut_slice().split_at_mut(mid)
    }

    #[inline]
    pub fn tail<'a>(&'a self) -> &'a [T] {
        &self.as_ref()[1..]
    }

    #[inline]
    pub fn last<'a>(&'a self) -> Option<&'a T> {
        self.as_ref().last()
    }

    #[inline]
    pub fn last_mut<'a>(&'a mut self) -> Option<&'a mut T> {
        self.as_mut_slice().last_mut()
    }

    #[inline]
    pub fn init<'a>(&'a self) -> &'a [T] {
        let s = self.as_ref();
        &s[0..s.len() - 1]
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        if self.len == self.vec.len() {
            self.vec.push(value);
        } else {
            self.vec[self.len] = value;
        }
        self.len += 1;
    }

    #[inline]
    pub fn pop(&mut self) -> Option<T> {
        if self.len == 0 {
            None
        } else {
            self.vec.truncate(self.len);
            self.len -= 1;
            self.vec.pop()
        }
    }

    #[inline]
    pub fn insert(&mut self, index: usize, value: T) {
        assert!(index <= self.len);
        self.vec.insert(index, value);
        self.len += 1;
    }

    #[inline]
    pub fn remove(&mut self, index: usize) -> T {
        assert!(index < self.len);
        self.len -= 1;
        self.vec.remove(index)
    }

    #[inline]
    pub fn truncate(&mut self, len: usize) {
        if self.len > len {
            self.len = len;
        }
    }

    #[inline]
    pub fn reverse(&mut self) {
        self.as_mut_slice().reverse()
    }

    #[inline]
    pub fn into_iter(mut self) -> vec::IntoIter<T> {
        self.vec.truncate(self.len);
        self.vec.into_iter()
    }

    #[inline]
    pub fn iter<'a>(&'a self) -> slice::Iter<'a, T> {
        self.as_ref().iter()
    }

    #[inline]
    pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, T> {
        self.as_mut_slice().iter_mut()
    }

    #[inline]
    pub fn sort_by<F>(&mut self, compare: F) where F: Fn(&T, &T) -> Ordering {
        self.as_mut_slice().sort_by(compare)
    }

    #[inline]
    pub fn as_ptr(&self) -> *const T {
        self.vec.as_ptr()
    }

    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut T {
        self.vec.as_mut_ptr()
    }
}

impl<T : Default+Clear> RepeatedField<T> {
    pub fn push_default<'a>(&'a mut self) -> &'a mut T {
        if self.len == self.vec.len() {
            self.vec.push(Default::default());
        } else {
            self.vec[self.len].clear();
        }
        self.len += 1;
        self.last_mut().unwrap()
    }
}

impl<T : Clone> RepeatedField<T> {
    // TODO: implement to_vec()
    #[inline]
    pub fn from_slice(values: &[T]) -> RepeatedField<T> {
        RepeatedField::from_vec(values.to_vec())
    }
}

impl<T : Clone> Clone for RepeatedField<T> {
    #[inline]
    fn clone(&self) -> RepeatedField<T> {
        RepeatedField {
            vec: self.to_vec(),
            len: self.len(),
        }
    }
}

impl<T> FromIterator<T> for RepeatedField<T> {
    #[inline]
    fn from_iter<I : IntoIterator<Item = T>>(iter: I) -> RepeatedField<T> {
        RepeatedField::from_vec(FromIterator::from_iter(iter))
    }
}

impl<T : PartialEq> PartialEq for RepeatedField<T> {
    #[inline]
    fn eq(&self, other: &RepeatedField<T>) -> bool {
        self.as_ref() == other.as_ref()
    }
}

impl<T : Eq> Eq for RepeatedField<T> {}

impl<T : PartialEq> RepeatedField<T> {
    #[inline]
    pub fn contains(&self, value: &T) -> bool {
        self.as_ref().contains(value)
    }
}

impl<T> AsRef<[T]> for RepeatedField<T> {
    #[inline]
    fn as_ref<'a>(&'a self) -> &'a [T] {
        &self.vec[..self.len]
    }
}

impl<T> Borrow<[T]> for RepeatedField<T> {
    #[inline]
    fn borrow(&self) -> &[T] {
        &self.vec[..self.len]
    }
}

impl<T> Deref for RepeatedField<T> {
    type Target = [T];
    #[inline]
    fn deref(&self) -> &[T] {
        &self.vec[..self.len]
    }
}

impl<T> DerefMut for RepeatedField<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut [T] {
        &mut self.vec[..self.len]
    }
}

impl<T> Index<usize> for RepeatedField<T> {
    type Output = T;

    #[inline]
    fn index<'a>(&'a self, index: usize) -> &'a T {
        &self.as_ref()[index]
    }
}

impl<T> IndexMut<usize> for RepeatedField<T> {
    #[inline]
    fn index_mut<'a>(&'a mut self, index: usize) -> &'a mut T {
        &mut self.as_mut_slice()[index]
    }
}

impl<T : fmt::Debug> fmt::Debug for RepeatedField<T> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.as_ref().fmt(f)
    }
}
<commit_msg>fix RepeatedField.push_default() return value<commit_after>use std::vec;
use std::slice;
use std::borrow::Borrow;
use std::default::Default;
use std::iter::FromIterator;
use std::iter::IntoIterator;
use std::ops::Index;
use std::ops::IndexMut;
use std::ops::Deref;
use std::ops::DerefMut;
use std::cmp::Ordering;
use std::fmt;

use clear::Clear;

pub struct RepeatedField<T> {
    vec: Vec<T>,
    len: usize,
}

impl<T> RepeatedField<T> {
    #[inline]
    fn len(&self) -> usize {
        self.len
    }

    #[inline]
    pub fn clear(&mut self) {
        self.len = 0;
    }
}

impl<T> Clear for RepeatedField<T> {
    #[inline]
    fn clear(&mut self) {
        self.len = 0;
    }
}

impl<T> Default for RepeatedField<T> {
    #[inline]
    fn default() -> RepeatedField<T> {
        RepeatedField {
            vec: Vec::new(),
            len: 0,
        }
    }
}

impl<T> RepeatedField<T> {
    #[inline]
    pub fn new() -> RepeatedField<T> {
        Default::default()
    }

    #[inline]
    pub fn from_vec(vec: Vec<T>) -> RepeatedField<T> {
        let len = vec.len();
        RepeatedField {
            vec: vec,
            len: len,
        }
    }

    #[inline]
    pub fn into_vec(self) -> Vec<T> {
        let mut vec = self.vec;
        vec.truncate(self.len);
        vec
    }

    #[inline]
    pub fn capacity(&self) -> usize {
        self.vec.capacity()
    }

    #[inline]
    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        &mut self.vec[..self.len]
    }

    #[inline]
    pub fn slice<'a>(&'a self, start: usize, end: usize) -> &'a [T] {
        &self.as_ref()[start..end]
    }

    #[inline]
    pub fn slice_mut<'a>(&'a mut self, start: usize, end: usize) -> &'a mut [T] {
        &mut self.as_mut_slice()[start..end]
    }

    #[inline]
    pub fn slice_from<'a>(&'a self, start: usize) -> &'a [T] {
        &self.as_ref()[start..]
    }

    #[inline]
    pub fn slice_from_mut<'a>(&'a mut self, start: usize) -> &'a mut [T] {
        &mut self.as_mut_slice()[start..]
    }

    #[inline]
    pub fn slice_to<'a>(&'a self, end: usize) -> &'a [T] {
        &self.as_ref()[..end]
    }

    #[inline]
    pub fn slice_to_mut<'a>(&'a mut self, end: usize) -> &'a mut [T] {
        &mut self.as_mut_slice()[..end]
    }

    #[inline]
    pub fn split_at<'a>(&'a self, mid: usize) -> (&'a [T], &'a [T]) {
        self.as_ref().split_at(mid)
    }

    #[inline]
    pub fn split_at_mut<'a>(&'a mut self, mid: usize) -> (&'a mut [T], &'a mut [T]) {
        self.as_mut_slice().split_at_mut(mid)
    }

    #[inline]
    pub fn tail<'a>(&'a self) -> &'a [T] {
        &self.as_ref()[1..]
    }

    #[inline]
    pub fn last<'a>(&'a self) -> Option<&'a T> {
        self.as_ref().last()
    }

    #[inline]
    pub fn last_mut<'a>(&'a mut self) -> Option<&'a mut T> {
        self.as_mut_slice().last_mut()
    }

    #[inline]
    pub fn init<'a>(&'a self) -> &'a [T] {
        let s = self.as_ref();
        &s[0..s.len() - 1]
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        if self.len == self.vec.len() {
            self.vec.push(value);
        } else {
            self.vec[self.len] = value;
        }
        self.len += 1;
    }

    #[inline]
    pub fn pop(&mut self) -> Option<T> {
        if self.len == 0 {
            None
        } else {
            self.vec.truncate(self.len);
            self.len -= 1;
            self.vec.pop()
        }
    }

    #[inline]
    pub fn insert(&mut self, index: usize, value: T) {
        assert!(index <= self.len);
        self.vec.insert(index, value);
        self.len += 1;
    }

    #[inline]
    pub fn remove(&mut self, index: usize) -> T {
        assert!(index < self.len);
        self.len -= 1;
        self.vec.remove(index)
    }

    #[inline]
    pub fn truncate(&mut self, len: usize) {
        if self.len > len {
            self.len = len;
        }
    }

    #[inline]
    pub fn reverse(&mut self) {
        self.as_mut_slice().reverse()
    }

    #[inline]
    pub fn into_iter(mut self) -> vec::IntoIter<T> {
        self.vec.truncate(self.len);
        self.vec.into_iter()
    }

    #[inline]
    pub fn iter<'a>(&'a self) -> slice::Iter<'a, T> {
        self.as_ref().iter()
    }

    #[inline]
    pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, T> {
        self.as_mut_slice().iter_mut()
    }

    #[inline]
    pub fn sort_by<F>(&mut self, compare: F) where F: Fn(&T, &T) -> Ordering {
        self.as_mut_slice().sort_by(compare)
    }

    #[inline]
    pub fn as_ptr(&self) -> *const T {
        self.vec.as_ptr()
    }

    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut T {
        self.vec.as_mut_ptr()
    }
}

impl<T : Default+Clear> RepeatedField<T> {
    pub fn push_default<'a>(&'a mut self) -> &'a mut T {
        if self.len == self.vec.len() {
            self.vec.push(Default::default());
        } else {
            self.vec[self.len].clear();
        }
        self.len += 1;
        self.last_mut().unwrap()
    }
}

impl<T : Clone> RepeatedField<T> {
    // TODO: implement to_vec()
    #[inline]
    pub fn from_slice(values: &[T]) -> RepeatedField<T> {
        RepeatedField::from_vec(values.to_vec())
    }
}

impl<T : Clone> Clone for RepeatedField<T> {
    #[inline]
    fn clone(&self) -> RepeatedField<T> {
        RepeatedField {
            vec: self.to_vec(),
            len: self.len(),
        }
    }
}

impl<T> FromIterator<T> for RepeatedField<T> {
    #[inline]
    fn from_iter<I : IntoIterator<Item = T>>(iter: I) -> RepeatedField<T> {
        RepeatedField::from_vec(FromIterator::from_iter(iter))
    }
}

impl<T : PartialEq> PartialEq for RepeatedField<T> {
    #[inline]
    fn eq(&self, other: &RepeatedField<T>) -> bool {
        self.as_ref() == other.as_ref()
    }
}

impl<T : Eq> Eq for RepeatedField<T> {}

impl<T : PartialEq> RepeatedField<T> {
    #[inline]
    pub fn contains(&self, value: &T) -> bool {
        self.as_ref().contains(value)
    }
}

impl<T> AsRef<[T]> for RepeatedField<T> {
    #[inline]
    fn as_ref<'a>(&'a self) -> &'a [T] {
        &self.vec[..self.len]
    }
}

impl<T> Borrow<[T]> for RepeatedField<T> {
    #[inline]
    fn borrow(&self) -> &[T] {
        &self.vec[..self.len]
    }
}

impl<T> Deref for RepeatedField<T> {
    type Target = [T];
    #[inline]
    fn deref(&self) -> &[T] {
        &self.vec[..self.len]
    }
}

impl<T> DerefMut for RepeatedField<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut [T] {
        &mut self.vec[..self.len]
    }
}

impl<T> Index<usize> for RepeatedField<T> {
    type Output = T;

    #[inline]
    fn index<'a>(&'a self, index: usize) -> &'a T {
        &self.as_ref()[index]
    }
}

impl<T> IndexMut<usize> for RepeatedField<T> {
    #[inline]
    fn index_mut<'a>(&'a mut self, index: usize) -> &'a mut T {
        &mut self.as_mut_slice()[index]
    }
}

impl<T : fmt::Debug> fmt::Debug for RepeatedField<T> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.as_ref().fmt(f)
    }
}

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

    #[test]
    fn as_mut_slice() {
        let mut v = RepeatedField::new();
        v.push(10);
        v.push(20);
        v.clear();
        assert_eq!(v.as_mut_slice(), &mut []);
        v.push(30);
        assert_eq!(v.as_mut_slice(), &mut [30]);
    }

    #[test]
    fn push_default() {
        let mut v = RepeatedField::new();
        v.push("aa".to_string());
        v.push("bb".to_string());
        v.clear();
        assert_eq!("".to_string(), *v.push_default());
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 T. Okubo
// This file is part of vlc-rs.
// Licensed under the MIT license, see the LICENSE file.

use sys;
use ::Instance;
use ::Media;
use ::EventManager;
use ::libc::{c_void, c_uint};
use ::enums::{State, Position};
use std::mem::transmute;

/// A LibVLC media player plays one media (usually in a custom drawable).
pub struct MediaPlayer {
    pub(crate) ptr: *mut sys::libvlc_media_player_t,
}

impl MediaPlayer {
    /// Create an empty Media Player object
    pub fn new(instance: &Instance) -> Option<MediaPlayer> {
        unsafe{
            let p = sys::libvlc_media_player_new(instance.ptr);

            if p.is_null() {
                return None;
            }
            Some(MediaPlayer{ptr: p})
        }
    }

    /// Set the media that will be used by the media_player. If any, previous md will be released.
    pub fn set_media(&self, md: &Media) {
        unsafe{ sys::libvlc_media_player_set_media(self.ptr, md.ptr) };
    }

    /// Get the media used by the media_player.
    pub fn get_media(&self) -> Option<Media> {
        let p = unsafe{ sys::libvlc_media_player_get_media(self.ptr) };
        if p.is_null() {
            None
        }else{
            Some(Media{ptr: p})
        }
    }

    /// Get the Event Manager from which the media player send event.
    pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
        unsafe{
            let p = sys::libvlc_media_player_event_manager(self.ptr);
            assert!(!p.is_null());
            EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
        }
    }

    /// is_playing
    pub fn is_playing(&self) -> bool {
        if unsafe{ sys::libvlc_media_player_is_playing(self.ptr) } == 0 {
            false
        }else{
            true
        }
    }

    /// Play
    pub fn play(&self) -> Result<(), ()> {
        if unsafe{ sys::libvlc_media_player_play(self.ptr) } == 0 {
            Ok(())
        }else{
            Err(())
        }
    }

    /// Pause or resume (no effect if there is no media)
    pub fn set_pause(&self, do_pause: bool) {
        unsafe{ sys::libvlc_media_player_set_pause(self.ptr, if do_pause {1} else {0}) };
    }

    /// Toggle pause (no effect if there is no media)
    pub fn pause(&self) {
        unsafe{ sys::libvlc_media_player_pause(self.ptr) };
    }

    /// Stop (no effect if there is no media)
    pub fn stop(&self) {
        unsafe{ sys::libvlc_media_player_stop(self.ptr) };
    }

    pub fn set_callbacks<F>(
        &self,
        play: F,
        pause: Option<Box<Fn(i64) + Send + 'static>>,
        resume: Option<Box<Fn(i64) + Send + 'static>>,
        flush: Option<Box<Fn(i64) + Send + 'static>>,
        drain: Option<Box<Fn() + Send + 'static>>)
        where F: Fn(*const c_void, u32, i64) + Send + 'static,
    {
        let flag_pause = pause.is_some();
        let flag_resume = resume.is_some();
        let flag_flush = flush.is_some();
        let flag_drain = drain.is_some();

        let data = AudioCallbacksData {
            play: Box::new(play), pause: pause, resume: resume,
            flush: flush, drain: drain,
        };
        let data = Box::into_raw(Box::new(data));

        unsafe{
            sys::libvlc_audio_set_callbacks(
                self.ptr,
                Some(audio_cb_play),
                if flag_pause {Some(audio_cb_pause)} else {None},
                if flag_resume {Some(audio_cb_resume)} else {None},
                if flag_flush {Some(audio_cb_flush)} else {None},
                if flag_drain {Some(audio_cb_drain)} else {None},
                data as *mut c_void);
        }
    }

    /// Set the NSView handler where the media player should render its video output.
    pub fn set_nsobject(&self, drawable: *mut c_void) {
        unsafe{ sys::libvlc_media_player_set_nsobject(self.ptr, drawable) };
    }

    /// Get the NSView handler previously set with set_nsobject().
    pub fn get_nsobject(&self) -> Option<*mut c_void> {
        let nso = unsafe{ sys::libvlc_media_player_get_nsobject(self.ptr) };
        if nso.is_null() { None }else{ Some(nso) }
    }

    /// Set an X Window System drawable where the media player should render its video output.
    pub fn set_xwindow(&self, drawable: u32) {
        unsafe{ sys::libvlc_media_player_set_xwindow(self.ptr, drawable) };
    }

    /// Get the X Window System window identifier previously set with set_xwindow().
    pub fn get_xwindow(&self) -> Option<u32> {
        let id = unsafe{ sys::libvlc_media_player_get_xwindow(self.ptr) };
        if id == 0 { None }else{ Some(id) }
    }

    /// Set a Win32/Win64 API window handle (HWND) where the media player should render its video output.
    /// If LibVLC was built without Win32/Win64 API output support, then this has no effects.
    pub fn set_hwnd(&self, drawable: *mut c_void) {
        unsafe{ sys::libvlc_media_player_set_hwnd(self.ptr, drawable) };
    }

    /// Get the Windows API window handle (HWND) previously set with set_hwnd().
    pub fn get_hwnd(&self) -> Option<*mut c_void> {
        let hwnd = unsafe{ sys::libvlc_media_player_get_hwnd(self.ptr) };
        if hwnd.is_null() { None }else{ Some(hwnd) }
    }

    /// Get the current movie time (in ms).
    pub fn get_time(&self) -> Option<i64> {
        unsafe{
            let t = sys::libvlc_media_player_get_time(self.ptr);
            if t == -1 { None }else{ Some(t) }
        }
    }

    /// Set the movie time (in ms).
    /// This has no effect if no media is being played. Not all formats and protocols support this.
    pub fn set_time(&self, time: i64) {
        unsafe{ sys::libvlc_media_player_set_time(self.ptr, time); }
    }

    /// Get movie position as percentage between 0.0 and 1.0.
    pub fn get_position(&self) -> Option<f32> {
        unsafe{
            let pos = sys::libvlc_media_player_get_position(self.ptr);
            if pos == -1f32 { None }else{ Some(pos) }
        }
    }

    /// Set movie position as percentage between 0.0 and 1.0.
    /// This has no effect if playback is not enabled. This might not work depending on the underlying input format and protocol.
    pub fn set_position(&self, pos: f32) {
        unsafe{ sys::libvlc_media_player_set_position(self.ptr, pos); }
    }

    /// Set movie chapter (if applicable).
    pub fn set_chapter(&self, chapter: i32) {
        unsafe{ sys::libvlc_media_player_set_chapter(self.ptr, chapter); }
    }

    /// Get movie chapter.
    pub fn get_chapter(&self) -> Option<i32> {
        unsafe{
            let c = sys::libvlc_media_player_get_chapter(self.ptr);
            if c == -1 { None }else{ Some(c) }
        }
    }

    /// Get movie chapter count.
    pub fn chapter_count(&self) -> Option<i32> {
        unsafe{
            let c = sys::libvlc_media_player_get_chapter_count(self.ptr);
            if c == -1 { None }else{ Some(c) }
        }
    }

    /// Is the player able to play.
    pub fn will_play(&self) -> bool {
        unsafe{
            let b = sys::libvlc_media_player_will_play(self.ptr);
            if b == 0 { false }else{ true }
        }
    }

    /// Get title chapter count.
    pub fn chapter_count_for_title(&self, title: i32) -> Option<i32> {
        unsafe{
            let c = sys::libvlc_media_player_get_chapter_count_for_title(self.ptr, title);
            if c == -1 { None }else{ Some(c) }
        }
    }

    /// Set movie title.
    pub fn set_title(&self, title: i32) {
        unsafe{ sys::libvlc_media_player_set_title(self.ptr, title); }
    }

    /// Get movie title.
    pub fn get_title(&self) -> Option<i32> {
        unsafe{
            let t = sys::libvlc_media_player_get_title(self.ptr);
            if t == -1 { None }else{ Some(t) }
        }
    }

    /// Get movie title count.
    pub fn title_count(&self) -> Option<i32> {
        unsafe{
            let t = sys::libvlc_media_player_get_title_count(self.ptr);
            if t == -1 { Some(t) } else { None }
        }
    }

    /// Set previous chapter (if applicable)
    pub fn previous_chapter(&self) {
        unsafe{ sys::libvlc_media_player_previous_chapter(self.ptr); }
    }

    /// Set next chapter (if applicable)
    pub fn next_chapter(&self) {
        unsafe{ sys::libvlc_media_player_next_chapter(self.ptr); }
    }

    /// Get the requested movie play rate.
    pub fn get_rate(&self) -> f32 {
        unsafe{ sys::libvlc_media_player_get_rate(self.ptr) }
    }

    /// Set movie play rate.
    pub fn set_rate(&self, rate: f32) -> Result<(),()> {
        unsafe{
            if sys::libvlc_media_player_set_rate(self.ptr, rate) == -1 {
                Err(())
            }else{
                Ok(())
            }
        }
    }

    /// Get current movie state.
    pub fn state(&self) -> State {
        unsafe{ sys::libvlc_media_player_get_state(self.ptr) }
    }

    /// How many video outputs does this media player have?
    pub fn has_vout(&self) -> u32 {
        unsafe{ sys::libvlc_media_player_has_vout(self.ptr) }
    }

    /// Is this media player seekable?
    pub fn is_seekable(&self) -> bool {
        unsafe{
            let b = sys::libvlc_media_player_is_seekable(self.ptr);
            if b == 0 { false }else{ true }
        }
    }

    /// Can this media player be paused?
    pub fn can_pause(&self) -> bool {
        unsafe{
            let b = sys::libvlc_media_player_can_pause(self.ptr);
            if b == 0 { false }else{ true }
        }
    }

    /// Check if the current program is scrambled.
    pub fn program_scrambled(&self) -> bool {
        unsafe{
            let b = sys::libvlc_media_player_program_scrambled(self.ptr);
            if b == 0 { false }else{ true }
        }
    }

    /// Display the next frame (if supported)
    pub fn next_frame(&self) {
        unsafe{ sys::libvlc_media_player_next_frame(self.ptr); }
    }

    /// Navigate through DVD Menu.
    pub fn navigate(&self, navigate: u32) {
        unsafe{ sys::libvlc_media_player_navigate(self.ptr, navigate); }
    }

    /// Set if, and how, the video title will be shown when media is played.
    pub fn set_video_title_display(&self, position: Position, timeout: u32) {
        unsafe{ sys::libvlc_media_player_set_video_title_display(self.ptr, position, timeout); }
    }

    /// Returns raw pointer
    pub fn raw(&self) -> *mut sys::libvlc_media_player_t {
        self.ptr
    }
}

impl Drop for MediaPlayer {
    fn drop(&mut self) {
        unsafe{ sys::libvlc_media_player_release(self.ptr) };
    }
}

// For audio_set_callbacks
struct AudioCallbacksData {
    play: Box<Fn(*const c_void, u32, i64) + Send + 'static>,
    pause: Option<Box<Fn(i64) + Send + 'static>>,
    resume: Option<Box<Fn(i64) + Send + 'static>>,
    flush: Option<Box<Fn(i64) + Send + 'static>>,
    drain: Option<Box<Fn() + Send + 'static>>,
}

unsafe extern "C" fn audio_cb_play(
    data: *mut c_void, samples: *const c_void, count: c_uint, pts: i64) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.play)(samples, count, pts);

}

unsafe extern "C" fn audio_cb_pause(data: *mut c_void, pts: i64) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.pause.as_ref().unwrap())(pts);
}

unsafe extern "C" fn audio_cb_resume(data: *mut c_void, pts: i64) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.resume.as_ref().unwrap())(pts);
}

unsafe extern "C" fn audio_cb_flush(data: *mut c_void, pts: i64) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.flush.as_ref().unwrap())(pts);
}

unsafe extern "C" fn audio_cb_drain(data: *mut c_void) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.drain.as_ref().unwrap())();
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct TrackDescription {
    pub id: i32,
    pub name: Option<String>,
}

<commit_msg>media_player: fix missing dyn<commit_after>// Copyright (c) 2015 T. Okubo
// This file is part of vlc-rs.
// Licensed under the MIT license, see the LICENSE file.

use sys;
use ::Instance;
use ::Media;
use ::EventManager;
use ::libc::{c_void, c_uint};
use ::enums::{State, Position};
use std::mem::transmute;

/// A LibVLC media player plays one media (usually in a custom drawable).
pub struct MediaPlayer {
    pub(crate) ptr: *mut sys::libvlc_media_player_t,
}

impl MediaPlayer {
    /// Create an empty Media Player object
    pub fn new(instance: &Instance) -> Option<MediaPlayer> {
        unsafe{
            let p = sys::libvlc_media_player_new(instance.ptr);

            if p.is_null() {
                return None;
            }
            Some(MediaPlayer{ptr: p})
        }
    }

    /// Set the media that will be used by the media_player. If any, previous md will be released.
    pub fn set_media(&self, md: &Media) {
        unsafe{ sys::libvlc_media_player_set_media(self.ptr, md.ptr) };
    }

    /// Get the media used by the media_player.
    pub fn get_media(&self) -> Option<Media> {
        let p = unsafe{ sys::libvlc_media_player_get_media(self.ptr) };
        if p.is_null() {
            None
        }else{
            Some(Media{ptr: p})
        }
    }

    /// Get the Event Manager from which the media player send event.
    pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
        unsafe{
            let p = sys::libvlc_media_player_event_manager(self.ptr);
            assert!(!p.is_null());
            EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
        }
    }

    /// is_playing
    pub fn is_playing(&self) -> bool {
        if unsafe{ sys::libvlc_media_player_is_playing(self.ptr) } == 0 {
            false
        }else{
            true
        }
    }

    /// Play
    pub fn play(&self) -> Result<(), ()> {
        if unsafe{ sys::libvlc_media_player_play(self.ptr) } == 0 {
            Ok(())
        }else{
            Err(())
        }
    }

    /// Pause or resume (no effect if there is no media)
    pub fn set_pause(&self, do_pause: bool) {
        unsafe{ sys::libvlc_media_player_set_pause(self.ptr, if do_pause {1} else {0}) };
    }

    /// Toggle pause (no effect if there is no media)
    pub fn pause(&self) {
        unsafe{ sys::libvlc_media_player_pause(self.ptr) };
    }

    /// Stop (no effect if there is no media)
    pub fn stop(&self) {
        unsafe{ sys::libvlc_media_player_stop(self.ptr) };
    }

    pub fn set_callbacks<F>(
        &self,
        play: F,
        pause: Option<Box<dyn Fn(i64) + Send + 'static>>,
        resume: Option<Box<dyn Fn(i64) + Send + 'static>>,
        flush: Option<Box<dyn Fn(i64) + Send + 'static>>,
        drain: Option<Box<dyn Fn() + Send + 'static>>)
        where F: Fn(*const c_void, u32, i64) + Send + 'static,
    {
        let flag_pause = pause.is_some();
        let flag_resume = resume.is_some();
        let flag_flush = flush.is_some();
        let flag_drain = drain.is_some();

        let data = AudioCallbacksData {
            play: Box::new(play), pause: pause, resume: resume,
            flush: flush, drain: drain,
        };
        let data = Box::into_raw(Box::new(data));

        unsafe{
            sys::libvlc_audio_set_callbacks(
                self.ptr,
                Some(audio_cb_play),
                if flag_pause {Some(audio_cb_pause)} else {None},
                if flag_resume {Some(audio_cb_resume)} else {None},
                if flag_flush {Some(audio_cb_flush)} else {None},
                if flag_drain {Some(audio_cb_drain)} else {None},
                data as *mut c_void);
        }
    }

    /// Set the NSView handler where the media player should render its video output.
    pub fn set_nsobject(&self, drawable: *mut c_void) {
        unsafe{ sys::libvlc_media_player_set_nsobject(self.ptr, drawable) };
    }

    /// Get the NSView handler previously set with set_nsobject().
    pub fn get_nsobject(&self) -> Option<*mut c_void> {
        let nso = unsafe{ sys::libvlc_media_player_get_nsobject(self.ptr) };
        if nso.is_null() { None }else{ Some(nso) }
    }

    /// Set an X Window System drawable where the media player should render its video output.
    pub fn set_xwindow(&self, drawable: u32) {
        unsafe{ sys::libvlc_media_player_set_xwindow(self.ptr, drawable) };
    }

    /// Get the X Window System window identifier previously set with set_xwindow().
    pub fn get_xwindow(&self) -> Option<u32> {
        let id = unsafe{ sys::libvlc_media_player_get_xwindow(self.ptr) };
        if id == 0 { None }else{ Some(id) }
    }

    /// Set a Win32/Win64 API window handle (HWND) where the media player should render its video output.
    /// If LibVLC was built without Win32/Win64 API output support, then this has no effects.
    pub fn set_hwnd(&self, drawable: *mut c_void) {
        unsafe{ sys::libvlc_media_player_set_hwnd(self.ptr, drawable) };
    }

    /// Get the Windows API window handle (HWND) previously set with set_hwnd().
    pub fn get_hwnd(&self) -> Option<*mut c_void> {
        let hwnd = unsafe{ sys::libvlc_media_player_get_hwnd(self.ptr) };
        if hwnd.is_null() { None }else{ Some(hwnd) }
    }

    /// Get the current movie time (in ms).
    pub fn get_time(&self) -> Option<i64> {
        unsafe{
            let t = sys::libvlc_media_player_get_time(self.ptr);
            if t == -1 { None }else{ Some(t) }
        }
    }

    /// Set the movie time (in ms).
    /// This has no effect if no media is being played. Not all formats and protocols support this.
    pub fn set_time(&self, time: i64) {
        unsafe{ sys::libvlc_media_player_set_time(self.ptr, time); }
    }

    /// Get movie position as percentage between 0.0 and 1.0.
    pub fn get_position(&self) -> Option<f32> {
        unsafe{
            let pos = sys::libvlc_media_player_get_position(self.ptr);
            if pos == -1f32 { None }else{ Some(pos) }
        }
    }

    /// Set movie position as percentage between 0.0 and 1.0.
    /// This has no effect if playback is not enabled. This might not work depending on the underlying input format and protocol.
    pub fn set_position(&self, pos: f32) {
        unsafe{ sys::libvlc_media_player_set_position(self.ptr, pos); }
    }

    /// Set movie chapter (if applicable).
    pub fn set_chapter(&self, chapter: i32) {
        unsafe{ sys::libvlc_media_player_set_chapter(self.ptr, chapter); }
    }

    /// Get movie chapter.
    pub fn get_chapter(&self) -> Option<i32> {
        unsafe{
            let c = sys::libvlc_media_player_get_chapter(self.ptr);
            if c == -1 { None }else{ Some(c) }
        }
    }

    /// Get movie chapter count.
    pub fn chapter_count(&self) -> Option<i32> {
        unsafe{
            let c = sys::libvlc_media_player_get_chapter_count(self.ptr);
            if c == -1 { None }else{ Some(c) }
        }
    }

    /// Is the player able to play.
    pub fn will_play(&self) -> bool {
        unsafe{
            let b = sys::libvlc_media_player_will_play(self.ptr);
            if b == 0 { false }else{ true }
        }
    }

    /// Get title chapter count.
    pub fn chapter_count_for_title(&self, title: i32) -> Option<i32> {
        unsafe{
            let c = sys::libvlc_media_player_get_chapter_count_for_title(self.ptr, title);
            if c == -1 { None }else{ Some(c) }
        }
    }

    /// Set movie title.
    pub fn set_title(&self, title: i32) {
        unsafe{ sys::libvlc_media_player_set_title(self.ptr, title); }
    }

    /// Get movie title.
    pub fn get_title(&self) -> Option<i32> {
        unsafe{
            let t = sys::libvlc_media_player_get_title(self.ptr);
            if t == -1 { None }else{ Some(t) }
        }
    }

    /// Get movie title count.
    pub fn title_count(&self) -> Option<i32> {
        unsafe{
            let t = sys::libvlc_media_player_get_title_count(self.ptr);
            if t == -1 { Some(t) } else { None }
        }
    }

    /// Set previous chapter (if applicable)
    pub fn previous_chapter(&self) {
        unsafe{ sys::libvlc_media_player_previous_chapter(self.ptr); }
    }

    /// Set next chapter (if applicable)
    pub fn next_chapter(&self) {
        unsafe{ sys::libvlc_media_player_next_chapter(self.ptr); }
    }

    /// Get the requested movie play rate.
    pub fn get_rate(&self) -> f32 {
        unsafe{ sys::libvlc_media_player_get_rate(self.ptr) }
    }

    /// Set movie play rate.
    pub fn set_rate(&self, rate: f32) -> Result<(),()> {
        unsafe{
            if sys::libvlc_media_player_set_rate(self.ptr, rate) == -1 {
                Err(())
            }else{
                Ok(())
            }
        }
    }

    /// Get current movie state.
    pub fn state(&self) -> State {
        unsafe{ sys::libvlc_media_player_get_state(self.ptr) }
    }

    /// How many video outputs does this media player have?
    pub fn has_vout(&self) -> u32 {
        unsafe{ sys::libvlc_media_player_has_vout(self.ptr) }
    }

    /// Is this media player seekable?
    pub fn is_seekable(&self) -> bool {
        unsafe{
            let b = sys::libvlc_media_player_is_seekable(self.ptr);
            if b == 0 { false }else{ true }
        }
    }

    /// Can this media player be paused?
    pub fn can_pause(&self) -> bool {
        unsafe{
            let b = sys::libvlc_media_player_can_pause(self.ptr);
            if b == 0 { false }else{ true }
        }
    }

    /// Check if the current program is scrambled.
    pub fn program_scrambled(&self) -> bool {
        unsafe{
            let b = sys::libvlc_media_player_program_scrambled(self.ptr);
            if b == 0 { false }else{ true }
        }
    }

    /// Display the next frame (if supported)
    pub fn next_frame(&self) {
        unsafe{ sys::libvlc_media_player_next_frame(self.ptr); }
    }

    /// Navigate through DVD Menu.
    pub fn navigate(&self, navigate: u32) {
        unsafe{ sys::libvlc_media_player_navigate(self.ptr, navigate); }
    }

    /// Set if, and how, the video title will be shown when media is played.
    pub fn set_video_title_display(&self, position: Position, timeout: u32) {
        unsafe{ sys::libvlc_media_player_set_video_title_display(self.ptr, position, timeout); }
    }

    /// Returns raw pointer
    pub fn raw(&self) -> *mut sys::libvlc_media_player_t {
        self.ptr
    }
}

impl Drop for MediaPlayer {
    fn drop(&mut self) {
        unsafe{ sys::libvlc_media_player_release(self.ptr) };
    }
}

// For audio_set_callbacks
struct AudioCallbacksData {
    play: Box<dyn Fn(*const c_void, u32, i64) + Send + 'static>,
    pause: Option<Box<dyn Fn(i64) + Send + 'static>>,
    resume: Option<Box<dyn Fn(i64) + Send + 'static>>,
    flush: Option<Box<dyn Fn(i64) + Send + 'static>>,
    drain: Option<Box<dyn Fn() + Send + 'static>>,
}

unsafe extern "C" fn audio_cb_play(
    data: *mut c_void, samples: *const c_void, count: c_uint, pts: i64) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.play)(samples, count, pts);

}

unsafe extern "C" fn audio_cb_pause(data: *mut c_void, pts: i64) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.pause.as_ref().unwrap())(pts);
}

unsafe extern "C" fn audio_cb_resume(data: *mut c_void, pts: i64) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.resume.as_ref().unwrap())(pts);
}

unsafe extern "C" fn audio_cb_flush(data: *mut c_void, pts: i64) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.flush.as_ref().unwrap())(pts);
}

unsafe extern "C" fn audio_cb_drain(data: *mut c_void) {
    let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
    (data.drain.as_ref().unwrap())();
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct TrackDescription {
    pub id: i32,
    pub name: Option<String>,
}

<|endoftext|>


<commit_before>// Copyright (c) 2015 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use python::{Python, PythonObject, ToPythonPointer, PyClone, PyDrop};
use err::{self, PyErr, PyResult};
use super::object::PyObject;
use ffi::{self, Py_ssize_t};
use conversion::{ToPyObject, FromPyObject};

/// Represents a Python `list`.
pub struct PyList(PyObject);

pyobject_newtype!(PyList, PyList_Check, PyList_Type);

impl PyList {
    /// Construct a new list with the given elements.
    pub fn new(py: Python, elements: &[PyObject]) -> PyList {
        unsafe {
            let ptr = ffi::PyList_New(elements.len() as Py_ssize_t);
            let t = err::result_from_owned_ptr(py, ptr).unwrap().unchecked_cast_into::<PyList>();
            for (i, e) in elements.iter().enumerate() {
                ffi::PyList_SetItem(ptr, i as Py_ssize_t, e.steal_ptr(py));
            }
            t
        }
    }

    /// Gets the length of the list.
    #[inline]
    pub fn len(&self, _py: Python) -> usize {
        // non-negative Py_ssize_t should always fit into Rust usize
        unsafe {
            ffi::PyList_Size(self.0.as_ptr()) as usize
        }
    }

    /// Gets the item at the specified index.
    ///
    /// Panics if the index is out of range.
    pub fn get_item(&self, py: Python, index: usize) -> PyObject {
        // TODO: do we really want to panic here?
        assert!(index < self.len(py));
        unsafe {
            PyObject::from_borrowed_ptr(py, ffi::PyList_GetItem(self.0.as_ptr(), index as Py_ssize_t))
        }
    }

    /// Sets the item at the specified index.
    ///
    /// Panics if the index is out of range.
    pub fn set_item(&self, _py: Python, index: usize, item: PyObject) {
        let r = unsafe { ffi::PyList_SetItem(self.0.as_ptr(), index as Py_ssize_t, item.steal_ptr()) };
        assert!(r == 0);
    }

    /// Inserts an item at the specified index.
    ///
    /// Panics if the index is out of range.
    pub fn insert_item(&self, _py: Python, index: usize, item: PyObject) {
        let r = unsafe { ffi::PyList_Insert(self.0.as_ptr(), index as Py_ssize_t, item.as_ptr()) };
        assert!(r == 0);
    }

    #[inline]
    pub fn iter<'a, 'p>(&'a self, py: Python<'p>) -> PyListIterator<'a, 'p> {
        PyListIterator { py: py, list: self, index: 0 }
    }
}

/// Used by `PyList::iter()`.
pub struct PyListIterator<'a, 'p> {
    py: Python<'p>,
    list: &'a PyList,
    index: usize
}

impl <'a, 'p> Iterator for PyListIterator<'a, 'p> {
    type Item = PyObject;

    #[inline]
    fn next(&mut self) -> Option<PyObject> {
        if self.index < self.list.len(self.py) {
            let item = self.list.get_item(self.py, self.index);
            self.index += 1;
            Some(item)
        } else {
            None
        }
    }

    // Note: we cannot implement size_hint because the length of the list
    // might change during the iteration.
}

/// Converts a Rust slice to a Python `list`.
///
/// Note: this conversion can be inefficient since a Python object is created
/// for each element of the list. For primitive types `T`, consider using
/// the buffer protocol instead.
impl <T> ToPyObject for [T] where T: ToPyObject {
    type ObjectType = PyList;

    fn to_py_object(&self, py: Python) -> PyList {
        unsafe {
            let ptr = ffi::PyList_New(self.len() as Py_ssize_t);
            let t = err::cast_from_owned_ptr_or_panic(py, ptr);
            for (i, e) in self.iter().enumerate() {
                let obj = e.to_py_object(py).into_object();
                ffi::PyList_SetItem(ptr, i as Py_ssize_t, obj.steal_ptr());
            }
            t
        }
    }
}

/// Converts a Rust slice to a Python `list`.
///
/// Note: this conversion can be inefficient since a Python object is created
/// for each element of the list. For primitive types `T`, consider using
/// the buffer protocol instead.
impl <T> ToPyObject for Vec<T> where T: ToPyObject {
    type ObjectType = PyList;

    fn to_py_object(&self, py: Python) -> PyList {
        self.as_slice().to_py_object(py)
    }

    fn into_py_object(self, py: Python) -> PyList {
        unsafe {
            let ptr = ffi::PyList_New(self.len() as Py_ssize_t);
            let t = err::cast_from_owned_ptr_or_panic(py, ptr);
            for (i, e) in self.into_iter().enumerate() {
                let obj = e.into_py_object(py).into_object();
                ffi::PyList_SetItem(ptr, i as Py_ssize_t, obj.steal_ptr());
            }
            t
        }
    }
}

#[cfg(test)]
mod test {
    use python::{Python, PythonObject};
    use conversion::ToPyObject;
    use objects::PyList;

    #[test]
    fn test_len() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![1,2,3,4];
        let list = v.to_py_object(py);
        assert_eq!(4, list.len(py));
    }

    #[test]
    fn test_get_item() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
        assert_eq!(3, list.get_item(py, 1).extract::<i32>(py).unwrap());
        assert_eq!(5, list.get_item(py, 2).extract::<i32>(py).unwrap());
        assert_eq!(7, list.get_item(py, 3).extract::<i32>(py).unwrap());
    }

    #[test]
    fn test_set_item() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        let val = 42i32.to_py_object(py).into_object();
        assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
        list.set_item(py, 0, val);
        assert_eq!(42, list.get_item(py, 0).extract::<i32>(py).unwrap());
    }

    #[test]
    fn test_insert_item() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        let val = 42i32.to_py_object(py).into_object();
        assert_eq!(4, list.len(py));
        assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
        list.insert_item(py, 0, val);
        assert_eq!(5, list.len(py));
        assert_eq!(42, list.get_item(py, 0).extract::<i32>(py).unwrap());
        assert_eq!(2, list.get_item(py, 1).extract::<i32>(py).unwrap());
    }

    #[test]
    fn test_iter() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        let mut idx = 0;
        for el in list.iter(py) {
            assert_eq!(v[idx], el.extract::<i32>(py).unwrap());
            idx += 1;
        }
        assert_eq!(idx, v.len());
    }

    #[test]
    fn test_extract() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        let v2 = list.into_object().extract::<Vec<i32>>(py).unwrap();
        assert_eq!(v, v2);
    }
}
<commit_msg>rename list.insert_item to list.insert<commit_after>// Copyright (c) 2015 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use python::{Python, PythonObject, ToPythonPointer, PyClone, PyDrop};
use err::{self, PyErr, PyResult};
use super::object::PyObject;
use ffi::{self, Py_ssize_t};
use conversion::{ToPyObject, FromPyObject};

/// Represents a Python `list`.
pub struct PyList(PyObject);

pyobject_newtype!(PyList, PyList_Check, PyList_Type);

impl PyList {
    /// Construct a new list with the given elements.
    pub fn new(py: Python, elements: &[PyObject]) -> PyList {
        unsafe {
            let ptr = ffi::PyList_New(elements.len() as Py_ssize_t);
            let t = err::result_from_owned_ptr(py, ptr).unwrap().unchecked_cast_into::<PyList>();
            for (i, e) in elements.iter().enumerate() {
                ffi::PyList_SetItem(ptr, i as Py_ssize_t, e.steal_ptr(py));
            }
            t
        }
    }

    /// Gets the length of the list.
    #[inline]
    pub fn len(&self, _py: Python) -> usize {
        // non-negative Py_ssize_t should always fit into Rust usize
        unsafe {
            ffi::PyList_Size(self.0.as_ptr()) as usize
        }
    }

    /// Gets the item at the specified index.
    ///
    /// Panics if the index is out of range.
    pub fn get_item(&self, py: Python, index: usize) -> PyObject {
        // TODO: do we really want to panic here?
        assert!(index < self.len(py));
        unsafe {
            PyObject::from_borrowed_ptr(py, ffi::PyList_GetItem(self.0.as_ptr(), index as Py_ssize_t))
        }
    }

    /// Sets the item at the specified index.
    ///
    /// Panics if the index is out of range.
    pub fn set_item(&self, _py: Python, index: usize, item: PyObject) {
        let r = unsafe { ffi::PyList_SetItem(self.0.as_ptr(), index as Py_ssize_t, item.steal_ptr()) };
        assert!(r == 0);
    }

    /// Inserts an item at the specified index.
    ///
    /// Panics if the index is out of range.
    pub fn insert(&self, _py: Python, index: usize, item: PyObject) {
        let r = unsafe { ffi::PyList_Insert(self.0.as_ptr(), index as Py_ssize_t, item.as_ptr()) };
        assert!(r == 0);
    }

    // Old name for `insert`.
    #[deprecated(since="0.3.1", note="use list.insert() instead")]
    #[doc(hidden)]
    pub fn insert_item(&self, py: Python, index: usize, item: PyObject) {
        self.insert(py, index, item);
    }

    #[inline]
    pub fn iter<'a, 'p>(&'a self, py: Python<'p>) -> PyListIterator<'a, 'p> {
        PyListIterator { py: py, list: self, index: 0 }
    }
}

/// Used by `PyList::iter()`.
pub struct PyListIterator<'a, 'p> {
    py: Python<'p>,
    list: &'a PyList,
    index: usize
}

impl <'a, 'p> Iterator for PyListIterator<'a, 'p> {
    type Item = PyObject;

    #[inline]
    fn next(&mut self) -> Option<PyObject> {
        if self.index < self.list.len(self.py) {
            let item = self.list.get_item(self.py, self.index);
            self.index += 1;
            Some(item)
        } else {
            None
        }
    }

    // Note: we cannot implement size_hint because the length of the list
    // might change during the iteration.
}

/// Converts a Rust slice to a Python `list`.
///
/// Note: this conversion can be inefficient since a Python object is created
/// for each element of the list. For primitive types `T`, consider using
/// the buffer protocol instead.
impl <T> ToPyObject for [T] where T: ToPyObject {
    type ObjectType = PyList;

    fn to_py_object(&self, py: Python) -> PyList {
        unsafe {
            let ptr = ffi::PyList_New(self.len() as Py_ssize_t);
            let t = err::cast_from_owned_ptr_or_panic(py, ptr);
            for (i, e) in self.iter().enumerate() {
                let obj = e.to_py_object(py).into_object();
                ffi::PyList_SetItem(ptr, i as Py_ssize_t, obj.steal_ptr());
            }
            t
        }
    }
}

/// Converts a Rust slice to a Python `list`.
///
/// Note: this conversion can be inefficient since a Python object is created
/// for each element of the list. For primitive types `T`, consider using
/// the buffer protocol instead.
impl <T> ToPyObject for Vec<T> where T: ToPyObject {
    type ObjectType = PyList;

    fn to_py_object(&self, py: Python) -> PyList {
        self.as_slice().to_py_object(py)
    }

    fn into_py_object(self, py: Python) -> PyList {
        unsafe {
            let ptr = ffi::PyList_New(self.len() as Py_ssize_t);
            let t = err::cast_from_owned_ptr_or_panic(py, ptr);
            for (i, e) in self.into_iter().enumerate() {
                let obj = e.into_py_object(py).into_object();
                ffi::PyList_SetItem(ptr, i as Py_ssize_t, obj.steal_ptr());
            }
            t
        }
    }
}

#[cfg(test)]
mod test {
    use python::{Python, PythonObject};
    use conversion::ToPyObject;
    use objects::PyList;

    #[test]
    fn test_len() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![1,2,3,4];
        let list = v.to_py_object(py);
        assert_eq!(4, list.len(py));
    }

    #[test]
    fn test_get_item() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
        assert_eq!(3, list.get_item(py, 1).extract::<i32>(py).unwrap());
        assert_eq!(5, list.get_item(py, 2).extract::<i32>(py).unwrap());
        assert_eq!(7, list.get_item(py, 3).extract::<i32>(py).unwrap());
    }

    #[test]
    fn test_set_item() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        let val = 42i32.to_py_object(py).into_object();
        assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
        list.set_item(py, 0, val);
        assert_eq!(42, list.get_item(py, 0).extract::<i32>(py).unwrap());
    }

    #[test]
    fn test_insert() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        let val = 42i32.to_py_object(py).into_object();
        assert_eq!(4, list.len(py));
        assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
        list.insert(py, 0, val);
        assert_eq!(5, list.len(py));
        assert_eq!(42, list.get_item(py, 0).extract::<i32>(py).unwrap());
        assert_eq!(2, list.get_item(py, 1).extract::<i32>(py).unwrap());
    }

    #[test]
    fn test_iter() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        let mut idx = 0;
        for el in list.iter(py) {
            assert_eq!(v[idx], el.extract::<i32>(py).unwrap());
            idx += 1;
        }
        assert_eq!(idx, v.len());
    }

    #[test]
    fn test_extract() {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let v = vec![2, 3, 5, 7];
        let list = v.to_py_object(py);
        let v2 = list.into_object().extract::<Vec<i32>>(py).unwrap();
        assert_eq!(v, v2);
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Noise-rs Developers.
//
// 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.

//! Note that this is NOT Ken Perlin's simplex noise, as that is patent encumbered.
//! Instead, these functions use the OpenSimplex algorithm, as detailed here:
//! http://uniblock.tumblr.com/post/97868843242/noise

use num::Float;

use {gradient, math, Seed};

const STRETCH_CONSTANT_2D: f64 = -0.211324865405187; //(1/sqrt(2+1)-1)/2;
const SQUISH_CONSTANT_2D: f64 = 0.366025403784439; //(sqrt(2+1)-1)/2;
const STRETCH_CONSTANT_3D: f64 = -1.0 / 6.0; //(1/Math.sqrt(3+1)-1)/3;
const SQUISH_CONSTANT_3D: f64 = 1.0 / 3.0; //(Math.sqrt(3+1)-1)/3;

const NORM_CONSTANT_2D: f32 = 1.0 / 14.0;
const NORM_CONSTANT_3D: f32 = 1.0 / 14.0;

/// 2-dimensional [OpenSimplex Noise](http://uniblock.tumblr.com/post/97868843242/noise)
///
/// This is a slower but higher quality form of gradient noise than `noise::perlin2`.
pub fn open_simplex2<T: Float>(seed: &Seed, point: &::Point2<T>) -> T {
    fn gradient<T: Float>(seed: &Seed, xs_floor: T, ys_floor: T, dx: T, dy: T) -> T {
        let zero: T = math::cast(0);

        let attn = math::cast::<_, T>(2.0_f64) - dx * dx - dy * dy;
        if attn > zero {
            let index = seed.get2::<isize>([math::cast(xs_floor), math::cast(ys_floor)]);
            let vec = gradient::get2::<T>(index);
            math::pow4(attn) * (dx * vec[0] + dy * vec[1])
        } else {
            zero
        }
    }

    let zero: T = math::cast(0);
    let one: T = math::cast(1);
    let squish_constant: T = math::cast(SQUISH_CONSTANT_2D);

    //Place input coordinates onto grid.
    let stretch_offset = (point[0] + point[1]) * math::cast(STRETCH_CONSTANT_2D);
    let xs = point[0] + stretch_offset;
    let ys = point[1] + stretch_offset;

    //Floor to get grid coordinates of rhombus (stretched square) super-cell origin.
    let mut xs_floor = xs.floor();
    let mut ys_floor = ys.floor();

    //Skew out to get actual coordinates of rhombus origin. We'll need these later.
    let squish_offset = (xs_floor + ys_floor) * squish_constant;
    let x_floor = xs_floor + squish_offset;
    let y_floor = ys_floor + squish_offset;

    //Compute grid coordinates relative to rhombus origin.
    let xs_frac = xs - xs_floor;
    let ys_frac = ys - ys_floor;

    //Sum those together to get a value that determines which region we're in.
    let frac_sum = xs_frac + ys_frac;

    //Positions relative to origin point.
    let mut dx0 = point[0] - x_floor;
    let mut dy0 = point[1] - y_floor;

    let mut value: T = zero;

    //Contribution (1,0)
    let dx1 = dx0 - one - squish_constant;
    let dy1 = dy0 - squish_constant;
    value = value + gradient(seed, xs_floor + one, ys_floor, dx1, dy1);

    //Contribution (0,1)
    let dx2 = dx0 - squish_constant;
    let dy2 = dy1 - one;
    value = value + gradient(seed, xs_floor, ys_floor + one, dx2, dy2);

    if frac_sum > one {
        xs_floor = xs_floor + one;
        ys_floor = ys_floor + one;
        dx0 = dx1 - squish_constant;
        dy0 = dy2 - squish_constant;
    }

    //Contribution (0,0) or (1,1)
    value = value + gradient(seed, xs_floor, ys_floor, dx0, dy0);

    value * math::cast(NORM_CONSTANT_2D)
}

/// 3-dimensional [OpenSimplex Noise](http://uniblock.tumblr.com/post/97868843242/noise)
///
/// This is a slower but higher quality form of gradient noise than `noise::perlin3`.
pub fn open_simplex3<T: Float>(seed: &Seed, point: &::Point3<T>) -> T {
    fn gradient<T: Float>(seed: &Seed, xs_floor: T, ys_floor: T, zs_floor: T, dx: T, dy: T, dz: T) -> T {
        let zero: T = math::cast(0);

        let attn = math::cast::<_, T>(2.0_f64) - dx * dx - dy * dy - dz * dz;
        if attn > zero {
            let index = seed.get3::<isize>([math::cast(xs_floor), math::cast(ys_floor), math::cast(zs_floor)]);
            let vec = gradient::get3::<T>(index);
            math::pow4(attn) * (dx * vec[0] + dy * vec[1] + dz * vec[2])
        } else {
            zero
        }
    }

    let zero: T = math::cast(0);
    let one: T = math::cast(1);
    let two: T = math::cast(2);
    let squish_constant: T = math::cast(SQUISH_CONSTANT_3D);

    //Place input coordinates on simplectic honeycomb.
    let stretch_offset = (point[0] + point[1] + point[2]) * math::cast(STRETCH_CONSTANT_3D);
    let xs = point[0] + stretch_offset;
    let ys = point[1] + stretch_offset;
    let zs = point[2] + stretch_offset;

    //Floor to get simplectic honeycomb coordinates of rhombohedron (stretched cube) super-cell origin.
    let xsb = xs.floor();
    let ysb = ys.floor();
    let zsb = zs.floor();

    //Skew out to get actual coordinates of rhombohedron origin. We'll need these later.
    let squish_offset = (xsb + ysb + zsb) * squish_constant;
    let xb = xsb + squish_offset;
    let yb = ysb + squish_offset;
    let zb = zsb + squish_offset;

    //Compute simplectic honeycomb coordinates relative to rhombohedral origin.
    let xins = xs - xsb;
    let yins = ys - ysb;
    let zins = zs - zsb;

    //Sum those together to get a value that determines which region we're in.
    let in_sum = xins + yins + zins;

    //Positions relative to origin point.
    let mut dx0 = point[0] - xb;
    let mut dy0 = point[1] - yb;
    let mut dz0 = point[2] - zb;

    let mut value = zero;
    let c0 = one + two * squish_constant;

    if in_sum <= one { //We're inside the tetrahedron (3-Simplex) at (0,0,0)
        //Contribution (0,0,0)
        value = value + gradient(seed, xsb, ysb, zsb, dx0, dy0, dz0);

        //Contribution (1,0,0)
        let dx1 = dx0 - one - squish_constant;
        let dy1 = dy0 - squish_constant;
        let dz1 = dz0 - squish_constant;
        value = value + gradient(seed, xsb + one, ysb, zsb, dx1, dy1, dz1);

        //Contribution (0,1,0)
        let dx2 = dx0 - squish_constant;
        let dy2 = dy1 - one;
        let dz2 = dz1;
        value = value + gradient(seed, xsb, ysb + one, zsb, dx2, dy2, dz2);

        //Contribution (0,0,1)
        let dx3 = dx2;
        let dy3 = dy1;
        let dz3 = dz1 - one;
        value = value + gradient(seed, xsb, ysb, zsb + one, dx3, dy3, dz3);
    } else if in_sum >= two { //We're inside the tetrahedron (3-Simplex) at (1,11)
        //Contribution (1,1,0)
        let dx3 = dx0 - c0;
        let dy3 = dy0 - c0;
        let dz3 = dz0 - c0 + one;
        value = value + gradient(seed, xsb + one, ysb + one, zsb, dx3, dy3, dz3);

        //Contribution (1,0,1)
        let dx2 = dx3;
        let dy2 = dy3 + one;
        let dz2 = dz3 - one;
        value = value + gradient(seed, xsb + one, ysb, zsb + one, dx2, dy2, dz2);

        //Contribution (0,1,1)
        let dx1 = dx3 + one;
        let dy1 = dy3;
        let dz1 = dz2;
        value = value + gradient(seed, xsb, ysb + one, zsb + one, dx1, dy1, dz1);

        //Contribution (1,1,1)
        let c1 = c0 + squish_constant;
        dx0 = dx0 - c1;
        dy0 = dy0 - c1;
        dz0 = dz0 - c1;
        value = value + gradient(seed, xsb + one, ysb + one, zsb + one, dx0, dy0, dz0);
    } else { //We're inside the octahedron (Rectified 3-Simplex) in between.
        //Contribution (1,0,0)
        let dx1 = dx0 - one - squish_constant;
        let dy1 = dy0 - squish_constant;
        let dz1 = dz0 - squish_constant;
        value = value + gradient(seed, xsb + one, ysb, zsb, dx1, dy1, dz1);

        //Contribution (0,1,0)
        let dx2 = dx1 + one;
        let dy2 = dy1 - one;
        let dz2 = dz1;
        value = value + gradient(seed, xsb, ysb + one, zsb, dx2, dy2, dz2);

        //Contribution (0,0,1)
        let dx3 = dx2;
        let dy3 = dy1;
        let dz3 = dz1 - one;
        value = value + gradient(seed, xsb, ysb, zsb + one, dx3, dy3, dz3);

        //Contribution (1,1,0)
        let dx4 = dx0 - c0;
        let dy4 = dy0 - c0;
        let dz4 = dz0 - c0 + one;
        value = value + gradient(seed, xsb + one, ysb + one, zsb, dx4, dy4, dz4);

        //Contribution (1,0,1)
        let dx5 = dx4;
        let dy5 = dy4 + one;
        let dz5 = dz4 - one;
        value = value + gradient(seed, xsb + one, ysb, zsb + one, dx5, dy5, dz5);

        //Contribution (0,1,1)
        let dx6 = dx4 + one;
        let dy6 = dy4;
        let dz6 = dz5;
        value = value + gradient(seed, xsb, ysb + one, zsb + one, dx6, dy6, dz6);
    }

    return value * math::cast(NORM_CONSTANT_3D);
}
<commit_msg>Removed more math calculations.<commit_after>// Copyright 2013 The Noise-rs Developers.
//
// 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.

//! Note that this is NOT Ken Perlin's simplex noise, as that is patent encumbered.
//! Instead, these functions use the OpenSimplex algorithm, as detailed here:
//! http://uniblock.tumblr.com/post/97868843242/noise

use num::Float;

use {gradient, math, Seed};

const STRETCH_CONSTANT_2D: f64 = -0.211324865405187; //(1/sqrt(2+1)-1)/2;
const SQUISH_CONSTANT_2D: f64 = 0.366025403784439; //(sqrt(2+1)-1)/2;
const STRETCH_CONSTANT_3D: f64 = -1.0 / 6.0; //(1/Math.sqrt(3+1)-1)/3;
const SQUISH_CONSTANT_3D: f64 = 1.0 / 3.0; //(Math.sqrt(3+1)-1)/3;

const NORM_CONSTANT_2D: f32 = 1.0 / 14.0;
const NORM_CONSTANT_3D: f32 = 1.0 / 14.0;

/// 2-dimensional [OpenSimplex Noise](http://uniblock.tumblr.com/post/97868843242/noise)
///
/// This is a slower but higher quality form of gradient noise than `noise::perlin2`.
pub fn open_simplex2<T: Float>(seed: &Seed, point: &::Point2<T>) -> T {
    fn gradient<T: Float>(seed: &Seed, xs_floor: T, ys_floor: T, dx: T, dy: T) -> T {
        let zero: T = math::cast(0);

        let attn = math::cast::<_, T>(2.0_f64) - dx * dx - dy * dy;
        if attn > zero {
            let index = seed.get2::<isize>([math::cast(xs_floor), math::cast(ys_floor)]);
            let vec = gradient::get2::<T>(index);
            math::pow4(attn) * (dx * vec[0] + dy * vec[1])
        } else {
            zero
        }
    }

    let zero: T = math::cast(0);
    let one: T = math::cast(1);
    let squish_constant: T = math::cast(SQUISH_CONSTANT_2D);

    //Place input coordinates onto grid.
    let stretch_offset = (point[0] + point[1]) * math::cast(STRETCH_CONSTANT_2D);
    let xs = point[0] + stretch_offset;
    let ys = point[1] + stretch_offset;

    //Floor to get grid coordinates of rhombus (stretched square) super-cell origin.
    let mut xs_floor = xs.floor();
    let mut ys_floor = ys.floor();

    //Skew out to get actual coordinates of rhombus origin. We'll need these later.
    let squish_offset = (xs_floor + ys_floor) * squish_constant;
    let x_floor = xs_floor + squish_offset;
    let y_floor = ys_floor + squish_offset;

    //Compute grid coordinates relative to rhombus origin.
    let xs_frac = xs - xs_floor;
    let ys_frac = ys - ys_floor;

    //Sum those together to get a value that determines which region we're in.
    let frac_sum = xs_frac + ys_frac;

    //Positions relative to origin point.
    let mut dx0 = point[0] - x_floor;
    let mut dy0 = point[1] - y_floor;

    let mut value: T = zero;

    //Contribution (1,0)
    let dx1 = dx0 - one - squish_constant;
    let dy1 = dy0 - squish_constant;
    value = value + gradient(seed, xs_floor + one, ys_floor, dx1, dy1);

    //Contribution (0,1)
    let dx2 = dx0 - squish_constant;
    let dy2 = dy1 - one;
    value = value + gradient(seed, xs_floor, ys_floor + one, dx2, dy2);

    if frac_sum > one {
        xs_floor = xs_floor + one;
        ys_floor = ys_floor + one;
        dx0 = dx1 - squish_constant;
        dy0 = dy2 - squish_constant;
    }

    //Contribution (0,0) or (1,1)
    value = value + gradient(seed, xs_floor, ys_floor, dx0, dy0);

    value * math::cast(NORM_CONSTANT_2D)
}

/// 3-dimensional [OpenSimplex Noise](http://uniblock.tumblr.com/post/97868843242/noise)
///
/// This is a slower but higher quality form of gradient noise than `noise::perlin3`.
pub fn open_simplex3<T: Float>(seed: &Seed, point: &::Point3<T>) -> T {
    fn gradient<T: Float>(seed: &Seed, xs_floor: T, ys_floor: T, zs_floor: T, dx: T, dy: T, dz: T) -> T {
        let zero: T = math::cast(0);

        let attn = math::cast::<_, T>(2.0_f64) - dx * dx - dy * dy - dz * dz;
        if attn > zero {
            let index = seed.get3::<isize>([math::cast(xs_floor), math::cast(ys_floor), math::cast(zs_floor)]);
            let vec = gradient::get3::<T>(index);
            math::pow4(attn) * (dx * vec[0] + dy * vec[1] + dz * vec[2])
        } else {
            zero
        }
    }

    let zero: T = math::cast(0);
    let one: T = math::cast(1);
    let two: T = math::cast(2);
    let squish_constant: T = math::cast(SQUISH_CONSTANT_3D);

    //Place input coordinates on simplectic honeycomb.
    let stretch_offset = (point[0] + point[1] + point[2]) * math::cast(STRETCH_CONSTANT_3D);
    let xs = point[0] + stretch_offset;
    let ys = point[1] + stretch_offset;
    let zs = point[2] + stretch_offset;

    //Floor to get simplectic honeycomb coordinates of rhombohedron (stretched cube) super-cell origin.
    let xsb = xs.floor();
    let ysb = ys.floor();
    let zsb = zs.floor();

    //Skew out to get actual coordinates of rhombohedron origin. We'll need these later.
    let squish_offset = (xsb + ysb + zsb) * squish_constant;
    let xb = xsb + squish_offset;
    let yb = ysb + squish_offset;
    let zb = zsb + squish_offset;

    //Compute simplectic honeycomb coordinates relative to rhombohedral origin.
    let xins = xs - xsb;
    let yins = ys - ysb;
    let zins = zs - zsb;

    //Sum those together to get a value that determines which region we're in.
    let in_sum = xins + yins + zins;

    //Positions relative to origin point.
    let mut dx0 = point[0] - xb;
    let mut dy0 = point[1] - yb;
    let mut dz0 = point[2] - zb;

    let mut value = zero;
    let c0 = one + two * squish_constant;

    if in_sum <= one { //We're inside the tetrahedron (3-Simplex) at (0,0,0)
        //Contribution (0,0,0)
        value = value + gradient(seed, xsb, ysb, zsb, dx0, dy0, dz0);

        //Contribution (1,0,0)
        let dx1 = dx0 - one - squish_constant;
        let dy1 = dy0 - squish_constant;
        let dz1 = dz0 - squish_constant;
        value = value + gradient(seed, xsb + one, ysb, zsb, dx1, dy1, dz1);

        //Contribution (0,1,0)
        let dx2 = dx0 - squish_constant;
        let dy2 = dy1 - one;
        let dz2 = dz1;
        value = value + gradient(seed, xsb, ysb + one, zsb, dx2, dy2, dz2);

        //Contribution (0,0,1)
        let dx3 = dx2;
        let dy3 = dy1;
        let dz3 = dz1 - one;
        value = value + gradient(seed, xsb, ysb, zsb + one, dx3, dy3, dz3);
    } else if in_sum >= two { //We're inside the tetrahedron (3-Simplex) at (1,11)
        //Contribution (1,1,0)
        let dx3 = dx0 - c0;
        let dy3 = dy0 - c0;
        let dz3 = dz0 - c0 + one;
        value = value + gradient(seed, xsb + one, ysb + one, zsb, dx3, dy3, dz3);

        //Contribution (1,0,1)
        let dx2 = dx3;
        let dy2 = dy3 + one;
        let dz2 = dz3 - one;
        value = value + gradient(seed, xsb + one, ysb, zsb + one, dx2, dy2, dz2);

        //Contribution (0,1,1)
        let dx1 = dx3 + one;
        let dy1 = dy3;
        let dz1 = dz2;
        value = value + gradient(seed, xsb, ysb + one, zsb + one, dx1, dy1, dz1);

        //Contribution (1,1,1)
        dx0 = dx3 - squish_constant;
        dy0 = dy3 - squish_constant;
        dz0 = dz2 - squish_constant;
        value = value + gradient(seed, xsb + one, ysb + one, zsb + one, dx0, dy0, dz0);
    } else { //We're inside the octahedron (Rectified 3-Simplex) in between.
        //Contribution (1,0,0)
        let dx1 = dx0 - one - squish_constant;
        let dy1 = dy0 - squish_constant;
        let dz1 = dz0 - squish_constant;
        value = value + gradient(seed, xsb + one, ysb, zsb, dx1, dy1, dz1);

        //Contribution (0,1,0)
        let dx2 = dx1 + one;
        let dy2 = dy1 - one;
        let dz2 = dz1;
        value = value + gradient(seed, xsb, ysb + one, zsb, dx2, dy2, dz2);

        //Contribution (0,0,1)
        let dx3 = dx2;
        let dy3 = dy1;
        let dz3 = dz1 - one;
        value = value + gradient(seed, xsb, ysb, zsb + one, dx3, dy3, dz3);

        //Contribution (1,1,0)
        let dx4 = dx0 - c0;
        let dy4 = dy0 - c0;
        let dz4 = dz1 - squish_constant;
        value = value + gradient(seed, xsb + one, ysb + one, zsb, dx4, dy4, dz4);

        //Contribution (1,0,1)
        let dx5 = dx4;
        let dy5 = dy4 + one;
        let dz5 = dz4 - one;
        value = value + gradient(seed, xsb + one, ysb, zsb + one, dx5, dy5, dz5);

        //Contribution (0,1,1)
        let dx6 = dx4 + one;
        let dy6 = dy4;
        let dz6 = dz5;
        value = value + gradient(seed, xsb, ysb + one, zsb + one, dx6, dy6, dz6);
    }

    return value * math::cast(NORM_CONSTANT_3D);
}
<|endoftext|>


<commit_before>extern crate birl;

use std::env::args;
use birl::context::Context;

fn start_interactive_console() {
	/* Print heading info. */
	eprintln!("O SHELL QUE CONSTRÓI FIBRA. VERSÃO {}", birl::context::BIRL_VERSION);
	eprintln!("BIRL  © 2018, RAFAEL RODRIGUES NAKANO.");
	eprintln!("SHELL © 2018, MATHEUS BRANCO BORELLA.");
	eprintln!();

	/* Setup BIRL.
	 * The Context interpreter is not built to run interactively,
	 * by default, as it lacks much of the framework that would be
	 * needed to properly implement an interactive shell with
	 * immidiate evaluation of expresssions.
	 *
	 * So, as a workaround, the shell cycles the interpreter manually
	 * to the completion of all instructions added by a line. To
	 * achieve that, we first call the root function, as any
	 * expression typed into the interpreted will be compiled as a
	 * root-level instruction.
	 */
	use birl::context::Context;
	let mut c = Context::new();

    c.set_interactive_mode();

	use birl::context::BIRL_GLOBAL_FUNCTION_ID;
	c.call_function_by_id(BIRL_GLOBAL_FUNCTION_ID, vec![])
		.expect("Could not setup BIRL runtime.");

	/* Bind the Context interpreter to standard IO */
	let _ = c.set_stdin({
		use std::io;
		let reader = io::BufReader::new(io::stdin());
		Some(Box::new(reader))
	});
	let _ = c.set_stdout({
		use std::io;
		Some(Box::new(io::stdout()))
	});

	/* Enter interactive loop */
	use std::io::{stdin, BufReader, BufRead};
	let mut prompt = BufReader::new(stdin());
	loop{
		eprint!("> ");

		let mut line = String::new();
		match prompt.read_line(&mut line){
			Ok(count) => if count == 0 {
				eprintln!("Reached end of input.");
				break
			},
			Err(what) => {
				eprintln!("A read error occured: {:?}", what);
				break
			}
		}

		/* Parse and evaluate */
		if let Err(what) = c.process_line(&line){
			eprintln!("{}", what);
		} else {
			/* Drives the currently pending instructions to
			 * completion. */

            use birl::vm::ExecutionStatus as Es;
            loop {
                match c.execute_next_instruction() {
                    Ok(Es::Quit) => {
                        eprintln!("Saindo...");
                        return;
                    }
                    Ok(Es::Halt) => break,
                    Ok(_) => {}
                    Err(e) => {
                        eprintln!("{}", e);
                    }
                }
            }
		}
	}

	/* Make sure the output is flushed */
	c.set_stdout(None).unwrap().flush()
		.expect("Could not flush io::stdout().");
}

fn print_help() {
	Context::print_version();

	println!("Ta querendo ajuda, cumpade?");
	println!("O uso é o seguinte: birl [opções] [arquivo ou arquivos]");
	println!("Cê pode passar mais de um arquivo, só que apenas um pode ter a seção \"SHOW\", que \
              é o ponto de partida do teu programa.");
	println!("As opções são as seguintes:");
	println!("\t-a ou --ajuda-o-maluco-ta-doente\t: Imprime essa mensagem de ajuda");
	println!("\t-v ou --versao\t\t\t\t: Imprime a versão do programa");
	println!("\t-s ou --string \"[codigo]\"\t\t: Executa o codigo na string ao inves de \
              um arquivo.");
	println!("\t-i ou --interativo\t\t\t\t: Inicia um console interativo pra rodar códigos");
}

/// Parameters passed through the command line
enum Param {
	PrintVersion,
	PrintHelp,
	/// Add a file to be processed
	InputFile(String),
	/// Processes code from a given string
	StringSource(String),
	/// Starts an interactive console for running code
	Interactive,
}

fn get_params() -> Vec<Param> {
	let mut arguments = args();
	let mut result: Vec<Param> = vec![];

	let _ = arguments.next().unwrap(); // Dispose of the first argument

	loop {
		if let Some(arg) = arguments.next() {
			match arg.as_str() {
				"-a" | "--ajuda-o-maluco-ta-doente" => result.push(Param::PrintHelp),
				"-v" | "--versao-cumpade" => result.push(Param::PrintVersion),
				"-i" | "--interativo" => result.push(Param::Interactive),
				"-s" | "--string" => {
					// The next argument is expected to be a string containing source code
					if let Some(code) = arguments.next() {
						result.push(Param::StringSource(code));
					} else {
						println!("Erro: O argumento {} precisa de um conteúdo logo em seguida, bixo.", arg);
					}
				}
				// Push the file to the result stack
				_ => result.push(Param::InputFile(arg))
			}
		} else {
			break;
		}
	}

	result
}

fn main() {
	let args = get_params();
	let mut interactive = false;

	let mut ctx = Context::new();
    ctx.add_file("fibonacci.birl");

	if args.len() > 0 {
		for arg in args {
			match arg {
				Param::PrintHelp => print_help(),
				Param::Interactive => interactive = true,
				Param::PrintVersion => Context::print_version(),
				Param::InputFile(file) => {
					match ctx.add_file(file.as_str()) {
						Ok(_) => {}
						Err(e) => {
							println!("Ocorreu um erro ao adicionar o arquivo \"{}\" pro contexto : {}",
									 file.as_str(), e);
							// Exit? continue?
						}
					}
				}
				Param::StringSource(source) => {
					match ctx.add_source_string(source) {
						Ok(_) => {}
						Err(e) => {
							println!("Erro ao adicionar string de código ao contexto : {}", e);
						}
					}
				}
			}
		}
	} else {
		//interactive = true;
	}

	if interactive {
		start_interactive_console();
	} else {
        /* Bind the Context interpreter to standard IO */
        let _ = ctx.set_stdin({
            use std::io;
            let reader = io::BufReader::new(io::stdin());
            Some(Box::new(reader))
        });
        let _ = ctx.set_stdout({
            use std::io;
            Some(Box::new(io::stdout()))
        });

		match ctx.start_program() {
			Ok(_) => {}
			Err(e) => println!("Erro de execução : {}", e),
		}
	}
}
<commit_msg>Removido código de debug<commit_after>extern crate birl;

use std::env::args;
use birl::context::Context;

fn start_interactive_console() {
	/* Print heading info. */
	eprintln!("O SHELL QUE CONSTRÓI FIBRA. VERSÃO {}", birl::context::BIRL_VERSION);
	eprintln!("BIRL  © 2018, RAFAEL RODRIGUES NAKANO.");
	eprintln!("SHELL © 2018, MATHEUS BRANCO BORELLA.");
	eprintln!();

	/* Setup BIRL.
	 * The Context interpreter is not built to run interactively,
	 * by default, as it lacks much of the framework that would be
	 * needed to properly implement an interactive shell with
	 * immidiate evaluation of expresssions.
	 *
	 * So, as a workaround, the shell cycles the interpreter manually
	 * to the completion of all instructions added by a line. To
	 * achieve that, we first call the root function, as any
	 * expression typed into the interpreted will be compiled as a
	 * root-level instruction.
	 */
	use birl::context::Context;
	let mut c = Context::new();

    c.set_interactive_mode();

	use birl::context::BIRL_GLOBAL_FUNCTION_ID;
	c.call_function_by_id(BIRL_GLOBAL_FUNCTION_ID, vec![])
		.expect("Could not setup BIRL runtime.");

	/* Bind the Context interpreter to standard IO */
	let _ = c.set_stdin({
		use std::io;
		let reader = io::BufReader::new(io::stdin());
		Some(Box::new(reader))
	});
	let _ = c.set_stdout({
		use std::io;
		Some(Box::new(io::stdout()))
	});

	/* Enter interactive loop */
	use std::io::{stdin, BufReader, BufRead};
	let mut prompt = BufReader::new(stdin());
	loop{
		eprint!("> ");

		let mut line = String::new();
		match prompt.read_line(&mut line){
			Ok(count) => if count == 0 {
				eprintln!("Reached end of input.");
				break
			},
			Err(what) => {
				eprintln!("A read error occured: {:?}", what);
				break
			}
		}

		/* Parse and evaluate */
		if let Err(what) = c.process_line(&line){
			eprintln!("{}", what);
		} else {
			/* Drives the currently pending instructions to
			 * completion. */

            use birl::vm::ExecutionStatus as Es;
            loop {
                match c.execute_next_instruction() {
                    Ok(Es::Quit) => {
                        eprintln!("Saindo...");
                        return;
                    }
                    Ok(Es::Halt) => break,
                    Ok(_) => {}
                    Err(e) => {
                        eprintln!("{}", e);
                    }
                }
            }
		}
	}

	/* Make sure the output is flushed */
	c.set_stdout(None).unwrap().flush()
		.expect("Could not flush io::stdout().");
}

fn print_help() {
	Context::print_version();

	println!("Ta querendo ajuda, cumpade?");
	println!("O uso é o seguinte: birl [opções] [arquivo ou arquivos]");
	println!("Cê pode passar mais de um arquivo, só que apenas um pode ter a seção \"SHOW\", que \
              é o ponto de partida do teu programa.");
	println!("As opções são as seguintes:");
	println!("\t-a ou --ajuda-o-maluco-ta-doente\t: Imprime essa mensagem de ajuda");
	println!("\t-v ou --versao\t\t\t\t: Imprime a versão do programa");
	println!("\t-s ou --string \"[codigo]\"\t\t: Executa o codigo na string ao inves de \
              um arquivo.");
	println!("\t-i ou --interativo\t\t\t\t: Inicia um console interativo pra rodar códigos");
}

/// Parameters passed through the command line
enum Param {
	PrintVersion,
	PrintHelp,
	/// Add a file to be processed
	InputFile(String),
	/// Processes code from a given string
	StringSource(String),
	/// Starts an interactive console for running code
	Interactive,
}

fn get_params() -> Vec<Param> {
	let mut arguments = args();
	let mut result: Vec<Param> = vec![];

	let _ = arguments.next().unwrap(); // Dispose of the first argument

	loop {
		if let Some(arg) = arguments.next() {
			match arg.as_str() {
				"-a" | "--ajuda-o-maluco-ta-doente" => result.push(Param::PrintHelp),
				"-v" | "--versao-cumpade" => result.push(Param::PrintVersion),
				"-i" | "--interativo" => result.push(Param::Interactive),
				"-s" | "--string" => {
					// The next argument is expected to be a string containing source code
					if let Some(code) = arguments.next() {
						result.push(Param::StringSource(code));
					} else {
						println!("Erro: O argumento {} precisa de um conteúdo logo em seguida, bixo.", arg);
					}
				}
				// Push the file to the result stack
				_ => result.push(Param::InputFile(arg))
			}
		} else {
			break;
		}
	}

	result
}

fn main() {
	let args = get_params();
	let mut interactive = false;

	let mut ctx = Context::new();

	if args.len() > 0 {
		for arg in args {
			match arg {
				Param::PrintHelp => print_help(),
				Param::Interactive => interactive = true,
				Param::PrintVersion => Context::print_version(),
				Param::InputFile(file) => {
					match ctx.add_file(file.as_str()) {
						Ok(_) => {}
						Err(e) => {
							println!("Ocorreu um erro ao adicionar o arquivo \"{}\" pro contexto : {}",
									 file.as_str(), e);
							// Exit? continue?
						}
					}
				}
				Param::StringSource(source) => {
					match ctx.add_source_string(source) {
						Ok(_) => {}
						Err(e) => {
							println!("Erro ao adicionar string de código ao contexto : {}", e);
						}
					}
				}
			}
		}
	} else {
		interactive = true;
	}

	if interactive {
		start_interactive_console();
	} else {
        /* Bind the Context interpreter to standard IO */
        let _ = ctx.set_stdin({
            use std::io;
            let reader = io::BufReader::new(io::stdin());
            Some(Box::new(reader))
        });
        let _ = ctx.set_stdout({
            use std::io;
            Some(Box::new(io::stdout()))
        });

		match ctx.start_program() {
			Ok(_) => {}
			Err(e) => println!("Erro de execução : {}", e),
		}
	}
}
<|endoftext|>


<commit_before>use anyhow::Result;
use rstest::rstest;

use crate::fixtures::*;
use crate::helper::*;

/// Test that the normal status command works as expected.
/// Calling `pueue` without any subcommand is equivalent of using `status`.
#[rstest]
#[case(false)]
#[case(true)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn default_status(#[case] use_subcommand: bool) -> Result<()> {
    let daemon = daemon().await?;
    let shared = &daemon.settings.shared;

    // Add a task and wait until it finishes.
    assert_success(add_task(shared, "ls", false).await?);
    wait_for_task_condition(shared, 0, |task| task.is_done()).await?;

    let subcommand = if use_subcommand {
        vec!["status"]
    } else {
        Vec::new()
    };

    let output = run_client_command(shared, &subcommand).await?;

    let context = get_task_context(&daemon.settings).await?;
    assert_stdout_matches("status__default_status", output.stdout, context)?;

    Ok(())
}

/// Test the status output with all columns enabled.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn full_status() -> Result<()> {
    let daemon = daemon().await?;
    let shared = &daemon.settings.shared;

    // Add a paused task so we can use it as a dependency.
    run_client_command(
        shared,
        &["add", "--label", "test", "--delay", "2 hours", "ls"],
    )
    .await?;

    // Add a second command that depends on the first one.
    run_client_command(shared, &["add", "--after=0", "ls"]).await?;

    let output = run_client_command(shared, &["status"]).await?;

    let context = get_task_context(&daemon.settings).await?;
    assert_stdout_matches("status__full_status", output.stdout, context)?;

    Ok(())
}

/// Calling `status` with the `--color=always` flag, colors the output as expected.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn colored_status() -> Result<()> {
    let daemon = daemon().await?;
    let shared = &daemon.settings.shared;

    // Add a task and wait until it finishes.
    assert_success(add_task(shared, "ls", false).await?);
    wait_for_task_condition(shared, 0, |task| task.is_done()).await?;

    let output = run_client_command(shared, &["--color", "always", "status"]).await?;

    let context = get_task_context(&daemon.settings).await?;
    assert_stdout_matches("status__status_with_color", output.stdout, context)?;

    Ok(())
}
<commit_msg>tests Client 'status --json'<commit_after>use anyhow::Context;
use anyhow::Result;
use pueue_lib::state::State;
use rstest::rstest;

use crate::fixtures::*;
use crate::helper::*;

/// Test that the normal status command works as expected.
/// Calling `pueue` without any subcommand is equivalent of using `status`.
#[rstest]
#[case(false)]
#[case(true)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn default_status(#[case] use_subcommand: bool) -> Result<()> {
    let daemon = daemon().await?;
    let shared = &daemon.settings.shared;

    // Add a task and wait until it finishes.
    assert_success(add_task(shared, "ls", false).await?);
    wait_for_task_condition(shared, 0, |task| task.is_done()).await?;

    let subcommand = if use_subcommand {
        vec!["status"]
    } else {
        Vec::new()
    };

    let output = run_client_command(shared, &subcommand).await?;

    let context = get_task_context(&daemon.settings).await?;
    assert_stdout_matches("status__default_status", output.stdout, context)?;

    Ok(())
}

/// Test the status output with all columns enabled.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn full_status() -> Result<()> {
    let daemon = daemon().await?;
    let shared = &daemon.settings.shared;

    // Add a paused task so we can use it as a dependency.
    run_client_command(
        shared,
        &["add", "--label", "test", "--delay", "2 hours", "ls"],
    )
    .await?;

    // Add a second command that depends on the first one.
    run_client_command(shared, &["add", "--after=0", "ls"]).await?;

    let output = run_client_command(shared, &["status"]).await?;

    let context = get_task_context(&daemon.settings).await?;
    assert_stdout_matches("status__full_status", output.stdout, context)?;

    Ok(())
}

/// Calling `status` with the `--color=always` flag, colors the output as expected.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn colored_status() -> Result<()> {
    let daemon = daemon().await?;
    let shared = &daemon.settings.shared;

    // Add a task and wait until it finishes.
    assert_success(add_task(shared, "ls", false).await?);
    wait_for_task_condition(shared, 0, |task| task.is_done()).await?;

    let output = run_client_command(shared, &["--color", "always", "status"]).await?;

    let context = get_task_context(&daemon.settings).await?;
    assert_stdout_matches("status__status_with_color", output.stdout, context)?;

    Ok(())
}

/// Calling `pueue status --json` will result in the current state being printed to the cli.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn status_json() -> Result<()> {
    let daemon = daemon().await?;
    let shared = &daemon.settings.shared;

    // Add a task and wait until it finishes.
    assert_success(add_task(shared, "ls", false).await?);
    wait_for_task_condition(shared, 0, |task| task.is_done()).await?;

    let output = run_client_command(shared, &["status", "--json"]).await?;

    let json = String::from_utf8_lossy(&output.stdout);
    let deserialized_state: State =
        serde_json::from_str(&*json).context("Failed to deserialize json state")?;

    let state = get_state(shared).await?;
    assert_eq!(
        deserialized_state, *state,
        "Json state differs from actual daemon state."
    );

    Ok(())
}
<|endoftext|>