<commit_before>use regex::Regex;

use std::convert::Into;
use std::convert::From;

use std::option::Option;

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct KeyValue<K, V> {
    k: K,
    v: V,
}

impl<K, V> KeyValue<K, V> {

    pub fn new(k: K, v: V) -> KeyValue<K, V> {
        KeyValue { k: k, v: v }
    }

    pub fn key(&self) -> &K {
        &self.k
    }

    pub fn value(&self) -> &V {
        &self.v
    }

}

impl<K, V> Into<(K, V)> for KeyValue<K, V> {

    fn into(self) -> (K, V) {
        (self.k, self.v)
    }

}

pub trait IntoKeyValue<K, V> {
    fn into_kv(self) -> Option<KeyValue<K, V>>;
}

impl IntoKeyValue<String, String> for String {

    fn into_kv(self) -> Option<KeyValue<String, String>> {
        let key = {
            lazy_static! {
                static ref R: Regex = Regex::new("^(?P<KEY>([^=]*))=(.*)$").unwrap();
            }
            R.captures(&self[..])
                .and_then(|caps| caps.name("KEY"))
        };

        let value = {
            lazy_static! {
                static ref R: Regex = Regex::new("(.*)=(\"(?P<QVALUE>([^\"]*))\"|(?P<VALUE>(.*)))$")
                    .unwrap();
            }
            R.captures(&self[..])
                .map(|caps| {
                    caps.name("VALUE")
                        .or(caps.name("QVALUE"))
                        .unwrap_or("")
                })
        };

        key.and_then(|k| {
            value.and_then(|v| {
                Some(KeyValue::new(String::from(k), String::from(v)))
            })
        })
    }

}

#[cfg(test)]
mod test {
    use super::{KeyValue, IntoKeyValue};

    #[test]
    fn test_single_quoted() {
        let s = String::from("foo='bar'").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("\'bar\'")), s);
    }

    #[test]
    fn test_double_quoted() {
        let s = String::from("foo=\"bar\"").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
    }

    #[test]
    fn test_double_and_single_quoted() {
        let s = String::from("foo=\"bar\'").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("\"bar\'")), s);
    }

    #[test]
    fn test_single_and_double_quoted() {
        let s = String::from("foo=\'bar\"").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("\'bar\"")), s);
    }

    #[test]
    fn test_not_quoted() {
        let s = String::from("foo=bar").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
    }

}

<commit_msg>Remove unneeded scopes<commit_after>use regex::Regex;

use std::convert::Into;
use std::convert::From;

use std::option::Option;

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct KeyValue<K, V> {
    k: K,
    v: V,
}

impl<K, V> KeyValue<K, V> {

    pub fn new(k: K, v: V) -> KeyValue<K, V> {
        KeyValue { k: k, v: v }
    }

    pub fn key(&self) -> &K {
        &self.k
    }

    pub fn value(&self) -> &V {
        &self.v
    }

}

impl<K, V> Into<(K, V)> for KeyValue<K, V> {

    fn into(self) -> (K, V) {
        (self.k, self.v)
    }

}

pub trait IntoKeyValue<K, V> {
    fn into_kv(self) -> Option<KeyValue<K, V>>;
}

impl IntoKeyValue<String, String> for String {

    fn into_kv(self) -> Option<KeyValue<String, String>> {
        let key = {
            lazy_static! {
                static ref R: Regex = Regex::new("^(?P<KEY>([^=]*))=(.*)$").unwrap();
            }
            R.captures(&self[..])
                .and_then(|caps| caps.name("KEY"))
        };

        let value = {
            lazy_static! {
                static ref R: Regex = Regex::new("(.*)=(\"(?P<QVALUE>([^\"]*))\"|(?P<VALUE>(.*)))$")
                    .unwrap();
            }
            R.captures(&self[..])
                .map(|caps| caps.name("VALUE").or(caps.name("QVALUE")).unwrap_or(""))
        };

        key.and_then(|k| value.and_then(|v| Some(KeyValue::new(String::from(k), String::from(v)))))
    }

}

#[cfg(test)]
mod test {
    use super::{KeyValue, IntoKeyValue};

    #[test]
    fn test_single_quoted() {
        let s = String::from("foo='bar'").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("\'bar\'")), s);
    }

    #[test]
    fn test_double_quoted() {
        let s = String::from("foo=\"bar\"").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
    }

    #[test]
    fn test_double_and_single_quoted() {
        let s = String::from("foo=\"bar\'").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("\"bar\'")), s);
    }

    #[test]
    fn test_single_and_double_quoted() {
        let s = String::from("foo=\'bar\"").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("\'bar\"")), s);
    }

    #[test]
    fn test_not_quoted() {
        let s = String::from("foo=bar").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
    }

}

<|endoftext|>


<commit_before><commit_msg>rename entry function to kmain instead of main<commit_after><|endoftext|>


<commit_before>use tensor::Tensor;
use std::fmt;

// Display for floats
macro_rules! add_impl {
    ($t:ty, $name:tt) => (
        impl fmt::Display for Tensor<$t> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                let mv = &self.data[..];
                let mut ret = "\n".to_string();
                // Limit to 1000 elements shown
                if self.ndim() <= 2 && self.size() <= 1000 {
                    // Pre-generate all strings
                    let mut ss: Vec<String> = Vec::with_capacity(self.size());
                    let mut longest: usize = 0;
                    for i in 0..self.size() {
                        let s = format!("{}", mv[i]);
                        ss.push(s.to_string());
                        if s.len() > longest {
                            longest = s.len();
                        }
                    }

                    if self.ndim() == 1 {
                        for i in 0..self.shape[0] {
                            let s = &ss[i];
                            for _ in 0..(1 + longest - s.len()) {
                                ret.push_str(" ");
                            }

                            ret = format!("{}{}", ret, s);
                        }
                    } else if self.ndim() == 2 {
                        let s0 = self.strides()[0];
                        //ret.push_str("[[");
                        for i in 0..self.shape[0] {
                            if i > 0 {
                                //ret.push_str(" [");
                            }
                            for j in 0..self.shape[1] {
                                let s = &ss[i * s0 + j];
                                for _ in 0..(1 + longest - s.len()) {
                                    ret.push_str(" ");
                                }
                                ret = format!("{}{}", ret, s);
                            }
                            if i == self.shape[0] - 1 {
                                //ret.push_str("]]");
                            } else {
                                //ret.push_str("]\n");
                                ret.push_str("\n");
                            }
                        }
                    }
                } else {
                    // For now, higher order are simply omitted
                    ret.push_str("...");
                }

                // Format shape
                // TODO: Is there an implode/join function?
                let mut shape_str = "".to_string();
                for i in 0..self.shape.len() {
                    if i == 0 {
                        shape_str.push_str(&format!("{}", self.shape[i])[..]);
                    } else {
                        shape_str.push_str(&format!("x{}", self.shape[i])[..]);
                    }
                }

                write!(f, "{}\n[Tensor<{}> of shape {}]", ret, $name, shape_str)
            }
        }
    )

}

add_impl!(f32,   "f32");
add_impl!(f64,   "f64");
add_impl!(usize, "usize");
add_impl!(u8,    "u8");
add_impl!(u16,   "u16");
add_impl!(u32,   "u32");
add_impl!(u64,   "u64");
add_impl!(isize, "isize");
add_impl!(i8,    "i8");
add_impl!(i16,   "i16");
add_impl!(i32,   "i32");
add_impl!(i64,   "i64");
add_impl!(bool,  "bool");
<commit_msg>Updated display for scalars<commit_after>use tensor::Tensor;
use std::fmt;

// Display for floats
macro_rules! add_impl {
    ($t:ty, $name:tt) => (
        impl fmt::Display for Tensor<$t> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                let mv = &self.data[..];
                let mut ret = "\n".to_string();
                // Limit to 1000 elements shown
                if self.is_scalar() {

                } if self.ndim() <= 2 && self.size() <= 1000 {
                    // Pre-generate all strings
                    let mut ss: Vec<String> = Vec::with_capacity(self.size());
                    let mut longest: usize = 0;
                    for i in 0..self.size() {
                        let s = format!("{}", mv[i]);
                        ss.push(s.to_string());
                        if s.len() > longest {
                            longest = s.len();
                        }
                    }

                    if self.ndim() == 1 {
                        for i in 0..self.shape[0] {
                            let s = &ss[i];
                            for _ in 0..(1 + longest - s.len()) {
                                ret.push_str(" ");
                            }

                            ret = format!("{}{}", ret, s);
                        }
                    } else if self.ndim() == 2 {
                        let s0 = self.strides()[0];
                        //ret.push_str("[[");
                        for i in 0..self.shape[0] {
                            if i > 0 {
                                //ret.push_str(" [");
                            }
                            for j in 0..self.shape[1] {
                                let s = &ss[i * s0 + j];
                                for _ in 0..(1 + longest - s.len()) {
                                    ret.push_str(" ");
                                }
                                ret = format!("{}{}", ret, s);
                            }
                            if i == self.shape[0] - 1 {
                                //ret.push_str("]]");
                            } else {
                                //ret.push_str("]\n");
                                ret.push_str("\n");
                            }
                        }
                    }
                } else {
                    // For now, higher order are simply omitted
                    ret.push_str("...");
                }

                if self.is_scalar() {
                    //write!(f, "{}\n[Tensor<{}> of shape scalar]", ret, $name)
                    write!(f, "Tensor<{}>::scalar({})", $name, self.data[0])
                } else {
                    // Format shape
                    // TODO: Is there an implode/join function?
                    let mut shape_str = "".to_string();
                    for i in 0..self.shape.len() {
                        if i == 0 {
                            shape_str.push_str(&format!("{}", self.shape[i])[..]);
                        } else {
                            shape_str.push_str(&format!("x{}", self.shape[i])[..]);
                        }
                    }

                    write!(f, "{}\n[Tensor<{}> of shape {}]", ret, $name, shape_str)
                }
            }
        }
    )

}

add_impl!(f32,   "f32");
add_impl!(f64,   "f64");
add_impl!(usize, "usize");
add_impl!(u8,    "u8");
add_impl!(u16,   "u16");
add_impl!(u32,   "u32");
add_impl!(u64,   "u64");
add_impl!(isize, "isize");
add_impl!(i8,    "i8");
add_impl!(i16,   "i16");
add_impl!(i32,   "i32");
add_impl!(i64,   "i64");
add_impl!(bool,  "bool");
<|endoftext|>


<commit_before>use crate::{
    executor::Executor,
    message::{Delivery, DeliveryResult},
    types::ShortString,
    BasicProperties, Error, Result,
};
use crossbeam_channel::{Receiver, Sender};
use futures_core::stream::Stream;
use log::trace;
use parking_lot::Mutex;
use std::{
    fmt,
    future::Future,
    pin::Pin,
    sync::Arc,
    task::{Context, Poll, Waker},
};

pub trait ConsumerDelegate: Send + Sync {
    fn on_new_delivery(&self, delivery: DeliveryResult)
        -> Pin<Box<dyn Future<Output = ()> + Send>>;
    fn drop_prefetched_messages(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
        Box::pin(async move {})
    }
}

