<commit_before>use std::rc::Rc;
use std::cell::Cell;
use std::sync::mpsc;
use std::any::Any;
use std::iter;
use types::{Callbacks, SumType2, MaybeOwned, Storage};
use helpers::{rc_and_weak, with_weak};
use signal::Signal;

#[cfg(feature="either")]
use either::Either;

/// A source of events that feeds the streams connected to it.
#[derive(Debug)]
pub struct Sink<T>
{
    cbs: Rc<Callbacks<T>>,
}

impl<T> Sink<T>
{
    /// Creates a new sink.
    pub fn new() -> Self
    {
        Sink{ cbs: Default::default() }
    }

    /// Creates a stream that receives the events sent to this sink.
    pub fn stream(&self) -> Stream<T>
    {
        Stream{ cbs: self.cbs.clone(), source: None }
    }

    /// Sends a value into the sink.
    #[inline]
    pub fn send(&self, val: T)
    {
        self.cbs.call(val)
    }

    /// Sends a value by reference.
    #[inline]
    pub fn send_ref(&self, val: &T)
    {
        self.cbs.call_ref(val)
    }

    /// Sends multiple values into the sink.
    #[inline]
    pub fn feed(&self, iter: I)
        where I: IntoIterator<Item=T>
    {
        for val in iter
        {
            self.cbs.call(val)
        }
    }

    /// Sends multiple values by reference.
    #[inline]
    pub fn feed_ref<'a, I>(&self, iter: I)
        where T: 'a, I: IntoIterator<Item=&'a T>
    {
        for val in iter
        {
            self.cbs.call_ref(val)
        }
    }
}

impl<T> Default for Sink<T>
{
    /// Creates a new sink.
    #[inline]
    fn default() -> Self
    {
        Sink::new()
    }
}

impl<T> Clone for Sink<T>
{
    /// Creates a copy of this sink that references the same event source.
    fn clone(&self) -> Self
    {
        Sink{ cbs: self.cbs.clone() }
    }
}

/// A stream of discrete events sent over time.
///
/// All the streams returned by the methods below contain an internal reference to it's parent,
/// so dropping intermediate streams won't break the chain.
#[derive(Debug)]
pub struct Stream<T>
{
    cbs: Rc<Callbacks<T>>,
    source: Option<Rc<Any>>,  // strong reference to a parent Stream
}

impl<T> Stream<T>
{
    fn new<S: 'static>(cbs: Rc<Callbacks<T>>, source: S) -> Self
    {
        Stream{ cbs, source: Some(Rc::new(source)) }
    }

    /// Creates a stream that never fires.
    pub fn never() -> Self
    {
        Stream{ cbs: Default::default(), source: None }
    }
}

impl<T: 'static> Stream<T>
{
    /// Maps this stream into another stream using the provided function.
    #[inline]
    pub fn map<F, R>(&self, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>) -> R + 'static,
        R: 'static
    {
        self.filter_map(move |arg| Some(f(arg)))
    }

    /// Creates a new stream that only contains the values where the predicate is `true`.
    pub fn filter<F>(&self, pred: F) -> Self
        where F: Fn(&T) -> bool + 'static
    {
        let (new_cbs, weak) = rc_and_weak(Callbacks::new());
        self.cbs.push(move |arg| {
            with_weak(&weak, |cb| if pred(&arg) { cb.call_dyn(arg) })
        });
        Stream::new(new_cbs, self.clone())
    }

    /// Filter and map a stream simultaneously.
    pub fn filter_map<F, R>(&self, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>) -> Option<R> + 'static,
        R: 'static
    {
        let (new_cbs, weak) = rc_and_weak(Callbacks::new());
        self.cbs.push(move |arg| {
            with_weak(&weak, |cb| if let Some(val) = f(arg) { cb.call(val) })
        });
        Stream::new(new_cbs, self.clone())
    }

    /// Creates a new stream that fires with the events from both streams.
    pub fn merge(&self, other: &Stream<T>) -> Self
    {
        let (new_cbs, weak1) = rc_and_weak(Callbacks::new());
        let weak2 = weak1.clone();
        self.cbs.push(move |arg| {
            with_weak(&weak1, |cb| cb.call_dyn(arg))
        });
        other.cbs.push(move |arg| {
            with_weak(&weak2, |cb| cb.call_dyn(arg))
        });
        Stream::new(new_cbs, (self.clone(), other.clone()))
    }

    /// Merges two streams of different types using the provided function.
    #[cfg(feature="either")]
    pub fn merge_with(&self, other: &Stream, f: F) -> Stream<R>
        where F: Fn(Either<MaybeOwned<T>, MaybeOwned>) -> R + 'static,
        U: 'static, R: 'static
    {
        let (new_cbs, weak1) = rc_and_weak(Callbacks::new());
        let weak2 = weak1.clone();
        let f1 = Rc::new(f);
        let f2 = f1.clone();
        self.cbs.push(move |arg| {
            with_weak(&weak1, |cb| cb.call(f1(Either::Left(arg))))
        });
        other.cbs.push(move |arg| {
            with_weak(&weak2, |cb| cb.call(f2(Either::Right(arg))))
        });
        Stream::new(new_cbs, (self.clone(), other.clone()))
    }

    /// Accumulates the values sent over this stream.
    ///
    /// The fold operation is done by taking the accumulator, consuming it's value, and then
    /// putting back the transformed value. This avoids cloning, but if the closure panics it will
    /// leave the storage empty, and then any sampling attempt on this object will panic until
    /// someone puts back a value on it.
    /// If this is undesirable, use `Stream::fold_clone` instead.
    pub fn fold(&self, initial: A, f: F) -> Signal
        where F: Fn(A, MaybeOwned<T>) -> A + 'static,
        A: 'static
    {
        let (storage, weak) = rc_and_weak(Storage::new(initial));
        self.cbs.push(move |arg| {
            weak.upgrade()
                .map(|st| {
                    let old = st.take();
                    let new = f(old, arg);
                    st.set(new);
                })
                .is_some()
        });

        Signal::from_storage(storage, self.clone())
    }

    /// Folds the stream by cloning the accumulator.
    ///
    /// This will clone the accumulator on every value processed, but if the closure panics, the
    /// storage will remain unchanged and later attempts at sampling will succeed like nothing
    /// happened.
    pub fn fold_clone(&self, initial: A, f: F) -> Signal
        where F: Fn(A, MaybeOwned<T>) -> A + 'static,
        A: Clone + 'static
    {
        let (storage, weak) = rc_and_weak(Storage::new(initial));
        self.cbs.push(move |arg| {
            weak.upgrade()
                .map(|st| {
                    let old = st.get();
                    let new = f(old, arg);
                    st.set(new);
                })
                .is_some()
        });

        Signal::from_storage(storage, self.clone())
    }

    /// Maps each stream event to `0..N` output values.
    ///
    /// The closure must return it's value by sending it through the provided sink.
    /// Multiple values (or none) can be sent to the output stream this way.
    ///
    /// This primitive is useful to construct asynchronous operations, since you can
    /// store the sink for later usage.
    pub fn map_n<F, R>(&self, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>, Sink<R>) + 'static,
        R: 'static
    {
        let (new_cbs, weak) = rc_and_weak(Callbacks::new());
        self.cbs.push(move |arg| {
            with_weak(&weak, |cb| f(arg, Sink{ cbs: cb }))
        });
        Stream::new(new_cbs, self.clone())
    }

    /// Reads the values without modifying them.
    ///
    /// This is meant to be used as a debugging tool and not to cause side effects.
    pub fn inspect<F>(self, f: F) -> Self
        where F: Fn(MaybeOwned<T>) + 'static
    {
        self.cbs.push(move |arg| { f(arg); true });
        self
    }
}

impl<T: Clone + 'static> Stream<T>
{
    /// Creates a Signal that holds the last value sent to this stream.
    #[inline]
    pub fn hold(&self, initial: T) -> Signal<T>
    {
        self.hold_if(initial, |_| true)
    }

    /// Holds the last value in this stream where the predicate is `true`.
    pub fn hold_if<F>(&self, initial: T, pred: F) -> Signal<T>
        where F: Fn(&T) -> bool + 'static
    {
        let (storage, weak) = rc_and_weak(Storage::new(initial));
        self.cbs.push(move |arg| {
            weak.upgrade()
                .map(|st| if pred(&arg) { st.set(arg.into_owned()); })
                .is_some()
        });

        Signal::from_storage(storage, self.clone())
    }

    /// Creates a collection from the values of this stream.
    #[inline]
    pub fn collect<C>(&self) -> Signal<C>
        where C: Default + Extend<T> + 'static
    {
        self.fold(C::default(), |mut a, v| {
            a.extend(iter::once(v.into_owned()));
            a
        })
    }

    /// Creates a channel and sends the stream events through it.
    ///
    /// This doesn't create a strong reference to the parent stream, so the sender will be dropped
    /// when the stream is deleted.
    pub fn as_channel(&self) -> mpsc::Receiver<T>
    {
        let (tx, rx) = mpsc::channel();
        self.cbs.push(move |arg| {
            tx.send(arg.into_owned()).is_ok()
        });
        rx
    }
}

impl<T: Clone + 'static> Stream<Option<T>>
{
    /// Filters a stream of `Option`, returning the unwrapped `Some` values
    #[inline]
    pub fn filter_some(&self) -> Stream<T>
    {
        self.filter_first()
    }
}

impl<T: SumType2 + Clone + 'static> Stream<T>
    where T::Type1: 'static, T::Type2: 'static
{
    /// Creates a stream with only the first element of a sum type
    pub fn filter_first(&self) -> Stream<T::Type1>
    {
        self.filter_map(|res| if res.is_type1() { res.into_owned().into_type1() } else { None })
    }

    /// Creates a stream with only the second element of a sum type
    pub fn filter_second(&self) -> Stream<T::Type2>
    {
        self.filter_map(|res| if res.is_type2() { res.into_owned().into_type2() } else { None })
    }

    /// Splits a two element sum type stream into two streams with the unwrapped values
    pub fn split(&self) -> (Stream<T::Type1>, Stream<T::Type2>)
    {
        let (cbs_1, weak_1) = rc_and_weak(Callbacks::new());
        let (cbs_2, weak_2) = rc_and_weak(Callbacks::new());
        self.cbs.push(move |result| {
            if result.is_type1()
            {
                if let Some(cb) = weak_1.upgrade()
                {
                    cb.call(result.into_owned().into_type1().unwrap());
                    true
                }
                else
                {
                    // drop callback if both output streams dropped
                    weak_2.upgrade().is_some()
                }
            }
            else // if result.is_type2()
            {
                if let Some(cb) = weak_2.upgrade()
                {
                    cb.call(result.into_owned().into_type2().unwrap());
                    true
                }
                else
                {
                    weak_1.upgrade().is_some()
                }
            }
        });
        let source_rc = Rc::new(self.clone());
        let stream_1 = Stream{ cbs: cbs_1, source: Some(source_rc.clone()) };
        let stream_2 = Stream{ cbs: cbs_2, source: Some(source_rc) };
        (stream_1, stream_2)
    }
}

