<commit_before>use cli::Command;

use std::io::Write;
use std::fs::File;
use std::error::Error;

pub const DEFAULT_CONTENT: &'static str = "
## Funzzy events file
# more details see: https://github.com/cristianoliveira/funzzy
#
# list here all the events and the commands that it should execute

- name: run my tests
  run:'ls -a'
  when:
    change: 'src/**'
";

/// # `InitCommand`
///
/// Creates a funzzy yaml boilerplate.
///
pub struct InitCommand {
    pub file_name: &'static str,
}

impl Command for InitCommand {
    fn execute(&self) -> Result<(), String> {
        let mut yaml: File = match File::create(self.file_name) {
            Ok(f) => f,
            Err(err) => panic!("File wasn't created. Cause: {}", err),
        };

        if let Err(err) = yaml.write_all(DEFAULT_CONTENT.as_ref()) {
            return Err(String::from(err.description()));
        }

        Ok(())
    }
}
<commit_msg>fix: boilerplate file close #28<commit_after>use cli::Command;

use std::io::Write;
use std::fs::File;
use std::error::Error;

pub const DEFAULT_CONTENT: &'static str = "
## Funzzy events file
# more details see: https://github.com/cristianoliveira/funzzy
#
# list here all the events and the commands that it should execute

- name: run my test
  run: 'ls -a'
  when:
    change: 'src/**'
";

/// # `InitCommand`
///
/// Creates a funzzy yaml boilerplate.
///
pub struct InitCommand {
    pub file_name: &'static str,
}