impl<
        F: Future<Output = ()> + Send + 'static,
        DeliveryHandler: Fn(DeliveryResult) -> F + Send + Sync + 'static,
    > ConsumerDelegate for DeliveryHandler
{
    fn on_new_delivery(
        &self,
        delivery: DeliveryResult,
    ) -> Pin<Box<dyn Future<Output = ()> + Send>> {
        Box::pin(self(delivery))
    }
}

#[derive(Clone)]
pub struct Consumer {
    inner: Arc<Mutex<ConsumerInner>>,
}

impl Consumer {
    pub(crate) fn new(consumer_tag: ShortString, executor: Arc<dyn Executor>) -> Consumer {
        Consumer {
            inner: Arc::new(Mutex::new(ConsumerInner::new(consumer_tag, executor))),
        }
    }

    pub fn set_delegate<D: ConsumerDelegate + 'static>(&self, delegate: D) -> Result<()> {
        let mut inner = self.inner.lock();
        while let Some(delivery) = inner.next_delivery() {
            inner.executor.spawn(delegate.on_new_delivery(delivery))?;
        }
        inner.delegate = Some(Arc::new(Box::new(delegate)));
        Ok(())
    }

    pub(crate) fn start_new_delivery(&mut self, delivery: Delivery) {
        self.inner.lock().current_message = Some(delivery)
    }

    pub(crate) fn set_delivery_properties(&mut self, properties: BasicProperties) {
        if let Some(delivery) = self.inner.lock().current_message.as_mut() {
            delivery.properties = properties;
        }
    }

    pub(crate) fn receive_delivery_content(&mut self, payload: Vec<u8>) {
        if let Some(delivery) = self.inner.lock().current_message.as_mut() {
            delivery.receive_content(payload);
        }
    }

    pub(crate) fn new_delivery_complete(&mut self) -> Result<()> {
        let mut inner = self.inner.lock();
        if let Some(delivery) = inner.current_message.take() {
            inner.new_delivery(delivery)?;
        }
        Ok(())
    }

    pub(crate) fn drop_prefetched_messages(&self) -> Result<()> {
        self.inner.lock().drop_prefetched_messages()
    }

    pub(crate) fn cancel(&self) -> Result<()> {
        self.inner.lock().cancel()
    }

    pub(crate) fn set_error(&self, error: Error) -> Result<()> {
        self.inner.lock().set_error(error)
    }
}

struct ConsumerInner {
    current_message: Option<Delivery>,
    deliveries_in: Sender<DeliveryResult>,
    deliveries_out: Receiver<DeliveryResult>,
    task: Option<Waker>,
    tag: ShortString,
    delegate: Option<Arc<Box<dyn ConsumerDelegate>>>,
    executor: Arc<dyn Executor>,
}

pub struct ConsumerIterator {
    receiver: Receiver<DeliveryResult>,
}

impl Iterator for ConsumerIterator {
    type Item = Result<Delivery>;

    fn next(&mut self) -> Option<Self::Item> {
        self.receiver.recv().ok().and_then(Result::transpose)
    }
}

impl IntoIterator for Consumer {
    type Item = Result<Delivery>;
    type IntoIter = ConsumerIterator;

    fn into_iter(self) -> Self::IntoIter {
        ConsumerIterator {
            receiver: self.inner.lock().deliveries_out.clone(),
        }
    }
}

impl fmt::Debug for Consumer {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut debug = f.debug_struct("Consumer");
        if let Some(inner) = self.inner.try_lock() {
            debug
                .field("tag", &inner.tag)
                .field("executor", &inner.executor)
                .field("task", &inner.task);
        }
        debug.finish()
    }
}

impl ConsumerInner {
    fn new(consumer_tag: ShortString, executor: Arc<dyn Executor>) -> Self {
        let (sender, receiver) = crossbeam_channel::unbounded();
        Self {
            current_message: None,
            deliveries_in: sender,
            deliveries_out: receiver,
            task: None,
            tag: consumer_tag,
            delegate: None,
            executor,
        }
    }

    fn next_delivery(&mut self) -> Option<DeliveryResult> {
        self.deliveries_out.try_recv().ok()
    }

    fn new_delivery(&mut self, delivery: Delivery) -> Result<()> {
        trace!("new_delivery; consumer_tag={}", self.tag);
        if let Some(delegate) = self.delegate.as_ref() {
            let delegate = delegate.clone();
            self.executor
                .spawn(delegate.on_new_delivery(Ok(Some(delivery))))?;
        } else {
            self.deliveries_in
                .send(Ok(Some(delivery)))
                .expect("failed to send delivery to consumer");
        }
        if let Some(task) = self.task.as_ref() {
            task.wake_by_ref();
        }
        Ok(())
    }

    fn drop_prefetched_messages(&mut self) -> Result<()> {
        trace!("drop_prefetched_messages; consumer_tag={}", self.tag);
        if let Some(delegate) = self.delegate.as_ref() {
            let delegate = delegate.clone();
            self.executor.spawn(delegate.drop_prefetched_messages())?;
        }
        while let Some(_) = self.next_delivery() {}
        Ok(())
    }

    fn cancel(&mut self) -> Result<()> {
        trace!("cancel; consumer_tag={}", self.tag);
        if let Some(delegate) = self.delegate.as_ref() {
            let delegate = delegate.clone();
            self.executor.spawn(delegate.on_new_delivery(Ok(None)))?;
        } else {
            self.deliveries_in
                .send(Ok(None))
                .expect("failed to send cancel to consumer");
        }
        if let Some(task) = self.task.take() {
            task.wake();
        }
        Ok(())
    }

    fn set_error(&mut self, error: Error) -> Result<()> {
        trace!("set_error; consumer_tag={}", self.tag);
        if let Some(delegate) = self.delegate.as_ref() {
            let delegate = delegate.clone();
            self.executor.spawn(delegate.on_new_delivery(Err(error)))?;
        } else {
            self.deliveries_in
                .send(Err(error))
                .expect("failed to send error to consumer");
        }
        self.cancel()
    }
}

impl Stream for Consumer {
    type Item = Result<Delivery>;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        trace!("consumer poll_next");
        let mut inner = self.inner.lock();
        trace!(
            "consumer poll; acquired inner lock, consumer_tag={}",
            inner.tag
        );
        inner.task = Some(cx.waker().clone());
        if let Some(delivery) = inner.next_delivery() {
            match delivery {
                Ok(Some(delivery)) => {
                    trace!(
                        "delivery; consumer_tag={}, delivery_tag={:?}",
                        inner.tag,
                        delivery.delivery_tag
                    );
                    Poll::Ready(Some(Ok(delivery)))
                }
                Ok(None) => {
                    trace!("consumer canceled; consumer_tag={}", inner.tag);
                    Poll::Ready(None)
                }
                Err(error) => Poll::Ready(Some(Err(error))),
            }
        } else {
            trace!("delivery; status=NotReady, consumer_tag={}", inner.tag);
            Poll::Pending
        }
    }
}

#[cfg(test)]
mod futures_tests {
    use super::*;
    use crate::executor::DefaultExecutor;

    use std::task::{Context, Poll};

    use futures_test::task::new_count_waker;
    use futures_util::stream::StreamExt;

    #[test]
    fn stream_on_cancel() {
        let (waker, awoken_count) = new_count_waker();
        let mut cx = Context::from_waker(&waker);

        let mut consumer = Consumer::new(
            ShortString::from("test-consumer"),
            Arc::new(DefaultExecutor::default()),
        );

        assert_eq!(awoken_count.get(), 0);
        assert_eq!(consumer.poll_next_unpin(&mut cx), Poll::Pending);

        consumer.cancel().unwrap();

        assert_eq!(awoken_count.get(), 1);
        assert_eq!(consumer.poll_next_unpin(&mut cx), Poll::Ready(None));
    }

    #[test]
    fn stream_on_error() {
        let (waker, awoken_count) = new_count_waker();
        let mut cx = Context::from_waker(&waker);

        let mut consumer = Consumer::new(
            ShortString::from("test-consumer"),
            Arc::new(DefaultExecutor::default()),
        );

        assert_eq!(awoken_count.get(), 0);
        assert_eq!(consumer.poll_next_unpin(&mut cx), Poll::Pending);

        consumer.set_error(Error::ChannelsLimitReached).unwrap();

        assert_eq!(awoken_count.get(), 1);
        assert_eq!(
            consumer.poll_next_unpin(&mut cx),
            Poll::Ready(Some(Err(Error::ChannelsLimitReached)))
        );
    }
}
<commit_msg>add Consumer::tag<commit_after>use crate::{
    executor::Executor,
    message::{Delivery, DeliveryResult},
    types::ShortString,
    BasicProperties, Error, Result,
};
use crossbeam_channel::{Receiver, Sender};
use futures_core::stream::Stream;
use log::trace;
use parking_lot::Mutex;
use std::{
    fmt,
    future::Future,
    pin::Pin,
    sync::Arc,
    task::{Context, Poll, Waker},
};

pub trait ConsumerDelegate: Send + Sync {
    fn on_new_delivery(&self, delivery: DeliveryResult)
        -> Pin<Box<dyn Future<Output = ()> + Send>>;
    fn drop_prefetched_messages(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
        Box::pin(async move {})
    }
}

impl<
        F: Future<Output = ()> + Send + 'static,
        DeliveryHandler: Fn(DeliveryResult) -> F + Send + Sync + 'static,
    > ConsumerDelegate for DeliveryHandler
{
    fn on_new_delivery(
        &self,
        delivery: DeliveryResult,
    ) -> Pin<Box<dyn Future<Output = ()> + Send>> {
        Box::pin(self(delivery))
    }
}

#[derive(Clone)]
pub struct Consumer {
    inner: Arc<Mutex<ConsumerInner>>,
}

impl Consumer {
    pub(crate) fn new(consumer_tag: ShortString, executor: Arc<dyn Executor>) -> Consumer {
        Consumer {
            inner: Arc::new(Mutex::new(ConsumerInner::new(consumer_tag, executor))),
        }
    }

    pub fn tag(&self) -> ShortString {
        self.inner.lock().tag.clone()
    }

    pub fn set_delegate<D: ConsumerDelegate + 'static>(&self, delegate: D) -> Result<()> {
        let mut inner = self.inner.lock();
        while let Some(delivery) = inner.next_delivery() {
            inner.executor.spawn(delegate.on_new_delivery(delivery))?;
        }
        inner.delegate = Some(Arc::new(Box::new(delegate)));
        Ok(())
    }

    pub(crate) fn start_new_delivery(&mut self, delivery: Delivery) {
        self.inner.lock().current_message = Some(delivery)
    }

    pub(crate) fn set_delivery_properties(&mut self, properties: BasicProperties) {
        if let Some(delivery) = self.inner.lock().current_message.as_mut() {
            delivery.properties = properties;
        }
    }

    pub(crate) fn receive_delivery_content(&mut self, payload: Vec<u8>) {
        if let Some(delivery) = self.inner.lock().current_message.as_mut() {
            delivery.receive_content(payload);
        }
    }

    pub(crate) fn new_delivery_complete(&mut self) -> Result<()> {
        let mut inner = self.inner.lock();
        if let Some(delivery) = inner.current_message.take() {
            inner.new_delivery(delivery)?;
        }
        Ok(())
    }

    pub(crate) fn drop_prefetched_messages(&self) -> Result<()> {
        self.inner.lock().drop_prefetched_messages()
    }

    pub(crate) fn cancel(&self) -> Result<()> {
        self.inner.lock().cancel()
    }

    pub(crate) fn set_error(&self, error: Error) -> Result<()> {
        self.inner.lock().set_error(error)
    }
}