impl<T: 'static> Stream<Stream<T>>
{
    /// Listens to the events from the last stream sent to a nested stream
    pub fn switch(&self) -> Stream<T>
    {
        let (new_cbs, weak) = rc_and_weak(Callbacks::new());
        let id = Rc::new(Cell::new(0u64));  // id of each stream sent
        self.cbs.push(move |stream| {
            if weak.upgrade().is_none() { return false }
            let cbs_w = weak.clone();
            let cur_id = id.clone();
            // increment the id so it will only send to the last stream
            let my_id = id.get() + 1;
            id.set(my_id);
            // redirect the inner stream to the output stream
            stream.cbs.push(move |arg| {
                if my_id != cur_id.get() { return false }
                with_weak(&cbs_w, |cb| cb.call_dyn(arg))
            });
            true
        });
        Stream::new(new_cbs, self.clone())
    }
}

impl<T> Clone for Stream<T>
{
    /// Creates a copy of this stream that references the same event chain.
    fn clone(&self) -> Self
    {
        Stream{ cbs: self.cbs.clone(), source: self.source.clone() }
    }
}

impl<T> Default for Stream<T>
{
    /// Creates a stream that never fires.
    #[inline]
    fn default() -> Self
    {
        Stream::never()
    }
}

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

    #[test]
    fn stream_basic()
    {
        let sink = Sink::new();
        let stream = sink.stream();
        let rx = stream.as_channel();

        sink.send(42);
        sink.send(33);
        sink.send_ref(&12);
        sink.feed(0..5);
        sink.feed_ref(&[11, 22, 33]);

        let result: Vec<_> = rx.try_iter().collect();
        assert_eq!(result, [42, 33, 12, 0, 1, 2, 3, 4, 11, 22, 33]);
    }

    #[test]
    fn stream_switch()
    {
        let stream_sink = Sink::new();
        let sink1 = Sink::new();
        let sink2 = Sink::new();

        let switched = stream_sink.stream().switch();
        let events = switched.as_channel();

        sink1.send(1);
        sink2.send(2);

        stream_sink.send(sink2.stream());
        sink1.send(3);
        sink2.send(4);
        assert_eq!(events.try_recv(), Ok(4));

        stream_sink.send(sink1.stream());
        sink1.send(5);
        sink2.send(6);
        assert_eq!(events.try_recv(), Ok(5));
    }
}
<commit_msg>removed option from stream source<commit_after>use std::rc::Rc;
use std::cell::Cell;
use std::sync::mpsc;
use std::any::Any;
use std::iter;
use types::{Callbacks, SumType2, MaybeOwned, Storage};
use helpers::{rc_and_weak, with_weak};
use signal::Signal;

#[cfg(feature="either")]
use either::Either;

/// A source of events that feeds the streams connected to it.
#[derive(Debug)]
pub struct Sink<T>
{
    cbs: Rc<Callbacks<T>>,
}

impl<T> Sink<T>
{
    /// Creates a new sink.
    pub fn new() -> Self
    {
        Sink{ cbs: Default::default() }
    }

    /// Creates a stream that receives the events sent to this sink.
    pub fn stream(&self) -> Stream<T>
    {
        Stream::new(self.cbs.clone(), ())
    }

    /// Sends a value into the sink.
    #[inline]
    pub fn send(&self, val: T)
    {
        self.cbs.call(val)
    }

    /// Sends a value by reference.
    #[inline]
    pub fn send_ref(&self, val: &T)
    {
        self.cbs.call_ref(val)
    }

    /// Sends multiple values into the sink.
    #[inline]
    pub fn feed(&self, iter: I)
        where I: IntoIterator<Item=T>
    {
        for val in iter
        {
            self.cbs.call(val)
        }
    }

    /// Sends multiple values by reference.
    #[inline]
    pub fn feed_ref<'a, I>(&self, iter: I)
        where T: 'a, I: IntoIterator<Item=&'a T>
    {
        for val in iter
        {
            self.cbs.call_ref(val)
        }
    }
}

impl<T> Default for Sink<T>
{
    /// Creates a new sink.
    #[inline]
    fn default() -> Self
    {
        Sink::new()
    }
}

impl<T> Clone for Sink<T>
{
    /// Creates a copy of this sink that references the same event source.
    fn clone(&self) -> Self
    {
        Sink{ cbs: self.cbs.clone() }
    }
}

/// A stream of discrete events sent over time.
///
/// All the streams returned by the methods below contain an internal reference to it's parent,
/// so dropping intermediate streams won't break the chain.
#[derive(Debug)]
pub struct Stream<T>
{
    cbs: Rc<Callbacks<T>>,
    source: Rc<Any>,  // strong reference to a parent Stream
}

impl<T> Stream<T>
{
    fn new<S: 'static>(cbs: Rc<Callbacks<T>>, source: S) -> Self
    {
        Stream{ cbs, source: Rc::new(source) }
    }

    /// Creates a stream that never fires.
    pub fn never() -> Self
    {
        Stream::new(Default::default(), ())
    }
}

impl<T: 'static> Stream<T>
{
    /// Maps this stream into another stream using the provided function.
    #[inline]
    pub fn map<F, R>(&self, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>) -> R + 'static,
        R: 'static
    {
        self.filter_map(move |arg| Some(f(arg)))
    }

    /// Creates a new stream that only contains the values where the predicate is `true`.
    pub fn filter<F>(&self, pred: F) -> Self
        where F: Fn(&T) -> bool + 'static
    {
        let (new_cbs, weak) = rc_and_weak(Callbacks::new());
        self.cbs.push(move |arg| {
            with_weak(&weak, |cb| if pred(&arg) { cb.call_dyn(arg) })
        });
        Stream::new(new_cbs, self.clone())
    }

    /// Filter and map a stream simultaneously.
    pub fn filter_map<F, R>(&self, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>) -> Option<R> + 'static,
        R: 'static
    {
        let (new_cbs, weak) = rc_and_weak(Callbacks::new());
        self.cbs.push(move |arg| {
            with_weak(&weak, |cb| if let Some(val) = f(arg) { cb.call(val) })
        });
        Stream::new(new_cbs, self.clone())
    }

    /// Creates a new stream that fires with the events from both streams.
    pub fn merge(&self, other: &Stream<T>) -> Self
    {
        let (new_cbs, weak1) = rc_and_weak(Callbacks::new());
        let weak2 = weak1.clone();
        self.cbs.push(move |arg| {
            with_weak(&weak1, |cb| cb.call_dyn(arg))
        });
        other.cbs.push(move |arg| {
            with_weak(&weak2, |cb| cb.call_dyn(arg))
        });
        Stream::new(new_cbs, (self.clone(), other.clone()))
    }

    /// Merges two streams of different types using the provided function.
    #[cfg(feature="either")]
    pub fn merge_with(&self, other: &Stream, f: F) -> Stream<R>
        where F: Fn(Either<MaybeOwned<T>, MaybeOwned>) -> R + 'static,
        U: 'static, R: 'static
    {
        let (new_cbs, weak1) = rc_and_weak(Callbacks::new());
        let weak2 = weak1.clone();
        let f1 = Rc::new(f);
        let f2 = f1.clone();
        self.cbs.push(move |arg| {
            with_weak(&weak1, |cb| cb.call(f1(Either::Left(arg))))
        });
        other.cbs.push(move |arg| {
            with_weak(&weak2, |cb| cb.call(f2(Either::Right(arg))))
        });
        Stream::new(new_cbs, (self.clone(), other.clone()))
    }

    /// Accumulates the values sent over this stream.
    ///
    /// The fold operation is done by taking the accumulator, consuming it's value, and then
    /// putting back the transformed value. This avoids cloning, but if the closure panics it will
    /// leave the storage empty, and then any sampling attempt on this object will panic until
    /// someone puts back a value on it.
    /// If this is undesirable, use `Stream::fold_clone` instead.
    pub fn fold(&self, initial: A, f: F) -> Signal
        where F: Fn(A, MaybeOwned<T>) -> A + 'static,
        A: 'static
    {
        let (storage, weak) = rc_and_weak(Storage::new(initial));
        self.cbs.push(move |arg| {
            weak.upgrade()
                .map(|st| {
                    let old = st.take();
                    let new = f(old, arg);
                    st.set(new);
                })
                .is_some()
        });

        Signal::from_storage(storage, self.clone())
    }

    /// Folds the stream by cloning the accumulator.
    ///
    /// This will clone the accumulator on every value processed, but if the closure panics, the
    /// storage will remain unchanged and later attempts at sampling will succeed like nothing
    /// happened.
    pub fn fold_clone(&self, initial: A, f: F) -> Signal
        where F: Fn(A, MaybeOwned<T>) -> A + 'static,
        A: Clone + 'static
    {
        let (storage, weak) = rc_and_weak(Storage::new(initial));
        self.cbs.push(move |arg| {
            weak.upgrade()
                .map(|st| {
                    let old = st.get();
                    let new = f(old, arg);
                    st.set(new);
                })
                .is_some()
        });

        Signal::from_storage(storage, self.clone())
    }

    /// Maps each stream event to `0..N` output values.
    ///
    /// The closure must return it's value by sending it through the provided sink.
    /// Multiple values (or none) can be sent to the output stream this way.
    ///
    /// This primitive is useful to construct asynchronous operations, since you can
    /// store the sink for later usage.
    pub fn map_n<F, R>(&self, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>, Sink<R>) + 'static,
        R: 'static
    {
        let (new_cbs, weak) = rc_and_weak(Callbacks::new());
        self.cbs.push(move |arg| {
            with_weak(&weak, |cb| f(arg, Sink{ cbs: cb }))
        });
        Stream::new(new_cbs, self.clone())
    }

    /// Reads the values without modifying them.
    ///
    /// This is meant to be used as a debugging tool and not to cause side effects.
    pub fn inspect<F>(self, f: F) -> Self
        where F: Fn(MaybeOwned<T>) + 'static
    {
        self.cbs.push(move |arg| { f(arg); true });
        self
    }
}

impl<T: Clone + 'static> Stream<T>
{
    /// Creates a Signal that holds the last value sent to this stream.
    #[inline]
    pub fn hold(&self, initial: T) -> Signal<T>
    {
        self.hold_if(initial, |_| true)
    }