impl Command for InitCommand {
    fn execute(&self) -> Result<(), String> {
        let mut yaml: File = match File::create(self.file_name) {
            Ok(f) => f,
            Err(err) => panic!("File wasn't created. Cause: {}", err),
        };

        if let Err(err) = yaml.write_all(DEFAULT_CONTENT.as_ref()) {
            return Err(String::from(err.description()));
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::path::Path;

use gltf;

use collision::{Aabb, Union};

use controls::CameraParams;
use render::math::*;
use render::mesh::Mesh;
use render::Root;
use render::camera::Camera;
use importdata::ImportData;

pub struct Node {
    pub index: usize, // glTF index
    pub children: Vec<usize>,
    pub matrix: Matrix4,
    pub mesh: Option<Rc<Mesh>>,
    pub rotation: Quaternion,
    pub scale: Vector3,
    pub translation: Vector3,
    // TODO: weights
    // weights_id: usize,
    pub camera: Option<Camera>,
    pub name: Option<String>,

    pub final_transform: Matrix4, // including parent transforms
    pub bounds: Aabb3,
}

impl Node {
    // TODO!: refactor transformations using mint and non-deprecated functions
    pub fn from_gltf(
        g_node: &gltf::Node,
        root: &mut Root,
        imp: &ImportData,
        base_path: &Path
    ) -> Node {
        // convert matrix in 3 steps due to type system weirdness
        let matrix = &g_node.transform().matrix();
        let matrix: &Matrix4 = matrix.into();
        let matrix = *matrix;

        let (trans, rot, scale) = g_node.transform().decomposed();
        let r = rot;
        let rotation = Quaternion::new(r[3], r[0], r[1], r[2]); // NOTE: different element order!

        let mut mesh = None;
        if let Some(g_mesh) = g_node.mesh() {
            if let Some(existing_mesh) = root.meshes.iter().find(|mesh| (***mesh).index == g_mesh.index()) {
                mesh = Some(Rc::clone(existing_mesh));
            }

            if mesh.is_none() { // not using else due to borrow-checking madness
                mesh = Some(Rc::new(Mesh::from_gltf(&g_mesh, root, imp, base_path)));
                root.meshes.push(mesh.clone().unwrap());
            }
        }
        let children: Vec<_> = g_node.children()
                .map(|g_node| g_node.index())
                .collect();

        Node {
            index: g_node.index(),
            children,
            matrix,
            mesh,
            rotation,
            scale: scale.into(),
            translation: trans.into(),
            camera: g_node.camera().as_ref().map(Camera::from_gltf),
            name: g_node.name().map(|s| s.into()),

            final_transform: Matrix4::identity(),

            bounds: Aabb3::zero(),
        }
    }

    pub fn update_transform(&mut self, root: &mut Root, parent_transform: &Matrix4) {
        self.final_transform = *parent_transform;

        if !self.matrix.is_identity() {
            self.final_transform = self.final_transform * self.matrix;
        }
        else {
            // TODO?: detect if all default and set None? does NOT happen for any sample model
            self.final_transform = self.final_transform *
                Matrix4::from_translation(self.translation) *
                Matrix4::from_nonuniform_scale(self.scale.x, self.scale.y, self.scale.z) *
                Matrix4::from(self.rotation);
        }

        for node_id in &self.children {
            let node = root.unsafe_get_node_mut(*node_id);
            node.update_transform(root, &self.final_transform);
        }
    }

    /// Should be called after update_transforms
    pub fn update_bounds(&mut self, root: &mut Root) {
        self.bounds = Aabb3::zero();
        if let Some(ref mesh) = self.mesh {
            self.bounds = mesh.bounds
                .transform(&self.final_transform);
        }
        else if self.children.is_empty() {
            // Cameras (others?) have neither mesh nor children. Their position is the origin
            // TODO!: are there other cases? Do bounds matter for cameras?
            self.bounds = Aabb3::zero();
            self.bounds = self.bounds.transform(&self.final_transform);
        }
        else {
            for node_id in &self.children {
                let node = root.unsafe_get_node_mut(*node_id);
                node.update_bounds(root);
                self.bounds = self.bounds.union(&node.bounds);
            }
        }
    }

    pub fn draw(&mut self, root: &mut Root, cam_params: &CameraParams) {
        if let Some(ref mesh) = self.mesh {
            let mvp_matrix = cam_params.projection_matrix * cam_params.view_matrix * self.final_transform;

            (*mesh).draw(&self.final_transform, &mvp_matrix, &cam_params.position);
        }
        for node_id in &self.children {
            let node = root.unsafe_get_node_mut(*node_id);
            node.draw(root, cam_params);
        }
    }
}
<commit_msg>remove matrix from primitive<commit_after>use std::rc::Rc;
use std::path::Path;

use gltf;

use collision::{Aabb, Union};

use controls::CameraParams;
use render::math::*;
use render::mesh::Mesh;
use render::Root;
use render::camera::Camera;
use importdata::ImportData;

pub struct Node {
    pub index: usize, // glTF index
    pub children: Vec<usize>,
    pub mesh: Option<Rc<Mesh>>,
    pub rotation: Quaternion,
    pub scale: Vector3,
    pub translation: Vector3,
    // TODO: weights
    // weights_id: usize,
    pub camera: Option<Camera>,
    pub name: Option<String>,

    pub final_transform: Matrix4, // including parent transforms
    pub bounds: Aabb3,
}

impl Node {
    pub fn from_gltf(
        g_node: &gltf::Node,
        root: &mut Root,
        imp: &ImportData,
        base_path: &Path
    ) -> Node {
        let (trans, rot, scale) = g_node.transform().decomposed();
        let r = rot;
        let rotation = Quaternion::new(r[3], r[0], r[1], r[2]); // NOTE: different element order!

        let mut mesh = None;
        if let Some(g_mesh) = g_node.mesh() {
            if let Some(existing_mesh) = root.meshes.iter().find(|mesh| (***mesh).index == g_mesh.index()) {
                mesh = Some(Rc::clone(existing_mesh));
            }

            if mesh.is_none() { // not using else due to borrow-checking madness
                mesh = Some(Rc::new(Mesh::from_gltf(&g_mesh, root, imp, base_path)));
                root.meshes.push(mesh.clone().unwrap());
            }
        }
        let children: Vec<_> = g_node.children()
                .map(|g_node| g_node.index())
                .collect();

        Node {
            index: g_node.index(),
            children,
            mesh,
            rotation,
            scale: scale.into(),
            translation: trans.into(),
            camera: g_node.camera().as_ref().map(Camera::from_gltf),
            name: g_node.name().map(|s| s.into()),

            final_transform: Matrix4::identity(),

            bounds: Aabb3::zero(),
        }
    }

    pub fn update_transform(&mut self, root: &mut Root, parent_transform: &Matrix4) {
        self.final_transform = *parent_transform;

        self.final_transform = self.final_transform *
            Matrix4::from_translation(self.translation) *
            Matrix4::from_nonuniform_scale(self.scale.x, self.scale.y, self.scale.z) *
            Matrix4::from(self.rotation);

        for node_id in &self.children {
            let node = root.unsafe_get_node_mut(*node_id);
            node.update_transform(root, &self.final_transform);
        }
    }

    /// Should be called after update_transforms
    pub fn update_bounds(&mut self, root: &mut Root) {
        self.bounds = Aabb3::zero();
        if let Some(ref mesh) = self.mesh {
            self.bounds = mesh.bounds
                .transform(&self.final_transform);
        }
        else if self.children.is_empty() {
            // Cameras (others?) have neither mesh nor children. Their position is the origin
            // TODO!: are there other cases? Do bounds matter for cameras?
            self.bounds = Aabb3::zero();
            self.bounds = self.bounds.transform(&self.final_transform);
        }
        else {
            for node_id in &self.children {
                let node = root.unsafe_get_node_mut(*node_id);
                node.update_bounds(root);
                self.bounds = self.bounds.union(&node.bounds);
            }
        }
    }

    pub fn draw(&mut self, root: &mut Root, cam_params: &CameraParams) {
        if let Some(ref mesh) = self.mesh {
            let mvp_matrix = cam_params.projection_matrix * cam_params.view_matrix * self.final_transform;

            (*mesh).draw(&self.final_transform, &mvp_matrix, &cam_params.position);
        }
        for node_id in &self.children {
            let node = root.unsafe_get_node_mut(*node_id);
            node.draw(root, cam_params);
        }
    }
}
<|endoftext|>


<commit_before>//! [RFC 5389](https://tools.ietf.org/html/rfc5389) specific components.
use trackable::error::ErrorKindExt;

use {Result, ErrorKind};
use message::RawMessage;
use attribute::{self, RawAttribute};
use types::U12;

pub mod methods;
pub mod attributes;
pub mod handlers;

/// Method set that are defined in [RFC 5389](https://tools.ietf.org/html/rfc5389).
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub enum Method {
    /// See [methods::Binding](methods/struct.Binding.html).
    Binding,
}
impl ::Method for Method {
    fn from_u12(value: U12) -> Option<Self> {
        match value.as_u16() {
            methods::METHOD_BINDING => Some(Method::Binding),
            _ => None,
        }
    }
    fn as_u12(&self) -> U12 {
        match *self {
            Method::Binding => methods::Binding.as_u12(),
        }
    }
}
impl From<methods::Binding> for Method {
    fn from(_: methods::Binding) -> Self {
        Method::Binding
    }
}

macro_rules! impl_attr_from {
    ($attr:ident) => {
        impl From<attributes::$attr> for Attribute {
            fn from(f: attributes::$attr) -> Self {
                Attribute::$attr(f)
            }
        }
    }
}

/// Attribute set that are defined in [RFC 5389](https://tools.ietf.org/html/rfc5389).
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Attribute {
    MappedAddress(attributes::MappedAddress),
    Username(attributes::Username),
    MessageIntegrity(attributes::MessageIntegrity),
    ErrorCode(attributes::ErrorCode),
    UnknownAttributes(attributes::UnknownAttributes),
    Realm(attributes::Realm),
    Nonce(attributes::Nonce),
    XorMappedAddress(attributes::XorMappedAddress),
    Software(attributes::Software),
    AlternateServer(attributes::AlternateServer),
    Fingerprint(attributes::Fingerprint),
}
impl_attr_from!(MappedAddress);
impl_attr_from!(Username);
impl_attr_from!(MessageIntegrity);
impl_attr_from!(ErrorCode);
impl_attr_from!(UnknownAttributes);
impl_attr_from!(Realm);
impl_attr_from!(Nonce);
impl_attr_from!(XorMappedAddress);
impl_attr_from!(Software);
impl_attr_from!(AlternateServer);
impl_attr_from!(Fingerprint);
impl ::Attribute for Attribute {
    fn get_type(&self) -> attribute::Type {
        match *self {
            Attribute::MappedAddress(ref a) => a.get_type(),
            Attribute::Username(ref a) => a.get_type(),
            Attribute::MessageIntegrity(ref a) => a.get_type(),
            Attribute::ErrorCode(ref a) => a.get_type(),
            Attribute::UnknownAttributes(ref a) => a.get_type(),
            Attribute::Realm(ref a) => a.get_type(),
            Attribute::Nonce(ref a) => a.get_type(),
            Attribute::XorMappedAddress(ref a) => a.get_type(),
            Attribute::Software(ref a) => a.get_type(),
            Attribute::AlternateServer(ref a) => a.get_type(),
            Attribute::Fingerprint(ref a) => a.get_type(),
        }
    }
    fn try_from_raw(attr: &RawAttribute, message: &RawMessage) -> Result<Self> {
        match attr.get_type().as_u16() {
            attributes::TYPE_MAPPED_ADDRESS => {
                attributes::MappedAddress::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_USERNAME => {
                attributes::Username::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_MESSAGE_INTEGRITY => {
                attributes::MessageIntegrity::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_ERROR_CODE => {
                attributes::ErrorCode::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_UNKNOWN_ATTRIBUTES => {
                attributes::UnknownAttributes::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_REALM => {
                attributes::Realm::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_NONCE => {
                attributes::Nonce::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_XOR_MAPPED_ADDRESS => {
                attributes::XorMappedAddress::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_SOFTWARE => {
                attributes::Software::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_ALTERNATE_SERVER => {
                attributes::AlternateServer::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_FINGERPRINT => {
                attributes::Fingerprint::try_from_raw(attr, message).map(From::from)
            }
            t => Err(ErrorKind::Unsupported.cause(format!("Unknown attribute: type={}", t))),
        }
    }
    fn encode_value(&self, message: &RawMessage) -> Result<Vec<u8>> {
        match *self {
            Attribute::MappedAddress(ref a) => a.encode_value(message),
            Attribute::Username(ref a) => a.encode_value(message),
            Attribute::MessageIntegrity(ref a) => a.encode_value(message),
            Attribute::ErrorCode(ref a) => a.encode_value(message),
            Attribute::UnknownAttributes(ref a) => a.encode_value(message),
            Attribute::Realm(ref a) => a.encode_value(message),
            Attribute::Nonce(ref a) => a.encode_value(message),
            Attribute::XorMappedAddress(ref a) => a.encode_value(message),
            Attribute::Software(ref a) => a.encode_value(message),
            Attribute::AlternateServer(ref a) => a.encode_value(message),
            Attribute::Fingerprint(ref a) => a.encode_value(message),
        }
    }
}
<commit_msg>Add `#[allow(missing_docs)]`<commit_after>//! [RFC 5389](https://tools.ietf.org/html/rfc5389) specific components.
use trackable::error::ErrorKindExt;

use {Result, ErrorKind};
use message::RawMessage;
use attribute::{self, RawAttribute};
use types::U12;

pub mod methods;
pub mod attributes;
pub mod handlers;

/// Method set that are defined in [RFC 5389](https://tools.ietf.org/html/rfc5389).
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub enum Method {
    /// See [methods::Binding](methods/struct.Binding.html).
    Binding,
}
impl ::Method for Method {
    fn from_u12(value: U12) -> Option<Self> {
        match value.as_u16() {
            methods::METHOD_BINDING => Some(Method::Binding),
            _ => None,
        }
    }
    fn as_u12(&self) -> U12 {
        match *self {
            Method::Binding => methods::Binding.as_u12(),
        }
    }
}
impl From<methods::Binding> for Method {
    fn from(_: methods::Binding) -> Self {
        Method::Binding
    }
}

macro_rules! impl_attr_from {
    ($attr:ident) => {
        impl From<attributes::$attr> for Attribute {
            fn from(f: attributes::$attr) -> Self {
                Attribute::$attr(f)
            }
        }
    }
}

/// Attribute set that are defined in [RFC 5389](https://tools.ietf.org/html/rfc5389).
#[allow(missing_docs)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Attribute {
    MappedAddress(attributes::MappedAddress),
    Username(attributes::Username),
    MessageIntegrity(attributes::MessageIntegrity),
    ErrorCode(attributes::ErrorCode),
    UnknownAttributes(attributes::UnknownAttributes),
    Realm(attributes::Realm),
    Nonce(attributes::Nonce),
    XorMappedAddress(attributes::XorMappedAddress),
    Software(attributes::Software),
    AlternateServer(attributes::AlternateServer),
    Fingerprint(attributes::Fingerprint),
}
impl_attr_from!(MappedAddress);
impl_attr_from!(Username);
impl_attr_from!(MessageIntegrity);
impl_attr_from!(ErrorCode);
impl_attr_from!(UnknownAttributes);
impl_attr_from!(Realm);
impl_attr_from!(Nonce);
impl_attr_from!(XorMappedAddress);
impl_attr_from!(Software);
impl_attr_from!(AlternateServer);
impl_attr_from!(Fingerprint);
impl ::Attribute for Attribute {
    fn get_type(&self) -> attribute::Type {
        match *self {
            Attribute::MappedAddress(ref a) => a.get_type(),
            Attribute::Username(ref a) => a.get_type(),
            Attribute::MessageIntegrity(ref a) => a.get_type(),
            Attribute::ErrorCode(ref a) => a.get_type(),
            Attribute::UnknownAttributes(ref a) => a.get_type(),
            Attribute::Realm(ref a) => a.get_type(),
            Attribute::Nonce(ref a) => a.get_type(),
            Attribute::XorMappedAddress(ref a) => a.get_type(),
            Attribute::Software(ref a) => a.get_type(),
            Attribute::AlternateServer(ref a) => a.get_type(),
            Attribute::Fingerprint(ref a) => a.get_type(),
        }
    }
    fn try_from_raw(attr: &RawAttribute, message: &RawMessage) -> Result<Self> {
        match attr.get_type().as_u16() {
            attributes::TYPE_MAPPED_ADDRESS => {
                attributes::MappedAddress::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_USERNAME => {
                attributes::Username::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_MESSAGE_INTEGRITY => {
                attributes::MessageIntegrity::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_ERROR_CODE => {
                attributes::ErrorCode::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_UNKNOWN_ATTRIBUTES => {
                attributes::UnknownAttributes::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_REALM => {
                attributes::Realm::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_NONCE => {
                attributes::Nonce::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_XOR_MAPPED_ADDRESS => {
                attributes::XorMappedAddress::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_SOFTWARE => {
                attributes::Software::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_ALTERNATE_SERVER => {
                attributes::AlternateServer::try_from_raw(attr, message).map(From::from)
            }
            attributes::TYPE_FINGERPRINT => {
                attributes::Fingerprint::try_from_raw(attr, message).map(From::from)
            }
            t => Err(ErrorKind::Unsupported.cause(format!("Unknown attribute: type={}", t))),
        }
    }
    fn encode_value(&self, message: &RawMessage) -> Result<Vec<u8>> {
        match *self {
            Attribute::MappedAddress(ref a) => a.encode_value(message),
            Attribute::Username(ref a) => a.encode_value(message),
            Attribute::MessageIntegrity(ref a) => a.encode_value(message),
            Attribute::ErrorCode(ref a) => a.encode_value(message),
            Attribute::UnknownAttributes(ref a) => a.encode_value(message),
            Attribute::Realm(ref a) => a.encode_value(message),
            Attribute::Nonce(ref a) => a.encode_value(message),
            Attribute::XorMappedAddress(ref a) => a.encode_value(message),
            Attribute::Software(ref a) => a.encode_value(message),
            Attribute::AlternateServer(ref a) => a.encode_value(message),
            Attribute::Fingerprint(ref a) => a.encode_value(message),
        }
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::sync::mpsc;
use std::fmt;
use types::{MaybeOwned, Storage};
use stream::Stream;

use self::SigValue::*;

/// Represents a discrete value that changes over time.
///
/// Signals are usually constructed by stream operations and can be read using the `sample` or
/// `sample_with` methods.
#[derive(Debug)]
pub struct Signal<T>(SigValue<T>);

enum SigValue<T>
{
    /// A signal with constant value.
    ///
    /// We store the value in a Rc to provide Clone support without a `T: Clone` bound.
    Constant(Rc<T>),
    /// A signal that generates it's values from a function.
    ///
    /// This is produced by `Signal::from_fn`
    Dynamic(Rc<Fn() -> T>),
    /// A signal that contains shared data.
    ///
    /// This is produced by stream methods that create a signal.
    /// It contains an updater function and a value storage.
    Shared(Rc<Fn()>, Rc<Storage<T>>),
    /// A signal that contains a signal, and allows sampling the inner signal directly.
    ///
    /// This is produced by `Signal::switch`
    Nested(Rc<Fn() -> Signal<T>>),
}

impl<T> Signal<T>
{
    /// Creates a signal with constant value.
    ///
    /// The value is assumed to be constant, so changing it while it's stored on the
    /// signal is a logic error and will cause unexpected results.
    pub fn constant<V: Into<Rc<T>>>(val: V) -> Self
    {
        Signal(Constant(val.into()))
    }

    /// Creates a signal that samples it's values from an external source.
    ///
    /// The closure is meant to sample a continuous value from the real world,
    /// so the signal value is assumed to be always changing.
    pub fn from_fn<F>(f: F) -> Self
        where F: Fn() -> T + 'static
    {
        Signal(Dynamic(Rc::new(f)))
    }

    /// Checks if the signal has changed since the last time it was sampled.
    pub fn has_changed(&self) -> bool
    {
        match self.0 {
            Constant(_) => false,
            Dynamic(_) | Nested(_) => true,
            Shared(_, ref st) => st.must_update(),
        }
    }

    /// Sample by reference.
    ///
    /// This is meant to be the most efficient way when cloning is undesirable,
    /// but it requires a callback to prevent outliving internal borrows.
    pub fn sample_with<F, R>(&self, cb: F) -> R
        where F: FnOnce(MaybeOwned<T>) -> R
    {
        match self.0
        {
            Constant(ref val) => cb(MaybeOwned::Borrowed(val)),
            Dynamic(ref f) => cb(MaybeOwned::Owned(f())),
            Shared(ref f, ref st) => { f(); st.borrow(cb) },
            Nested(ref f) => f().sample_with(cb),
        }
    }
}

impl<T: Clone> Signal<T>
{
    /// Sample by value.
    ///
    /// This will clone the content of the signal.
    pub fn sample(&self) -> T
    {
        match self.0
        {
            Constant(ref val) => (**val).clone(),
            Dynamic(ref f) => f(),
            Shared(ref f, ref st) => { f(); st.get() },
            Nested(ref f) => f().sample(),
        }
    }
}

impl<T: 'static> Signal<T>
{
    /// Maps a signal with the provided function.
    ///
    /// The closure is called only when the parent signal changes.
    pub fn map<F, R>(&self, f: F) -> Signal<R>
        where F: Fn(MaybeOwned<T>) -> R + 'static,
        R: 'static
    {
        match self.0 {
            // constant signal: apply f once to produce another constant signal
            Constant(ref val) => {
                Signal::constant(f(MaybeOwned::Borrowed(val)))
            }
            // shared signal: apply f only when the parent signal has changed
            Shared(ref upd_, ref st) => {
                let updater = upd_.clone();
                let parent_st = st.clone();
                // the storage inherits the root serial so we can track changes at the source
                let storage = Rc::new(Storage::empty(st.root_ser.clone()));
                let st_cloned = storage.clone();
                Signal(Shared(Rc::new(move || {
                    if storage.must_update()
                    {
                        // sample and map the parent signal
                        updater();
                        storage.set_local(parent_st.borrow(&f))
                    }
                }), st_cloned))
            }
            // dynamic/nested signal: apply f unconditionally
            Dynamic(_) | Nested(_) => {
                let this = self.clone();
                Signal::from_fn(move || this.sample_with(&f))
            }
        }
    }

    /// Samples the value of this signal every time the trigger stream fires.
    pub fn snapshot<S, F, R>(&self, trigger: &Stream<S>, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>, MaybeOwned<S>) -> R + 'static,
        S: 'static, R: 'static
    {
        let this = self.clone();
        trigger.map(move |b| this.sample_with(|a| f(a, b)))
    }

    /// Creates a signal from a shared value.
    pub(crate) fn from_storage<A: 'static>(storage: Rc<Storage<T>>, keepalive: A) -> Self
    {
        Signal(Shared(Rc::new(move || {
            // the closure owns and does type erasure on the value
            let _keepalive = &keepalive;
        }), storage))
    }

    /// Stores the last value sent to a channel.
    ///
    /// When sampled, the resulting signal consumes all the current values on the channel
    /// (using non-blocking operations) and returns the last value seen.
    pub fn from_channel(initial: T, rx: mpsc::Receiver<T>) -> Self
    {
        let storage = Rc::new(Storage::new(initial));
        let st_cloned = storage.clone();
        Signal(Shared(Rc::new(move || {
            let last = rx.try_iter().last();
            if let Some(val) = last { storage.set(val); }
        }), st_cloned))
    }

    /// Creates a signal that folds the values from a channel.
    ///
    /// When sampled, the resulting signal consumes all the current values on the channel
    /// (using non-blocking operations) and folds them using the current signal value as the
    /// initial accumulator state.
    pub fn fold_channel<V, F>(initial: T, rx: mpsc::Receiver<V>, f: F) -> Self
        where F: Fn(T, V) -> T + 'static,
        V: 'static
    {
        let storage = Rc::new(Storage::new(initial));
        let st_cloned = storage.clone();
        Signal(Shared(Rc::new(move || {
            let acc = storage.take();
            let current = rx.try_iter().fold(acc, &f);
            storage.set(current);
        }), st_cloned))
    }
}

impl<T: 'static> Signal<Signal<T>>
{
    /// Creates a new signal that samples the inner value of a nested signal.
    pub fn switch(&self) -> Signal<T>
    {
        match self.0
        {
            // constant signal: just extract the inner signal
            Constant(ref sig) => (**sig).clone(),
            // dynamic signal: re-label as nested
            Dynamic(ref f) => Signal(Nested(f.clone())),
            // shared signal: sample to extract the inner signal
            Shared(ref upd, ref st) => {
                let updater = upd.clone();
                let storage = st.clone();
                Signal(Nested(Rc::new(move || { updater(); storage.get() })))
            }
            // nested signal: remove one layer
            Nested(ref f_) => {
                let f = f_.clone();
                Signal(Nested(Rc::new(move || f().sample())))
            }
        }
    }
}

impl<T: Default> Default for Signal<T>
{
    /// Creates a constant signal with T's default value.
    #[inline]
    fn default() -> Self
    {
        Signal::constant(T::default())
    }
}

impl<T> From<T> for Signal<T>
{
    /// Creates a constant signal from T.
    #[inline]
    fn from(val: T) -> Self
    {
        Signal::constant(val)
    }
}

impl<T> From<Rc<T>> for Signal<T>
{
    /// Creates a constant signal from T (avoids re-wrapping the Rc).
    #[inline]
    fn from(val: Rc<T>) -> Self
    {
        Signal(Constant(val))
    }
}

// the derive impl adds a `T: Clone` we don't want
impl<T> Clone for Signal<T>
{
    /// Creates a copy of this signal that references the same value.
    fn clone(&self) -> Self
    {
        Signal(match self.0
        {
            Constant(ref val) => Constant(val.clone()),
            Dynamic(ref rf) => Dynamic(rf.clone()),
            Shared(ref rf, ref st) => Shared(rf.clone(), st.clone()),
            Nested(ref rf) => Nested(rf.clone()),
        })
    }
}

impl<T: fmt::Debug> fmt::Debug for SigValue<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match *self
        {
            Constant(ref val) => write!(f, "Constant({:?})", val),
            Dynamic(ref rf) => write!(f, "Dynamic(Fn@{:p})", rf),
            Shared(ref rf, ref st) => write!(f, "Shared(Fn@{:p}, {:?})", rf, st),
            Nested(ref rf) => write!(f, "Nested(Fn@{:p})", rf),
        }
    }
}

impl<T: fmt::Display> fmt::Display for Signal<T>
{
    /// Samples the signal and formats the value.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        self.sample_with(|val| fmt::Display::fmt(&*val, f))
    }
}

#[cfg(test)]
mod tests
{
    use super::*;
    use std::rc::Rc;
    use std::cell::Cell;
    use std::time::Instant;

    #[test]
    fn signal_basic()
    {
        let signal = Signal::constant(42);
        let double = signal.map(|a| *a * 2);
        let plusone = double.map(|a| *a + 1);
        assert_eq!(signal.sample(), 42);
        assert_eq!(double.sample(), 84);
        assert_eq!(plusone.sample(), 85);
        signal.sample_with(|val| assert_eq!(*val, 42));
    }

    #[test]
    fn signal_shared()
    {
        let st = Rc::new(Storage::new(1));
        let signal = Signal::from_storage(st.clone(), ());
        let double = signal.map(|a| *a * 2);

        assert_eq!(signal.sample(), 1);
        assert_eq!(double.sample(), 2);
        st.set(42);
        assert_eq!(signal.sample(), 42);
        assert_eq!(double.sample(), 84);
    }

    #[test]
    fn signal_dynamic()
    {
        let t = Instant::now();
        let signal = Signal::from_fn(move || t);
        assert_eq!(signal.sample(), t);
        signal.sample_with(|val| assert_eq!(*val, t));

        let n = Rc::new(Cell::new(1));
        let cloned = n.clone();
        let signal = Signal::from_fn(move || cloned.get());
        let double = signal.map(|a| *a * 2);
        let plusone = double.map(|a| *a + 1);
        assert_eq!(signal.sample(), 1);
        assert_eq!(double.sample(), 2);
        assert_eq!(plusone.sample(), 3);
        n.set(13);
        assert_eq!(signal.sample(), 13);
        assert_eq!(double.sample(), 26);
        assert_eq!(plusone.sample(), 27);
    }
}
<commit_msg>fold_channel: only write to the storage when there is data to process<commit_after>use std::rc::Rc;
use std::sync::mpsc;
use std::fmt;
use types::{MaybeOwned, Storage};
use stream::Stream;

use self::SigValue::*;

/// Represents a discrete value that changes over time.
///
/// Signals are usually constructed by stream operations and can be read using the `sample` or
/// `sample_with` methods.
#[derive(Debug)]
pub struct Signal<T>(SigValue<T>);

enum SigValue<T>
{
    /// A signal with constant value.
    ///
    /// We store the value in a Rc to provide Clone support without a `T: Clone` bound.
    Constant(Rc<T>),
    /// A signal that generates it's values from a function.
    ///
    /// This is produced by `Signal::from_fn`
    Dynamic(Rc<Fn() -> T>),
    /// A signal that contains shared data.
    ///
    /// This is produced by stream methods that create a signal.
    /// It contains an updater function and a value storage.
    Shared(Rc<Fn()>, Rc<Storage<T>>),
    /// A signal that contains a signal, and allows sampling the inner signal directly.
    ///
    /// This is produced by `Signal::switch`
    Nested(Rc<Fn() -> Signal<T>>),
}

impl<T> Signal<T>
{
    /// Creates a signal with constant value.
    ///
    /// The value is assumed to be constant, so changing it while it's stored on the
    /// signal is a logic error and will cause unexpected results.
    pub fn constant<V: Into<Rc<T>>>(val: V) -> Self
    {
        Signal(Constant(val.into()))
    }

    /// Creates a signal that samples it's values from an external source.
    ///
    /// The closure is meant to sample a continuous value from the real world,
    /// so the signal value is assumed to be always changing.
    pub fn from_fn<F>(f: F) -> Self
        where F: Fn() -> T + 'static
    {
        Signal(Dynamic(Rc::new(f)))
    }

    /// Checks if the signal has changed since the last time it was sampled.
    pub fn has_changed(&self) -> bool
    {
        match self.0 {
            Constant(_) => false,
            Dynamic(_) | Nested(_) => true,
            Shared(_, ref st) => st.must_update(),
        }
    }

    /// Sample by reference.
    ///
    /// This is meant to be the most efficient way when cloning is undesirable,
    /// but it requires a callback to prevent outliving internal borrows.
    pub fn sample_with<F, R>(&self, cb: F) -> R
        where F: FnOnce(MaybeOwned<T>) -> R
    {
        match self.0
        {
            Constant(ref val) => cb(MaybeOwned::Borrowed(val)),
            Dynamic(ref f) => cb(MaybeOwned::Owned(f())),
            Shared(ref f, ref st) => { f(); st.borrow(cb) },
            Nested(ref f) => f().sample_with(cb),
        }
    }
}

impl<T: Clone> Signal<T>
{
    /// Sample by value.
    ///
    /// This will clone the content of the signal.
    pub fn sample(&self) -> T
    {
        match self.0
        {
            Constant(ref val) => (**val).clone(),
            Dynamic(ref f) => f(),
            Shared(ref f, ref st) => { f(); st.get() },
            Nested(ref f) => f().sample(),
        }
    }
}

impl<T: 'static> Signal<T>
{
    /// Maps a signal with the provided function.
    ///
    /// The closure is called only when the parent signal changes.
    pub fn map<F, R>(&self, f: F) -> Signal<R>
        where F: Fn(MaybeOwned<T>) -> R + 'static,
        R: 'static
    {
        match self.0 {
            // constant signal: apply f once to produce another constant signal
            Constant(ref val) => {
                Signal::constant(f(MaybeOwned::Borrowed(val)))
            }
            // shared signal: apply f only when the parent signal has changed
            Shared(ref upd_, ref st) => {
                let updater = upd_.clone();
                let parent_st = st.clone();
                // the storage inherits the root serial so we can track changes at the source
                let storage = Rc::new(Storage::empty(st.root_ser.clone()));
                let st_cloned = storage.clone();
                Signal(Shared(Rc::new(move || {
                    if storage.must_update()
                    {
                        // sample and map the parent signal
                        updater();
                        storage.set_local(parent_st.borrow(&f))
                    }
                }), st_cloned))
            }
            // dynamic/nested signal: apply f unconditionally
            Dynamic(_) | Nested(_) => {
                let this = self.clone();
                Signal::from_fn(move || this.sample_with(&f))
            }
        }
    }

    /// Samples the value of this signal every time the trigger stream fires.
    pub fn snapshot<S, F, R>(&self, trigger: &Stream<S>, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>, MaybeOwned<S>) -> R + 'static,
        S: 'static, R: 'static
    {
        let this = self.clone();
        trigger.map(move |b| this.sample_with(|a| f(a, b)))
    }

    /// Creates a signal from a shared value.
    pub(crate) fn from_storage<A: 'static>(storage: Rc<Storage<T>>, keepalive: A) -> Self
    {
        Signal(Shared(Rc::new(move || {
            // the closure owns and does type erasure on the value
            let _keepalive = &keepalive;
        }), storage))
    }

    /// Stores the last value sent to a channel.
    ///
    /// When sampled, the resulting signal consumes all the current values on the channel
    /// (using non-blocking operations) and returns the last value seen.
    pub fn from_channel(initial: T, rx: mpsc::Receiver<T>) -> Self
    {
        let storage = Rc::new(Storage::new(initial));
        let st_cloned = storage.clone();
        Signal(Shared(Rc::new(move || {
            let last = rx.try_iter().last();
            if let Some(val) = last { storage.set(val); }
        }), st_cloned))
    }

    /// Creates a signal that folds the values from a channel.
    ///
    /// When sampled, the resulting signal consumes all the current values on the channel
    /// (using non-blocking operations) and folds them using the current signal value as the
    /// initial accumulator state.
    pub fn fold_channel<V, F>(initial: T, rx: mpsc::Receiver<V>, f: F) -> Self
        where F: Fn(T, V) -> T + 'static,
        V: 'static
    {
        let storage = Rc::new(Storage::new(initial));
        let st_cloned = storage.clone();
        Signal(Shared(Rc::new(move || {
            if let Ok(first) = rx.try_recv()
            {
                let acc = f(storage.take(), first);
                let current = rx.try_iter().fold(acc, &f);
                storage.set(current);
            }
        }), st_cloned))
    }
}

impl<T: 'static> Signal<Signal<T>>
{
    /// Creates a new signal that samples the inner value of a nested signal.
    pub fn switch(&self) -> Signal<T>
    {
        match self.0
        {
            // constant signal: just extract the inner signal
            Constant(ref sig) => (**sig).clone(),
            // dynamic signal: re-label as nested
            Dynamic(ref f) => Signal(Nested(f.clone())),
            // shared signal: sample to extract the inner signal
            Shared(ref upd, ref st) => {
                let updater = upd.clone();
                let storage = st.clone();
                Signal(Nested(Rc::new(move || { updater(); storage.get() })))
            }
            // nested signal: remove one layer
            Nested(ref f_) => {
                let f = f_.clone();
                Signal(Nested(Rc::new(move || f().sample())))
            }
        }
    }
}

impl<T: Default> Default for Signal<T>
{
    /// Creates a constant signal with T's default value.
    #[inline]
    fn default() -> Self
    {
        Signal::constant(T::default())
    }
}

impl<T> From<T> for Signal<T>
{
    /// Creates a constant signal from T.
    #[inline]
    fn from(val: T) -> Self
    {
        Signal::constant(val)
    }
}

impl<T> From<Rc<T>> for Signal<T>
{
    /// Creates a constant signal from T (avoids re-wrapping the Rc).
    #[inline]
    fn from(val: Rc<T>) -> Self
    {
        Signal(Constant(val))
    }
}

// the derive impl adds a `T: Clone` we don't want
impl<T> Clone for Signal<T>
{
    /// Creates a copy of this signal that references the same value.
    fn clone(&self) -> Self
    {
        Signal(match self.0
        {
            Constant(ref val) => Constant(val.clone()),
            Dynamic(ref rf) => Dynamic(rf.clone()),
            Shared(ref rf, ref st) => Shared(rf.clone(), st.clone()),
            Nested(ref rf) => Nested(rf.clone()),
        })
    }
}

impl<T: fmt::Debug> fmt::Debug for SigValue<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match *self
        {
            Constant(ref val) => write!(f, "Constant({:?})", val),
            Dynamic(ref rf) => write!(f, "Dynamic(Fn@{:p})", rf),
            Shared(ref rf, ref st) => write!(f, "Shared(Fn@{:p}, {:?})", rf, st),
            Nested(ref rf) => write!(f, "Nested(Fn@{:p})", rf),
        }
    }
}

impl<T: fmt::Display> fmt::Display for Signal<T>
{
    /// Samples the signal and formats the value.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        self.sample_with(|val| fmt::Display::fmt(&*val, f))
    }
}

#[cfg(test)]
mod tests
{
    use super::*;
    use std::rc::Rc;
    use std::cell::Cell;
    use std::time::Instant;

    #[test]
    fn signal_basic()
    {
        let signal = Signal::constant(42);
        let double = signal.map(|a| *a * 2);
        let plusone = double.map(|a| *a + 1);
        assert_eq!(signal.sample(), 42);
        assert_eq!(double.sample(), 84);
        assert_eq!(plusone.sample(), 85);
        signal.sample_with(|val| assert_eq!(*val, 42));
    }

    #[test]
    fn signal_shared()
    {
        let st = Rc::new(Storage::new(1));
        let signal = Signal::from_storage(st.clone(), ());
        let double = signal.map(|a| *a * 2);

        assert_eq!(signal.sample(), 1);
        assert_eq!(double.sample(), 2);
        st.set(42);
        assert_eq!(signal.sample(), 42);
        assert_eq!(double.sample(), 84);
    }

    #[test]
    fn signal_dynamic()
    {
        let t = Instant::now();
        let signal = Signal::from_fn(move || t);
        assert_eq!(signal.sample(), t);
        signal.sample_with(|val| assert_eq!(*val, t));

        let n = Rc::new(Cell::new(1));
        let cloned = n.clone();
        let signal = Signal::from_fn(move || cloned.get());
        let double = signal.map(|a| *a * 2);
        let plusone = double.map(|a| *a + 1);
        assert_eq!(signal.sample(), 1);
        assert_eq!(double.sample(), 2);
        assert_eq!(plusone.sample(), 3);
        n.set(13);
        assert_eq!(signal.sample(), 13);
        assert_eq!(double.sample(), 26);
        assert_eq!(plusone.sample(), 27);
    }
}
<|endoftext|>


<commit_before>// rustfmt-normalize_comments: true
// rustfmt-error_on_line_overflow: false

// Imports.

// Long import.
use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA,
                                                                                ItemB};
use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA,
                                                                                ItemB};
use syntax::ast::{ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};

use list::{// Another item
           AnotherItem, // Another Comment
           // Last Item
           LastItem,
           // Some item
           SomeItem /* Comment */};

use test::{/* A */ self /* B */, Other /* C */};

use Foo::{Bar, Baz};
use syntax;
pub use syntax::ast::{Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath, Expr_};
use {Bar /* comment */, /* Pre-comment! */ Foo};

use self;
use std::io;
use std::io;

mod Foo {
    pub use syntax::ast::{ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};

    mod Foo2 {
        pub use syntax::ast::{self, ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod,
                              ItemStatic};
    }
}

fn test() {
    use Baz::*;
    use Qux;
}

// Simple imports
use bar::quux as kaas;
use foo;
use foo::bar::baz;

// With aliases.
use foo as bar;
use foo::qux as bar;
use foo::{self as bar, baz};
use foo::{baz, qux as bar};

// With absolute paths
use Foo;
use foo;
use foo::Bar;
use foo::{Bar, Baz};
use {Bar, Baz};

// Root globs
use ::*;
use ::*;

// spaces used to cause glob imports to disappear (#1356)
use super::*;
use foo::issue_1356::*;

// We shouldn't remove imports which have attributes attached (#1858)
#[cfg(unix)]
use self::unix::{};

// nested imports
use foo::{a, b, boo, c,
          bar::{baz, qux, xxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzzzzz,
                foo::{a, b, cxxxxxxxxxxxxx, yyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz}}};

use fooo::{bar, x, y, z,
           baar::foobar::{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,
                          zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz},
           bar::*};

// nested imports with a single sub-tree.
use a::b::c::d;
use a::b::c::*;
use a::b::c::{xxx, yyy, zzz};
<commit_msg>Update a test<commit_after>// rustfmt-normalize_comments: true
// rustfmt-error_on_line_overflow: false

// Imports.

// Long import.
use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA,
                                                                                ItemB};
use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA,
                                                                                ItemB};
use syntax::ast::{ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};

use list::{// Another item
           AnotherItem, // Another Comment
           // Last Item
           LastItem,
           // Some item
           SomeItem /* Comment */};

use test::{/* A */ self /* B */, Other /* C */};

use Foo::{Bar, Baz};
use syntax;
pub use syntax::ast::{Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath, Expr_};
use {Bar /* comment */, /* Pre-comment! */ Foo};

use self;
use std::io;
use std::io;

mod Foo {
    pub use syntax::ast::{ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};

    mod Foo2 {
        pub use syntax::ast::{self, ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod,
                              ItemStatic};
    }
}

fn test() {
    use Baz::*;
    use Qux;
}

// Simple imports
use bar::quux as kaas;
use foo;
use foo::bar::baz;

// With aliases.
use foo as bar;
use foo::qux as bar;
use foo::{self as bar, baz};
use foo::{baz, qux as bar};

// With absolute paths
use Foo;
use foo;
use foo::Bar;
use foo::{Bar, Baz};
use {Bar, Baz};

// Root globs
use ::*;
use *;

// spaces used to cause glob imports to disappear (#1356)
use super::*;
use foo::issue_1356::*;

// We shouldn't remove imports which have attributes attached (#1858)
#[cfg(unix)]
use self::unix::{};

// nested imports
use foo::{a, b, boo, c,
          bar::{baz, qux, xxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzzzzz,
                foo::{a, b, cxxxxxxxxxxxxx, yyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz}}};

use fooo::{bar, x, y, z,
           baar::foobar::{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,
                          zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz},
           bar::*};

// nested imports with a single sub-tree.
use a::b::c::d;
use a::b::c::*;
use a::b::c::{xxx, yyy, zzz};
<|endoftext|>


<commit_before>use super::{Token, TokenFilter, TokenStream};
use rust_stemmers::{self, Algorithm};

/// Available stemmer languages.
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Copy, Clone)]
#[allow(missing_docs)]
pub enum Language {
    Arabic,
    Danish,
    Dutch,
    English,
    Finnish,
    French,
    German,
    Greek,
    Hungarian,
    Italian,
    Portuguese,
    Romanian,
    Russian,
    Spanish,
    Swedish,
    Tamil,
    Turkish,
}

impl Language {
    fn algorithm(self) -> Algorithm {
        use self::Language::*;
        match self {
            Arabic => Algorithm::Arabic,
            Danish => Algorithm::Danish,
            Dutch => Algorithm::Dutch,
            English => Algorithm::English,
            Finnish => Algorithm::Finnish,
            French => Algorithm::French,
            German => Algorithm::German,
            Greek => Algorithm::Greek,
            Hungarian => Algorithm::Hungarian,
            Italian => Algorithm::Italian,
            Portuguese => Algorithm::Portuguese,
            Romanian => Algorithm::Romanian,
            Russian => Algorithm::Russian,
            Spanish => Algorithm::Spanish,
            Swedish => Algorithm::Swedish,
            Tamil => Algorithm::Tamil,
            Turkish => Algorithm::Turkish,
        }
    }
}

/// `Stemmer` token filter. Several languages are supported, see `Language` for the available
/// languages.
/// Tokens are expected to be lowercased beforehand.
#[derive(Clone)]
pub struct Stemmer {
    stemmer_algorithm: Algorithm,
}

impl Stemmer {
    /// Creates a new Stemmer `TokenFilter` for a given language algorithm.
    pub fn new(language: Language) -> Stemmer {
        Stemmer {
            stemmer_algorithm: language.algorithm(),
        }
    }
}

impl Default for Stemmer {
    /// Creates a new Stemmer `TokenFilter` for English.
    fn default() -> Self {
        Stemmer::new(Language::English)
    }
}

impl<TailTokenStream> TokenFilter<TailTokenStream> for Stemmer
where
    TailTokenStream: TokenStream,
{
    type ResultTokenStream = StemmerTokenStream<TailTokenStream>;

    fn transform(&self, token_stream: TailTokenStream) -> Self::ResultTokenStream {
        let inner_stemmer = rust_stemmers::Stemmer::create(self.stemmer_algorithm);
        StemmerTokenStream::wrap(inner_stemmer, token_stream)
    }
}

pub struct StemmerTokenStream<TailTokenStream>
where
    TailTokenStream: TokenStream,
{
    tail: TailTokenStream,
    stemmer: rust_stemmers::Stemmer,
}

impl<TailTokenStream> TokenStream for StemmerTokenStream<TailTokenStream>
where
    TailTokenStream: TokenStream,
{
    fn token(&self) -> &Token {
        self.tail.token()
    }

    fn token_mut(&mut self) -> &mut Token {
        self.tail.token_mut()
    }

    fn advance(&mut self) -> bool {
        if !self.tail.advance() {
            return false;
        }
        // TODO remove allocation
        let stemmed_str: String = self.stemmer.stem(&self.token().text).into_owned();
        self.token_mut().text.clear();
        self.token_mut().text.push_str(&stemmed_str);
        true
    }
}

impl<TailTokenStream> StemmerTokenStream<TailTokenStream>
where
    TailTokenStream: TokenStream,
{
    fn wrap(
        stemmer: rust_stemmers::Stemmer,
        tail: TailTokenStream,
    ) -> StemmerTokenStream<TailTokenStream> {
        StemmerTokenStream { tail, stemmer }
    }
}
<commit_msg>add norwegian stemmer (#717)<commit_after>use super::{Token, TokenFilter, TokenStream};
use rust_stemmers::{self, Algorithm};

/// Available stemmer languages.
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Copy, Clone)]
#[allow(missing_docs)]
pub enum Language {
    Arabic,
    Danish,
    Dutch,
    English,
    Finnish,
    French,
    German,
    Greek,
    Hungarian,
    Italian,
    Norwegian,
    Portuguese,
    Romanian,
    Russian,
    Spanish,
    Swedish,
    Tamil,
    Turkish,
}

impl Language {
    fn algorithm(self) -> Algorithm {
        use self::Language::*;
        match self {
            Arabic => Algorithm::Arabic,
            Danish => Algorithm::Danish,
            Dutch => Algorithm::Dutch,
            English => Algorithm::English,
            Finnish => Algorithm::Finnish,
            French => Algorithm::French,
            German => Algorithm::German,
            Greek => Algorithm::Greek,
            Hungarian => Algorithm::Hungarian,
            Italian => Algorithm::Italian,
            Norwegian => Algorithm::Norwegian,
            Portuguese => Algorithm::Portuguese,
            Romanian => Algorithm::Romanian,
            Russian => Algorithm::Russian,
            Spanish => Algorithm::Spanish,
            Swedish => Algorithm::Swedish,
            Tamil => Algorithm::Tamil,
            Turkish => Algorithm::Turkish,
        }
    }
}

/// `Stemmer` token filter. Several languages are supported, see `Language` for the available
/// languages.
/// Tokens are expected to be lowercased beforehand.
#[derive(Clone)]
pub struct Stemmer {
    stemmer_algorithm: Algorithm,
}

impl Stemmer {
    /// Creates a new Stemmer `TokenFilter` for a given language algorithm.
    pub fn new(language: Language) -> Stemmer {
        Stemmer {
            stemmer_algorithm: language.algorithm(),
        }
    }
}

impl Default for Stemmer {
    /// Creates a new Stemmer `TokenFilter` for English.
    fn default() -> Self {
        Stemmer::new(Language::English)
    }
}

impl<TailTokenStream> TokenFilter<TailTokenStream> for Stemmer
where
    TailTokenStream: TokenStream,
{
    type ResultTokenStream = StemmerTokenStream<TailTokenStream>;

    fn transform(&self, token_stream: TailTokenStream) -> Self::ResultTokenStream {
        let inner_stemmer = rust_stemmers::Stemmer::create(self.stemmer_algorithm);
        StemmerTokenStream::wrap(inner_stemmer, token_stream)
    }
}

pub struct StemmerTokenStream<TailTokenStream>
where
    TailTokenStream: TokenStream,
{
    tail: TailTokenStream,
    stemmer: rust_stemmers::Stemmer,
}

impl<TailTokenStream> TokenStream for StemmerTokenStream<TailTokenStream>
where
    TailTokenStream: TokenStream,
{
    fn token(&self) -> &Token {
        self.tail.token()
    }

    fn token_mut(&mut self) -> &mut Token {
        self.tail.token_mut()
    }

    fn advance(&mut self) -> bool {
        if !self.tail.advance() {
            return false;
        }
        // TODO remove allocation
        let stemmed_str: String = self.stemmer.stem(&self.token().text).into_owned();
        self.token_mut().text.clear();
        self.token_mut().text.push_str(&stemmed_str);
        true
    }
}

impl<TailTokenStream> StemmerTokenStream<TailTokenStream>
where
    TailTokenStream: TokenStream,
{
    fn wrap(
        stemmer: rust_stemmers::Stemmer,
        tail: TailTokenStream,
    ) -> StemmerTokenStream<TailTokenStream> {
        StemmerTokenStream { tail, stemmer }
    }
}
<|endoftext|>


<commit_before>use clap::ArgMatches;
use client::Client;
use std::io::Write;
use std::thread::sleep;
use std::time::Duration;
use super::Result;
use termion;

pub fn run<W: Write, C: Client>(matches: &ArgMatches, buffer: &mut W, client: &C) -> Result<()> {
    if let Some(interval_string) = matches.value_of("interval") {
        let interval = interval_string.parse::<u64>()?;
        loop {
            print_status(buffer, client)?;
            buffer.flush()?;
            sleep(Duration::from_secs(interval));
        }
    };

    print_status(buffer, client)?;
    Ok(())
}

fn print_status<W: Write, C: Client>(buffer: &mut W, client: &C) -> Result<()> {
    write!(buffer, "{}{}", termion::clear::All, termion::cursor::Goto(1,1))?;

    match client.fetch_team() {
        Ok(team) => {
            write!(buffer, "Current Driver: {}", team.driver)?;
            Ok(())
        },
        Err(_error) => {
            write!(buffer, "No mob")?;
            Ok(())
        }
    }
}

#[cfg(test)]
mod test {
    use super::print_status;
    use client::{Client, MockClient};

    #[test]
    fn test_print_status() {
        let client = MockClient::new();
        let mut buffer = vec![];

        print_status(&mut buffer, &client).unwrap();

        let actual = String::from_utf8(buffer).unwrap();
        assert_eq!(actual, "\u{1b}[2J\u{1b}[1;1HCurrent Driver: Mike");
    }
}
<commit_msg>feat: Only clear terminal if interval<commit_after>use clap::ArgMatches;
use client::Client;
use std::io::Write;
use std::thread::sleep;
use std::time::Duration;
use super::Result;
use termion;

pub fn run<W: Write, C: Client>(matches: &ArgMatches, buffer: &mut W, client: &C) -> Result<()> {
    if let Some(interval_string) = matches.value_of("interval") {
        let interval = interval_string.parse::<u64>()?;
        loop {
            write!(buffer, "{}{}", termion::clear::All, termion::cursor::Goto(1,1))?;
            print_status(buffer, client)?;
            buffer.flush()?;
            sleep(Duration::from_secs(interval));
        }
    };

    print_status(buffer, client)?;
    Ok(())
}

fn print_status<W: Write, C: Client>(buffer: &mut W, client: &C) -> Result<()> {
    match client.fetch_team() {
        Ok(team) => {
            write!(buffer, "Current Driver: {}", team.driver)?;
            Ok(())
        },
        Err(_error) => {
            write!(buffer, "No mob")?;
            Ok(())
        }
    }
}

#[cfg(test)]
mod test {
    use super::print_status;
    use client::{Client, MockClient};

    #[test]
    fn test_print_status() {
        let client = MockClient::new();
        let mut buffer = vec![];

        print_status(&mut buffer, &client).unwrap();

        let actual = String::from_utf8(buffer).unwrap();
        assert_eq!(actual, "Current Driver: Mike");
    }
}
<|endoftext|>


<commit_before>use std::{
    io::{self, ErrorKind},
    net::{IpAddr, SocketAddr},
    pin::Pin,
    sync::Arc,
    task::{Context, Poll},
};

use futures::{future, ready};
use kcp::{Error as KcpError, KcpResult};
use tokio::{
    io::{AsyncRead, AsyncWrite, ReadBuf},
    net::UdpSocket,
    sync::mpsc,
};

use crate::{config::KcpConfig, session::KcpSession, skcp::KcpSocket};

pub struct KcpStream {
    session: Arc<KcpSession>,
    udp: Arc<UdpSocket>,
    recv_buffer: Vec<u8>,
    recv_buffer_pos: usize,
    recv_buffer_cap: usize,
}

impl Drop for KcpStream {
    fn drop(&mut self) {
        self.session.close();
    }
}

impl KcpStream {
    pub async fn connect(config: &KcpConfig, addr: SocketAddr) -> KcpResult<KcpStream> {
        let udp = match addr.ip() {
            IpAddr::V4(..) => UdpSocket::bind("0.0.0.0:0").await?,
            IpAddr::V6(..) => UdpSocket::bind("[::]:0").await?,
        };

        let udp = Arc::new(udp);
        let socket = KcpSocket::new(config, 0, udp.clone(), addr, config.stream)?;

        let session = KcpSession::new_shared(socket, config.session_expire, None);

        Ok(KcpStream {
            session,
            udp,
            recv_buffer: Vec::new(),
            recv_buffer_pos: 0,
            recv_buffer_cap: 0,
        })
    }

    pub fn poll_send(&mut self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<KcpResult<usize>> {
        // Mutex doesn't have poll_lock, spinning on it.
        let socket = self.session.kcp_socket();
        let mut kcp = match socket.try_lock() {
            Ok(guard) => guard,
            Err(..) => {
                cx.waker().wake_by_ref();
                return Poll::Pending;
            }
        };

        kcp.poll_send(cx, buf)
    }

    pub async fn send(&mut self, buf: &[u8]) -> KcpResult<usize> {
        future::poll_fn(|cx| self.poll_send(cx, buf)).await
    }

    pub fn poll_recv(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<KcpResult<usize>> {
        loop {
            // Consumes all data in buffer
            if self.recv_buffer_pos < self.recv_buffer_cap {
                let remaining = self.recv_buffer_cap - self.recv_buffer_pos;
                let copy_length = remaining.min(buf.len());

                buf.copy_from_slice(&self.recv_buffer[self.recv_buffer_pos..self.recv_buffer_pos + copy_length]);
                self.recv_buffer_pos += copy_length;
                return Ok(copy_length).into();
            }

            // Mutex doesn't have poll_lock, spinning on it.
            let socket = self.session.kcp_socket();
            let mut kcp = match socket.try_lock() {
                Ok(guard) => guard,
                Err(..) => {
                    cx.waker().wake_by_ref();
                    return Poll::Pending;
                }
            };

            loop {
                // Try to read from KCP
                // 1. Read directly with user provided `buf`
                match kcp.try_recv(buf) {
                    Ok(n) => return Ok(n).into(),
                    Err(KcpError::RecvQueueEmpty) => {
                        // Nothing in recv queue, read from UDP socket
                        let mut packet_buffer = [0u8; 65536];
                        let mut read_buffer = ReadBuf::new(&mut packet_buffer);
                        ready!(self.udp.poll_recv(cx, &mut read_buffer))?;
                        let packet = read_buffer.filled();

                        log::trace!("client read {} bytes", packet.len());

                        kcp.input(packet)?;
                        continue;
                    }
                    Err(KcpError::UserBufTooSmall) => {}
                    Err(err) => return Err(err).into(),
                }

                // 2. User `buf` too small, read to recv_buffer
                let required_size = kcp.peek_size()?;
                if self.recv_buffer.len() < required_size {
                    self.recv_buffer.resize(required_size, 0);
                }

                match kcp.try_recv(&mut self.recv_buffer) {
                    Ok(n) => {
                        self.recv_buffer_pos = 0;
                        self.recv_buffer_cap = n;
                        break;
                    }
                    Err(err) => return Err(err).into(),
                }
            }
        }
    }

    pub async fn recv(&mut self, buf: &mut [u8]) -> KcpResult<usize> {
        future::poll_fn(|cx| self.poll_recv(cx, buf)).await
    }
}

impl AsyncRead for KcpStream {
    fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {
        match ready!(self.poll_recv(cx, buf.initialize_unfilled())) {
            Ok(n) => {
                buf.advance(n);
                Ok(()).into()
            }
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }
}

impl AsyncWrite for KcpStream {
    fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
        match ready!(self.poll_send(cx, buf)) {
            Ok(n) => Ok(n).into(),
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }

    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        // Mutex doesn't have poll_lock, spinning on it.
        let socket = self.session.kcp_socket();
        let mut kcp = match socket.try_lock() {
            Ok(guard) => guard,
            Err(..) => {
                cx.waker().wake_by_ref();
                return Poll::Pending;
            }
        };

        match kcp.flush() {
            Ok(..) => Ok(()).into(),
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }

    fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        Ok(()).into()
    }
}

pub struct KcpServerStream {
    session: Arc<KcpSession>,
    recv_buffer: Vec<u8>,
    recv_buffer_pos: usize,
    recv_buffer_cap: usize,
}

impl Drop for KcpServerStream {
    fn drop(&mut self) {
        self.session.close();
    }
}

impl KcpServerStream {
    pub fn new(
        config: &KcpConfig,
        udp: Arc<UdpSocket>,
        conv: u32,
        peer_addr: SocketAddr,
        session_close_notifier: mpsc::Sender<u32>,
    ) -> KcpResult<KcpServerStream> {
        let socket = KcpSocket::new(config, conv, udp.clone(), peer_addr, true)?;
        let session = KcpSession::new_shared(socket, config.session_expire, Some(session_close_notifier));
        Ok(KcpServerStream::with_session(session))
    }

    pub fn with_session(session: Arc<KcpSession>) -> KcpServerStream {
        KcpServerStream {
            session,
            recv_buffer: Vec::new(),
            recv_buffer_pos: 0,
            recv_buffer_cap: 0,
        }
    }

    pub fn poll_send(&mut self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<KcpResult<usize>> {
        // Mutex doesn't have poll_lock, spinning on it.
        let socket = self.session.kcp_socket();
        let mut kcp = match socket.try_lock() {
            Ok(guard) => guard,
            Err(..) => {
                cx.waker().wake_by_ref();
                return Poll::Pending;
            }
        };

        kcp.poll_send(cx, buf)
    }

    pub async fn send(&mut self, buf: &[u8]) -> KcpResult<usize> {
        future::poll_fn(|cx| self.poll_send(cx, buf)).await
    }

    pub fn poll_recv(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<KcpResult<usize>> {
        loop {
            // Consumes all data in buffer
            if self.recv_buffer_pos < self.recv_buffer_cap {
                let remaining = self.recv_buffer_cap - self.recv_buffer_pos;
                let copy_length = remaining.min(buf.len());

                buf.copy_from_slice(&self.recv_buffer[self.recv_buffer_pos..self.recv_buffer_pos + copy_length]);
                self.recv_buffer_pos += copy_length;
                return Ok(copy_length).into();
            }

            // Mutex doesn't have poll_lock, spinning on it.
            let socket = self.session.kcp_socket();
            let mut kcp = match socket.try_lock() {
                Ok(guard) => guard,
                Err(..) => {
                    cx.waker().wake_by_ref();
                    return Poll::Pending;
                }
            };

            // Try to read from KCP
            // 1. Read directly with user provided `buf`
            match ready!(kcp.poll_recv(cx, buf)) {
                Ok(n) => return Ok(n).into(),
                Err(KcpError::UserBufTooSmall) => {}
                Err(err) => return Err(err).into(),
            }

            // 2. User `buf` too small, read to recv_buffer
            let required_size = kcp.peek_size()?;
            if self.recv_buffer.len() < required_size {
                self.recv_buffer.resize(required_size, 0);
            }

            match ready!(kcp.poll_recv(cx, &mut self.recv_buffer)) {
                Ok(n) => {
                    self.recv_buffer_pos = 0;
                    self.recv_buffer_cap = n;
                }
                Err(err) => return Err(err).into(),
            }
        }
    }

    pub async fn recv(&mut self, buf: &mut [u8]) -> KcpResult<usize> {
        future::poll_fn(|cx| self.poll_recv(cx, buf)).await
    }
}

impl AsyncRead for KcpServerStream {
    fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {
        match ready!(self.poll_recv(cx, buf.initialize_unfilled())) {
            Ok(n) => {
                buf.advance(n);
                Ok(()).into()
            }
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }
}

impl AsyncWrite for KcpServerStream {
    fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
        match ready!(self.poll_send(cx, buf)) {
            Ok(n) => Ok(n).into(),
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }

    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        // Mutex doesn't have poll_lock, spinning on it.
        let socket = self.session.kcp_socket();
        let mut kcp = match socket.try_lock() {
            Ok(guard) => guard,
            Err(..) => {
                cx.waker().wake_by_ref();
                return Poll::Pending;
            }
        };

        match kcp.flush() {
            Ok(..) => Ok(()).into(),
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }

    fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        Ok(()).into()
    }
}
<commit_msg>fix lint<commit_after>use std::{
    io::{self, ErrorKind},
    net::{IpAddr, SocketAddr},
    pin::Pin,
    sync::Arc,
    task::{Context, Poll},
};

use futures::{future, ready};
use kcp::{Error as KcpError, KcpResult};
use tokio::{
    io::{AsyncRead, AsyncWrite, ReadBuf},
    net::UdpSocket,
    sync::mpsc,
};

use crate::{config::KcpConfig, session::KcpSession, skcp::KcpSocket};

pub struct KcpStream {
    session: Arc<KcpSession>,
    udp: Arc<UdpSocket>,
    recv_buffer: Vec<u8>,
    recv_buffer_pos: usize,
    recv_buffer_cap: usize,
}

impl Drop for KcpStream {
    fn drop(&mut self) {
        self.session.close();
    }
}

impl KcpStream {
    pub async fn connect(config: &KcpConfig, addr: SocketAddr) -> KcpResult<KcpStream> {
        let udp = match addr.ip() {
            IpAddr::V4(..) => UdpSocket::bind("0.0.0.0:0").await?,
            IpAddr::V6(..) => UdpSocket::bind("[::]:0").await?,
        };

        let udp = Arc::new(udp);
        let socket = KcpSocket::new(config, 0, udp.clone(), addr, config.stream)?;

        let session = KcpSession::new_shared(socket, config.session_expire, None);

        Ok(KcpStream {
            session,
            udp,
            recv_buffer: Vec::new(),
            recv_buffer_pos: 0,
            recv_buffer_cap: 0,
        })
    }

    pub fn poll_send(&mut self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<KcpResult<usize>> {
        // Mutex doesn't have poll_lock, spinning on it.
        let socket = self.session.kcp_socket();
        let mut kcp = match socket.try_lock() {
            Ok(guard) => guard,
            Err(..) => {
                cx.waker().wake_by_ref();
                return Poll::Pending;
            }
        };

        kcp.poll_send(cx, buf)
    }

    pub async fn send(&mut self, buf: &[u8]) -> KcpResult<usize> {
        future::poll_fn(|cx| self.poll_send(cx, buf)).await
    }

    pub fn poll_recv(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<KcpResult<usize>> {
        loop {
            // Consumes all data in buffer
            if self.recv_buffer_pos < self.recv_buffer_cap {
                let remaining = self.recv_buffer_cap - self.recv_buffer_pos;
                let copy_length = remaining.min(buf.len());

                buf.copy_from_slice(&self.recv_buffer[self.recv_buffer_pos..self.recv_buffer_pos + copy_length]);
                self.recv_buffer_pos += copy_length;
                return Ok(copy_length).into();
            }

            // Mutex doesn't have poll_lock, spinning on it.
            let socket = self.session.kcp_socket();
            let mut kcp = match socket.try_lock() {
                Ok(guard) => guard,
                Err(..) => {
                    cx.waker().wake_by_ref();
                    return Poll::Pending;
                }
            };

            loop {
                // Try to read from KCP
                // 1. Read directly with user provided `buf`
                match kcp.try_recv(buf) {
                    Ok(n) => return Ok(n).into(),
                    Err(KcpError::RecvQueueEmpty) => {
                        // Nothing in recv queue, read from UDP socket
                        let mut packet_buffer = [0u8; 65536];
                        let mut read_buffer = ReadBuf::new(&mut packet_buffer);
                        ready!(self.udp.poll_recv(cx, &mut read_buffer))?;
                        let packet = read_buffer.filled();

                        log::trace!("client read {} bytes", packet.len());

                        kcp.input(packet)?;
                        continue;
                    }
                    Err(KcpError::UserBufTooSmall) => {}
                    Err(err) => return Err(err).into(),
                }

                // 2. User `buf` too small, read to recv_buffer
                let required_size = kcp.peek_size()?;
                if self.recv_buffer.len() < required_size {
                    self.recv_buffer.resize(required_size, 0);
                }

                match kcp.try_recv(&mut self.recv_buffer) {
                    Ok(n) => {
                        self.recv_buffer_pos = 0;
                        self.recv_buffer_cap = n;
                        break;
                    }
                    Err(err) => return Err(err).into(),
                }
            }
        }
    }

    pub async fn recv(&mut self, buf: &mut [u8]) -> KcpResult<usize> {
        future::poll_fn(|cx| self.poll_recv(cx, buf)).await
    }
}

impl AsyncRead for KcpStream {
    fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {
        match ready!(self.poll_recv(cx, buf.initialize_unfilled())) {
            Ok(n) => {
                buf.advance(n);
                Ok(()).into()
            }
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }
}

impl AsyncWrite for KcpStream {
    fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
        match ready!(self.poll_send(cx, buf)) {
            Ok(n) => Ok(n).into(),
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }

    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        // Mutex doesn't have poll_lock, spinning on it.
        let socket = self.session.kcp_socket();
        let mut kcp = match socket.try_lock() {
            Ok(guard) => guard,
            Err(..) => {
                cx.waker().wake_by_ref();
                return Poll::Pending;
            }
        };

        match kcp.flush() {
            Ok(..) => Ok(()).into(),
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }

    fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        Ok(()).into()
    }
}

pub struct KcpServerStream {
    session: Arc<KcpSession>,
    recv_buffer: Vec<u8>,
    recv_buffer_pos: usize,
    recv_buffer_cap: usize,
}

impl Drop for KcpServerStream {
    fn drop(&mut self) {
        self.session.close();
    }
}

impl KcpServerStream {
    pub fn new(
        config: &KcpConfig,
        udp: Arc<UdpSocket>,
        conv: u32,
        peer_addr: SocketAddr,
        session_close_notifier: mpsc::Sender<u32>,
    ) -> KcpResult<KcpServerStream> {
        let socket = KcpSocket::new(config, conv, udp, peer_addr, true)?;
        let session = KcpSession::new_shared(socket, config.session_expire, Some(session_close_notifier));
        Ok(KcpServerStream::with_session(session))
    }

    pub fn with_session(session: Arc<KcpSession>) -> KcpServerStream {
        KcpServerStream {
            session,
            recv_buffer: Vec::new(),
            recv_buffer_pos: 0,
            recv_buffer_cap: 0,
        }
    }

    pub fn poll_send(&mut self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<KcpResult<usize>> {
        // Mutex doesn't have poll_lock, spinning on it.
        let socket = self.session.kcp_socket();
        let mut kcp = match socket.try_lock() {
            Ok(guard) => guard,
            Err(..) => {
                cx.waker().wake_by_ref();
                return Poll::Pending;
            }
        };

        kcp.poll_send(cx, buf)
    }

    pub async fn send(&mut self, buf: &[u8]) -> KcpResult<usize> {
        future::poll_fn(|cx| self.poll_send(cx, buf)).await
    }

    pub fn poll_recv(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<KcpResult<usize>> {
        loop {
            // Consumes all data in buffer
            if self.recv_buffer_pos < self.recv_buffer_cap {
                let remaining = self.recv_buffer_cap - self.recv_buffer_pos;
                let copy_length = remaining.min(buf.len());

                buf.copy_from_slice(&self.recv_buffer[self.recv_buffer_pos..self.recv_buffer_pos + copy_length]);
                self.recv_buffer_pos += copy_length;
                return Ok(copy_length).into();
            }

            // Mutex doesn't have poll_lock, spinning on it.
            let socket = self.session.kcp_socket();
            let mut kcp = match socket.try_lock() {
                Ok(guard) => guard,
                Err(..) => {
                    cx.waker().wake_by_ref();
                    return Poll::Pending;
                }
            };

            // Try to read from KCP
            // 1. Read directly with user provided `buf`
            match ready!(kcp.poll_recv(cx, buf)) {
                Ok(n) => return Ok(n).into(),
                Err(KcpError::UserBufTooSmall) => {}
                Err(err) => return Err(err).into(),
            }

            // 2. User `buf` too small, read to recv_buffer
            let required_size = kcp.peek_size()?;
            if self.recv_buffer.len() < required_size {
                self.recv_buffer.resize(required_size, 0);
            }

            match ready!(kcp.poll_recv(cx, &mut self.recv_buffer)) {
                Ok(n) => {
                    self.recv_buffer_pos = 0;
                    self.recv_buffer_cap = n;
                }
                Err(err) => return Err(err).into(),
            }
        }
    }

    pub async fn recv(&mut self, buf: &mut [u8]) -> KcpResult<usize> {
        future::poll_fn(|cx| self.poll_recv(cx, buf)).await
    }
}

impl AsyncRead for KcpServerStream {
    fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {
        match ready!(self.poll_recv(cx, buf.initialize_unfilled())) {
            Ok(n) => {
                buf.advance(n);
                Ok(()).into()
            }
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }
}

impl AsyncWrite for KcpServerStream {
    fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
        match ready!(self.poll_send(cx, buf)) {
            Ok(n) => Ok(n).into(),
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }

    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        // Mutex doesn't have poll_lock, spinning on it.
        let socket = self.session.kcp_socket();
        let mut kcp = match socket.try_lock() {
            Ok(guard) => guard,
            Err(..) => {
                cx.waker().wake_by_ref();
                return Poll::Pending;
            }
        };

        match kcp.flush() {
            Ok(..) => Ok(()).into(),
            Err(KcpError::IoError(err)) => Err(err).into(),
            Err(err) => Err(io::Error::new(ErrorKind::Other, err)).into(),
        }
    }

    fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        Ok(()).into()
    }
}
<|endoftext|>


<commit_before>use std::os::raw::{c_int, c_double, c_void};

use ffi;
use base::*;

extern "C" fn write_callback_wrapper<W>(raw_out: *mut ffi::SoundIoOutStream,
                                        min: c_int,
                                        max: c_int)
    where W: Fn(OutStream, i32, i32)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    match callbacks.write {
        Some(ref f) => f(out, min as i32, max as i32),
        None => println!("No registered callback found!"),
    }
}

extern "C" fn underflow_callback_wrapper<U>(raw_out: *mut ffi::SoundIoOutStream)
    where U: Fn(OutStream)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    println!("match");
    match callbacks.underflow {
        Some(ref f) => f(out),
        None => println!("No registered callback found!"),
    }
}

extern "C" fn error_callback_wrapper<E>(raw_out: *mut ffi::SoundIoOutStream, error: ffi::SioError)
    where E: Fn(OutStream, ffi::SioError)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    println!("match");
    match callbacks.error {
        Some(ref f) => f(out, error),
        None => println!("No registered callback found!"),
    }
}

struct OutStreamCallbacks<'a> {
    write: Option<Box<Fn(OutStream, i32, i32) + 'a>>,
    underflow: Option<Box<Fn(OutStream) + 'a>>,
    error: Option<Box<Fn(OutStream, ffi::SioError) + 'a>>,
}
impl<'a> Default for OutStreamCallbacks<'a> {
    fn default() -> Self {
        OutStreamCallbacks {
            write: None,
            underflow: None,
            error: None,
        }
    }
}
impl<'a> Drop for OutStreamCallbacks<'a> {
    fn drop(&mut self) {}
}

pub struct OutStream<'a> {
    stream: *mut ffi::SoundIoOutStream,
    callbacks: Box<OutStreamCallbacks<'a>>,
}
impl<'a> OutStream<'a> {
    pub fn new(raw_stream: *mut ffi::SoundIoOutStream) -> Self {
        let callbacks = Box::new(OutStreamCallbacks::default());
        OutStream {
            stream: raw_stream,
            callbacks: callbacks,
        }
    }

    pub fn open(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_open(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn start(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_start(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn register_write_callback<W>(&mut self, callback: Box<W>)
        where W: Fn(OutStream, i32, i32) + 'a
    {
        // stored box reference to callback closure
        self.callbacks.write = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).write_callback = Some(write_callback_wrapper::<W>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn register_underflow_callback<U>(&mut self, callback: Box<U>)
        where U: Fn(OutStream) + 'a
    {
        self.callbacks.underflow = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).underflow_callback = Some(underflow_callback_wrapper::<U>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn register_error_callback<E>(&mut self, callback: Box<E>)
        where E: Fn(OutStream, ffi::SioError) + 'a
    {
        self.callbacks.error = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).error_callback = Some(error_callback_wrapper::<E>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn begin_write(&self,
                       areas: *mut *mut ffi::SoundIoChannelArea,
                       frame_count: *mut c_int)
                       -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_begin_write(self.stream, areas, frame_count) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn end_write(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_end_write(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn clear_buffer(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_clear_buffer(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn pause(&self, pause: bool) -> Option<ffi::SioError> {
        let pause_c_bool = match pause {
            true => 1u8,
            false => 0u8,
        };
        match unsafe { ffi::soundio_outstream_pause(self.stream, pause_c_bool) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn get_latency(&self) -> Result<f64, ffi::SioError> {
        let mut latency = 0.0f64;
        match unsafe {
            ffi::soundio_outstream_get_latency(self.stream, &mut latency as *mut c_double)
        } {
            ffi::SioError::None => Ok(latency),
            err @ _ => Err(err),
        }

    }

    pub fn current_format(&self) -> Result<ffi::SioFormat, ffi::SioError> {
        match unsafe { (*self.stream).format } {
            ffi::SioFormat::Invalid => Err(ffi::SioError::Invalid),
            fmt @ _ => Ok(fmt),
        }
    }

    pub fn get_layout(&self) -> ChannelLayout {
        ChannelLayout::new(unsafe { &(*self.stream).layout })
    }

    pub fn get_sample_rate(&self) -> i32 {
        unsafe { (*self.stream).sample_rate as i32 }
    }

    pub fn get_device(&self) -> Device {
        let dev = Device::new(unsafe { (*self.stream).device });
        dev.inc_ref();
        dev
    }

    pub fn destroy(&self) {
        unsafe { ffi::soundio_outstream_destroy(self.stream) }
    }
}
impl<'a> Drop for OutStream<'a> {
    fn drop(&mut self) {
        // TODO: call destroy manually.
        // OutStream will get dropped each time a new
        // struct is created from the same *mut pointer.
    }
}
<commit_msg>Replace match cases with `map` because `None` case doesn't need special treatment<commit_after>use std::os::raw::{c_int, c_double, c_void};

use ffi;
use base::*;

extern "C" fn write_callback_wrapper<W>(raw_out: *mut ffi::SoundIoOutStream,
                                        min: c_int,
                                        max: c_int)
    where W: Fn(OutStream, i32, i32)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    callbacks.write.as_ref().map(|ref f| f(out, min as i32, max as i32));
}

extern "C" fn underflow_callback_wrapper<U>(raw_out: *mut ffi::SoundIoOutStream)
    where U: Fn(OutStream)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    callbacks.underflow.as_ref().map(|ref f| f(out));
}

extern "C" fn error_callback_wrapper<E>(raw_out: *mut ffi::SoundIoOutStream, error: ffi::SioError)
    where E: Fn(OutStream, ffi::SioError)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    callbacks.error.as_ref().map(|ref f| f(out, error));
}

struct OutStreamCallbacks<'a> {
    write: Option<Box<Fn(OutStream, i32, i32) + 'a>>,
    underflow: Option<Box<Fn(OutStream) + 'a>>,
    error: Option<Box<Fn(OutStream, ffi::SioError) + 'a>>,
}
impl<'a> Default for OutStreamCallbacks<'a> {
    fn default() -> Self {
        OutStreamCallbacks {
            write: None,
            underflow: None,
            error: None,
        }
    }
}
impl<'a> Drop for OutStreamCallbacks<'a> {
    fn drop(&mut self) {}
}

pub struct OutStream<'a> {
    stream: *mut ffi::SoundIoOutStream,
    callbacks: Box<OutStreamCallbacks<'a>>,
}
impl<'a> OutStream<'a> {
    pub fn new(raw_stream: *mut ffi::SoundIoOutStream) -> Self {
        let callbacks = Box::new(OutStreamCallbacks::default());
        OutStream {
            stream: raw_stream,
            callbacks: callbacks,
        }
    }

    pub fn open(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_open(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn start(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_start(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn register_write_callback<W>(&mut self, callback: Box<W>)
        where W: Fn(OutStream, i32, i32) + 'a
    {
        // stored box reference to callback closure
        self.callbacks.write = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).write_callback = Some(write_callback_wrapper::<W>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn register_underflow_callback<U>(&mut self, callback: Box<U>)
        where U: Fn(OutStream) + 'a
    {
        self.callbacks.underflow = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).underflow_callback = Some(underflow_callback_wrapper::<U>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn register_error_callback<E>(&mut self, callback: Box<E>)
        where E: Fn(OutStream, ffi::SioError) + 'a
    {
        self.callbacks.error = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).error_callback = Some(error_callback_wrapper::<E>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn begin_write(&self,
                       areas: *mut *mut ffi::SoundIoChannelArea,
                       frame_count: *mut c_int)
                       -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_begin_write(self.stream, areas, frame_count) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn end_write(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_end_write(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn clear_buffer(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_clear_buffer(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn pause(&self, pause: bool) -> Option<ffi::SioError> {
        let pause_c_bool = match pause {
            true => 1u8,
            false => 0u8,
        };
        match unsafe { ffi::soundio_outstream_pause(self.stream, pause_c_bool) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn get_latency(&self) -> Result<f64, ffi::SioError> {
        let mut latency = 0.0f64;
        match unsafe {
            ffi::soundio_outstream_get_latency(self.stream, &mut latency as *mut c_double)
        } {
            ffi::SioError::None => Ok(latency),
            err @ _ => Err(err),
        }

    }

    pub fn current_format(&self) -> Result<ffi::SioFormat, ffi::SioError> {
        match unsafe { (*self.stream).format } {
            ffi::SioFormat::Invalid => Err(ffi::SioError::Invalid),
            fmt @ _ => Ok(fmt),
        }
    }

    pub fn get_layout(&self) -> ChannelLayout {
        ChannelLayout::new(unsafe { &(*self.stream).layout })
    }

    pub fn get_sample_rate(&self) -> i32 {
        unsafe { (*self.stream).sample_rate as i32 }
    }

    pub fn get_device(&self) -> Device {
        let dev = Device::new(unsafe { (*self.stream).device });
        dev.inc_ref();
        dev
    }

    pub fn destroy(&self) {
        unsafe { ffi::soundio_outstream_destroy(self.stream) }
    }
}
impl<'a> Drop for OutStream<'a> {
    fn drop(&mut self) {
        // TODO: call destroy manually.
        // OutStream will get dropped each time a new
        // struct is created from the same *mut pointer.
    }
}
<|endoftext|>