struct ConsumerInner {
    current_message: Option<Delivery>,
    deliveries_in: Sender<DeliveryResult>,
    deliveries_out: Receiver<DeliveryResult>,
    task: Option<Waker>,
    tag: ShortString,
    delegate: Option<Arc<Box<dyn ConsumerDelegate>>>,
    executor: Arc<dyn Executor>,
}

pub struct ConsumerIterator {
    receiver: Receiver<DeliveryResult>,
}

impl Iterator for ConsumerIterator {
    type Item = Result<Delivery>;

    fn next(&mut self) -> Option<Self::Item> {
        self.receiver.recv().ok().and_then(Result::transpose)
    }
}

impl IntoIterator for Consumer {
    type Item = Result<Delivery>;
    type IntoIter = ConsumerIterator;

    fn into_iter(self) -> Self::IntoIter {
        ConsumerIterator {
            receiver: self.inner.lock().deliveries_out.clone(),
        }
    }
}

impl fmt::Debug for Consumer {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut debug = f.debug_struct("Consumer");
        if let Some(inner) = self.inner.try_lock() {
            debug
                .field("tag", &inner.tag)
                .field("executor", &inner.executor)
                .field("task", &inner.task);
        }
        debug.finish()
    }
}

impl ConsumerInner {
    fn new(consumer_tag: ShortString, executor: Arc<dyn Executor>) -> Self {
        let (sender, receiver) = crossbeam_channel::unbounded();
        Self {
            current_message: None,
            deliveries_in: sender,
            deliveries_out: receiver,
            task: None,
            tag: consumer_tag,
            delegate: None,
            executor,
        }
    }

    fn next_delivery(&mut self) -> Option<DeliveryResult> {
        self.deliveries_out.try_recv().ok()
    }

    fn new_delivery(&mut self, delivery: Delivery) -> Result<()> {
        trace!("new_delivery; consumer_tag={}", self.tag);
        if let Some(delegate) = self.delegate.as_ref() {
            let delegate = delegate.clone();
            self.executor
                .spawn(delegate.on_new_delivery(Ok(Some(delivery))))?;
        } else {
            self.deliveries_in
                .send(Ok(Some(delivery)))
                .expect("failed to send delivery to consumer");
        }
        if let Some(task) = self.task.as_ref() {
            task.wake_by_ref();
        }
        Ok(())
    }

    fn drop_prefetched_messages(&mut self) -> Result<()> {
        trace!("drop_prefetched_messages; consumer_tag={}", self.tag);
        if let Some(delegate) = self.delegate.as_ref() {
            let delegate = delegate.clone();
            self.executor.spawn(delegate.drop_prefetched_messages())?;
        }
        while let Some(_) = self.next_delivery() {}
        Ok(())
    }

    fn cancel(&mut self) -> Result<()> {
        trace!("cancel; consumer_tag={}", self.tag);
        if let Some(delegate) = self.delegate.as_ref() {
            let delegate = delegate.clone();
            self.executor.spawn(delegate.on_new_delivery(Ok(None)))?;
        } else {
            self.deliveries_in
                .send(Ok(None))
                .expect("failed to send cancel to consumer");
        }
        if let Some(task) = self.task.take() {
            task.wake();
        }
        Ok(())
    }

    fn set_error(&mut self, error: Error) -> Result<()> {
        trace!("set_error; consumer_tag={}", self.tag);
        if let Some(delegate) = self.delegate.as_ref() {
            let delegate = delegate.clone();
            self.executor.spawn(delegate.on_new_delivery(Err(error)))?;
        } else {
            self.deliveries_in
                .send(Err(error))
                .expect("failed to send error to consumer");
        }
        self.cancel()
    }
}

impl Stream for Consumer {
    type Item = Result<Delivery>;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        trace!("consumer poll_next");
        let mut inner = self.inner.lock();
        trace!(
            "consumer poll; acquired inner lock, consumer_tag={}",
            inner.tag
        );
        inner.task = Some(cx.waker().clone());
        if let Some(delivery) = inner.next_delivery() {
            match delivery {
                Ok(Some(delivery)) => {
                    trace!(
                        "delivery; consumer_tag={}, delivery_tag={:?}",
                        inner.tag,
                        delivery.delivery_tag
                    );
                    Poll::Ready(Some(Ok(delivery)))
                }
                Ok(None) => {
                    trace!("consumer canceled; consumer_tag={}", inner.tag);
                    Poll::Ready(None)
                }
                Err(error) => Poll::Ready(Some(Err(error))),
            }
        } else {
            trace!("delivery; status=NotReady, consumer_tag={}", inner.tag);
            Poll::Pending
        }
    }
}

#[cfg(test)]
mod futures_tests {
    use super::*;
    use crate::executor::DefaultExecutor;

    use std::task::{Context, Poll};

    use futures_test::task::new_count_waker;
    use futures_util::stream::StreamExt;

    #[test]
    fn stream_on_cancel() {
        let (waker, awoken_count) = new_count_waker();
        let mut cx = Context::from_waker(&waker);

        let mut consumer = Consumer::new(
            ShortString::from("test-consumer"),
            Arc::new(DefaultExecutor::default()),
        );

        assert_eq!(awoken_count.get(), 0);
        assert_eq!(consumer.poll_next_unpin(&mut cx), Poll::Pending);

        consumer.cancel().unwrap();

        assert_eq!(awoken_count.get(), 1);
        assert_eq!(consumer.poll_next_unpin(&mut cx), Poll::Ready(None));
    }

    #[test]
    fn stream_on_error() {
        let (waker, awoken_count) = new_count_waker();
        let mut cx = Context::from_waker(&waker);

        let mut consumer = Consumer::new(
            ShortString::from("test-consumer"),
            Arc::new(DefaultExecutor::default()),
        );

        assert_eq!(awoken_count.get(), 0);
        assert_eq!(consumer.poll_next_unpin(&mut cx), Poll::Pending);

        consumer.set_error(Error::ChannelsLimitReached).unwrap();

        assert_eq!(awoken_count.get(), 1);
        assert_eq!(
            consumer.poll_next_unpin(&mut cx),
            Poll::Ready(Some(Err(Error::ChannelsLimitReached)))
        );
    }
}
<|endoftext|>


<commit_before>extern crate herder;
extern crate serde_json;

use herder::api::v1::{
    Account,
    Application,
    Attachment,
    Card,
    Context,
    Error,
    Instance,
    Mention,
    Notification,
    Relationship,
    Report,
    Results,
    Status,
    Tag
};

#[test]
fn account_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn application_deserialize_from_json() {
    let ojson = r#"{
                    "name": "MYNAME",
                    "website": "MYURI"
                 }"#;
    let application: Application = serde_json::from_str(ojson).unwrap();
    assert_eq!(application, Application {
                        name: String::from("MYNAME"),
                        website: Some(String::from("MYURI"))
    });
}

#[test]
fn attachment_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "type": "video",
                    "url": "MYURL",
                    "remote_url": "MYURL",
                    "preview_url": "MYURL",
                    "text_url": "MYURL"
                 }"#;
    let attachment: Attachment = serde_json::from_str(ojson).unwrap();
    assert_eq!(attachment, Attachment {
                        attachment_id: 1234,
                        attachment_type: String::from("video"),
                        url: String::from("MYURL"),
                        remote_url: String::from("MYURL"),
                        preview_url: String::from("MYURL"),
                        text_url: String::from("MYURL")
    });
}

#[test]
fn card_deserialize_from_json() {
    let ojson = r#"{
                    "url": "MYURL",
                    "title": "My Title",
                    "description": "My description",
                    "image": "MYIMG.png"
                 }"#;
    let card: Card = serde_json::from_str(ojson).unwrap();
    assert_eq!(card, Card {
                        url: String::from("MYURL"),
                        title: String::from("My Title"),
                        description: String::from("My description"),
                        image: String::from("MYIMG.png")
    });
}

#[test]
fn context_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn error_deserialize_from_json() {
    let ojson = r#"{
                    "error": "Error message"
                 }"#;
    let error: Error = serde_json::from_str(ojson).unwrap();
    assert_eq!(error, Error {
                        error: String::from("Error message")
    });
}

#[test]
fn instance_deserialize_from_json() {
    let ojson = r#"{
                    "url": "MYURL",
                    "title": "My Title",
                    "description": "My description",
                    "email": "MYEMAIL"
                 }"#;
    let instance: Instance = serde_json::from_str(ojson).unwrap();
    assert_eq!(instance, Instance {
                        url: String::from("MYURL"),
                        title: String::from("My Title"),
                        description: String::from("My description"),
                        email: String::from("MYEMAIL")
    });
}

#[test]
fn mention_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "url": "MYURL",
                    "username": "MYUSERNAME",
                    "acct": "MYUSERNAME@REMOTEDOMAIN"
                 }"#;
    let mention: Mention = serde_json::from_str(ojson).unwrap();
    assert_eq!(mention, Mention {
                        mention_id: 1234,
                        url: String::from("MYURL"),
                        username: String::from("MYUSERNAME"),
                        acct: String::from("MYUSERNAME@REMOTEDOMAIN")
    });
}

#[test]
fn notification_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn relationship_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "following": true,
                    "followed_by": true,
                    "blocking": true,
                    "muting": true,
                    "requested": true
                 }"#;
    let relationship: Relationship = serde_json::from_str(ojson).unwrap();
    assert_eq!(relationship, Relationship {
                        relationship_id: 1234,
                        following: true,
                        followed_by: true,
                        blocking: true,
                        muting: true,
                        requested: true
    });
}

#[test]
fn report_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "action_taken": "Some action taken"
                 }"#;
    let report: Report = serde_json::from_str(ojson).unwrap();
    assert_eq!(report, Report {
                        report_id: 1234,
                        action_taken: String::from("Some action taken")
    });
}

#[test]
fn results_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn status_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn tag_deserialize_from_json() {
    let ojson = r#"{
                    "name": "rustlang",
                    "url": "MYURL"
                 }"#;
    let tag: Tag = serde_json::from_str(ojson).unwrap();
    assert_eq!(tag, Tag {
                        name: String::from("rustlang"),
                        url: String::from("MYURL")
    });
}
<commit_msg>tests for all entitities deserialization<commit_after>extern crate herder;
extern crate serde_json;