    /// Holds the last value in this stream where the predicate is `true`.
    pub fn hold_if<F>(&self, initial: T, pred: F) -> Signal<T>
        where F: Fn(&T) -> bool + 'static
    {
        let (storage, weak) = rc_and_weak(Storage::new(initial));
        self.cbs.push(move |arg| {
            weak.upgrade()
                .map(|st| if pred(&arg) { st.set(arg.into_owned()); })
                .is_some()
        });

        Signal::from_storage(storage, self.clone())
    }

    /// Creates a collection from the values of this stream.
    #[inline]
    pub fn collect<C>(&self) -> Signal<C>
        where C: Default + Extend<T> + 'static
    {
        self.fold(C::default(), |mut a, v| {
            a.extend(iter::once(v.into_owned()));
            a
        })
    }

    /// Creates a channel and sends the stream events through it.
    ///
    /// This doesn't create a strong reference to the parent stream, so the sender will be dropped
    /// when the stream is deleted.
    pub fn as_channel(&self) -> mpsc::Receiver<T>
    {
        let (tx, rx) = mpsc::channel();
        self.cbs.push(move |arg| {
            tx.send(arg.into_owned()).is_ok()
        });
        rx
    }
}

impl<T: Clone + 'static> Stream<Option<T>>
{
    /// Filters a stream of `Option`, returning the unwrapped `Some` values
    #[inline]
    pub fn filter_some(&self) -> Stream<T>
    {
        self.filter_first()
    }
}

impl<T: SumType2 + Clone + 'static> Stream<T>
    where T::Type1: 'static, T::Type2: 'static
{
    /// Creates a stream with only the first element of a sum type
    pub fn filter_first(&self) -> Stream<T::Type1>
    {
        self.filter_map(|res| if res.is_type1() { res.into_owned().into_type1() } else { None })
    }

    /// Creates a stream with only the second element of a sum type
    pub fn filter_second(&self) -> Stream<T::Type2>
    {
        self.filter_map(|res| if res.is_type2() { res.into_owned().into_type2() } else { None })
    }

    /// Splits a two element sum type stream into two streams with the unwrapped values
    pub fn split(&self) -> (Stream<T::Type1>, Stream<T::Type2>)
    {
        let (cbs_1, weak_1) = rc_and_weak(Callbacks::new());
        let (cbs_2, weak_2) = rc_and_weak(Callbacks::new());
        self.cbs.push(move |result| {
            if result.is_type1()
            {
                if let Some(cb) = weak_1.upgrade()
                {
                    cb.call(result.into_owned().into_type1().unwrap());
                    true
                }
                else
                {
                    // drop callback if both output streams dropped
                    weak_2.upgrade().is_some()
                }
            }
            else // if result.is_type2()
            {
                if let Some(cb) = weak_2.upgrade()
                {
                    cb.call(result.into_owned().into_type2().unwrap());
                    true
                }
                else
                {
                    weak_1.upgrade().is_some()
                }
            }
        });
        let source_rc = Rc::new(self.clone());
        let stream_1 = Stream{ cbs: cbs_1, source: source_rc.clone() };
        let stream_2 = Stream{ cbs: cbs_2, source: source_rc };
        (stream_1, stream_2)
    }
}

impl<T: 'static> Stream<Stream<T>>
{
    /// Listens to the events from the last stream sent to a nested stream
    pub fn switch(&self) -> Stream<T>
    {
        let (new_cbs, weak) = rc_and_weak(Callbacks::new());
        let id = Rc::new(Cell::new(0u64));  // id of each stream sent
        self.cbs.push(move |stream| {
            if weak.upgrade().is_none() { return false }
            let cbs_w = weak.clone();
            let cur_id = id.clone();
            // increment the id so it will only send to the last stream
            let my_id = id.get() + 1;
            id.set(my_id);
            // redirect the inner stream to the output stream
            stream.cbs.push(move |arg| {
                if my_id != cur_id.get() { return false }
                with_weak(&cbs_w, |cb| cb.call_dyn(arg))
            });
            true
        });
        Stream::new(new_cbs, self.clone())
    }
}

impl<T> Clone for Stream<T>
{
    /// Creates a copy of this stream that references the same event chain.
    fn clone(&self) -> Self
    {
        Stream{ cbs: self.cbs.clone(), source: self.source.clone() }
    }
}

impl<T> Default for Stream<T>
{
    /// Creates a stream that never fires.
    #[inline]
    fn default() -> Self
    {
        Stream::never()
    }
}

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

    #[test]
    fn stream_basic()
    {
        let sink = Sink::new();
        let stream = sink.stream();
        let rx = stream.as_channel();

        sink.send(42);
        sink.send(33);
        sink.send_ref(&12);
        sink.feed(0..5);
        sink.feed_ref(&[11, 22, 33]);

        let result: Vec<_> = rx.try_iter().collect();
        assert_eq!(result, [42, 33, 12, 0, 1, 2, 3, 4, 11, 22, 33]);
    }

    #[test]
    fn stream_switch()
    {
        let stream_sink = Sink::new();
        let sink1 = Sink::new();
        let sink2 = Sink::new();

        let switched = stream_sink.stream().switch();
        let events = switched.as_channel();

        sink1.send(1);
        sink2.send(2);

        stream_sink.send(sink2.stream());
        sink1.send(3);
        sink2.send(4);
        assert_eq!(events.try_recv(), Ok(4));

        stream_sink.send(sink1.stream());
        sink1.send(5);
        sink2.send(6);
        assert_eq!(events.try_recv(), Ok(5));
    }
}
<|endoftext|>


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

use ffi;
use base::*;

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

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

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

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

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

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

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

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

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

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

    pub fn write_stream(&self,
                        min_frame_count: i32,
                        buffers: &Vec<Vec<f32>>)
                        -> Result<i32, ffi::SioError> {
        let channel_count = self.get_layout().channel_count();
        // check if buffer contains frames for all channels
        if buffers.len() < channel_count as usize {
            return Err(ffi::SioError::Invalid);
        }
        // check if there are at least min_frame_count frames for all channels
        if !buffers.iter().map(|c| c.len()).all(|l| l >= min_frame_count as usize) {
            return Err(ffi::SioError::Invalid);
        }

        // assuming that every channel buffer has the same length
        let mut frame_count = buffers[0].len() as c_int;
        let mut raw_areas: *mut ffi::SoundIoChannelArea = ptr::null_mut();
        let actual_frame_count = try!(self.begin_write(&mut raw_areas, &frame_count));
        let areas = unsafe { ::std::slice::from_raw_parts_mut(raw_areas, channel_count as usize) };
        for idx in 0..actual_frame_count as usize {
            for channel in 0..channel_count as usize {
                let area = areas[channel];
                let addr = (area.ptr as usize + area.step as usize * idx) as *mut f32;
                unsafe { *addr = buffers[channel][idx] }
            }
        }
        self.end_write().map_or(Ok(actual_frame_count), |err| Err(err))
    }

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

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

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

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

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

    }

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

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

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

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

    pub fn destroy(&self) {
        unsafe { ffi::soundio_outstream_destroy(self.stream) }
    }
}
impl<'a> Drop for OutStream<'a> {
    fn drop(&mut self) {
        // TODO: call destroy manually.
        // OutStream will get dropped each time a new
        // struct is created from the same *mut pointer.
    }
}
<commit_msg>Let `begin_write` return a Result<commit_after>use std::os::raw::{c_int, c_double, c_void};
use std::ptr;

use ffi;
use base::*;

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

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

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

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

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

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

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

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

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

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

    pub fn write_stream(&self,
                        min_frame_count: i32,
                        buffers: &Vec<Vec<f32>>)
                        -> Result<i32, ffi::SioError> {
        let channel_count = self.get_layout().channel_count();
        // check if buffer contains frames for all channels
        if buffers.len() < channel_count as usize {
            return Err(ffi::SioError::Invalid);
        }
        // check if there are at least min_frame_count frames for all channels
        if !buffers.iter().map(|c| c.len()).all(|l| l >= min_frame_count as usize) {
            return Err(ffi::SioError::Invalid);
        }

        // assuming that every channel buffer has the same length
        let mut frame_count = buffers[0].len() as c_int;
        let mut raw_areas: *mut ffi::SoundIoChannelArea = ptr::null_mut();
        let actual_frame_count = try!(self.begin_write(&mut raw_areas, &frame_count));
        let areas = unsafe { ::std::slice::from_raw_parts_mut(raw_areas, channel_count as usize) };
        for idx in 0..actual_frame_count as usize {
            for channel in 0..channel_count as usize {
                let area = areas[channel];
                let addr = (area.ptr as usize + area.step as usize * idx) as *mut f32;
                unsafe { *addr = buffers[channel][idx] }
            }
        }
        self.end_write().map_or(Ok(actual_frame_count), |err| Err(err))
    }

    pub fn begin_write(&self,
                       areas: *mut *mut ffi::SoundIoChannelArea,
                       frame_count: &i32)
                       -> Result<i32, ffi::SioError> {
        let mut actual_frame_count = *frame_count as c_int;
        match unsafe {
            ffi::soundio_outstream_begin_write(self.stream,
                                               areas,
                                               &mut actual_frame_count as *mut c_int)
        } {
            ffi::SioError::None => Ok(actual_frame_count),
            err @ _ => Err(err),
        }
    }

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

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

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

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

    }

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

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

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

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

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


<commit_before>//! Fundamental traits

use ndarray::*;
use ndarray_linalg::*;

pub trait ModelSpec: Clone {
    type Scalar: Scalar;
    type Dim: Dimension;
    fn model_size(&self) -> <Self::Dim as Dimension>::Pattern;
}

/// Interface for time-step
pub trait TimeStep {
    type Time: RealScalar;
    fn get_dt(&self) -> Self::Time;
    fn set_dt(&mut self, dt: Self::Time);
}

/// EoM for explicit schemes
pub trait Explicit: ModelSpec {
    /// calculate right hand side (rhs) of Explicit from current state
    fn rhs<'a, S>(&mut self, &'a mut ArrayBase<S, Self::Dim>) -> &'a mut ArrayBase<S, Self::Dim>
    where
        S: DataMut<Elem = Self::Scalar>;
}

/// EoM for semi-implicit schemes
pub trait SemiImplicit: ModelSpec {
    /// non-linear part of stiff equation
    fn nlin<'a, S>(&mut self, &'a mut ArrayBase<S, Self::Dim>) -> &'a mut ArrayBase<S, Self::Dim>
    where
        S: DataMut<Elem = Self::Scalar>;
    /// diagonal elements of stiff linear part
    fn diag(&self) -> Array<Self::Scalar, Self::Dim>;
}