use herder::api::v1::{
    Account,
    Application,
    Attachment,
    Card,
    Context,
    Error,
    Instance,
    Mention,
    Notification,
    Relationship,
    Report,
    Results,
    Status,
    Tag
};

fn mock_account() -> Account {
    Account {
        account_id: 1234,
        username: String::from("MYUSERNAME"),
        acct: String::from("MYUSERNAME@MYREMOTEDOMAIN"),
        display_name: String::from("jane_sanchez"),
        note: String::from("A self-described person"),
        url: String::from("MYRUL"),
        avatar: String::from("MYURL.png"),
        header: String::from("MYHEADER.png"),
        locked: false,
        created_at: String::from("2000-01-01T00:00:00Z"),
        followers_count: 1234,
        following_count: 1234,
        statuses_count: 1234
    }
}

fn mock_application() -> Application {
    Application {
        name: String::from("MYNAME"),
        website: Some(String::from("MYURI"))
    }
}

fn mock_status() -> Status {
    Status {
        status_id: 1234,
        uri: String::from("MYURI"),
        url: String::from("MYURL"),
        account: mock_account(),
        in_reply_to_id: Some(1234),
        in_reply_to_account_id: Some(1234),
        reblog: None,
        content: String::from("My tooted toot!"),
        created_at: String::from("2000-01-01T00:00:00Z"),
        reblogs_count: 555,
        favourites_count: 777,
        reblogged: true,
        favourited: true,
        sensitive: false,
        spoiler_text: String::from(""),
        visibility: String::from(""),
        media_attachments: Vec::new(),
        mentions: Vec::new(),
        tags: Vec::new(),
        application: mock_application()
    }
}

#[test]
fn account_deserialize_from_json() {
    let ojson = r#"{
        "id": 1234,
        "username": "MYUSERNAME",
        "acct": "MYUSERNAME@MYREMOTEDOMAIN",
        "display_name": "jane_sanchez",
        "note": "A self-described person",
        "url": "MYRUL",
        "avatar": "MYURL.png",
        "header": "MYHEADER.png",
        "locked": false,
        "created_at": "2000-01-01T00:00:00Z",
        "followers_count": 1234,
        "following_count": 1234,
        "statuses_count": 1234
    }"#;
    let account: Account = serde_json::from_str(ojson).unwrap();
    assert_eq!(account, mock_account());
}

#[test]
fn application_deserialize_from_json() {
    let ojson = r#"{
                    "name": "MYNAME",
                    "website": "MYURI"
                 }"#;
    let application: Application = serde_json::from_str(ojson).unwrap();
    assert_eq!(application, mock_application());
}

#[test]
fn attachment_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "type": "video",
                    "url": "MYURL",
                    "remote_url": "MYURL",
                    "preview_url": "MYURL",
                    "text_url": "MYURL"
                 }"#;
    let attachment: Attachment = serde_json::from_str(ojson).unwrap();
    assert_eq!(attachment, Attachment {
        attachment_id: 1234,
        attachment_type: String::from("video"),
        url: String::from("MYURL"),
        remote_url: String::from("MYURL"),
        preview_url: String::from("MYURL"),
        text_url: String::from("MYURL")
    });
}

#[test]
fn card_deserialize_from_json() {
    let ojson = r#"{
                    "url": "MYURL",
                    "title": "My Title",
                    "description": "My description",
                    "image": "MYIMG.png"
                 }"#;
    let card: Card = serde_json::from_str(ojson).unwrap();
    assert_eq!(card, Card {
        url: String::from("MYURL"),
        title: String::from("My Title"),
        description: String::from("My description"),
        image: String::from("MYIMG.png")
    });
}

#[test]
fn context_deserialize_from_json() {
    let ojson = r#"{
                    "ancestors": [],
                    "descendants": []
                 }"#;
    let context: Context = serde_json::from_str(ojson).unwrap();
    assert_eq!(context, Context {
        ancestors: Vec::new(),
        descendants: Vec::new()
    });
}

#[test]
fn error_deserialize_from_json() {
    let ojson = r#"{
                    "error": "Error message"
                 }"#;
    let error: Error = serde_json::from_str(ojson).unwrap();
    assert_eq!(error, Error {
        error: String::from("Error message")
    });
}

#[test]
fn instance_deserialize_from_json() {
    let ojson = r#"{
                    "url": "MYURL",
                    "title": "My Title",
                    "description": "My description",
                    "email": "MYEMAIL"
                 }"#;
    let instance: Instance = serde_json::from_str(ojson).unwrap();
    assert_eq!(instance, Instance {
        url: String::from("MYURL"),
        title: String::from("My Title"),
        description: String::from("My description"),
        email: String::from("MYEMAIL")
    });
}

#[test]
fn mention_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "url": "MYURL",
                    "username": "MYUSERNAME",
                    "acct": "MYUSERNAME@REMOTEDOMAIN"
                 }"#;
    let mention: Mention = serde_json::from_str(ojson).unwrap();
    assert_eq!(mention, Mention {
        mention_id: 1234,
        url: String::from("MYURL"),
        username: String::from("MYUSERNAME"),
        acct: String::from("MYUSERNAME@REMOTEDOMAIN")
    });
}

#[test]
fn notification_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "type": "NOTIFICATIONTYPE",
                    "created_at": "2000-01-01T00:00:00Z",
                    "account": {
                        "id": 1234,
                        "username": "MYUSERNAME",
                        "acct": "MYUSERNAME@MYREMOTEDOMAIN",
                        "display_name": "jane_sanchez",
                        "note": "A self-described person",
                        "url": "MYRUL",
                        "avatar": "MYURL.png",
                        "header": "MYHEADER.png",
                        "locked": false,
                        "created_at": "2000-01-01T00:00:00Z",
                        "followers_count": 1234,
                        "following_count": 1234,
                        "statuses_count": 1234
                    },
                    "status": null
                 }"#;
    let notification: Notification = serde_json::from_str(ojson).unwrap();
    assert_eq!(notification, Notification {
        notification_id: 1234,
        notification_type: String::from("NOTIFICATIONTYPE"),
        created_at: String::from("2000-01-01T00:00:00Z"),
        account: mock_account(),
        status: None
    });
}

#[test]
fn relationship_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "following": true,
                    "followed_by": true,
                    "blocking": true,
                    "muting": true,
                    "requested": true
                 }"#;
    let relationship: Relationship = serde_json::from_str(ojson).unwrap();
    assert_eq!(relationship, Relationship {
        relationship_id: 1234,
        following: true,
        followed_by: true,
        blocking: true,
        muting: true,
        requested: true
    });
}

#[test]
fn report_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "action_taken": "Some action taken"
                 }"#;
    let report: Report = serde_json::from_str(ojson).unwrap();
    assert_eq!(report, Report {
        report_id: 1234,
        action_taken: String::from("Some action taken")
    });
}

#[test]
fn results_deserialize_from_json() {
    let ojson = r#"{
                    "accounts": [],
                    "statuses": [],
                    "hashtags": []
                 }"#;
    let results: Results = serde_json::from_str(ojson).unwrap();
    assert_eq!(results, Results {
        accounts: Vec::new(),
        statuses: Vec::new(),
        hashtags: Vec::new()
    });
}

#[test]
fn status_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "uri": "MYURI",
                    "url": "MYURL",
                    "account": {
                        "id": 1234,
                        "username": "MYUSERNAME",
                        "acct": "MYUSERNAME@MYREMOTEDOMAIN",
                        "display_name": "jane_sanchez",
                        "note": "A self-described person",
                        "url": "MYRUL",
                        "avatar": "MYURL.png",
                        "header": "MYHEADER.png",
                        "locked": false,
                        "created_at": "2000-01-01T00:00:00Z",
                        "followers_count": 1234,
                        "following_count": 1234,
                        "statuses_count": 1234
                    },
                    "in_reply_to_id": 1234,
                    "in_reply_to_account_id": 1234,
                    "reblog": null,
                    "content": "My tooted toot!",
                    "created_at": "2000-01-01T00:00:00Z",
                    "reblogs_count": 555,
                    "favourites_count": 777,
                    "reblogged": true,
                    "favourited": true,
                    "sensitive": false,
                    "spoiler_text": "",
                    "visibility": "",
                    "media_attachments": [],
                    "mentions": [],
                    "tags": [],
                    "application": {
                        "name": "MYNAME",
                        "website": "MYURI"
                    }
                 }"#;
    let status: Status = serde_json::from_str(ojson).unwrap();
    assert_eq!(status, mock_status());
}

#[test]
fn tag_deserialize_from_json() {
    let ojson = r#"{
                    "name": "rustlang",
                    "url": "MYURL"
                 }"#;
    let tag: Tag = serde_json::from_str(ojson).unwrap();
    assert_eq!(tag, Tag {
        name: String::from("rustlang"),
        url: String::from("MYURL")
    });
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::sync::{
    Arc,
    Mutex,
};
use std::thread;
use std::time::Duration;

use c_ares;
use mio;

use error::Error;
use eventloop::EventLoopHandle;

// The EventLoop will set up a mio::Poll and use it to wait for the following:
//
// -  messages telling it which file descriptors it should be interested in.
//    These file descriptors are then registered (or deregistered) with the
//    mio::Poll as required.
//
// -  events telling it that something has happened on one of these file
//    descriptors.  When this happens, it tells the c_ares::Channel about it.
//
// -  a message telling it to shut down.
pub struct EventLoop {
    poll: mio::Poll,
    tx_msg_channel: mio::channel::Sender<Message>,
    rx_msg_channel: mio::channel::Receiver<Message>,
    tracked_fds: HashSet<c_ares::Socket>,
    pub ares_channel: Arc<Mutex<c_ares::Channel>>,
    quit: bool,
}

// Messages for the event loop.
#[derive(Debug)]
pub enum Message {
    // 'Notify me when this file descriptor becomes readable, or writable'.
    // The first bool is for 'readable' and the second is for 'writable'.  It's
    // allowed to set both of these - or neither, meaning 'I am no longer
    // interested in this file descriptor'.
    RegisterInterest(c_ares::Socket, bool, bool),

    // 'Shut down'.
    ShutDown,
}

// A token identifying that the message channel has become available for reading.
//
// We use Token(fd) for file descriptors, so this relies on zero not being a
// valid file descriptor for c-ares to use.  Zero is stdin, so that's true.
const CHANNEL: mio::Token = mio::Token(0);

impl EventLoop {
    // Create a new event loop.
    pub fn new(mut options: c_ares::Options) -> Result<EventLoop, Error> {
        // Create a mio::Poll on which to wait for events, and register a
        // channel with it.
        let poll = mio::Poll::new()?;
        let (tx, rx) = mio::channel::channel();
        poll.register(
            &rx,
            CHANNEL,
            mio::Ready::readable(),
            mio::PollOpt::edge()
        )?;

        // Whenever c-ares tells us what to do with a file descriptor, we'll
        // send that request along, through the channel we just created.
        let tx_clone = tx.clone();
        let sock_callback =
            move |fd: c_ares::Socket, readable: bool, writable: bool| {
                let _ = tx_clone.send(
                    Message::RegisterInterest(fd, readable, writable));
            };
        options.set_socket_state_callback(sock_callback);

        // Create the c-ares channel.
        let ares_channel = c_ares::Channel::new(options)?;
        let locked_channel = Arc::new(Mutex::new(ares_channel));

        // Create and return the event loop.
        let event_loop = EventLoop {
            poll: poll,
            tx_msg_channel: tx,
            rx_msg_channel: rx,
            tracked_fds: HashSet::<c_ares::Socket>::new(),
            ares_channel: locked_channel,
            quit: false,
        };
        Ok(event_loop)
    }

    // Run the event loop.
    pub fn run(self) -> EventLoopHandle {
        let tx_clone = self.tx_msg_channel.clone();
        let join_handle = thread::spawn(|| self.event_loop_thread());
        EventLoopHandle::new(join_handle, tx_clone)
    }

    // Event loop thread - waits for events, and handles them.
    fn event_loop_thread(mut self) {
        let mut events = mio::Events::with_capacity(16);
        loop {
            // Wait for something to happen.
            let timeout = Duration::from_millis(100);
            let results = self.poll
                .poll(&mut events, Some(timeout))
                .expect("poll failed");

            // Process whatever happened.
            match results {
                0 => {
                    // No events - must be a timeout.  Tell c-ares about it.
                    self.ares_channel.lock().unwrap().process_fd(
                        c_ares::SOCKET_BAD,
                        c_ares::SOCKET_BAD
                    );
                },
                _ => {
                    // Process events.  One of them might have asked us to quit.
                    for event in &events {
                        self.handle_event(&event);
                        if self.quit { return }
                    }
                }
            }
        }
    }

    // Handle a single event.
    fn handle_event(&mut self, event: &mio::Event) {
        match event.token() {
            CHANNEL => {
                // The channel is readable.
                self.handle_messages()
            },

            mio::Token(fd) => {
                // Sockets became readable or writable - tell c-ares.
                let rfd = if event.kind().is_readable() {
                    fd as c_ares::Socket
                } else {
                    c_ares::SOCKET_BAD
                };
                let wfd = if event.kind().is_writable() {
                    fd as c_ares::Socket
                } else {
                    c_ares::SOCKET_BAD
                };
                self.ares_channel.lock().unwrap().process_fd(rfd, wfd);
            }
        }
    }

    // Process messages incoming on the channel.
    fn handle_messages(&mut self) {
        loop {
            match self.rx_msg_channel.try_recv() {
                Ok(Message::RegisterInterest(fd, readable, writable)) => {
                    // Instruction to do something with a file descriptor.
                    let efd = mio::unix::EventedFd(&fd);
                    if !readable && !writable {
                        self.tracked_fds.remove(&fd);
                        let _ = self.poll.deregister(&efd);
                    } else {
                        let token = mio::Token(fd as usize);
                        let mut interest = mio::Ready::none();
                        if readable { interest.insert(mio::Ready::readable()) }
                        if writable { interest.insert(mio::Ready::writable()) }
                        let register_result = if !self.tracked_fds.insert(fd) {
                            self.poll.reregister(
                                &efd,
                                token,
                                interest,
                                mio::PollOpt::level()
                            )
                        } else {
                            self.poll.register(
                                &efd,
                                token,
                                interest,
                                mio::PollOpt::level()
                            )
                        };
                        register_result.expect("failed to register interest");
                    }
                },

                Ok(Message::ShutDown) => {
                    // Instruction to shut down.
                    self.quit = true;
                    break
                },

                // No more instructions.
                Err(_) => break,
            }
        }
    }
}
<commit_msg>assert that we're not messing up file descriptors<commit_after>use std::collections::HashSet;
use std::sync::{
    Arc,
    Mutex,
};
use std::thread;
use std::time::Duration;

use c_ares;
use mio;

use error::Error;
use eventloop::EventLoopHandle;

// The EventLoop will set up a mio::Poll and use it to wait for the following:
//
// -  messages telling it which file descriptors it should be interested in.
//    These file descriptors are then registered (or deregistered) with the
//    mio::Poll as required.
//
// -  events telling it that something has happened on one of these file
//    descriptors.  When this happens, it tells the c_ares::Channel about it.
//
// -  a message telling it to shut down.
pub struct EventLoop {
    poll: mio::Poll,
    tx_msg_channel: mio::channel::Sender<Message>,
    rx_msg_channel: mio::channel::Receiver<Message>,
    tracked_fds: HashSet<c_ares::Socket>,
    pub ares_channel: Arc<Mutex<c_ares::Channel>>,
    quit: bool,
}

// Messages for the event loop.
#[derive(Debug)]
pub enum Message {
    // 'Notify me when this file descriptor becomes readable, or writable'.
    // The first bool is for 'readable' and the second is for 'writable'.  It's
    // allowed to set both of these - or neither, meaning 'I am no longer
    // interested in this file descriptor'.
    RegisterInterest(c_ares::Socket, bool, bool),

    // 'Shut down'.
    ShutDown,
}

// A token identifying that the message channel has become available for reading.
//
// We use Token(fd) for file descriptors, so this relies on zero not being a
// valid file descriptor for c-ares to use.  Zero is stdin, so that's true.
const CHANNEL: mio::Token = mio::Token(0);

impl EventLoop {
    // Create a new event loop.
    pub fn new(mut options: c_ares::Options) -> Result<EventLoop, Error> {
        // Create a mio::Poll on which to wait for events, and register a
        // channel with it.
        let poll = mio::Poll::new()?;
        let (tx, rx) = mio::channel::channel();
        poll.register(
            &rx,
            CHANNEL,
            mio::Ready::readable(),
            mio::PollOpt::edge()
        )?;

        // Whenever c-ares tells us what to do with a file descriptor, we'll
        // send that request along, through the channel we just created.
        let tx_clone = tx.clone();
        let sock_callback =
            move |fd: c_ares::Socket, readable: bool, writable: bool| {
                let _ = tx_clone.send(
                    Message::RegisterInterest(fd, readable, writable));
            };
        options.set_socket_state_callback(sock_callback);

        // Create the c-ares channel.
        let ares_channel = c_ares::Channel::new(options)?;
        let locked_channel = Arc::new(Mutex::new(ares_channel));

        // Create and return the event loop.
        let event_loop = EventLoop {
            poll: poll,
            tx_msg_channel: tx,
            rx_msg_channel: rx,
            tracked_fds: HashSet::<c_ares::Socket>::new(),
            ares_channel: locked_channel,
            quit: false,
        };
        Ok(event_loop)
    }

    // Run the event loop.
    pub fn run(self) -> EventLoopHandle {
        let tx_clone = self.tx_msg_channel.clone();
        let join_handle = thread::spawn(|| self.event_loop_thread());
        EventLoopHandle::new(join_handle, tx_clone)
    }

    // Event loop thread - waits for events, and handles them.
    fn event_loop_thread(mut self) {
        let mut events = mio::Events::with_capacity(16);
        loop {
            // Wait for something to happen.
            let timeout = Duration::from_millis(100);
            let results = self.poll
                .poll(&mut events, Some(timeout))
                .expect("poll failed");

            // Process whatever happened.
            match results {
                0 => {
                    // No events - must be a timeout.  Tell c-ares about it.
                    self.ares_channel.lock().unwrap().process_fd(
                        c_ares::SOCKET_BAD,
                        c_ares::SOCKET_BAD
                    );
                },
                _ => {
                    // Process events.  One of them might have asked us to quit.
                    for event in &events {
                        self.handle_event(&event);
                        if self.quit { return }
                    }
                }
            }
        }
    }

    // Handle a single event.
    fn handle_event(&mut self, event: &mio::Event) {
        match event.token() {
            CHANNEL => {
                // The channel is readable.
                self.handle_messages()
            },

            mio::Token(fd) => {
                // Sockets became readable or writable - tell c-ares.
                let rfd = if event.kind().is_readable() {
                    fd as c_ares::Socket
                } else {
                    c_ares::SOCKET_BAD
                };
                let wfd = if event.kind().is_writable() {
                    fd as c_ares::Socket
                } else {
                    c_ares::SOCKET_BAD
                };
                self.ares_channel.lock().unwrap().process_fd(rfd, wfd);
            }
        }
    }