/// Time-evolution operator with buffer
pub trait TimeEvolution: ModelSpec + TimeStep {
    /// calculate next step
    fn iterate<'a, S>(
        &mut self,
        &'a mut ArrayBase<S, Self::Dim>,
    ) -> &'a mut ArrayBase<S, Self::Dim>
    where
        S: DataMut<Elem = Self::Scalar>;

    /// calculate next step
    fn iterate_n<'a, S>(
        &mut self,
        a: &'a mut ArrayBase<S, Self::Dim>,
        n: usize,
    ) -> &'a mut ArrayBase<S, Self::Dim>
    where
        S: DataMut<Elem = Self::Scalar>,
    {
        for _ in 0..n {
            self.iterate(a);
        }
        a
    }
}

/// Time evolution schemes
pub trait Scheme: TimeEvolution {
    type Core: ModelSpec<Scalar = Self::Scalar, Dim = Self::Dim>;
    fn new(f: Self::Core, dt: Self::Time) -> Self;
    fn core(&self) -> &Self::Core;
    fn core_mut(&mut self) -> &mut Self::Core;
}
<commit_msg>Doc for traits<commit_after>//! Fundamental traits for solving EoM

use ndarray::*;
use ndarray_linalg::*;

/// Model specification
pub trait ModelSpec: Clone {
    type Scalar: Scalar;
    type Dim: Dimension;
    fn model_size(&self) -> <Self::Dim as Dimension>::Pattern;
}

/// Interface for time-step
pub trait TimeStep {
    type Time: RealScalar;
    fn get_dt(&self) -> Self::Time;
    fn set_dt(&mut self, dt: Self::Time);
}

/// Core implementation for explicit schemes
pub trait Explicit: ModelSpec {
    /// calculate right hand side (rhs) of Explicit from current state
    fn rhs<'a, S>(&mut self, &'a mut ArrayBase<S, Self::Dim>) -> &'a mut ArrayBase<S, Self::Dim>
    where
        S: DataMut<Elem = Self::Scalar>;
}

/// Core implementation for semi-implicit schemes
pub trait SemiImplicit: ModelSpec {
    /// non-linear part of stiff equation
    fn nlin<'a, S>(&mut self, &'a mut ArrayBase<S, Self::Dim>) -> &'a mut ArrayBase<S, Self::Dim>
    where
        S: DataMut<Elem = Self::Scalar>;
    /// diagonal elements of stiff linear part
    fn diag(&self) -> Array<Self::Scalar, Self::Dim>;
}

/// Time-evolution operator
pub trait TimeEvolution: ModelSpec + TimeStep {
    /// calculate next step
    fn iterate<'a, S>(
        &mut self,
        &'a mut ArrayBase<S, Self::Dim>,
    ) -> &'a mut ArrayBase<S, Self::Dim>
    where
        S: DataMut<Elem = Self::Scalar>;

    /// calculate n-step
    fn iterate_n<'a, S>(
        &mut self,
        a: &'a mut ArrayBase<S, Self::Dim>,
        n: usize,
    ) -> &'a mut ArrayBase<S, Self::Dim>
    where
        S: DataMut<Elem = Self::Scalar>,
    {
        for _ in 0..n {
            self.iterate(a);
        }
        a
    }
}

/// Time evolution schemes
pub trait Scheme: TimeEvolution {
    type Core: ModelSpec<Scalar = Self::Scalar, Dim = Self::Dim>;
    /// Initialize with a core implementation
    fn new(f: Self::Core, dt: Self::Time) -> Self;
    /// Get immutable core
    fn core(&self) -> &Self::Core;
    /// Get mutable core
    fn core_mut(&mut self) -> &mut Self::Core;
}
<|endoftext|>


<commit_before>use std::convert::From;

// a generic triple that is used everywhere and might implement other traits
// if the types match
#[derive(Clone, Debug)]
pub struct Triple<S,P=S,O=S>{
    pub subject: S,
    pub predicate: P,
    pub object: O
}

impl<S, P, O> From<(S, P, O)> for Triple<S, P, O>{
    fn from(t: (S, P, O)) -> Triple<S, P, O>{
        Triple{
            subject: t.0,
            predicate: t.1,
            object: t.2
        }
    }
}

impl<I: Clone> From<[I; 3]> for Triple<I>{
    fn from(t: [I; 3]) -> Triple<I>{
        Triple{
            subject: t[0].clone(),
            predicate: t[1].clone(),
            object: t[2].clone()
        }
    }
}

impl<S,P,O> Triple<S,P,O>{
    pub fn new(s: S, p: P, o: O) -> Triple<S,P,O>{
        Triple{
            subject: s,
            predicate: p,
            object: o
        }
    }
}
<commit_msg>derive more things for Triple<commit_after>use std::convert::From;

// a generic triple that is used everywhere and might implement other traits
// if the types match
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Triple<S,P=S,O=S>{
    pub subject: S,
    pub predicate: P,
    pub object: O
}

impl<S, P, O> From<(S, P, O)> for Triple<S, P, O>{
    fn from(t: (S, P, O)) -> Triple<S, P, O>{
        Triple{
            subject: t.0,
            predicate: t.1,
            object: t.2
        }
    }
}

impl<I: Clone> From<[I; 3]> for Triple<I>{
    fn from(t: [I; 3]) -> Triple<I>{
        Triple{
            subject: t[0].clone(),
            predicate: t[1].clone(),
            object: t[2].clone()
        }
    }
}

impl<S,P,O> Triple<S,P,O>{
    pub fn new(s: S, p: P, o: O) -> Triple<S,P,O>{
        Triple{
            subject: s,
            predicate: p,
            object: o
        }
    }
}
<|endoftext|>


<commit_before>use std::ops::{
  Add, AddAssign,
  Sub, SubAssign,
  Mul, MulAssign,
  Div, DivAssign,
  Index, IndexMut,
};

#[derive(Debug, Copy, Clone)]
pub struct Vec3 {
  pub i : f64,
  pub j : f64,
  pub k : f64,
}

impl Vec3 {
  pub fn length(&self) -> f64 {
    (self.i * self.i + self.j * self.j + self.k * self.k).sqrt()
  }
}

impl Add for Vec3 {
  type Output = Vec3;
  fn add(self, other: Vec3) -> Vec3 {
      Vec3 {i: self.i + other.i, j: self.j + other.j, k: self.k + other.k}
  }
}

impl AddAssign for Vec3 {
  fn add_assign(&mut self, other: Vec3) {
    *self = Vec3 {
      i: self.i + other.i,
      j: self.j + other.j,
      k: self.k + other.k,
    };
  }
}

impl Sub for Vec3 {
  type Output = Vec3;
  fn sub(self, other: Vec3) -> Vec3 {
      Vec3 {i: self.i - other.i, j: self.j - other.j, k: self.k - other.k}
  }
}

impl SubAssign for Vec3 {
  fn sub_assign(&mut self, other: Vec3) {
    *self = Vec3 {
      i: self.i - other.i,
      j: self.j - other.j,
      k: self.k - other.k,
    }
  }
}

impl Mul<Vec3> for Vec3 {
  type Output = Vec3;
  fn mul(self, rhs: Vec3) -> Vec3 {
    Vec3 {i: self.i * rhs.i, j: self.j * rhs.j, k: self.k * rhs.k}
  }
}

impl Mul<f64> for Vec3 {
  type Output = Vec3;
  fn mul(self, scalar: f64) -> Vec3 {
    Vec3 {i: self.i * scalar, j: self.j * scalar, k: self.k * scalar}
  }
}

impl MulAssign<Vec3> for Vec3 {
  fn mul_assign(&mut self, rhs: Vec3) {
    *self = Vec3 {
      i: self.i * rhs.i,
      j: self.j * rhs.j,
      k: self.k * rhs.k,
    }
  }
}

impl MulAssign<f64> for Vec3 {
  fn mul_assign(&mut self, scalar: f64) {
    *self = Vec3 {
      i: self.i * scalar,
      j: self.j * scalar,
      k: self.k * scalar,
    }
  }
}

impl Div<Vec3> for Vec3 {
  type Output = Vec3;
  fn div(self, rhs: Vec3) -> Vec3 {
    Vec3 {i: self.i / rhs.i, j: self.j / rhs.j, k: self.k / rhs.k}
  }
}

impl Div<f64> for Vec3 {
  type Output = Vec3;
  fn div(self, scalar: f64) -> Vec3 {
    Vec3 {i: self.i / scalar, j: self.j / scalar, k: self.k / scalar}
  }
}

impl DivAssign<Vec3> for Vec3 {
  fn div_assign(&mut self, rhs: Vec3) {
    *self = Vec3 {
      i: self.i / rhs.i,
      j: self.j / rhs.j,
      k: self.k / rhs.k,
    }
  }
}

impl DivAssign<f64> for Vec3 {
  fn div_assign(&mut self, scalar: f64) {
    *self = Vec3 {
      i: self.i / scalar,
      j: self.j / scalar,
      k: self.k / scalar,
    }
  }
}

impl Index<i32> for Vec3 {
  type Output = f64;
  fn index(&self, idx: i32) -> &f64 {
    match idx {
      0 => &self.i,
      1 => &self.j,
      2 => &self.k,
      _ => panic!("index out of range: {}", idx),
    }
  }
}

impl IndexMut<i32> for Vec3 {
  fn index_mut<'a>(&'a mut self, idx: i32) -> &'a mut f64 {
    match idx {
      0 => &mut self.i,
      1 => &mut self.j,
      2 => &mut self.k,
      _ => panic!("index out of range: {}", idx),
    }
  }
}