    // Process messages incoming on the channel.
    fn handle_messages(&mut self) {
        loop {
            match self.rx_msg_channel.try_recv() {
                // Instruction to do something with a file descriptor.
                Ok(Message::RegisterInterest(fd, readable, writable)) => {
                    let efd = mio::unix::EventedFd(&fd);
                    if !readable && !writable {
                        self.tracked_fds.remove(&fd);
                        let _ = self.poll.deregister(&efd);
                    } else {
                        assert!(fd != 0);
                        let token = mio::Token(fd as usize);
                        let mut interest = mio::Ready::none();
                        if readable { interest.insert(mio::Ready::readable()) }
                        if writable { interest.insert(mio::Ready::writable()) }
                        let register_result = if !self.tracked_fds.insert(fd) {
                            self.poll.reregister(
                                &efd,
                                token,
                                interest,
                                mio::PollOpt::level()
                            )
                        } else {
                            self.poll.register(
                                &efd,
                                token,
                                interest,
                                mio::PollOpt::level()
                            )
                        };
                        register_result.expect("failed to register interest");
                    }
                },

                // Instruction to shut down.
                Ok(Message::ShutDown) => {
                    self.quit = true;
                    break
                },

                // No more instructions.
                Err(_) => break,
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate pink_spider;

use pink_spider::apple_music;
use pink_spider::apple_music::country;
use pink_spider::model::{Track, Album, Artist, Provider};
use pink_spider::model::Enclosure;
use pink_spider::model::State;
use pink_spider::model::Model;

pub fn main() {
    let mut tracks = Track::find_by_provider(&Provider::AppleMusic);
    for track in tracks.iter_mut().filter(|a| a.state == State::Alive) {
        println!("update {:?} {:?}", track.identifier, track.title);
        match apple_music::fetch_song(&country(&track.url),
                                      &track.identifier) {
            Ok(am_song) => track.update_with_am_song(&am_song),
            Err(_)       => track.disable(),
        };
        let _ = track.save();
    }

    update_artists()
}

pub fn update_artists() {
    let artists = Artist::find_all();
    println!("len {}\n", artists.len());
    for mut artist in artists {
        println!("{:?} {:?} {:?}", artist.identifier, artist.provider, artist.name);
        match artist.provider {
            Provider::AppleMusic => update_apple_music(&mut artist),
            Provider::Spotify => update_artist(&mut artist),
            Provider::YouTube => update_artist(&mut artist),
            Provider::SoundCloud => update_artist(&mut artist),
            _ => (),
        }
    }
}

pub fn update_artist(artist: &mut Artist) {
    let _ = artist.fetch_props();
}

pub fn update_apple_music(artist: &mut Artist) {
    let country = country_of_am_artist(artist);
    match apple_music::search_artists(&country, &artist.name) {
        Ok(items) => {
            println!("  {:?} {:?} {}", artist.identifier, country, items.len());
            if items.len() == 1 {
                update_apple_music_artist(artist, &country, &items[0].id);
                //                    println!("Updated {:?}", artist);
                return
            }
            let items = items.iter().filter(|item| {
                item.attributes.name.to_lowercase() == artist.name.to_lowercase()
            }).collect::<Vec<&apple_music::Artist>>();
            if items.len() > 0 {
                update_apple_music_artist(artist, &country, &items[0].id);
                println!("  Updated {:?}", artist.identifier);
                return
            }
            println!("  Not updated {:?}", artist.identifier);
        },
        Err(_) => {
            println!("{:?} {:?} {}", artist.identifier, country, 0);
        },
    }
}

pub fn update_apple_music_artist(artist: &mut Artist, country: &str, id: &str) {
    artist.identifier = id.to_string();
    match apple_music::fetch_artist(country, id) {
        Ok(item) => artist.update_with_am_artist(&item),
        Err(e)   => {
            println!("{:?}", e);
            artist
        },
    };
}

pub fn country_of_am_artist(artist: &Artist) -> String {
    let tracks = Track::find_by_artist(artist.id);
    let albums = Album::find_by_artist(artist.id);
    if tracks.len() > 0 {
        return apple_music::country(&tracks[0].url);
    }
    if albums.len() > 0 {
        return apple_music::country(&albums[0].url);
    }
    println!("-- not found {:?}", artist.id);
    "us".to_string()
}
<commit_msg>`update_artists` showes error<commit_after>extern crate pink_spider;

use pink_spider::apple_music;
use pink_spider::apple_music::country;
use pink_spider::model::{Track, Album, Artist, Provider};
use pink_spider::model::Enclosure;
use pink_spider::model::State;
use pink_spider::model::Model;

pub fn main() {
    let mut tracks = Track::find_by_provider(&Provider::AppleMusic);
    for track in tracks.iter_mut().filter(|a| a.state == State::Alive) {
        println!("update {:?} {:?}", track.identifier, track.title);
        match apple_music::fetch_song(&country(&track.url),
                                      &track.identifier) {
            Ok(am_song) => track.update_with_am_song(&am_song),
            Err(e)      => {
                println!("{:?}", e);
                track.disable()
            },
        };
        let _ = track.save();
    }

    update_artists()
}

pub fn update_artists() {
    let artists = Artist::find_all();
    println!("len {}\n", artists.len());
    for mut artist in artists {
        println!("{:?} {:?} {:?}", artist.identifier, artist.provider, artist.name);
        match artist.provider {
            Provider::AppleMusic => update_apple_music(&mut artist),
            Provider::Spotify => update_artist(&mut artist),
            Provider::YouTube => update_artist(&mut artist),
            Provider::SoundCloud => update_artist(&mut artist),
            _ => (),
        }
    }
}

pub fn update_artist(artist: &mut Artist) {
    let _ = artist.fetch_props();
}

pub fn update_apple_music(artist: &mut Artist) {
    let country = country_of_am_artist(artist);
    match apple_music::search_artists(&country, &artist.name) {
        Ok(items) => {
            println!("  {:?} {:?} {}", artist.identifier, country, items.len());
            if items.len() == 1 {
                update_apple_music_artist(artist, &country, &items[0].id);
                //                    println!("Updated {:?}", artist);
                return
            }
            let items = items.iter().filter(|item| {
                item.attributes.name.to_lowercase() == artist.name.to_lowercase()
            }).collect::<Vec<&apple_music::Artist>>();
            if items.len() > 0 {
                update_apple_music_artist(artist, &country, &items[0].id);
                println!("  Updated {:?}", artist.identifier);
                return
            }
            println!("  Not updated {:?}", artist.identifier);
        },
        Err(e) => println!("{:?}", e),
    }
}

pub fn update_apple_music_artist(artist: &mut Artist, country: &str, id: &str) {
    artist.identifier = id.to_string();
    match apple_music::fetch_artist(country, id) {
        Ok(item) => artist.update_with_am_artist(&item),
        Err(e)   => {
            println!("{:?}", e);
            artist
        },
    };
}

pub fn country_of_am_artist(artist: &Artist) -> String {
    let tracks = Track::find_by_artist(artist.id);
    let albums = Album::find_by_artist(artist.id);
    if tracks.len() > 0 {
        return apple_music::country(&tracks[0].url);
    }
    if albums.len() > 0 {
        return apple_music::country(&albums[0].url);
    }
    println!("-- not found {:?}", artist.id);
    "us".to_string()
}
<|endoftext|>


<commit_before>//use serde;
// use serde::de::Deserialize;
// #![feature(custom_derive, plugin)]
// #![plugin(serde_macros)]

extern crate serde_json;
extern crate serde;

use serde_json::Value;

use std::collections;
use std::collections::BTreeMap;
use std::fmt::Debug;

// --------------------------------------------------------
// root obj.  contains controls.
// --------------------------------------------------------

// root is not itself a Control!  although maybe it should be?
#[derive(Debug)]
pub struct Root {
  pub title: String,
  pub rootControl: Box<Control>,
}

pub fn deserializeRoot(data: &Value) -> Option<Box<Root>>
{
  let obj = data.as_object().unwrap();
  let title = obj.get("title").unwrap().as_string().unwrap();

  let rc = obj.get("rootControl").unwrap();

  let rootcontrol = deserializeControl(Vec::new(), rc).unwrap();

  Some(Box::new(Root { title: String::new() + title, rootControl: rootcontrol }))
}

// --------------------------------------------------------
// controls.
// --------------------------------------------------------

//pub trait Control : Debug + Clone {
pub trait Control : Debug {
  fn controlType(&self) -> &'static str;
  fn controlId(&self) -> &Vec<i32>;
  fn subControls(&self) -> Option<&Vec<Box<Control>>>;
}

//#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct Slider {
  controlId: Vec<i32>,
  name: String,
  pressed: bool,
  location: f32,
}

impl Control for Slider {
  fn controlType(&self) -> &'static str { "slider" }
  fn controlId(&self) -> &Vec<i32> { &self.controlId }
  fn subControls(&self) -> Option<&Vec<Box<Control>>> { None }
}

//#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct Button {
  controlId: Vec<i32>,
  name: String,
  pressed: bool,
}

impl Control for Button {
  fn controlType(&self) -> &'static str { "button" }
  fn controlId(&self) -> &Vec<i32> { &self.controlId }
  fn subControls(&self) -> Option<&Vec<Box<Control>>> { None }
}

//#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct Sizer {
  controlId: Vec<i32>,
  controls: Vec<Box<Control>>,
}

impl Control for Sizer {
  fn controlType(&self) -> &'static str { "sizer" }
  fn controlId(&self) -> &Vec<i32> { &self.controlId }
  fn subControls(&self) -> Option<&Vec<Box<Control>>> { None }
}

fn deserializeControl(aVId: Vec<i32>, data: &Value) -> Option<Box<Control>>
{
  // what's the type?
  let obj = data.as_object().unwrap();
  let objtype =
    obj.get("type").unwrap().as_string().unwrap();

  match objtype {
    "slider" => {
      let name = obj.get("name").unwrap().as_string().unwrap();
      Some(Box::new(Slider { controlId: aVId.clone(), name: String::new() + name, pressed: false, location: 0.5 }))
      },
    "button" => {
      let name = obj.get("name").unwrap().as_string().unwrap();
      Some(Box::new(Button { controlId: aVId.clone(), name: String::new() + name, pressed: false }))
      },
    "sizer" => {
      let name = obj.get("name").unwrap().as_string().unwrap();
      let controls = obj.get("controls").unwrap().as_array().unwrap();

      let mut controlv = Vec::new();

      for (i, v) in controls.into_iter().enumerate() {
          let mut id = aVId.clone();
          id.push(i as i32);
          let c = deserializeControl(id, v).unwrap();
          controlv.push(c);
          }
      // loop through controls, makin controls.
      Some(Box::new(Sizer { controlId: aVId.clone(), controls: controlv }))
      },
    _ => None,
    }
}

// --------------------------------------------------------
// control state map.
// --------------------------------------------------------

/*
fn makeControlMap (control: &Control, map: BTreeMap<Vec<i32>,Box<Control>>) -> BTreeMap<Vec<i32>,Box<Control>> {

  let v = control.subControls();

//  map.insert(control.controlId().clone(), Box::new(control.clone()));

  map
}
*/
<commit_msg>cloneTrol ftn; makeControlMap.<commit_after>//use serde;
// use serde::de::Deserialize;
// #![feature(custom_derive, plugin)]
// #![plugin(serde_macros)]

extern crate serde_json;
extern crate serde;

use serde_json::Value;

use std::collections;
use std::collections::BTreeMap;
use std::fmt::Debug;

// --------------------------------------------------------
// root obj.  contains controls.
// --------------------------------------------------------

// root is not itself a Control!  although maybe it should be?
#[derive(Debug)]
pub struct Root {
  pub title: String,
  pub rootControl: Box<Control>,
}

pub fn deserializeRoot(data: &Value) -> Option<Box<Root>>
{
  let obj = data.as_object().unwrap();
  let title = obj.get("title").unwrap().as_string().unwrap();

  let rc = obj.get("rootControl").unwrap();

  let rootcontrol = deserializeControl(Vec::new(), rc).unwrap();

  Some(Box::new(Root { title: String::new() + title, rootControl: rootcontrol }))
}

// --------------------------------------------------------
// controls.
// --------------------------------------------------------

pub trait Control : Debug {
  fn controlType(&self) -> &'static str;
  fn controlId(&self) -> &Vec<i32>;
  fn cloneTrol(&self) -> Box<Control>;
  fn subControls(&self) -> Option<&Vec<Box<Control>>>;
}

#[derive(Debug)]
pub struct Slider {
  controlId: Vec<i32>,
  name: String,
  pressed: bool,
  location: f32,
}

impl Control for Slider {
  fn controlType(&self) -> &'static str { "slider" }
  fn controlId(&self) -> &Vec<i32> { &self.controlId }
  // fn cloneTrol(&self) -> Box<Control> { Box::new( Slider { *self } ) }
  fn cloneTrol(&self) -> Box<Control> {
    Box::new(
      Slider { controlId: self.controlId.clone(),
              name: self.name.clone(),
              pressed: self.pressed.clone(),
              location: self.location.clone() } ) }
  fn subControls(&self) -> Option<&Vec<Box<Control>>> { None }
}

#[derive(Debug)]
pub struct Button {
  controlId: Vec<i32>,
  name: String,
  pressed: bool,
}

impl Control for Button {
  fn controlType(&self) -> &'static str { "button" }
  fn controlId(&self) -> &Vec<i32> { &self.controlId }
  fn cloneTrol(&self) -> Box<Control> {
    Box::new(
      Button { controlId: self.controlId.clone(),
              name: self.name.clone(),
              pressed: self.pressed.clone() } ) }
  fn subControls(&self) -> Option<&Vec<Box<Control>>> { None }
}

//#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct Sizer {
  controlId: Vec<i32>,
  controls: Vec<Box<Control>>,
}