#[cfg(test)]
mod should {
  use super::Vec3;
  #[test]
  fn add() {
    let v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let sum = v1 + v2;
    assert_eq!(sum.i, 3.0);
    assert_eq!(sum.j, 3.0);
    assert_eq!(sum.k, 3.0);
  }
  #[test]
  fn add_assign() {
    let mut v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 += v2;
    assert_eq!(v1.i, 3.0);
    assert_eq!(v1.j, 3.0);
    assert_eq!(v1.k, 3.0);
  }
  #[test]
  fn subtract() {
    let v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let diff = v1 - v2;
    assert_eq!(diff.i, -1.0);
    assert_eq!(diff.j, -1.0);
    assert_eq!(diff.k, -1.0);
  }
  #[test]
  fn subtract_assign() {
    let mut v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 -= v2;
    assert_eq!(v1.i, -1.0);
    assert_eq!(v1.j, -1.0);
    assert_eq!(v1.k, -1.0);
  }
  #[test]
  fn multiply_by_vec3_elementwise() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    let product = v1 * v2;
    assert_eq!(product.i, 6.0);
    assert_eq!(product.j, 6.0);
    assert_eq!(product.k, 6.0);
  }
  #[test]
  fn multiply_by_vec3_assign_elementwise() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    v1 *= v2;
    assert_eq!(v1.i, 6.0);
    assert_eq!(v1.j, 6.0);
    assert_eq!(v1.k, 6.0);
  }
  #[test]
  fn multiply_by_f64() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let product = v1 * 3.0;

    assert_eq!(product.i, 6.0);
    assert_eq!(product.j, 6.0);
    assert_eq!(product.k, 6.0);
  }
  #[test]
  fn multiply_by_f64_assign() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 *= 3.0;

    assert_eq!(v1.i, 6.0);
    assert_eq!(v1.j, 6.0);
    assert_eq!(v1.k, 6.0);
  }
  #[test]
  fn divide_by_vec3_elementwise() {
    let v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    let quotient = v1 / v2;
    assert_eq!(quotient.i, 2.0);
    assert_eq!(quotient.j, 2.0);
    assert_eq!(quotient.k, 2.0);
  }
  #[test]
  fn divide_by_vec3_assign_elementwise() {
    let mut v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    v1 /= v2;
    assert_eq!(v1.i, 2.0);
    assert_eq!(v1.j, 2.0);
    assert_eq!(v1.k, 2.0);
  }
  #[test]
  fn divide_by_f64() {
    let v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let quotient = v1 / 3.0;

    assert_eq!(quotient.i, 2.0);
    assert_eq!(quotient.j, 2.0);
    assert_eq!(quotient.k, 2.0);
  }
  #[test]
  fn divide_by_f64_assign() {
    let mut v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    v1 /= 3.0;

    assert_eq!(v1.i, 2.0);
    assert_eq!(v1.j, 2.0);
    assert_eq!(v1.k, 2.0);
  }
  #[test]
  fn allow_index_access() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};

    assert_eq!(v1[0], 2.0);
    assert_eq!(v1[1], 2.0);
    assert_eq!(v1[2], 2.0);
  }
  #[test]
  #[should_panic(expected = "index out of range: 9")]
  fn panic_on_bad_index() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};

    assert_eq!(v1[9], 2.0);
  }
  #[test]
  fn allow_index_mut_access() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1[0] = 9.0;

    assert_eq!(v1[0], 9.0);
    assert_eq!(v1[1], 2.0);
    assert_eq!(v1[2], 2.0);
  }

  #[test]
  fn calculate_length() {
    let v1 = Vec3 { i: 4.0, j: 4.0, k: 2.0};

    assert_eq!(v1.length(), 6.0);
  }
  #[test]
  fn calculate_length_with_some_zeros() {
    let v2 = Vec3 { i: 4.0, j: 0.0, k: 0.0};

    assert_eq!(v2.length(), 4.0);
  }
  #[test]
  fn calculate_length_for_zero_vector() {
    let v2 = Vec3 { i: 0.0, j: 0.0, k: 0.0};

    assert_eq!(v2.length(), 0.0);
  }
}<commit_msg>Add dot product funtion and test<commit_after>use std::ops::{
  Add, AddAssign,
  Sub, SubAssign,
  Mul, MulAssign,
  Div, DivAssign,
  Index, IndexMut,
};

#[derive(Debug, Copy, Clone)]
pub struct Vec3 {
  pub i : f64,
  pub j : f64,
  pub k : f64,
}

impl Vec3 {
  pub fn length(&self) -> f64 {
    (self.i * self.i + self.j * self.j + self.k * self.k).sqrt()
  }
  pub fn dot(&self, other: Vec3) -> f64 {
    self.i * other.i + self.j * other.j + self.k * other.k
  }
}

impl Add for Vec3 {
  type Output = Vec3;
  fn add(self, other: Vec3) -> Vec3 {
      Vec3 {i: self.i + other.i, j: self.j + other.j, k: self.k + other.k}
  }
}

impl AddAssign for Vec3 {
  fn add_assign(&mut self, other: Vec3) {
    *self = Vec3 {
      i: self.i + other.i,
      j: self.j + other.j,
      k: self.k + other.k,
    };
  }
}

impl Sub for Vec3 {
  type Output = Vec3;
  fn sub(self, other: Vec3) -> Vec3 {
      Vec3 {i: self.i - other.i, j: self.j - other.j, k: self.k - other.k}
  }
}

impl SubAssign for Vec3 {
  fn sub_assign(&mut self, other: Vec3) {
    *self = Vec3 {
      i: self.i - other.i,
      j: self.j - other.j,
      k: self.k - other.k,
    }
  }
}

impl Mul<Vec3> for Vec3 {
  type Output = Vec3;
  fn mul(self, rhs: Vec3) -> Vec3 {
    Vec3 {i: self.i * rhs.i, j: self.j * rhs.j, k: self.k * rhs.k}
  }
}

impl Mul<f64> for Vec3 {
  type Output = Vec3;
  fn mul(self, scalar: f64) -> Vec3 {
    Vec3 {i: self.i * scalar, j: self.j * scalar, k: self.k * scalar}
  }
}

impl MulAssign<Vec3> for Vec3 {
  fn mul_assign(&mut self, rhs: Vec3) {
    *self = Vec3 {
      i: self.i * rhs.i,
      j: self.j * rhs.j,
      k: self.k * rhs.k,
    }
  }
}

impl MulAssign<f64> for Vec3 {
  fn mul_assign(&mut self, scalar: f64) {
    *self = Vec3 {
      i: self.i * scalar,
      j: self.j * scalar,
      k: self.k * scalar,
    }
  }
}

impl Div<Vec3> for Vec3 {
  type Output = Vec3;
  fn div(self, rhs: Vec3) -> Vec3 {
    Vec3 {i: self.i / rhs.i, j: self.j / rhs.j, k: self.k / rhs.k}
  }
}

impl Div<f64> for Vec3 {
  type Output = Vec3;
  fn div(self, scalar: f64) -> Vec3 {
    Vec3 {i: self.i / scalar, j: self.j / scalar, k: self.k / scalar}
  }
}

impl DivAssign<Vec3> for Vec3 {
  fn div_assign(&mut self, rhs: Vec3) {
    *self = Vec3 {
      i: self.i / rhs.i,
      j: self.j / rhs.j,
      k: self.k / rhs.k,
    }
  }
}

impl DivAssign<f64> for Vec3 {
  fn div_assign(&mut self, scalar: f64) {
    *self = Vec3 {
      i: self.i / scalar,
      j: self.j / scalar,
      k: self.k / scalar,
    }
  }
}

impl Index<i32> for Vec3 {
  type Output = f64;
  fn index(&self, idx: i32) -> &f64 {
    match idx {
      0 => &self.i,
      1 => &self.j,
      2 => &self.k,
      _ => panic!("index out of range: {}", idx),
    }
  }
}

impl IndexMut<i32> for Vec3 {
  fn index_mut<'a>(&'a mut self, idx: i32) -> &'a mut f64 {
    match idx {
      0 => &mut self.i,
      1 => &mut self.j,
      2 => &mut self.k,
      _ => panic!("index out of range: {}", idx),
    }
  }
}

#[cfg(test)]
mod should {
  use super::Vec3;
  #[test]
  fn add() {
    let v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let sum = v1 + v2;
    assert_eq!(sum.i, 3.0);
    assert_eq!(sum.j, 3.0);
    assert_eq!(sum.k, 3.0);
  }
  #[test]
  fn add_assign() {
    let mut v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 += v2;
    assert_eq!(v1.i, 3.0);
    assert_eq!(v1.j, 3.0);
    assert_eq!(v1.k, 3.0);
  }
  #[test]
  fn subtract() {
    let v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let diff = v1 - v2;
    assert_eq!(diff.i, -1.0);
    assert_eq!(diff.j, -1.0);
    assert_eq!(diff.k, -1.0);
  }
  #[test]
  fn subtract_assign() {
    let mut v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 -= v2;
    assert_eq!(v1.i, -1.0);
    assert_eq!(v1.j, -1.0);
    assert_eq!(v1.k, -1.0);
  }
  #[test]
  fn multiply_by_vec3_elementwise() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    let product = v1 * v2;
    assert_eq!(product.i, 6.0);
    assert_eq!(product.j, 6.0);
    assert_eq!(product.k, 6.0);
  }
  #[test]
  fn multiply_by_vec3_assign_elementwise() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    v1 *= v2;
    assert_eq!(v1.i, 6.0);
    assert_eq!(v1.j, 6.0);
    assert_eq!(v1.k, 6.0);
  }
  #[test]
  fn multiply_by_f64() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let product = v1 * 3.0;

    assert_eq!(product.i, 6.0);
    assert_eq!(product.j, 6.0);
    assert_eq!(product.k, 6.0);
  }
  #[test]
  fn multiply_by_f64_assign() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 *= 3.0;

    assert_eq!(v1.i, 6.0);
    assert_eq!(v1.j, 6.0);
    assert_eq!(v1.k, 6.0);
  }
  #[test]
  fn divide_by_vec3_elementwise() {
    let v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    let quotient = v1 / v2;
    assert_eq!(quotient.i, 2.0);
    assert_eq!(quotient.j, 2.0);
    assert_eq!(quotient.k, 2.0);
  }
  #[test]
  fn divide_by_vec3_assign_elementwise() {
    let mut v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    v1 /= v2;
    assert_eq!(v1.i, 2.0);
    assert_eq!(v1.j, 2.0);
    assert_eq!(v1.k, 2.0);
  }
  #[test]
  fn divide_by_f64() {
    let v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let quotient = v1 / 3.0;

    assert_eq!(quotient.i, 2.0);
    assert_eq!(quotient.j, 2.0);
    assert_eq!(quotient.k, 2.0);
  }
  #[test]
  fn divide_by_f64_assign() {
    let mut v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    v1 /= 3.0;

    assert_eq!(v1.i, 2.0);
    assert_eq!(v1.j, 2.0);
    assert_eq!(v1.k, 2.0);
  }
  #[test]
  fn allow_index_access() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};

    assert_eq!(v1[0], 2.0);
    assert_eq!(v1[1], 2.0);
    assert_eq!(v1[2], 2.0);
  }
  #[test]
  #[should_panic(expected = "index out of range: 9")]
  fn panic_on_bad_index() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};

    assert_eq!(v1[9], 2.0);
  }
  #[test]
  fn allow_index_mut_access() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1[0] = 9.0;

    assert_eq!(v1[0], 9.0);
    assert_eq!(v1[1], 2.0);
    assert_eq!(v1[2], 2.0);
  }

  #[test]
  fn calculate_length() {
    let v1 = Vec3 { i: 4.0, j: 4.0, k: 2.0};

    assert_eq!(v1.length(), 6.0);
  }
  #[test]
  fn calculate_length_with_some_zeros() {
    let v2 = Vec3 { i: 4.0, j: 0.0, k: 0.0};

    assert_eq!(v2.length(), 4.0);
  }
  #[test]
  fn calculate_length_for_zero_vector() {
    let v2 = Vec3 { i: 0.0, j: 0.0, k: 0.0};

    assert_eq!(v2.length(), 0.0);
  }
  #[test]
  fn calculate_dot_product() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};

    let product = v1.dot(v2);

    assert_eq!(product, 18.0);
  }
}<|endoftext|>


<commit_before>// Copyright 2014 Strahinja Val Markovic
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![allow(non_snake_case)]
#![cfg_attr(test, allow(dead_code))]
#![feature(unicode)]
#![feature(slice_patterns)]

use std::str::from_utf8;
use std::char::from_u32;

// See:
//   http://en.wikipedia.org/wiki/Escape_sequences_in_C
//   http://en.cppreference.com/w/cpp/language/escape
// No question mark escape supported because there are no trigraphs in PEG.
pub fn unescape( input: &[u8] ) -> Vec<u8> {
  let mut final_bytes = Vec::new();
  let mut index = 0;
  loop {
    // TODO: support \u12345678, not just \u1234
    match &input[ index.. ] {
      [ b'\\', b'u', c1, c2, c3, c4, .. ]
          if isHex( c1 ) && isHex( c2 ) && isHex( c3 ) && isHex( c4 ) => {
        final_bytes = addFourBytesAsCodepoint( final_bytes, [c1, c2, c3, c4] );
        index += 6;
      }
      [ b'\\', b'x', c1, c2, .. ]
          if isHex( c1 ) && isHex( c2 ) => {
        final_bytes = addTwoBytesAsHex( final_bytes, [c1, c2] );
        index += 4;
      }
      [ b'\\', c1, c2, c3, .. ]
          if isOctal( c1 ) && isOctal( c2 ) && isOctal( c3 ) => {
        final_bytes = addThreeBytesAsOctal( final_bytes, [c1, c2, c3] );
        index += 4;
      }
      [ b'\\', c, .. ] => {
        final_bytes = addEscapedByte( final_bytes, c );
        index += 2;
      }
      [ c, .. ] => {
        final_bytes.push( c );
        index += 1;
      }
      [] => break,
    }
  }

  return final_bytes;
}

pub fn unescapeString( input: &str ) -> String {
  from_utf8( &unescape( input.as_bytes() ) ).unwrap().to_string()
}

fn isOctal( byte: u8 ) -> bool {
  (byte as char).is_digit( 8 )
}

fn isHex( byte: u8 ) -> bool {
  (byte as char).is_digit( 16 )
}

fn addFourBytesAsCodepoint( mut input: Vec<u8>, bytes: [u8; 4] ) -> Vec<u8> {
  let slice = from_utf8( &bytes ).unwrap();
  match u32::from_str_radix( slice, 16 ) {
    Ok( x ) => match from_u32( x ) {
      Some( character ) => {
        let mut utf8chars = [0; 4];
        let num_written = character.encode_utf8( &mut utf8chars ).unwrap();
        for i in 0 .. num_written {
          input.push( *utf8chars.get( i ).unwrap() );
        }
      },
      _ => panic!( "Invalid unicode code point: {}", x )
    },
    _ => panic!( r"Invalid unicode escape sequence: \u{}{}{}{}",
                bytes.get( 0 ).unwrap(),
                bytes.get( 1 ).unwrap(),
                bytes.get( 2 ).unwrap(),
                bytes.get( 3 ).unwrap() )
  }
  input
}

fn addTwoBytesAsHex( mut input: Vec<u8>, bytes: [u8; 2] ) -> Vec<u8> {
  let slice = from_utf8( &bytes ).unwrap();
  match u8::from_str_radix( slice, 16 ) {
    Ok( byte ) => input.push( byte ),
    _ => panic!( r"Invalid hex escape sequence: \x{}{}",
                bytes.get( 0 ).unwrap(),
                bytes.get( 1 ).unwrap() )
  }
  input
}

fn addThreeBytesAsOctal( mut input: Vec<u8>, bytes: [u8; 3] ) -> Vec<u8> {
  let slice = from_utf8( &bytes ).unwrap();
  match u8::from_str_radix( slice, 8 ) {
    Ok( byte ) => input.push( byte ),
    _ => panic!( r"Invalid octal escape sequence: \{}{}{}",
                bytes.get( 0 ).unwrap(),
                bytes.get( 1 ).unwrap(),
                bytes.get( 2 ).unwrap() )
  }
  input
}

fn addEscapedByte( mut input: Vec<u8>, byte: u8 ) -> Vec<u8> {
  let unescaped_char = match byte {
    b'a'  => Some( b'\x07' ),
    b'b'  => Some( b'\x08' ),
    b'f'  => Some( b'\x0c' ),
    b'n'  => Some( b'\n'   ),
    b'r'  => Some( b'\r'   ),
    b't'  => Some( b'\t'   ),
    b'v'  => Some( b'\x0b' ),
    b'0'  => Some( b'\0'   ),
    b'\'' => Some( b'\''   ),
    b'"'  => Some( b'"'    ),
    b'\\' => Some( b'\\'   ),
    _     => None
  };

  match unescaped_char {
    Some( x ) => input.push( x ),
    None => {
      input.push( b'\\' );
      input.push( byte )
    }
  };
  input
}

#[cfg(test)]
mod tests {
  use super::{unescape};

  fn vecBytes( input: &'static str ) -> Vec<u8> {
    input.as_bytes().to_vec()
  }

  #[test]
  fn unescape_Nothing() {
    assert_eq!( unescape( b"foobar" ),         vecBytes( "foobar" ) );
    assert_eq!( unescape( b"123"    ),         vecBytes( "123" )    );
    assert_eq!( unescape( "葉".as_bytes() ),   vecBytes( "葉" )     );
    assert_eq!( unescape( "a葉8".as_bytes() ), vecBytes( "a葉8" )   );
  }

  #[test]
  fn unescape_LooksLikeEscapeButNot() {
    assert_eq!( unescape( b"\\z" ), vecBytes( "\\z" ) );
    assert_eq!( unescape( b"a\\zg" ), vecBytes( "a\\zg" ) );
  }

  #[test]
  fn unescape_SingleCharEscapeCodes() {
    assert_eq!( unescape( b"\\a"  ), vecBytes( "\x07" ) );
    assert_eq!( unescape( b"\\b"  ), vecBytes( "\x08" ) );
    assert_eq!( unescape( b"\\f"  ), vecBytes( "\x0c" ) );
    assert_eq!( unescape( b"\\n"  ), vecBytes( "\n" )   );
    assert_eq!( unescape( b"\\r"  ), vecBytes( "\r" )   );
    assert_eq!( unescape( b"\\t"  ), vecBytes( "\t" )   );
    assert_eq!( unescape( b"\\v"  ), vecBytes( "\x0b" ) );
    assert_eq!( unescape( b"\\0"  ), vecBytes( "\0" )   );
    assert_eq!( unescape( b"\\'"  ), vecBytes( "\'" )   );
    assert_eq!( unescape( b"\\\"" ), vecBytes( "\"" )   );
    assert_eq!( unescape( b"\\\\" ), vecBytes( "\\" )   );
  }

  #[test]
  fn unescape_MultipleSingleCharEscapeCodes() {
    assert_eq!( unescape( b"\\r\\n" ), vecBytes( "\r\n" ) );
    assert_eq!( unescape( b"\\\\\\\\" ), vecBytes( "\\\\" ) );
  }

  #[test]
  fn unescape_HexEscape() {
    assert_eq!( unescape( b"\\x4E" ), vecBytes( "N" ) );
    assert_eq!( unescape( b"\\x4e" ), vecBytes( "N" ) );
    assert_eq!( unescape( b"\\x00\\x01" ), vec!( 0, 1 ) );
  }

  #[test]
  fn unescape_HexEscape_Bad() {
    assert_eq!( unescape( b"\\x" ), vecBytes( "\\x" ) );
    assert_eq!( unescape( b"\\xgg" ), vecBytes( "\\xgg" ) );
  }

  #[test]
  fn unescape_UnicodeEscape() {
    assert_eq!( unescape( b"\\u0106" ), vecBytes( "Ć" ) );
    assert_eq!( unescape( b"\\u0106\\u04E8" ), vecBytes( "ĆӨ" ) );
    assert_eq!( unescape( b"\\u81EA\\u7531" ), vecBytes( "自由" ) );
  }

  #[test]
  fn unescape_UnicodeEscape_Bad() {
    assert_eq!( unescape( b"\\u" ), vecBytes( "\\u" ) );
    assert_eq!( unescape( b"\\u01x" ), vecBytes( "\\u01x" ) );
  }

  #[test]
  fn unescape_OctalEscape() {
    assert_eq!( unescape( b"\\001" ), vec!( 1 ) );
    assert_eq!( unescape( b"\\157" ), vec!( 111 ) );
  }
}
<commit_msg>unescape.rs now compiles on stable channel<commit_after>// Copyright 2014 Strahinja Val Markovic
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![allow(non_snake_case)]
#![cfg_attr(test, allow(dead_code))]

use std::str::from_utf8;
use std::char::from_u32;

// See:
//   http://en.wikipedia.org/wiki/Escape_sequences_in_C
//   http://en.cppreference.com/w/cpp/language/escape
// No question mark escape supported because there are no trigraphs in PEG.
pub fn unescape( input: &[u8] ) -> Vec<u8> {
  let mut final_bytes = Vec::new();
  let mut index = 0;

  while index < input.len() {
    if input[ index ] != b'\\' {
      final_bytes.push( input[ index ] );
      index += 1;
      continue;
    }
    let num_chars_past_slash = input.len() - index - 1;

    // TODO: support \u12345678, not just \u1234
    if num_chars_past_slash >= 5 &&
       input[ index + 1 ] == b'u' &&
       isHex( input[ index + 2 ] ) &&
       isHex( input[ index + 3 ] ) &&
       isHex( input[ index + 4 ] ) &&
       isHex( input[ index + 5 ] ) {
      final_bytes = addFourBytesAsCodepoint( final_bytes,
                                             &input[ index + 2 .. index + 6 ] );
      index += 6;
      continue;
    }

    if num_chars_past_slash >= 3 &&
       input[ index + 1 ] == b'x' &&
       isHex( input[ index + 2 ] ) &&
       isHex( input[ index + 3 ] ) {
      final_bytes = addTwoBytesAsHex( final_bytes,
                                      &input[ index + 2 .. index + 4 ] );
      index += 4;
      continue;
    }

    if num_chars_past_slash >= 3 &&
       isOctal( input[ index + 1 ] ) &&
       isOctal( input[ index + 2 ] ) &&
       isOctal( input[ index + 3 ] ) {
      final_bytes = addThreeBytesAsOctal( final_bytes,
                                          &input[ index + 1 .. index + 4 ] );
      index += 4;
      continue;
    }

    if num_chars_past_slash >= 1 {
      final_bytes = addEscapedByte( final_bytes, input[ index + 1 ] );
      index += 2;
    }
  }

  final_bytes
}