impl Control for Sizer {
  fn controlType(&self) -> &'static str { "sizer" }
  fn controlId(&self) -> &Vec<i32> { &self.controlId }
  fn cloneTrol(&self) -> Box<Control> {
    Box::new(
      Sizer { controlId: self.controlId.clone(),
              controls: Vec::new() } ) }
  fn subControls(&self) -> Option<&Vec<Box<Control>>> { None }
}

fn deserializeControl(aVId: Vec<i32>, data: &Value) -> Option<Box<Control>>
{
  // what's the type?
  let obj = data.as_object().unwrap();
  let objtype =
    obj.get("type").unwrap().as_string().unwrap();

  match objtype {
    "slider" => {
      let name = obj.get("name").unwrap().as_string().unwrap();
      Some(Box::new(Slider { controlId: aVId.clone(), name: String::new() + name, pressed: false, location: 0.5 }))
      },
    "button" => {
      let name = obj.get("name").unwrap().as_string().unwrap();
      Some(Box::new(Button { controlId: aVId.clone(), name: String::new() + name, pressed: false }))
      },
    "sizer" => {
      let name = obj.get("name").unwrap().as_string().unwrap();
      let controls = obj.get("controls").unwrap().as_array().unwrap();

      let mut controlv = Vec::new();

      for (i, v) in controls.into_iter().enumerate() {
          let mut id = aVId.clone();
          id.push(i as i32);
          let c = deserializeControl(id, v).unwrap();
          controlv.push(c);
          }
      // loop through controls, makin controls.
      Some(Box::new(Sizer { controlId: aVId.clone(), controls: controlv }))
      },
    _ => None,
    }
}

// --------------------------------------------------------
// control state map.  copies all the controls.
// --------------------------------------------------------

pub fn makeControlMap (control: &Control) -> BTreeMap<Vec<i32>,Box<Control>> {
  //.let mut btm = BTreeMap<Vec<i32>,Box<Control>>::new();
  let mut btm = BTreeMap::new();

  makeControlMap_impl(control, btm)
}

fn makeControlMap_impl (control: &Control, mut map: BTreeMap<Vec<i32>,Box<Control>>) -> BTreeMap<Vec<i32>,Box<Control>> {

  map.insert(control.controlId().clone(), control.cloneTrol());

  match control.subControls() {
    Some(trols) => {
      let mut item = trols.into_iter();

      loop {
          match item.next() {
            Some(x) => {
              map = makeControlMap_impl(&**x, map)
              },
            None => { break },
          }
        }
      }
    None => {}
    }

  map
}
<|endoftext|>


<commit_before>use metric::{Measured, Line, Grapheme, Metric};
use super::{NodeLink, LeafRepr };

use self::Value::*;

use std::cell::Cell;
use std::convert;
use std::default::Default;
use std::fmt;
use std::ops;

/// A lazily-evaluated field
#[derive(Clone)]
struct Lazy<T: Copy>(Cell<Option<T>>);

impl<T> Lazy<T>
where T: Copy {

    /// Get the value of the field if it has been computed
    ///
    /// # Returns
    /// - `Some(T)` if the value of this field has been computed
    /// - `None` if the field has yet to be computed
    #[inline]
    pub fn get(&self) -> Option<T> { self.0.get() }

    /// Get the value of the field, or compute it
    ///
    /// # Arguments
    /// - `f`: a function returning type `T` to use to calculate the value of
    ///        the field if it has not already been calculated
    ///
    /// # Returns
    /// - If the field has already been evaluated, the value of the field.
    /// - If the field has not been evaluated, the value of `f`
    #[inline]
    pub fn get_or_else<F>(&self, f: F) -> T
    where F: FnOnce() -> T {
        if let Some(value) = self.0.get() {
            value
        } else {
            let value = f();
            self.0.set(Some(value));
            value
        }
    }

    #[inline]
    pub fn new() -> Self {
        Lazy(Cell::new(None))
    }

}

impl<T> Default for Lazy<T>
where T: Copy {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> fmt::Debug for Lazy<T>
where T: fmt::Debug
    , T: Copy {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0.get() { Some(value) => value.fmt(f)
                           , None => write!(f, "?")

        }
    }
}

macro_rules! lazy_field {
    ($method: ident, $field: ident, $ty:ty) => {
        #[inline] fn $method(&self) -> $ty {
            self.$field.get_or_else(|| { self.value.$method() })
        }

    }
}

/// A `Node`.
#[derive(Clone, Default)]
pub struct Node { len: Lazy<usize>
                , weight: Lazy<usize>
                , line_count: Lazy<Line>
                , line_weight: Lazy<Line>
                , grapheme_count: Lazy<Grapheme>
                , grapheme_weight: Lazy<Grapheme>
                , pub value: Value
                }

impl Node {
    pub fn new(value: Value) -> Self {
        Node { value: value, ..Default::default() }
    }

    pub fn spanning(&self, i: usize, span_len: usize) -> (&Node, usize)
    where Node: Measured<usize> {
        assert!(self.len() >= span_len);
        match **self {
            Branch { ref right, ref left } if < Node as Measured<usize>>::measure_weight(self) < i => {
                // if this node is a branch, and the weight is less than the
                // index, where the span begins, then the first index of the
                // span is on the right side
                let span_i = or_zero!(i, left.len());
                assert!(or_zero!(right.len(), span_i) >= span_len);
                right.spanning(span_i, span_len)
            }
          , Branch { ref left, .. }
            // if the left child is long enough to contain the entire span,
            // walk to the left child
            if or_zero!(left.len(), i) >= span_len => left.spanning(i, span_len)
         ,  Leaf(_) | Branch {..} =>
            // if this function has walked as far as a leaf node,
            // then that leaf must be the spanning node. return it;
            //
            // otherwise, if the node is a branch node and the span is longer
            // than the left child, then this node must be the minimum
            // spanning node
            (self, i)
        }
    }
}

impl fmt::Display for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.strings()
            .fold(Ok(()), |r, string| r.and_then(|_| write!(f, "{}", string)))
    }
}

impl fmt::Debug for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!( f, "({:?}{}{}{}{}{}{})"
              , self.value
              , self.len.get().map(|l| format!(", length: {:?}", l))
                    .unwrap_or_else(|| { String::new() })
              , self.weight.get().map(|w| format!(", weight: {:?}", w))
                    .unwrap_or_else(|| { String::new() })
              , self.grapheme_count.get().map(|w| format!(", length: {:?}", w))
                    .unwrap_or_else(|| { String::new() })
              , self.grapheme_weight.get().map(|w| format!(", weight: {:?}", w))
                    .unwrap_or_else(|| { String::new() })
              , self.line_count.get().map(|w| format!(", length: {:?}", w))
                    .unwrap_or_else(|| { String::new() })
              , self.line_weight.get().map(|w| format!(", weight: {:?}", w))
                    .unwrap_or_else(|| { String::new() })
              )
    }
}

impl convert::Into<NodeLink> for Node {
    #[inline] fn into(self) -> NodeLink {
        NodeLink::new(self)
    }
}

impl ops::Deref for Node {
    type Target = Value;
    fn deref(&self) -> &Value { &self.value }
}

impl Measured<usize> for Node {

        #[inline] fn to_byte_index(&self, index: usize) -> Option<usize>  {
             Some(index)
        }

        lazy_field!(measure, len, usize);
        lazy_field!(measure_weight, weight, usize);

}

impl Measured<Grapheme> for Node {

        #[inline] fn to_byte_index(&self, index: Grapheme) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, grapheme_count, Grapheme);
        lazy_field!(measure_weight, grapheme_weight, Grapheme);

}

impl Measured<Line> for Node {

        #[inline] fn to_byte_index(&self, index: Line) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, line_count, Line);
        lazy_field!(measure_weight, line_weight, Line);

}

impl<M> ops::Index<M> for Node
where M: Metric
    , Node: Measured<M>
    , LeafRepr: Measured<M>
    {
    type Output = str;

    fn index(&self, i: M) -> &str {
        let len = self.measure();
        assert!( i < len
               , "Node::index: index {:?} out of bounds (length {:?})", i, len);
        match **self {
            Leaf(ref string) => {
                let idx = string.to_byte_index(i)
                                .expect("index out of bounds!");
                &string[idx..idx+1]
            }
          , Branch { ref right, .. } if len < i =>
                &right[i - len]
          , Branch { ref left, .. } => &left[i]
        }
    }
}

/// A `Node` in the `Rope`'s tree.
///
/// A `Node` is either a `Leaf` holding a `String`, or a
/// a `Branch` concatenating together two `Node`s.
#[derive(Clone)]
pub enum Value {
    /// A leaf node
    Leaf(LeafRepr)
  , /// A branch concatenating together `l`eft and `r`ight nodes.
    Branch { /// The left branch node
             left: NodeLink
           , /// The right branch node
             right: NodeLink }
}

impl Value {
    #[inline]
    pub fn new_branch(left: NodeLink, right: NodeLink) -> Self {
        Branch { left: left, right: right }
    }
}

impl<M> Measured<M> for Value
where M: Metric
    , LeafRepr: Measured<M>
    , Node: Measured<M>
{
    fn to_byte_index(&self, index: M) -> Option<usize> {
        unimplemented!()
    }

    fn measure(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure()
          , Branch { ref left, ref right } =>
                left.measure() + right.measure()
        }
    }

    fn measure_weight(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure_weight()
          , Branch { ref left, .. } => left.measure()
        }
    }

}

impl convert::Into<Node> for Value {
    #[inline] fn into(self) -> Node {
        Node::new(self)
    }
}

impl Default for Value {
    fn default() -> Self {
        Leaf(LeafRepr::default())
    }
}

impl fmt::Debug for Value {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Leaf(ref r) => write!(f, "Leaf({:?})", r)
          , Branch { ref left, ref right } => write!( f, "Branch({:?}, {:?})"
                                                    , left
                                                    , right)
        }
    }
}
<commit_msg>fix(rope internals): make node debug formatting prettier _again_<commit_after>use metric::{Measured, Line, Grapheme, Metric};
use super::{NodeLink, LeafRepr };

use self::Value::*;

use std::cell::Cell;
use std::convert;
use std::default::Default;
use std::fmt;
use std::ops;

/// A lazily-evaluated field
#[derive(Clone)]
struct Lazy<T: Copy>(Cell<Option<T>>);

impl<T> Lazy<T>
where T: Copy {

    /// Get the value of the field if it has been computed
    ///
    /// # Returns
    /// - `Some(T)` if the value of this field has been computed
    /// - `None` if the field has yet to be computed
    #[inline]
    pub fn get(&self) -> Option<T> { self.0.get() }

    /// Get the value of the field, or compute it
    ///
    /// # Arguments
    /// - `f`: a function returning type `T` to use to calculate the value of
    ///        the field if it has not already been calculated
    ///
    /// # Returns
    /// - If the field has already been evaluated, the value of the field.
    /// - If the field has not been evaluated, the value of `f`
    #[inline]
    pub fn get_or_else<F>(&self, f: F) -> T
    where F: FnOnce() -> T {
        if let Some(value) = self.0.get() {
            value
        } else {
            let value = f();
            self.0.set(Some(value));
            value
        }
    }

    #[inline]
    pub fn new() -> Self {
        Lazy(Cell::new(None))
    }

}