pub fn unescapeString( input: &str ) -> String {
  from_utf8( &unescape( input.as_bytes() ) ).unwrap().to_string()
}

fn isOctal( byte: u8 ) -> bool {
  (byte as char).is_digit( 8 )
}

fn isHex( byte: u8 ) -> bool {
  (byte as char).is_digit( 16 )
}

fn addFourBytesAsCodepoint( mut input: Vec<u8>, bytes: &[u8] ) -> Vec<u8> {
  // &[u8] -> &str -> u32 -> char -> encode as utf8 bytes to input

  let slice: &str = from_utf8( &bytes ).unwrap();
  match u32::from_str_radix( slice, 16 ) {
    Ok( x ) => match from_u32( x ) {
      Some( character ) => {
        let mut utf8chars = [0; 4];
        let num_written = encode_utf8_raw( character as u32,
                                           &mut utf8chars ).unwrap();
        for i in 0 .. num_written {
          input.push( *utf8chars.get( i ).unwrap() );
        }
      },
      _ => panic!( "Invalid unicode code point: {}", x )
    },
    _ => panic!( r"Invalid unicode escape sequence: \u{}{}{}{}",
                bytes.get( 0 ).unwrap(),
                bytes.get( 1 ).unwrap(),
                bytes.get( 2 ).unwrap(),
                bytes.get( 3 ).unwrap() )
  }
  input
}

fn addTwoBytesAsHex( mut input: Vec<u8>, bytes: &[u8] ) -> Vec<u8> {
  // &[u8] -> &str -> u8 -> write to input

  let slice: &str = from_utf8( &bytes ).unwrap();
  match u8::from_str_radix( slice, 16 ) {
    Ok( byte ) => input.push( byte ),
    _ => panic!( r"Invalid hex escape sequence: \x{}{}",
                bytes.get( 0 ).unwrap(),
                bytes.get( 1 ).unwrap() )
  }
  input
}

fn addThreeBytesAsOctal( mut input: Vec<u8>, bytes: &[u8] ) -> Vec<u8> {
  // &[u8] -> &str -> u8 -> write to input

  let slice: &str = from_utf8( &bytes ).unwrap();
  match u8::from_str_radix( slice, 8 ) {
    Ok( byte ) => input.push( byte ),
    _ => panic!( r"Invalid octal escape sequence: \{}{}{}",
                bytes.get( 0 ).unwrap(),
                bytes.get( 1 ).unwrap(),
                bytes.get( 2 ).unwrap() )
  }
  input
}

fn addEscapedByte( mut input: Vec<u8>, byte: u8 ) -> Vec<u8> {
  let unescaped_char = match byte {
    b'a'  => Some( b'\x07' ),
    b'b'  => Some( b'\x08' ),
    b'f'  => Some( b'\x0c' ),
    b'n'  => Some( b'\n'   ),
    b'r'  => Some( b'\r'   ),
    b't'  => Some( b'\t'   ),
    b'v'  => Some( b'\x0b' ),
    b'0'  => Some( b'\0'   ),
    b'\'' => Some( b'\''   ),
    b'"'  => Some( b'"'    ),
    b'\\' => Some( b'\\'   ),
    _     => None
  };

  match unescaped_char {
    Some( x ) => input.push( x ),
    None => {
      input.push( b'\\' );
      input.push( byte )
    }
  };
  input
}

// UTF-8 ranges and tags for encoding characters
const TAG_CONT: u8    = 0b1000_0000;
const TAG_TWO_B: u8   = 0b1100_0000;
const TAG_THREE_B: u8 = 0b1110_0000;
const TAG_FOUR_B: u8  = 0b1111_0000;
const MAX_ONE_B: u32   =     0x80;
const MAX_TWO_B: u32   =    0x800;
const MAX_THREE_B: u32 =  0x10000;

// Unstable api, so copied from:
//   https://github.com/rust-lang/rust/blob/master/src/libcore/char.rs#L238
// Replace with upstream char::encode_utf8 when it becomes stable!
#[inline]
pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> Option<usize> {
  // Marked #[inline] to allow llvm optimizing it away
  if code < MAX_ONE_B && !dst.is_empty() {
    dst[0] = code as u8;
    Some(1)
  } else if code < MAX_TWO_B && dst.len() >= 2 {
    dst[0] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
    dst[1] = (code & 0x3F) as u8 | TAG_CONT;
    Some(2)
  } else if code < MAX_THREE_B && dst.len() >= 3  {
    dst[0] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
    dst[1] = (code >>  6 & 0x3F) as u8 | TAG_CONT;
    dst[2] = (code & 0x3F) as u8 | TAG_CONT;
    Some(3)
  } else if dst.len() >= 4 {
    dst[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
    dst[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT;
    dst[2] = (code >>  6 & 0x3F) as u8 | TAG_CONT;
    dst[3] = (code & 0x3F) as u8 | TAG_CONT;
    Some(4)
  } else {
    None
  }
}

#[cfg(test)]
mod tests {
  use super::{unescape};

  fn vecBytes( input: &'static str ) -> Vec<u8> {
    input.as_bytes().to_vec()
  }

  #[test]
  fn unescape_Nothing() {
    assert_eq!( unescape( b"foobar" ),         vecBytes( "foobar" ) );
    assert_eq!( unescape( b"123"    ),         vecBytes( "123" )    );
    assert_eq!( unescape( "葉".as_bytes() ),   vecBytes( "葉" )     );
    assert_eq!( unescape( "a葉8".as_bytes() ), vecBytes( "a葉8" )   );
  }

  #[test]
  fn unescape_LooksLikeEscapeButNot() {
    assert_eq!( unescape( b"\\z" ), vecBytes( "\\z" ) );
    assert_eq!( unescape( b"a\\zg" ), vecBytes( "a\\zg" ) );
  }

  #[test]
  fn unescape_SingleCharEscapeCodes() {
    assert_eq!( unescape( b"\\a"  ), vecBytes( "\x07" ) );
    assert_eq!( unescape( b"\\b"  ), vecBytes( "\x08" ) );
    assert_eq!( unescape( b"\\f"  ), vecBytes( "\x0c" ) );
    assert_eq!( unescape( b"\\n"  ), vecBytes( "\n" )   );
    assert_eq!( unescape( b"\\r"  ), vecBytes( "\r" )   );
    assert_eq!( unescape( b"\\t"  ), vecBytes( "\t" )   );
    assert_eq!( unescape( b"\\v"  ), vecBytes( "\x0b" ) );
    assert_eq!( unescape( b"\\0"  ), vecBytes( "\0" )   );
    assert_eq!( unescape( b"\\'"  ), vecBytes( "\'" )   );
    assert_eq!( unescape( b"\\\"" ), vecBytes( "\"" )   );
    assert_eq!( unescape( b"\\\\" ), vecBytes( "\\" )   );
  }

  #[test]
  fn unescape_MultipleSingleCharEscapeCodes() {
    assert_eq!( unescape( b"\\r\\n" ), vecBytes( "\r\n" ) );
    assert_eq!( unescape( b"\\\\\\\\" ), vecBytes( "\\\\" ) );
  }

  #[test]
  fn unescape_HexEscape() {
    assert_eq!( unescape( b"\\x4E" ), vecBytes( "N" ) );
    assert_eq!( unescape( b"\\x4e" ), vecBytes( "N" ) );
    assert_eq!( unescape( b"\\x00\\x01" ), vec!( 0, 1 ) );
  }

  #[test]
  fn unescape_HexEscape_Bad() {
    assert_eq!( unescape( b"\\x" ), vecBytes( "\\x" ) );
    assert_eq!( unescape( b"\\xgg" ), vecBytes( "\\xgg" ) );
  }

  #[test]
  fn unescape_UnicodeEscape() {
    assert_eq!( unescape( b"\\u0106" ), vecBytes( "Ć" ) );
    assert_eq!( unescape( b"\\u0106\\u04E8" ), vecBytes( "ĆӨ" ) );
    assert_eq!( unescape( b"\\u81EA\\u7531" ), vecBytes( "自由" ) );
  }

  #[test]
  fn unescape_UnicodeEscape_Bad() {
    assert_eq!( unescape( b"\\u" ), vecBytes( "\\u" ) );
    assert_eq!( unescape( b"\\u01x" ), vecBytes( "\\u01x" ) );
  }

  #[test]
  fn unescape_OctalEscape() {
    assert_eq!( unescape( b"\\001" ), vec!( 1 ) );
    assert_eq!( unescape( b"\\157" ), vec!( 111 ) );
  }
}
<|endoftext|>


<commit_before>use buffer;
use extensions;
use serde;
use serde_json;
use std::{self, fmt, io, marker};
use texture;
use validation;

use path::Path;
use validation::Validate;
use {Accessor, Animation, Asset, Buffer, Camera, Error, Extras, Image, Material, Mesh, Node, Scene, Skin, Texture, Value};

/// Helper trait for retrieving top-level objects by a universal identifier.
pub trait Get<T> {
    /// Retrieves a single value at the given index.
    fn get(&self, id: &Index<T>) -> Option<&T>;
}

/// Represents an offset into an array of type `T` owned by the root glTF object.
#[derive(Clone, Copy)]
pub struct Index<T>(u32, marker::PhantomData<T>);

/// The root object of a glTF 2.0 asset.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct Root {
    /// An array of accessors.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub accessors: Vec<Accessor>,

    /// An array of keyframe animations.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub animations: Vec<Animation>,

    /// Metadata about the glTF asset.
    pub asset: Asset,

    /// An array of buffers.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub buffers: Vec<Buffer>,

    /// An array of buffer views.
    #[serde(default, rename = "bufferViews")]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub buffer_views: Vec<buffer::View>,

    /// The default scene.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub scene: Option<Index<Scene>>,

    /// Extension specific data.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub extensions: Option<extensions::root::Root>,

    /// Optional application specific data.
    #[serde(default)]
    #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
    pub extras: Extras,

    /// Names of glTF extensions used somewhere in this asset.
    #[serde(default, rename = "extensionsUsed")]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub extensions_used: Vec<String>,

    /// Names of glTF extensions required to properly load this asset.
    #[serde(default, rename = "extensionsRequired")]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub extensions_required: Vec<String>,

    /// An array of cameras.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub cameras: Vec<Camera>,

    /// An array of images.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub images: Vec<Image>,

    /// An array of materials.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub materials: Vec<Material>,

    /// An array of meshes.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub meshes: Vec<Mesh>,

    /// An array of nodes.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub nodes: Vec<Node>,

    /// An array of samplers.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub samplers: Vec<texture::Sampler>,

    /// An array of scenes.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub scenes: Vec<Scene>,

    /// An array of skins.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub skins: Vec<Skin>,

    /// An array of textures.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub textures: Vec<Texture>,
}

impl Root {
    /// Returns a single item from the root object.
    pub fn get<T>(&self, index: &Index<T>) -> Option<&T>
        where Self: Get<T>
    {
        (self as &Get<T>).get(index)
    }

    /// Deserialize from a JSON string slice.
    pub fn from_str(str_: &str) -> Result<Self, Error> {
        serde_json::from_str(str_)
    }

    /// Deserialize from a JSON byte slice.
    pub fn from_slice(slice: &[u8]) -> Result<Self, Error> {
        serde_json::from_slice(slice)
    }

    /// Deserialize from a stream of JSON.
    pub fn from_reader<R>(reader: R) -> Result<Self, Error>
        where R: io::Read
    {
        serde_json::from_reader(reader)
    }

    /// Serialize as a `String` of JSON.
    pub fn to_string(&self) -> Result<String, Error> {
        serde_json::to_string(self)
    }

    /// Serialize as a pretty-printed `String` of JSON.
    pub fn to_string_pretty(&self) -> Result<String, Error> {
        serde_json::to_string_pretty(self)
    }

    /// Serialize as a generic JSON value.
    pub fn to_value(&self) -> Result<Value, Error> {
        serde_json::to_value(self)
    }

    /// Serialize as a JSON byte vector.
    pub fn to_vec(&self) -> Result<Vec<u8>, Error> {
        serde_json::to_vec(self)
    }

    /// Serialize as a pretty-printed JSON byte vector.
    pub fn to_vec_pretty(&self) -> Result<Vec<u8>, Error> {
        serde_json::to_vec_pretty(self)
    }

    /// Serialize as a JSON byte writertor.
    pub fn to_writer<W>(&self, writer: W) -> Result<(), Error>
        where W: io::Write,
    {
        serde_json::to_writer(writer, self)
    }

    /// Serialize as a pretty-printed JSON byte writertor.
    pub fn to_writer_pretty<W>(&self, writer: W) -> Result<(), Error>
        where W: io::Write,
    {
        serde_json::to_writer_pretty(writer, self)
    }
}

impl<T> Index<T> {
    /// Creates a new `Index` representing an offset into an array containing `T`.
    pub fn new(value: u32) -> Self {
        Index(value, std::marker::PhantomData)
    }

    /// Returns the internal offset value.
    pub fn value(&self) -> usize {
        self.0 as usize
    }
}

impl<T> serde::Serialize for Index<T> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ::serde::Serializer
    {
        serializer.serialize_u64(self.value() as u64)
    }
}