impl<T> Default for Lazy<T>
where T: Copy {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> fmt::Debug for Lazy<T>
where T: fmt::Debug
    , T: Copy {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0.get() { Some(value) => value.fmt(f)
                           , None => write!(f, "?")

        }
    }
}

macro_rules! lazy_field {
    ($method: ident, $field: ident, $ty:ty) => {
        #[inline] fn $method(&self) -> $ty {
            self.$field.get_or_else(|| { self.value.$method() })
        }

    }
}

/// A `Node`.
#[derive(Clone, Default)]
pub struct Node { len: Lazy<usize>
                , weight: Lazy<usize>
                , line_count: Lazy<Line>
                , line_weight: Lazy<Line>
                , grapheme_count: Lazy<Grapheme>
                , grapheme_weight: Lazy<Grapheme>
                , pub value: Value
                }

impl Node {
    pub fn new(value: Value) -> Self {
        Node { value: value, ..Default::default() }
    }

    pub fn spanning(&self, i: usize, span_len: usize) -> (&Node, usize)
    where Node: Measured<usize> {
        assert!(self.len() >= span_len);
        match **self {
            Branch { ref right, ref left } if < Node as Measured<usize>>::measure_weight(self) < i => {
                // if this node is a branch, and the weight is less than the
                // index, where the span begins, then the first index of the
                // span is on the right side
                let span_i = or_zero!(i, left.len());
                assert!(or_zero!(right.len(), span_i) >= span_len);
                right.spanning(span_i, span_len)
            }
          , Branch { ref left, .. }
            // if the left child is long enough to contain the entire span,
            // walk to the left child
            if or_zero!(left.len(), i) >= span_len => left.spanning(i, span_len)
         ,  Leaf(_) | Branch {..} =>
            // if this function has walked as far as a leaf node,
            // then that leaf must be the spanning node. return it;
            //
            // otherwise, if the node is a branch node and the span is longer
            // than the left child, then this node must be the minimum
            // spanning node
            (self, i)
        }
    }
}

impl fmt::Display for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.strings()
            .fold(Ok(()), |r, string| r.and_then(|_| write!(f, "{}", string)))
    }
}

impl fmt::Debug for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!( f, "Node {{{}{}{}\n\t{:#?} }}"
              , self.len.get().map(|l| format!("{} chars, ", l))
                    .unwrap_or_else(|| { String::new() })
            //   , self.weight.get().map(|w| format!("weight: {:?}, ", w))
            //         .unwrap_or_else(|| { String::new() })
              , self.grapheme_count.get()
                    .map(|w| format!("{} graphemes, ", w.0))
                    .unwrap_or_else(|| { String::new() })
            //   , self.grapheme_weight.get().map(|w| format!("weight: {:?}, ", w))
            //         .unwrap_or_else(|| { String::new() })
              , self.line_count.get()
                  .map(|w| format!("{} lines, ", w.0))
                  .unwrap_or_else(|| { String::new() })
            //   , self.line_weight.get().map(|w| format!(", weight: {:?}", w))
            //         .unwrap_or_else(|| { String::new() })
              , self.value
              )
    }
}

impl convert::Into<NodeLink> for Node {
    #[inline] fn into(self) -> NodeLink {
        NodeLink::new(self)
    }
}

impl ops::Deref for Node {
    type Target = Value;
    fn deref(&self) -> &Value { &self.value }
}

impl Measured<usize> for Node {

        #[inline] fn to_byte_index(&self, index: usize) -> Option<usize>  {
             Some(index)
        }

        lazy_field!(measure, len, usize);
        lazy_field!(measure_weight, weight, usize);

}

impl Measured<Grapheme> for Node {

        #[inline] fn to_byte_index(&self, index: Grapheme) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, grapheme_count, Grapheme);
        lazy_field!(measure_weight, grapheme_weight, Grapheme);

}

impl Measured<Line> for Node {

        #[inline] fn to_byte_index(&self, index: Line) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, line_count, Line);
        lazy_field!(measure_weight, line_weight, Line);

}

impl<M> ops::Index<M> for Node
where M: Metric
    , Node: Measured<M>
    , LeafRepr: Measured<M>
    {
    type Output = str;

    fn index(&self, i: M) -> &str {
        let len = self.measure();
        assert!( i < len
               , "Node::index: index {:?} out of bounds (length {:?})", i, len);
        match **self {
            Leaf(ref string) => {
                let idx = string.to_byte_index(i)
                                .expect("index out of bounds!");
                &string[idx..idx+1]
            }
          , Branch { ref right, .. } if len < i =>
                &right[i - len]
          , Branch { ref left, .. } => &left[i]
        }
    }
}

/// A `Node` in the `Rope`'s tree.
///
/// A `Node` is either a `Leaf` holding a `String`, or a
/// a `Branch` concatenating together two `Node`s.
#[derive(Clone)]
pub enum Value {
    /// A leaf node
    Leaf(LeafRepr)
  , /// A branch concatenating together `l`eft and `r`ight nodes.
    Branch { /// The left branch node
             left: NodeLink
           , /// The right branch node
             right: NodeLink }
}

impl Value {
    #[inline]
    pub fn new_branch(left: NodeLink, right: NodeLink) -> Self {
        Branch { left: left, right: right }
    }
}

impl<M> Measured<M> for Value
where M: Metric
    , LeafRepr: Measured<M>
    , Node: Measured<M>
{
    fn to_byte_index(&self, index: M) -> Option<usize> {
        unimplemented!()
    }

    fn measure(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure()
          , Branch { ref left, ref right } =>
                left.measure() + right.measure()
        }
    }

    fn measure_weight(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure_weight()
          , Branch { ref left, .. } => left.measure()
        }
    }

}

impl convert::Into<Node> for Value {
    #[inline] fn into(self) -> Node {
        Node::new(self)
    }
}

impl Default for Value {
    fn default() -> Self {
        Leaf(LeafRepr::default())
    }
}

impl fmt::Debug for Value {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Leaf(ref r) => write!(f, "Leaf({:?})", r)
          , Branch { ref left, ref right } => write!( f, "Branch({:?}, {:?})"
                                                    , left
                                                    , right)
        }
    }
}
<|endoftext|>


<commit_before>use log::trace;
use serde::de::DeserializeOwned;
use std::{error::Error, ffi::OsStr, fs::read_dir, path::Path};

use super::*;
use crate::models;

pub trait Load: Sized {
    fn load(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>>;
}

impl Load for ProjectBundle {
    fn load(bundle_path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
        let bundle_path: &Path = bundle_path.as_ref();
        trace!("Loading {:?}", bundle_path);

        Ok(ProjectBundle {
            path: std::fs::canonicalize(bundle_path.to_path_buf())?,
            project: Load::load(&bundle_path.join("project.yaml"))?,
            layouts: Load::load(&bundle_path.join("layouts"))?,
            targets: Load::load(&bundle_path.join("targets"))?,
        })
    }
}

impl Load for models::Project {
    fn load(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
        Ok(read_yml(path.as_ref())?)
    }
}

impl Load for Vec<models::Layout> {
    fn load(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
        let yml_files = read_dir(path.as_ref())?
            .filter_map(Result::ok)
            .map(|f| f.path())
            .filter(|p| p.is_file())
            .filter(|p| p.extension() == Some(OsStr::new("yaml")));

        yml_files.map(|p| read_yml(&p)).collect()
    }
}

impl Load for Targets {
    fn load(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
        let path: &Path = path.as_ref();
        Ok(Targets {
            android: read_yml_if_exists(&path.join("android.yaml"))?,
            i_os: read_yml_if_exists(&path.join("ios.yaml"))?,
            mac_os: read_yml_if_exists(&path.join("macos.yaml"))?,
            windows: read_yml_if_exists(&path.join("windows.yaml"))?,
        })
    }
}

fn read_yml<'a, T: DeserializeOwned>(path: &'a Path) -> Result<T, Box<dyn Error>> {
    use std::{fs::File, io::BufReader};
    let file = File::open(path)?;
    let reader = BufReader::new(file);
    let parsed = serde_yaml::from_reader(reader)?;
    Ok(parsed)
}

fn read_yml_if_exists<'a, T: DeserializeOwned>(
    path: &'a Path,
) -> Result<Option<T>, Box<dyn Error>> {
    let path: &Path = path.as_ref();
    if !path.is_file() {
        return Ok(None);
    }
    read_yml(path)
}
<commit_msg>Streamline imports<commit_after>use log::trace;
use serde::de::DeserializeOwned;
use std::{
    error::Error,
    ffi::OsStr,
    fs::{canonicalize, read_dir},
    path::Path,
};

use super::*;
use crate::models;

pub trait Load: Sized {
    /// Read data from given path into a structure of this type
    fn load(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>>;
}

impl Load for ProjectBundle {
    fn load(bundle_path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
        let bundle_path: &Path = bundle_path.as_ref();
        trace!("Loading {:?}", bundle_path);

        Ok(ProjectBundle {
            path: canonicalize(bundle_path.to_path_buf())?,
            project: Load::load(&bundle_path.join("project.yaml"))?,
            layouts: Load::load(&bundle_path.join("layouts"))?,
            targets: Load::load(&bundle_path.join("targets"))?,
        })
    }
}

impl Load for models::Project {
    fn load(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
        Ok(read_yml(path.as_ref())?)
    }
}

impl Load for Vec<models::Layout> {
    fn load(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
        let yml_files = read_dir(path.as_ref())?
            .filter_map(Result::ok)
            .map(|f| f.path())
            .filter(|p| p.is_file())
            .filter(|p| p.extension() == Some(OsStr::new("yaml")));

        yml_files.map(|p| read_yml(&p)).collect()
    }
}

impl Load for Targets {
    fn load(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
        let path: &Path = path.as_ref();
        Ok(Targets {
            android: read_yml_if_exists(&path.join("android.yaml"))?,
            i_os: read_yml_if_exists(&path.join("ios.yaml"))?,
            mac_os: read_yml_if_exists(&path.join("macos.yaml"))?,
            windows: read_yml_if_exists(&path.join("windows.yaml"))?,
        })
    }
}

fn read_yml<'a, T: DeserializeOwned>(path: &'a Path) -> Result<T, Box<dyn Error>> {
    use std::{fs::File, io::BufReader};

    let file = File::open(path)?;
    let reader = BufReader::new(file);
    let parsed = serde_yaml::from_reader(reader)?;
    Ok(parsed)
}

fn read_yml_if_exists<'a, T: DeserializeOwned>(
    path: &'a Path,
) -> Result<Option<T>, Box<dyn Error>> {
    let path: &Path = path.as_ref();
    if !path.is_file() {
        return Ok(None);
    }
    read_yml(path)
}
<|endoftext|>