impl<'de, T> serde::Deserialize<'de> for Index<T> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: serde::Deserializer<'de>
    {
        struct Visitor<T>(marker::PhantomData<T>);
        impl<'de, T> serde::de::Visitor<'de> for Visitor<T> {
            type Value = Index<T>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("index into child of root")
            }

            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
                where E: serde::de::Error
            {
                Ok(Index::new(value as u32))
            }
        }
        deserializer.deserialize_u64(Visitor::<T>(marker::PhantomData))
    }
}

impl<T> fmt::Debug for Index<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl<T> fmt::Display for Index<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl<T: Validate> Validate for Index<T>
    where Root: Get<T>
{
    fn validate_minimally<P, R>(&self, root: &Root, path: P, report: &mut R)
        where P: Fn() -> Path, R: FnMut(&Fn() -> Path, validation::Error)
    {
        if root.get(self).is_none() {
            report(&path, validation::Error::IndexOutOfBounds);
        }
    }
}

macro_rules! impl_get {
    ($ty:ty, $field:ident) => {
        impl<'a> Get<$ty> for Root {
            fn get(&self, index: &Index<$ty>) -> Option<&$ty> {
                self.$field.get(index.value())
            }
        }
    }
}

impl_get!(Accessor, accessors);
impl_get!(Animation, animations);
impl_get!(Buffer, buffers);
impl_get!(buffer::View, buffer_views);
impl_get!(Camera, cameras);
impl_get!(Image, images);
impl_get!(Material, materials);
impl_get!(Mesh, meshes);
impl_get!(Node, nodes);
impl_get!(texture::Sampler, samplers);
impl_get!(Scene, scenes);
impl_get!(Skin, skins);
impl_get!(Texture, textures);
<commit_msg>make Index<T> Copy for all T<commit_after>use buffer;
use extensions;
use serde;
use serde_json;
use std::{self, fmt, io, marker};
use texture;
use validation;

use path::Path;
use validation::Validate;
use {Accessor, Animation, Asset, Buffer, Camera, Error, Extras, Image, Material, Mesh, Node, Scene, Skin, Texture, Value};

/// Helper trait for retrieving top-level objects by a universal identifier.
pub trait Get<T> {
    /// Retrieves a single value at the given index.
    fn get(&self, id: &Index<T>) -> Option<&T>;
}

/// Represents an offset into an array of type `T` owned by the root glTF object.
pub struct Index<T>(u32, marker::PhantomData<*const T>);

/// The root object of a glTF 2.0 asset.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct Root {
    /// An array of accessors.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub accessors: Vec<Accessor>,

    /// An array of keyframe animations.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub animations: Vec<Animation>,

    /// Metadata about the glTF asset.
    pub asset: Asset,

    /// An array of buffers.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub buffers: Vec<Buffer>,

    /// An array of buffer views.
    #[serde(default, rename = "bufferViews")]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub buffer_views: Vec<buffer::View>,

    /// The default scene.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub scene: Option<Index<Scene>>,

    /// Extension specific data.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub extensions: Option<extensions::root::Root>,

    /// Optional application specific data.
    #[serde(default)]
    #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
    pub extras: Extras,

    /// Names of glTF extensions used somewhere in this asset.
    #[serde(default, rename = "extensionsUsed")]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub extensions_used: Vec<String>,

    /// Names of glTF extensions required to properly load this asset.
    #[serde(default, rename = "extensionsRequired")]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub extensions_required: Vec<String>,

    /// An array of cameras.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub cameras: Vec<Camera>,

    /// An array of images.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub images: Vec<Image>,

    /// An array of materials.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub materials: Vec<Material>,

    /// An array of meshes.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub meshes: Vec<Mesh>,

    /// An array of nodes.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub nodes: Vec<Node>,

    /// An array of samplers.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub samplers: Vec<texture::Sampler>,

    /// An array of scenes.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub scenes: Vec<Scene>,

    /// An array of skins.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub skins: Vec<Skin>,

    /// An array of textures.
    #[serde(default)]
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub textures: Vec<Texture>,
}

impl Root {
    /// Returns a single item from the root object.
    pub fn get<T>(&self, index: &Index<T>) -> Option<&T>
        where Self: Get<T>
    {
        (self as &Get<T>).get(index)
    }

    /// Deserialize from a JSON string slice.
    pub fn from_str(str_: &str) -> Result<Self, Error> {
        serde_json::from_str(str_)
    }

    /// Deserialize from a JSON byte slice.
    pub fn from_slice(slice: &[u8]) -> Result<Self, Error> {
        serde_json::from_slice(slice)
    }

    /// Deserialize from a stream of JSON.
    pub fn from_reader<R>(reader: R) -> Result<Self, Error>
        where R: io::Read
    {
        serde_json::from_reader(reader)
    }

    /// Serialize as a `String` of JSON.
    pub fn to_string(&self) -> Result<String, Error> {
        serde_json::to_string(self)
    }

    /// Serialize as a pretty-printed `String` of JSON.
    pub fn to_string_pretty(&self) -> Result<String, Error> {
        serde_json::to_string_pretty(self)
    }

    /// Serialize as a generic JSON value.
    pub fn to_value(&self) -> Result<Value, Error> {
        serde_json::to_value(self)
    }

    /// Serialize as a JSON byte vector.
    pub fn to_vec(&self) -> Result<Vec<u8>, Error> {
        serde_json::to_vec(self)
    }

    /// Serialize as a pretty-printed JSON byte vector.
    pub fn to_vec_pretty(&self) -> Result<Vec<u8>, Error> {
        serde_json::to_vec_pretty(self)
    }

    /// Serialize as a JSON byte writertor.
    pub fn to_writer<W>(&self, writer: W) -> Result<(), Error>
        where W: io::Write,
    {
        serde_json::to_writer(writer, self)
    }

    /// Serialize as a pretty-printed JSON byte writertor.
    pub fn to_writer_pretty<W>(&self, writer: W) -> Result<(), Error>
        where W: io::Write,
    {
        serde_json::to_writer_pretty(writer, self)
    }
}

impl<T> Index<T> {
    /// Creates a new `Index` representing an offset into an array containing `T`.
    pub fn new(value: u32) -> Self {
        Index(value, std::marker::PhantomData)
    }

    /// Returns the internal offset value.
    pub fn value(&self) -> usize {
        self.0 as usize
    }
}

impl<T> serde::Serialize for Index<T> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ::serde::Serializer
    {
        serializer.serialize_u64(self.value() as u64)
    }
}

impl<'de, T> serde::Deserialize<'de> for Index<T> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: serde::Deserializer<'de>
    {
        struct Visitor<T>(marker::PhantomData<T>);
        impl<'de, T> serde::de::Visitor<'de> for Visitor<T> {
            type Value = Index<T>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("index into child of root")
            }

            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
                where E: serde::de::Error
            {
                Ok(Index::new(value as u32))
            }
        }
        deserializer.deserialize_u64(Visitor::<T>(marker::PhantomData))
    }
}

impl<T> Clone for Index<T> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<T> Copy for Index<T> {}

unsafe impl<T> Send for Index<T> {}
unsafe impl<T> Sync for Index<T> {}

impl<T> fmt::Debug for Index<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl<T> fmt::Display for Index<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl<T: Validate> Validate for Index<T>
    where Root: Get<T>
{
    fn validate_minimally<P, R>(&self, root: &Root, path: P, report: &mut R)
        where P: Fn() -> Path, R: FnMut(&Fn() -> Path, validation::Error)
    {
        if root.get(self).is_none() {
            report(&path, validation::Error::IndexOutOfBounds);
        }
    }
}

macro_rules! impl_get {
    ($ty:ty, $field:ident) => {
        impl<'a> Get<$ty> for Root {
            fn get(&self, index: &Index<$ty>) -> Option<&$ty> {
                self.$field.get(index.value())
            }
        }
    }
}

impl_get!(Accessor, accessors);
impl_get!(Animation, animations);
impl_get!(Buffer, buffers);
impl_get!(buffer::View, buffer_views);
impl_get!(Camera, cameras);
impl_get!(Image, images);
impl_get!(Material, materials);
impl_get!(Mesh, meshes);
impl_get!(Node, nodes);
impl_get!(texture::Sampler, samplers);
impl_get!(Scene, scenes);
impl_get!(Skin, skins);
impl_get!(Texture, textures);
<|endoftext|>