<commit_before>//! This crate implements a structure that can be used as a generic array type.use
//! Core Rust array types `[T; N]` can't be used generically with respect to `N`, so for example this:
//!
//! ```{should_fail}
//! struct Foo<T, N> {
//!     data: [T; N]
//! }
//! ```
//!
//! won't work.
//!
//! **generic-array** exports a `GenericArray<T,N>` type, which lets the above be implemented as:
//!
//! ```
//!# use generic_array::{ArrayLength, GenericArray};
//! struct Foo<T, N: ArrayLength<T>> {
//!     data: GenericArray<T,N>
//! }
//! ```
//!
//! The `ArrayLength<T>` trait is implemented by default for [unsigned integer types](../typenum/uint/index.html) from [typenum](../typenum/index.html).
//!
//! For ease of use, an `arr!` macro is provided - example below:
//!
//! ```
//! # #[macro_use]
//! # extern crate generic_array;
//! # extern crate typenum;
//! # fn main() {
//! let array = arr![u32; 1, 2, 3];
//! assert_eq!(array[2], 3);
//! # }
//! ```
#![cfg_attr(feature="no_std", no_std)]
#[cfg(feature="no_std")]
extern crate core as std;
extern crate typenum;
extern crate nodrop;
pub mod arr;
use nodrop::NoDrop;
use typenum::uint::{Unsigned, UTerm, UInt};
use typenum::bit::{B0, B1};
use std::fmt::Debug;
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;
use std::slice;

/// Trait making `GenericArray` work, marking types to be used as length of an array
pub unsafe trait ArrayLength<T> : Unsigned {
    /// Associated type representing the array type for the number
    type ArrayType;
}

unsafe impl<T> ArrayLength<T> for UTerm {
    type ArrayType = ();
}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplEven<T, U> {
    parent1: U,
    parent2: U,
    _marker: PhantomData<T>
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
    fn clone(&self) -> GenericArrayImplEven<T, U> {
        GenericArrayImplEven {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            _marker: PhantomData
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplOdd<T, U> {
    parent1: U,
    parent2: U,
    data: T
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
    fn clone(&self) -> GenericArrayImplOdd<T, U> {
        GenericArrayImplOdd {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            data: self.data.clone()
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
}

/// Struct representing a generic array - `GenericArray<T, N>` works like [T; N]
#[allow(dead_code)]
pub struct GenericArray<T, U: ArrayLength<T>> {
    data: U::ArrayType
}

impl<T, N> Deref for GenericArray<T, N> where N: ArrayLength<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self as *const Self as *const T, N::to_usize())
        }
    }
}

impl<T, N> DerefMut for GenericArray<T, N> where N: ArrayLength<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize())
        }
    }
}

impl<T, N> GenericArray<T, N> where N: ArrayLength<T> {
    /// map a function over a  slice to a `GenericArray`.
    /// The length of the slice *must* be equal to the length of the array
    pub fn map_slice<S, F: Fn(&S) -> T>(s: &[S], f: F) -> GenericArray<T, N> {
        assert_eq!(s.len(), N::to_usize());
        map_inner(s, f)
    }

    /// map a function over a `GenericArray`.
    pub fn map<U, F>(self, f: F) -> GenericArray<U, N>
    where F: Fn(&T) -> U, N: ArrayLength<U> {
        map_inner(&self, f)
    }
}

#[inline]
fn map_inner<S, F, T, N>(list: &[S], f: F) -> GenericArray<T, N>
where F: Fn(&S) -> T, N: ArrayLength<T> {
     unsafe {
        let mut res : NoDrop<GenericArray<T, N>> =
                      NoDrop::new(std::mem::uninitialized());
        for (s, r) in list.iter().zip(res.iter_mut()) {
            std::ptr::write(r, f(s))
        }
        res.into_inner()
    }
}

impl<T: Default, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array filled with default values
    pub fn new() -> GenericArray<T, N> {
        unsafe {
            let mut res: GenericArray<T, N> = mem::uninitialized();
            if let Err(e) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
                for r in res.iter_mut() {
                    ptr::write(r, T::default())
                }
            })) {
                std::mem::forget(res);
                std::panic::resume_unwind(e);
            };
            res
        }
    }

}

impl<T: Clone, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array from a slice; the length of the slice must be equal to the length of the array
    pub fn from_slice(list: &[T]) -> GenericArray<T, N> {
        assert_eq!(list.len(), N::to_usize());
        map_inner(list, |x: &T| x.clone())
    }

}

impl<T: Clone, N> Clone for GenericArray<T, N> where N: ArrayLength<T> {
    fn clone(&self) -> GenericArray<T, N> {
        unsafe {
            let mut res: GenericArray<T, N> = mem::uninitialized();
            for i in 0..N::to_usize() { ptr::write(&mut res[i], self[i].clone()) }
            res
        }
    }
}
impl<T: Copy, N> Copy for GenericArray<T, N> where N: ArrayLength<T>, N::ArrayType: Copy {}

impl<T: PartialEq, N> PartialEq for GenericArray<T, N> where N: ArrayLength<T> {
    fn eq(&self, other: &Self) -> bool { **self == **other }
}
impl<T: Eq, N> Eq for GenericArray<T, N> where N: ArrayLength<T> {}

impl<T: Debug, N> Debug for GenericArray<T, N> where N: ArrayLength<T> {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { self[..].fmt(fmt) }
}
<commit_msg>extended pre-leaking technique to other methods<commit_after>//! This crate implements a structure that can be used as a generic array type.use
//! Core Rust array types `[T; N]` can't be used generically with respect to `N`, so for example this:
//!
//! ```{should_fail}
//! struct Foo<T, N> {
//!     data: [T; N]
//! }
//! ```
//!
//! won't work.
//!
//! **generic-array** exports a `GenericArray<T,N>` type, which lets the above be implemented as:
//!
//! ```
//!# use generic_array::{ArrayLength, GenericArray};
//! struct Foo<T, N: ArrayLength<T>> {
//!     data: GenericArray<T,N>
//! }
//! ```
//!
//! The `ArrayLength<T>` trait is implemented by default for [unsigned integer types](../typenum/uint/index.html) from [typenum](../typenum/index.html).
//!
//! For ease of use, an `arr!` macro is provided - example below:
//!
//! ```
//! # #[macro_use]
//! # extern crate generic_array;
//! # extern crate typenum;
//! # fn main() {
//! let array = arr![u32; 1, 2, 3];
//! assert_eq!(array[2], 3);
//! # }
//! ```
#![cfg_attr(feature="no_std", no_std)]
#[cfg(feature="no_std")]
extern crate core as std;
extern crate typenum;
extern crate nodrop;
pub mod arr;
use nodrop::NoDrop;
use typenum::uint::{Unsigned, UTerm, UInt};
use typenum::bit::{B0, B1};
use std::fmt::Debug;
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;
use std::slice;

/// Trait making `GenericArray` work, marking types to be used as length of an array
pub unsafe trait ArrayLength<T> : Unsigned {
    /// Associated type representing the array type for the number
    type ArrayType;
}

unsafe impl<T> ArrayLength<T> for UTerm {
    type ArrayType = ();
}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplEven<T, U> {
    parent1: U,
    parent2: U,
    _marker: PhantomData<T>
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
    fn clone(&self) -> GenericArrayImplEven<T, U> {
        GenericArrayImplEven {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            _marker: PhantomData
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplOdd<T, U> {
    parent1: U,
    parent2: U,
    data: T
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
    fn clone(&self) -> GenericArrayImplOdd<T, U> {
        GenericArrayImplOdd {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            data: self.data.clone()
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
}

/// Struct representing a generic array - `GenericArray<T, N>` works like [T; N]
#[allow(dead_code)]
pub struct GenericArray<T, U: ArrayLength<T>> {
    data: U::ArrayType
}

impl<T, N> Deref for GenericArray<T, N> where N: ArrayLength<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self as *const Self as *const T, N::to_usize())
        }
    }
}

impl<T, N> DerefMut for GenericArray<T, N> where N: ArrayLength<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize())
        }
    }
}

impl<T, N> GenericArray<T, N> where N: ArrayLength<T> {
    /// map a function over a  slice to a `GenericArray`.
    /// The length of the slice *must* be equal to the length of the array
    pub fn map_slice<S, F: Fn(&S) -> T>(s: &[S], f: F) -> GenericArray<T, N> {
        assert_eq!(s.len(), N::to_usize());
        map_inner(s, f)
    }

    /// map a function over a `GenericArray`.
    pub fn map<U, F>(self, f: F) -> GenericArray<U, N>
    where F: Fn(&T) -> U, N: ArrayLength<U> {
        map_inner(&self, f)
    }
}

#[inline]
fn map_inner<S, F, T, N>(list: &[S], f: F) -> GenericArray<T, N>
where F: Fn(&S) -> T, N: ArrayLength<T> {
     unsafe {
        let mut res : NoDrop<GenericArray<T, N>> =
                      NoDrop::new(std::mem::uninitialized());
        for (s, r) in list.iter().zip(res.iter_mut()) {
            std::ptr::write(r, f(s))
        }
        res.into_inner()
    }
}

impl<T: Default, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array filled with default values
    pub fn new() -> GenericArray<T, N> {
        unsafe {
            let mut res : NoDrop<GenericArray<T, N>> =
                          NoDrop::new(std::mem::uninitialized());
            for r in res.iter_mut() {
                ptr::write(r, T::default())
            }
            res.into_inner()
        }
    }

}

impl<T: Clone, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array from a slice; the length of the slice must be equal to the length of the array
    pub fn from_slice(list: &[T]) -> GenericArray<T, N> {
        assert_eq!(list.len(), N::to_usize());
        map_inner(list, |x: &T| x.clone())
    }

}

impl<T: Clone, N> Clone for GenericArray<T, N> where N: ArrayLength<T> {
    fn clone(&self) -> GenericArray<T, N> {
        unsafe {
            let mut res : NoDrop<GenericArray<T, N>> =
                          NoDrop::new(std::mem::uninitialized());
            for i in 0..N::to_usize() { ptr::write(&mut res[i], self[i].clone()) }
            res.into_inner()
        }
    }
}
impl<T: Copy, N> Copy for GenericArray<T, N> where N: ArrayLength<T>, N::ArrayType: Copy {}

impl<T: PartialEq, N> PartialEq for GenericArray<T, N> where N: ArrayLength<T> {
    fn eq(&self, other: &Self) -> bool { **self == **other }
}
impl<T: Eq, N> Eq for GenericArray<T, N> where N: ArrayLength<T> {}

impl<T: Debug, N> Debug for GenericArray<T, N> where N: ArrayLength<T> {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { self[..].fmt(fmt) }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "cargo-clippy", allow(mutex_atomic))]
#![feature(try_from)]

#[macro_use]
extern crate enum_iter;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate serde_derive;

pub mod errors;
pub mod models;
pub mod shmem;
pub mod app_connection;
pub mod client_connection;
pub mod connection_util;

#[cfg(test)]
mod tests {
    extern crate tokio_core;
    extern crate tokio_timer;
    use client_connection::*;
    use app_connection::*;
    use models::*;
    use shmem::*;
    use self::tokio_timer::*;
    use futures::{Future, Sink, Stream};
    use std::convert::TryFrom;
    use std::time::Duration;
    use std::sync::Arc;

    #[test]
    fn test_from_ipc() {
        let expectation = StatusMessage::AppStatus(AppStatus {
            current_cpu_time: 9999.0,
            checkpoint_cpu_time: 8888.0,
            want_network: true,
            fraction_done: 0.1,
            other_pid: Some(345),

            bytes_received: None,
            bytes_sent: None,
        });

        let result = StatusMessage::try_from((
            StatusMsgChannel::AppStatus,
            "
            <current_cpu_time>9999.0</current_cpu_time>\n
            <checkpoint_cpu_time>8888.0</checkpoint_cpu_time>\n
            <want_network />
            <fraction_done>0.1</fraction_done>
            <other_pid>345</other_pid>
        "
                .into(),
        )).unwrap();

        assert_eq!(expectation, result);
    }

    #[test]
    /// In this test we create two IPCStreams which communicate via a shared AppChannel.
    fn test_inmemory_stream() {
        let fixture = AppStatus {
            current_cpu_time: 4.0,
            checkpoint_cpu_time: 5.0,
            want_network: true,
            fraction_done: 0.15,
            other_pid: None,
            bytes_sent: Some(256.0),
            bytes_received: Some(128.0),
        };
        let expectation = StatusMessage::AppStatus(fixture.clone());

        let c = MemoryAppChannel::default();
        let app_channel: SharedAppChannel = Arc::new(c);

        let client_connection = ControlConnection::new(Arc::clone(&app_channel));
        let app_connection = AppConnection::new(Arc::clone(&app_channel));

        client_connection
            .send(StatusMessage::AppStatus(fixture.clone()))
            .wait()
            .unwrap();

        let timer = Timer::default();
        let timeout = timer.sleep(Duration::from_millis(1500)).then(|_| Err(()));
        let output = timeout
            .select(
                app_connection
                    .into_future()
                    .map(|(v, _)| v.unwrap())
                    .map_err(|(_, _)| ()),
            )
            .map(|(v, _)| v)
            .wait();
        match output {
            Ok(result) => assert_eq!(expectation, result),
            Err(_) => panic!("Failed to get result within time limit"),
        };
    }
}
<commit_msg>Export errors::Error from crate root<commit_after>#![cfg_attr(feature = "cargo-clippy", allow(mutex_atomic))]
#![feature(try_from)]

#[macro_use]
extern crate enum_iter;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate serde_derive;

pub mod errors;
pub mod models;
pub mod shmem;
pub mod app_connection;
pub mod client_connection;
pub mod connection_util;

pub use errors::Error;

#[cfg(test)]
mod tests {
    extern crate tokio_core;
    extern crate tokio_timer;
    use client_connection::*;
    use app_connection::*;
    use models::*;
    use shmem::*;
    use self::tokio_timer::*;
    use futures::{Future, Sink, Stream};
    use std::convert::TryFrom;
    use std::time::Duration;
    use std::sync::Arc;

    #[test]
    fn test_from_ipc() {
        let expectation = StatusMessage::AppStatus(AppStatus {
            current_cpu_time: 9999.0,
            checkpoint_cpu_time: 8888.0,
            want_network: true,
            fraction_done: 0.1,
            other_pid: Some(345),

            bytes_received: None,
            bytes_sent: None,
        });

        let result = StatusMessage::try_from((
            StatusMsgChannel::AppStatus,
            "
            <current_cpu_time>9999.0</current_cpu_time>\n
            <checkpoint_cpu_time>8888.0</checkpoint_cpu_time>\n
            <want_network />
            <fraction_done>0.1</fraction_done>
            <other_pid>345</other_pid>
        "
                .into(),
        )).unwrap();

        assert_eq!(expectation, result);
    }

    #[test]
    /// In this test we create two IPCStreams which communicate via a shared AppChannel.
    fn test_inmemory_stream() {
        let fixture = AppStatus {
            current_cpu_time: 4.0,
            checkpoint_cpu_time: 5.0,
            want_network: true,
            fraction_done: 0.15,
            other_pid: None,
            bytes_sent: Some(256.0),
            bytes_received: Some(128.0),
        };
        let expectation = StatusMessage::AppStatus(fixture.clone());

        let c = MemoryAppChannel::default();
        let app_channel: SharedAppChannel = Arc::new(c);

        let client_connection = ControlConnection::new(Arc::clone(&app_channel));
        let app_connection = AppConnection::new(Arc::clone(&app_channel));

        client_connection
            .send(StatusMessage::AppStatus(fixture.clone()))
            .wait()
            .unwrap();

        let timer = Timer::default();
        let timeout = timer.sleep(Duration::from_millis(1500)).then(|_| Err(()));
        let output = timeout
            .select(
                app_connection
                    .into_future()
                    .map(|(v, _)| v.unwrap())
                    .map_err(|(_, _)| ()),
            )
            .map(|(v, _)| v)
            .wait();
        match output {
            Ok(result) => assert_eq!(expectation, result),
            Err(_) => panic!("Failed to get result within time limit"),
        };
    }
}
<|endoftext|>


<commit_before>#![feature(custom_derive)]
#![feature(proc_macro)]

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

//pub mod reference;

use serde_json::Value;

#[derive(Deserialize, Debug)]
pub struct Response {
    took: u64,
    timed_out: bool,
    _shards: Shards,
    hits: Hits,
    aggregations: Option<Aggregations>,
    status: Option<u16>
}

#[derive(Deserialize, Debug)]
pub struct Aggregations(Value);

impl IntoIterator for Aggregations {
    type Item = Value;
    type IntoIter = AggregationIterator;

    fn into_iter(self) -> Self::IntoIter {
        AggregationIterator::new(self)
    }
}

#[derive(Debug)]
pub struct AggregationIterator {
    start_at: Option<Value>,
    count: u64,
    aggregations: Aggregations
}

impl AggregationIterator {
    fn new(a: Aggregations) -> AggregationIterator {
        AggregationIterator {
            start_at: None,
            count: 0,
            aggregations: a
        }
    }
}

impl Iterator for AggregationIterator {
    type Item = Value;

    fn next(&mut self) -> Option<Value> {
        let v = match self.aggregations {
            Aggregations(ref v) => v
        };

//        match self.start_at {
//            None => {
//                self.start_at = Some(*v);
//            },
//            Some(ref mut x) => {
//                self.start_at = Some(*x)
//            }
//        };
////
//        println!("{:#?}", current);

//        println!("{:#?}", v);

        if self.count < 6 {
            Some(Value::U64(0))
        } else {
            None
        }
    }
}

#[derive(Deserialize, Debug)]
struct Shards {
    total: u32,
    successful: u32,
    failed: u32
}

#[derive(Deserialize, Debug)]
pub struct Hits {
    total: u64,
    max_score: u64,
    hits: Vec<Value>
}

impl Response {
    pub fn hits(&self) -> &Vec<Value> {
        &self.hits.hits()
    }

    pub fn aggs(self) -> std::option::Option<Aggregations> {
        self.aggregations
    }
}

impl Hits {
    pub fn hits(&self) -> &Vec<Value> {
        &self.hits
    }
}

#[derive(Deserialize, Debug)]
struct Hit {
    _index: String
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>Try introduce ref/lifetimes<commit_after>#![feature(custom_derive)]
#![feature(proc_macro)]

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

//pub mod reference;

use serde_json::Value;

#[derive(Deserialize, Debug)]
pub struct Response {
    took: u64,
    timed_out: bool,
    _shards: Shards,
    hits: Hits,
    aggregations: Option<Aggregations>,
    status: Option<u16>
}

#[derive(Deserialize, Debug)]
pub struct Aggregations(Value);

impl<'a> IntoIterator for Aggregations {
    type Item = Value;
    type IntoIter = AggregationIterator<'a>;

    fn into_iter(self) -> Self::IntoIter {
        AggregationIterator::new(self)
    }
}

#[derive(Debug)]
pub struct AggregationIterator<'a> {
    start_at: Option<&'a Value>,
    count: u64,
    aggregations: Aggregations
}

impl<'a> AggregationIterator<'a> {
    fn new(a: Aggregations) -> AggregationIterator<'a> {

        let v : &Value = match a {
            Aggregations(v) => v
        };

        AggregationIterator {
            start_at: Some(v),
            count: 0,
            aggregations: a
        }
    }
}

impl<'a> Iterator for AggregationIterator<'a> {
    type Item = Value;

    fn next(&mut self) -> Option<Value> {

        if self.count < 6 {
            Some(Value::U64(0))
        } else {
            None
        }
    }
}

#[derive(Deserialize, Debug)]
struct Shards {
    total: u32,
    successful: u32,
    failed: u32
}

#[derive(Deserialize, Debug)]
pub struct Hits {
    total: u64,
    max_score: u64,
    hits: Vec<Value>
}

impl Response {
    pub fn hits(&self) -> &Vec<Value> {
        &self.hits.hits()
    }

    pub fn aggs(self) -> std::option::Option<Aggregations> {
        self.aggregations
    }
}

impl Hits {
    pub fn hits(&self) -> &Vec<Value> {
        &self.hits
    }
}

#[derive(Deserialize, Debug)]
struct Hit {
    _index: String
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<|endoftext|>


<commit_before>//! Open URLs in the web browsers available on a platform
//!
//! Inspired by the [webbrowser](https://docs.python.org/2/library/webbrowser.html) python library
//!
//! #Examples
//!
//! ```
//! use webbrowser;
//!
//! if webbrowser::open("http://github.com").is_ok() {
//!     // ...
//! }
//! ```
//!
//! Currently state of platform support is:
//!
//! * macos => default, as well as browsers listed under [Browser](enum.Browser.html)
//! * windows => default browser only
//! * linux => default browser only (uses $BROWSER env var, failing back to xdg-open, gvfs-open and
//! gnome-open, in that order)
//! * android => not supported right now
//! * ios => not supported right now
//!
//! Important note:
//!
//! * This library requires availability of browsers and a graphical environment during runtime
//! * `cargo test` will actually open the browser locally

use std::process::{Command, Output};
use std::io::{Result, Error, ErrorKind};
use std::env;

#[derive(Debug)]
/// Browser types available
pub enum Browser {
    Default,
    Firefox,
    InternetExplorer,
    Chrome,
    Opera,
    Safari
}

/// Opens the URL on the default browser of this platform
///
/// Returns Ok(..) so long as the browser invocation was successful. An Err(..) is returned only if
/// there was an error in running the command, or if the browser was not found
///
/// # Examples
/// ```
/// use webbrowser;
///
/// if webbrowser::open("http://github.com").is_ok() {
///     // ...
/// }
/// ```
pub fn open(url: &str) -> Result<Output> {
    open_browser(Browser::Default, url)
}

/// Opens the specified URL on the specific browser (if available) requested. Return semantics are
/// the same as for [open](fn.open.html)
///
/// # Examples
/// ```
/// use webbrowser::{open_browser, Browser};
///
/// if open_browser(Browser::Firefox, "http://github.com").is_ok() {
///     // ...
/// }
/// ```
pub fn open_browser(browser: Browser, url: &str) -> Result<Output> {
    open_browser_internal(browser, url)
}

/// Deal with opening of browsers on Windows, using `start` command
#[cfg(target_os = "windows")]
#[inline]
fn open_browser_internal(browser: Browser, url: &str) -> Result<Output> {
    match browser {
        Browser::Default => Command::new("cmd").arg("/C").arg("start").arg(url).output(),
        _ => Err(Error::new(
            ErrorKind::NotFound,
            "Only the default browser is supported on this platform right now"
        ))
    }
}

/// Deal with opening of browsers on Mac OS X, using `open` command
#[cfg(target_os = "macos")]
#[inline]
fn open_browser_internal(browser: Browser, url: &str) -> Result<Output> {
    let mut cmd = Command::new("open");
    match browser {
        Browser::Default => cmd.arg(url).output(),
        _ => {
            let app: Option<&str> = match browser {
                Browser::Firefox => Some("Firefox"),
                Browser::Chrome => Some("Google Chrome"),
                Browser::Opera => Some("Opera"),
                Browser::Safari => Some("Safari"),
                _ => None
            };
            match app {
                Some(name) => cmd.arg("-a").arg(name).arg(url).output(),
                None => Err(Error::new(ErrorKind::NotFound, format!("Unsupported browser {:?}", browser)))
            }
        }
    }
}

/*pub fn open_browser(browser: Browser, url: &str) -> Result<Output> {
    let os = std::env::consts::OS;
    match os {
        "macos" => open_on_macos(browser, url),
        "windows" => open_on_windows(browser, url),
        "linux" => open_on_linux(browser, url),
        _ => Err(Error::new(ErrorKind::NotFound, format!("Platform {} not yet supported by this library", os)))
    }
}

/// Deal with opening of browsers on Mac OS X, using `open` command
fn open_on_macos(browser: Browser, url: &str) -> Result<Output> {
    let mut cmd = Command::new("open");
    match browser {
        Browser::Default => cmd.arg(url).output(),
        _ => {
            let app: Option<&str> = match browser {
                Browser::Firefox => Some("Firefox"),
                Browser::Chrome => Some("Google Chrome"),
                Browser::Opera => Some("Opera"),
                Browser::Safari => Some("Safari"),
                _ => None
            };
            match app {
                Some(name) => cmd.arg("-a").arg(name).arg(url).output(),
                None => Err(Error::new(ErrorKind::NotFound, format!("Unsupported browser {:?}", browser)))
            }
        }
    }
}

/// Deal with opening of browsers on Windows, using `start` command
fn open_on_windows(browser: Browser, url: &str) -> Result<Output> {
    match browser {
        Browser::Default => Command::new("cmd").arg("/C").arg("start").arg(url).output(),
        _ => Err(Error::new(
                ErrorKind::NotFound,
                "Only the default browser is supported on this platform right now"
            ))
    }
}

*/
/// Deal with opening of browsers on Linux - currently supports only the default browser
///
/// The mechanism of opening the default browser is as follows:
/// 1. Attempt to use $BROWSER env var if available
/// 2. Attempt to open the url via xdg-open, gvfs-open, gnome-open, respectively, whichever works
///    first
#[cfg(target_os = "linux")]
#[inline]
fn open_browser_internal(browser: Browser, url: &str) -> Result<Output> {
    match browser {
        Browser::Default => open_on_linux_using_browser_env(url)
            .or_else(|_| -> Result<Output> {Command::new("xdg-open").arg(url).output()})
            .or_else(|_| -> Result<Output> {Command::new("gvfs-open").arg(url).output()})
            .or_else(|_| -> Result<Output> {Command::new("gnome-open").arg(url).output()}),
        _ => Err(Error::new(
                ErrorKind::NotFound,
                "Only the default browser is supported on this platform right now"
            ))
    }
}

/// Open on Linux using the $BROWSER env var
#[cfg(target_os = "linux")]
fn open_on_linux_using_browser_env(url: &str) -> Result<Output> {
    let browsers = try!(env::var("BROWSER").map_err(|_| -> Error {Error::new(ErrorKind::NotFound, format!("BROWSER env not set"))}));
    for browser in browsers.split(':') { // $BROWSER can contain ':' delimited options, each representing a potential browser command line
        if !browser.is_empty() {
            // each browser command can have %s to represent URL, while %c needs to be replaced
            // with ':' and %% with '%'
            let cmdline = browser.replace("%s", url).replace("%c", ":").replace("%%", "%");
            let cmdarr: Vec<&str> = cmdline.split_whitespace().collect();
            let mut cmd = Command::new(&cmdarr[0]);
            if cmdarr.len() > 1 {
                cmd.args(&cmdarr[1..cmdarr.len()]);
            }
            if !browser.contains("%s") {
                // append the url as an argument only if it was not already set via %s
                cmd.arg(url);
            }
            if let Ok(output) = cmd.output() {
                return Ok(output);
            }
        }
    }
    return Err(Error::new(ErrorKind::NotFound, "No valid command in $BROWSER"));
}

#[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
compile_error!("Only Windows, Mac OS and Linux are currently supported");

#[test]
fn test_open_default() {
    assert!(open("http://github.com").is_ok());
}

#[test]
#[cfg(target_os = "macos")]
fn test_open_browser() {
    assert!(open_browser(Browser::Firefox, "http://github.com").is_ok());
}
<commit_msg>Remove commented code<commit_after>//! Open URLs in the web browsers available on a platform
//!
//! Inspired by the [webbrowser](https://docs.python.org/2/library/webbrowser.html) python library
//!
//! #Examples
//!
//! ```
//! use webbrowser;
//!
//! if webbrowser::open("http://github.com").is_ok() {
//!     // ...
//! }
//! ```
//!
//! Currently state of platform support is:
//!
//! * macos => default, as well as browsers listed under [Browser](enum.Browser.html)
//! * windows => default browser only
//! * linux => default browser only (uses $BROWSER env var, failing back to xdg-open, gvfs-open and
//! gnome-open, in that order)
//! * android => not supported right now
//! * ios => not supported right now
//!
//! Important note:
//!
//! * This library requires availability of browsers and a graphical environment during runtime
//! * `cargo test` will actually open the browser locally

use std::process::{Command, Output};
use std::io::{Result, Error, ErrorKind};
use std::env;

#[derive(Debug)]
/// Browser types available
pub enum Browser {
    Default,
    Firefox,
    InternetExplorer,
    Chrome,
    Opera,
    Safari
}

/// Opens the URL on the default browser of this platform
///
/// Returns Ok(..) so long as the browser invocation was successful. An Err(..) is returned only if
/// there was an error in running the command, or if the browser was not found
///
/// # Examples
/// ```
/// use webbrowser;
///
/// if webbrowser::open("http://github.com").is_ok() {
///     // ...
/// }
/// ```
pub fn open(url: &str) -> Result<Output> {
    open_browser(Browser::Default, url)
}

/// Opens the specified URL on the specific browser (if available) requested. Return semantics are
/// the same as for [open](fn.open.html)
///
/// # Examples
/// ```
/// use webbrowser::{open_browser, Browser};
///
/// if open_browser(Browser::Firefox, "http://github.com").is_ok() {
///     // ...
/// }
/// ```
pub fn open_browser(browser: Browser, url: &str) -> Result<Output> {
    open_browser_internal(browser, url)
}

/// Deal with opening of browsers on Windows, using `start` command
#[cfg(target_os = "windows")]
#[inline]
fn open_browser_internal(browser: Browser, url: &str) -> Result<Output> {
    match browser {
        Browser::Default => Command::new("cmd").arg("/C").arg("start").arg(url).output(),
        _ => Err(Error::new(
            ErrorKind::NotFound,
            "Only the default browser is supported on this platform right now"
        ))
    }
}

/// Deal with opening of browsers on Mac OS X, using `open` command
#[cfg(target_os = "macos")]
#[inline]
fn open_browser_internal(browser: Browser, url: &str) -> Result<Output> {
    let mut cmd = Command::new("open");
    match browser {
        Browser::Default => cmd.arg(url).output(),
        _ => {
            let app: Option<&str> = match browser {
                Browser::Firefox => Some("Firefox"),
                Browser::Chrome => Some("Google Chrome"),
                Browser::Opera => Some("Opera"),
                Browser::Safari => Some("Safari"),
                _ => None
            };
            match app {
                Some(name) => cmd.arg("-a").arg(name).arg(url).output(),
                None => Err(Error::new(ErrorKind::NotFound, format!("Unsupported browser {:?}", browser)))
            }
        }
    }
}

/// Deal with opening of browsers on Linux - currently supports only the default browser
///
/// The mechanism of opening the default browser is as follows:
/// 1. Attempt to use $BROWSER env var if available
/// 2. Attempt to open the url via xdg-open, gvfs-open, gnome-open, respectively, whichever works
///    first
#[cfg(target_os = "linux")]
#[inline]
fn open_browser_internal(browser: Browser, url: &str) -> Result<Output> {
    match browser {
        Browser::Default => open_on_linux_using_browser_env(url)
            .or_else(|_| -> Result<Output> {Command::new("xdg-open").arg(url).output()})
            .or_else(|_| -> Result<Output> {Command::new("gvfs-open").arg(url).output()})
            .or_else(|_| -> Result<Output> {Command::new("gnome-open").arg(url).output()}),
        _ => Err(Error::new(
                ErrorKind::NotFound,
                "Only the default browser is supported on this platform right now"
            ))
    }
}

/// Open on Linux using the $BROWSER env var
#[cfg(target_os = "linux")]
fn open_on_linux_using_browser_env(url: &str) -> Result<Output> {
    let browsers = try!(env::var("BROWSER").map_err(|_| -> Error {Error::new(ErrorKind::NotFound, format!("BROWSER env not set"))}));
    for browser in browsers.split(':') { // $BROWSER can contain ':' delimited options, each representing a potential browser command line
        if !browser.is_empty() {
            // each browser command can have %s to represent URL, while %c needs to be replaced
            // with ':' and %% with '%'
            let cmdline = browser.replace("%s", url).replace("%c", ":").replace("%%", "%");
            let cmdarr: Vec<&str> = cmdline.split_whitespace().collect();
            let mut cmd = Command::new(&cmdarr[0]);
            if cmdarr.len() > 1 {
                cmd.args(&cmdarr[1..cmdarr.len()]);
            }
            if !browser.contains("%s") {
                // append the url as an argument only if it was not already set via %s
                cmd.arg(url);
            }
            if let Ok(output) = cmd.output() {
                return Ok(output);
            }
        }
    }
    return Err(Error::new(ErrorKind::NotFound, "No valid command in $BROWSER"));
}

#[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
compile_error!("Only Windows, Mac OS and Linux are currently supported");

#[test]
fn test_open_default() {
    assert!(open("http://github.com").is_ok());
}

#[test]
#[cfg(target_os = "macos")]
fn test_open_browser() {
    assert!(open_browser(Browser::Firefox, "http://github.com").is_ok());
}
<|endoftext|>


<commit_before>#![feature(old_io)]

extern crate xml;

use xml::attribute::Attribute;
use xml::common::XmlVersion;
use xml::name::Name;
use xml::namespace::Namespace;
use xml::writer::EventWriter;
use xml::writer::events::XmlEvent;

fn add_block<'a>(events: &mut Vec<XmlEvent<'a>>, namespace: &'a Namespace, tag_name: &'static str, chars: &'a str) {
    // <(tag_name)>
    events.push(XmlEvent::StartElement {
        name: Name::local(tag_name),
        attributes: vec![],
        namespace: namespace,
    });

    events.push(XmlEvent::Characters(chars));

    // </(tag_name)>
    events.push(XmlEvent::EndElement {
        name: Name::local(tag_name),
    });
}

trait Write {
    fn write<W: Writer>(&self, writer: W) -> Result<(), ()>;
}

trait ToXml<'a> {
    // todo: get rid of namespace parameter
    fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent>;
}

/// RSS version 2.0
pub struct Rss<'a>(pub Vec<Channel<'a>>);

impl<'a> ToXml<'a> for Rss<'a> {
    fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent> {
        let mut events = vec![];

        // <?xml version="1.0" encoding="UTF-8"?>
        events.push(XmlEvent::StartDocument{
            version: XmlVersion::Version10,
            encoding: Some("UTF-8"),
            standalone: None,
        });

        // <rss version="2.0">
        events.push(XmlEvent::StartElement {
            name: Name::local("rss"),
            attributes: vec![
                Attribute::new(Name::local("version"), "2.0"),
            ],
            namespace: namespace,
        });

        let &Rss(ref channels) = self;
        for channel in channels {
            for event in channel.to_xml(namespace) {
                events.push(event);
            }
        }

        // </rss>
        events.push(XmlEvent::EndElement {
            name: Name::local("rss"),
        });

        events
    }
}

impl<'a> Write for Rss<'a> {
    fn write<W: Writer>(&self, writer: W) -> Result<(), ()> {
        let mut event_writer = EventWriter::new(writer);

        let namespace = Namespace::empty();
        let events = self.to_xml(&namespace);

        for event in events {
            event_writer.write(event);
        };

        Ok(())
    }
}

pub struct Channel<'a> {
    pub title: &'a str,
    pub link: &'a str,
    pub description: &'a str,
    pub items: Vec<Item<'a>>,
}

impl<'a> ToXml<'a> for Channel<'a> {
    fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent> {
        let mut events = vec![];

        // <channel>
        events.push(XmlEvent::StartElement {
            name: Name::local("channel"),
            attributes: vec![],
            namespace: namespace,
        });

        add_block(&mut events, namespace, "title", self.title);
        add_block(&mut events, namespace, "link", self.link);
        add_block(&mut events, namespace, "description", self.description);

        for item in &self.items {
            for event in item.to_xml(namespace) {
                events.push(event);
            }
        }

        // </channel>
        events.push(XmlEvent::EndElement {
            name: Name::local("channel"),
        });

        events
    }
}

pub struct Item<'a> {
    pub title: Option<&'a str>,
    pub link: Option<&'a str>,
    pub description: Option<&'a str>,
}

impl<'a> ToXml<'a> for Item<'a> {
    fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent> {
        let mut events = vec![];

        // <channel>
        events.push(XmlEvent::StartElement {
            name: Name::local("item"),
            attributes: vec![],
            namespace: namespace,
        });

        if let Some(s) = self.title {
            add_block(&mut events, namespace, "title", s);
        }

        if let Some(s) = self.link {
            add_block(&mut events, namespace, "link", s);
        }

        if let Some(s) = self.description {
            add_block(&mut events, namespace, "description", s);
        }

        // </channel>
        events.push(XmlEvent::EndElement {
            name: Name::local("item"),
        });

        events
    }
}

#[test]
fn test_consruct() {
    use std::old_io;

    let item = Item {
        title: Some("My first post!"),
        link: Some("http://myblog.com/post1"),
        description: Some("This is my first post"),
    };

    let channel = Channel {
        title: "My Blog",
        link: "http://myblog.com",
        description: "Where I write stuff",
        items: vec![item],
    };

    let rss = Rss(vec![channel]);
    rss.write(old_io::stdout());
}
<commit_msg>Fix inaccurate comment<commit_after>#![feature(old_io)]

extern crate xml;

use xml::attribute::Attribute;
use xml::common::XmlVersion;
use xml::name::Name;
use xml::namespace::Namespace;
use xml::writer::EventWriter;
use xml::writer::events::XmlEvent;

fn add_block<'a>(events: &mut Vec<XmlEvent<'a>>, namespace: &'a Namespace, tag_name: &'static str, chars: &'a str) {
    // <(tag_name)>
    events.push(XmlEvent::StartElement {
        name: Name::local(tag_name),
        attributes: vec![],
        namespace: namespace,
    });

    events.push(XmlEvent::Characters(chars));

    // </(tag_name)>
    events.push(XmlEvent::EndElement {
        name: Name::local(tag_name),
    });
}

trait Write {
    fn write<W: Writer>(&self, writer: W) -> Result<(), ()>;
}

trait ToXml<'a> {
    // todo: get rid of namespace parameter
    fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent>;
}

/// RSS version 2.0
pub struct Rss<'a>(pub Vec<Channel<'a>>);

impl<'a> ToXml<'a> for Rss<'a> {
    fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent> {
        let mut events = vec![];

        // <?xml version="1.0" encoding="UTF-8"?>
        events.push(XmlEvent::StartDocument{
            version: XmlVersion::Version10,
            encoding: Some("UTF-8"),
            standalone: None,
        });

        // <rss version="2.0">
        events.push(XmlEvent::StartElement {
            name: Name::local("rss"),
            attributes: vec![
                Attribute::new(Name::local("version"), "2.0"),
            ],
            namespace: namespace,
        });

        let &Rss(ref channels) = self;
        for channel in channels {
            for event in channel.to_xml(namespace) {
                events.push(event);
            }
        }

        // </rss>
        events.push(XmlEvent::EndElement {
            name: Name::local("rss"),
        });

        events
    }
}

impl<'a> Write for Rss<'a> {
    fn write<W: Writer>(&self, writer: W) -> Result<(), ()> {
        let mut event_writer = EventWriter::new(writer);

        let namespace = Namespace::empty();
        let events = self.to_xml(&namespace);

        for event in events {
            event_writer.write(event);
        };

        Ok(())
    }
}

pub struct Channel<'a> {
    pub title: &'a str,
    pub link: &'a str,
    pub description: &'a str,
    pub items: Vec<Item<'a>>,
}

impl<'a> ToXml<'a> for Channel<'a> {
    fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent> {
        let mut events = vec![];

        // <channel>
        events.push(XmlEvent::StartElement {
            name: Name::local("channel"),
            attributes: vec![],
            namespace: namespace,
        });

        add_block(&mut events, namespace, "title", self.title);
        add_block(&mut events, namespace, "link", self.link);
        add_block(&mut events, namespace, "description", self.description);

        for item in &self.items {
            for event in item.to_xml(namespace) {
                events.push(event);
            }
        }

        // </channel>
        events.push(XmlEvent::EndElement {
            name: Name::local("channel"),
        });

        events
    }
}

pub struct Item<'a> {
    pub title: Option<&'a str>,
    pub link: Option<&'a str>,
    pub description: Option<&'a str>,
}

impl<'a> ToXml<'a> for Item<'a> {
    fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent> {
        let mut events = vec![];

        // <item>
        events.push(XmlEvent::StartElement {
            name: Name::local("item"),
            attributes: vec![],
            namespace: namespace,
        });

        if let Some(s) = self.title {
            add_block(&mut events, namespace, "title", s);
        }

        if let Some(s) = self.link {
            add_block(&mut events, namespace, "link", s);
        }

        if let Some(s) = self.description {
            add_block(&mut events, namespace, "description", s);
        }

        // </item>
        events.push(XmlEvent::EndElement {
            name: Name::local("item"),
        });

        events
    }
}

#[test]
fn test_consruct() {
    use std::old_io;

    let item = Item {
        title: Some("My first post!"),
        link: Some("http://myblog.com/post1"),
        description: Some("This is my first post"),
    };

    let channel = Channel {
        title: "My Blog",
        link: "http://myblog.com",
        description: "Where I write stuff",
        items: vec![item],
    };

    let rss = Rss(vec![channel]);
    rss.write(old_io::stdout());
}
<|endoftext|>


<commit_before>#![allow(dead_code, unused_variables)]
use alloc::heap::{Heap, Alloc, Layout};
use bytes::BytesMut;

use std::rc::Rc;

use audiosample::*;
use pixel::*;
use timeinfo::*;

pub mod error {
    error_chain! {
        errors {
            InvalidIndex
            InvalidConversion
        }
    }
}

use self::error::*;

// TODO: Document
// TODO: Change it to provide Droppable/Seekable information or use a separate enum?
#[derive(Clone, Debug, PartialEq)]
pub enum PictureType {
    UNKNOWN,
    I,
    P,
    B,
    S,
    SI,
    SP,
    SB,
    BI,
}

#[derive(Clone, Debug, PartialEq)]
pub struct VideoInfo {
    pub pic_type: PictureType,
    pub width: usize,
    pub height: usize,
    pub format: Rc<Formaton>,
}

impl VideoInfo {
    fn size(&self, align: usize) -> usize {
        let mut size = 0;
        for &component in self.format.into_iter() {
            if let Some(c) = component {
                size += c.get_data_size(self.width, self.height, align);
            }
        }
        size
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct AudioInfo {
    pub samples: usize,
    pub rate: usize,
    pub map: ChannelMap,
    pub format: Rc<Soniton>,
}

impl AudioInfo {
    fn size(&self, align: usize) -> usize {
        self.format.get_audio_size(self.samples, align) * self.map.len()
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum MediaKind {
    Video(VideoInfo),
    Audio(AudioInfo),
}

use std::convert::From;

impl From<VideoInfo> for MediaKind {
    fn from(v: VideoInfo) -> Self {
        MediaKind::Video(v)
    }
}

impl From<AudioInfo> for MediaKind {
    fn from(a: AudioInfo) -> Self {
        MediaKind::Audio(a)
    }
}

use self::MediaKind::*;

pub trait FrameBufferSize {
    fn linesize(&self, idx: usize) -> Result<usize>;
    fn count(&self) -> usize;
}

pub trait FrameBufferSlice: FrameBufferSize {
    fn as_slice_inner<'a>(&'a self, idx: usize) -> Result<&'a [u8]>;
    fn as_mut_slice_inner<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8]>;
}

pub trait FrameBufferConv<T> : FrameBufferSlice {
    fn as_slice<'a>(&'a self, idx: usize) -> Result<&'a [T]> {
        let size = mem::size_of::<T>();
        if (self.linesize(idx)? % size) != 0 {
            Err(ErrorKind::InvalidConversion.into())
        } else {
            let s = self.as_slice_inner(idx)?;
            let r = unsafe {
                slice::from_raw_parts::<T>(mem::transmute(s.as_ptr()), s.len() / size)
            };

            Ok(r)
        }
    }
    fn as_mut_slice<'a>(&'a mut self, idx: usize) -> Result<&'a mut [T]> {
        let size = mem::size_of::<T>();
        if (self.linesize(idx)? % size) != 0 {
            Err(ErrorKind::InvalidConversion.into())
        } else {
            let s = self.as_mut_slice_inner(idx)?;
            let r = unsafe {
                slice::from_raw_parts_mut::<T>(mem::transmute(s.as_ptr()), s.len() / size)
            };

            Ok(r)
        }
    }
}

pub trait FrameBuffer : FrameBufferSize + FrameBufferConv<u8> + FrameBufferConv<i16> + FrameBufferConv<f32> {}

use std::fmt;

impl fmt::Debug for FrameBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "FrameBuffer")
    }
}

#[derive(Debug)]
pub struct Frame {
    pub kind: MediaKind,
    pub buf: Box<FrameBuffer>,
    pub t: Option<TimeInfo>,
}

const ALIGNMENT: usize = 32;

struct Plane {
    buf: BytesMut,
    linesize: usize,
}

struct DefaultFrameBuffer {
    buf: BytesMut,
    planes: Vec<Plane>,
}

impl FrameBufferSize for DefaultFrameBuffer {
    fn linesize(&self, idx: usize) -> Result<usize> {
        match self.planes.get(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(plane.linesize),
        }
    }
    fn count(&self) -> usize {
        self.planes.len()
    }
}

impl FrameBufferSlice for DefaultFrameBuffer {
    fn as_slice_inner<'a>(&'a self, idx: usize) -> Result<&'a [u8]> {
        match self.planes.get(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(&plane.buf),
        }
    }
    fn as_mut_slice_inner<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8]> {
        match self.planes.get_mut(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(&mut plane.buf),
        }
    }
}

impl FrameBufferConv<u8> for DefaultFrameBuffer {}
impl FrameBufferConv<i16> for DefaultFrameBuffer {}
impl FrameBufferConv<f32> for DefaultFrameBuffer {}
impl FrameBuffer for DefaultFrameBuffer {}

impl DefaultFrameBuffer {
    pub fn new<'a>(kind: &'a MediaKind) -> DefaultFrameBuffer {
        match kind {
            &Video(ref video) => {
                let size = video.size(ALIGNMENT);
                let data = unsafe {
                    Heap.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap())
                        .unwrap()
                };
                //let data = unsafe { Heap.alloc_zeroed(Layout::from_size_align(size, ALIGNMENT)) };
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for &component in video.format.iter() {
                    if let Some(c) = component {
                        let planesize = c.get_data_size(video.width, video.height, ALIGNMENT);
                        let linesize = c.get_linesize(video.width, ALIGNMENT);
                        buffer.planes.push(Plane {
                            buf: buffer.buf.split_to(planesize),
                            linesize: linesize,
                        });
                    }
                }
                buffer
            },
            &Audio(ref audio) => {
                let size = audio.size(ALIGNMENT);
                let data = unsafe {
                    Heap.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap())
                        .unwrap()
                };
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for _ in 0..audio.map.len() {
                    let size = audio.format.get_audio_size(audio.samples, ALIGNMENT);
                    buffer.planes.push(Plane {
                        buf: buffer.buf.split_to(size),
                        linesize: size,
                    });
                }
                buffer
            },
        }
    }
}

pub fn new_default_frame<T>(kind: T, t: Option<TimeInfo>) -> Frame
where T: Into<MediaKind> + Clone
{
    let k = kind.into();
    let buf = DefaultFrameBuffer::new(&k);

    Frame {
        kind: k,
        buf: box buf,
        t: t,
    }
}

use std::ptr::copy_nonoverlapping;

fn copy_plane(
    dst: &mut [u8],
    dst_linesize: usize,
    src: &[u8],
    src_linesize: usize,
    w: usize,
    h: usize,
) {
    let dst_chunks = dst.chunks_mut(dst_linesize);
    let src_chunks = src.chunks(src_linesize);

    for (d, s) in dst_chunks.zip(src_chunks).take(h) {
        unsafe {
            copy_nonoverlapping(s.as_ptr(), d.as_mut_ptr(), w);
        }
    }
}

fn copy_image<'a, IM, IU, I>(
    dst: IM,
    dst_linesizes: IU,
    src: I,
    src_linesizes: IU,
    w: usize,
    h: usize,
    fmt: &Formaton,
) where
    IM: Iterator<Item = &'a mut [u8]>,
    I: Iterator<Item = &'a [u8]>,
    IU: Iterator<Item = usize>,
{
    let dst_iter = dst.zip(dst_linesizes);
    let src_iter = src.zip(src_linesizes);
    let iter = dst_iter.zip(src_iter).zip(fmt.iter());

    for (((d, d_linesize), (s, s_linesize)), c) in iter {
        copy_plane(
            d,
            d_linesize,
            s,
            s_linesize,
            c.unwrap().get_width(w),
            c.unwrap().get_height(h),
        );
    }
}

// TODO: Add proper tests
fn copy_to_frame<'a, I, IU>(dst: &mut Frame, mut src: I, mut src_linesize: IU, w: usize, h: usize)
where
    I: Iterator<Item = &'a [u8]>,
    IU: Iterator<Item = usize>,
{
    if let MediaKind::Video(ref fmt) = dst.kind {
        let mut f_iter = fmt.format.iter();
        let w = fmt.width;
        let h = fmt.height;
        for i in 0..dst.buf.count() {
            let d_linesize = dst.buf.linesize(i).unwrap();
            let s_linesize = src_linesize.next().unwrap();
            let d = dst.buf.as_mut_slice(i).unwrap();
            let s = src.next().unwrap();
            let c = f_iter.next().unwrap();
            copy_plane(
                d,
                d_linesize,
                s,
                s_linesize,
                c.unwrap().get_width(w),
                c.unwrap().get_height(h),
            );
        }
    } else {
        unimplemented!();
    }
}

use std::mem;
use std::slice;

// TODO make it a separate trait
impl Frame {
    pub fn copy_from_slice<'a, I, IU>(&mut self, mut src: I, mut src_linesize: IU)
    where
        I: Iterator<Item = &'a [u8]>,
        IU: Iterator<Item = usize>,
    {
        if let MediaKind::Video(ref fmt) = self.kind {
            let mut f_iter = fmt.format.iter();
            let w = fmt.width;
            let h = fmt.height;
            for i in 0..self.buf.count() {
                let d_linesize = self.buf.linesize(i).unwrap();
                let s_linesize = src_linesize.next().unwrap();
                let d = self.buf.as_mut_slice(i).unwrap();
                let s = src.next().unwrap();
                let c = f_iter.next().unwrap();
                copy_plane(
                    d,
                    d_linesize,
                    s,
                    s_linesize,
                    c.unwrap().get_width(w),
                    c.unwrap().get_height(h),
                );
            }
        } else {
            unimplemented!();
        }
    }

    pub fn copy_from_raw_parts<'a, I, IU>(&mut self, mut src: I, mut src_linesize: IU)
    where
        I: Iterator<Item = *const u8>,
        IU: Iterator<Item = usize>,
    {
        if let MediaKind::Video(ref fmt) = self.kind {
            let mut f_iter = fmt.format.iter();
            let w = fmt.width;
            let h = fmt.height;
            for i in 0..self.buf.count() {
                let d_linesize = self.buf.linesize(i).unwrap();
                let s_linesize = src_linesize.next().unwrap();
                let d = self.buf.as_mut_slice(i).unwrap();
                let c = f_iter.next().unwrap();
                let r = src.next().unwrap();
                let hb = c.unwrap().get_height(h);
                let s = unsafe { slice::from_raw_parts(r, hb * s_linesize) };
                copy_plane(d, d_linesize, s, s_linesize, c.unwrap().get_width(w), hb);
                mem::forget(s);
            }
        } else {
            unimplemented!();
        }
    }
}
<commit_msg>Simplify the FrameBuffer traits further<commit_after>#![allow(dead_code, unused_variables)]
use alloc::heap::{Heap, Alloc, Layout};
use bytes::BytesMut;

use std::rc::Rc;

use audiosample::*;
use pixel::*;
use timeinfo::*;

pub mod error {
    error_chain! {
        errors {
            InvalidIndex
            InvalidConversion
        }
    }
}

use self::error::*;

// TODO: Document
// TODO: Change it to provide Droppable/Seekable information or use a separate enum?
#[derive(Clone, Debug, PartialEq)]
pub enum PictureType {
    UNKNOWN,
    I,
    P,
    B,
    S,
    SI,
    SP,
    SB,
    BI,
}

#[derive(Clone, Debug, PartialEq)]
pub struct VideoInfo {
    pub pic_type: PictureType,
    pub width: usize,
    pub height: usize,
    pub format: Rc<Formaton>,
}

impl VideoInfo {
    fn size(&self, align: usize) -> usize {
        let mut size = 0;
        for &component in self.format.into_iter() {
            if let Some(c) = component {
                size += c.get_data_size(self.width, self.height, align);
            }
        }
        size
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct AudioInfo {
    pub samples: usize,
    pub rate: usize,
    pub map: ChannelMap,
    pub format: Rc<Soniton>,
}

impl AudioInfo {
    fn size(&self, align: usize) -> usize {
        self.format.get_audio_size(self.samples, align) * self.map.len()
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum MediaKind {
    Video(VideoInfo),
    Audio(AudioInfo),
}

use std::convert::From;

impl From<VideoInfo> for MediaKind {
    fn from(v: VideoInfo) -> Self {
        MediaKind::Video(v)
    }
}

impl From<AudioInfo> for MediaKind {
    fn from(a: AudioInfo) -> Self {
        MediaKind::Audio(a)
    }
}

use self::MediaKind::*;

pub trait FrameBuffer {
    fn linesize(&self, idx: usize) -> Result<usize>;
    fn count(&self) -> usize;
    fn as_slice_inner<'a>(&'a self, idx: usize) -> Result<&'a [u8]>;
    fn as_mut_slice_inner<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8]>;
}

pub trait FrameBufferConv<T> : FrameBuffer {
    fn as_slice<'a>(&'a self, idx: usize) -> Result<&'a [T]> {
        let size = mem::size_of::<T>();
        if (self.linesize(idx)? % size) != 0 {
            Err(ErrorKind::InvalidConversion.into())
        } else {
            let s = self.as_slice_inner(idx)?;
            let r = unsafe {
                slice::from_raw_parts::<T>(mem::transmute(s.as_ptr()), s.len() / size)
            };

            Ok(r)
        }
    }
    fn as_mut_slice<'a>(&'a mut self, idx: usize) -> Result<&'a mut [T]> {
        let size = mem::size_of::<T>();
        if (self.linesize(idx)? % size) != 0 {
            Err(ErrorKind::InvalidConversion.into())
        } else {
            let s = self.as_mut_slice_inner(idx)?;
            let r = unsafe {
                slice::from_raw_parts_mut::<T>(mem::transmute(s.as_ptr()), s.len() / size)
            };

            Ok(r)
        }
    }
}

impl FrameBufferConv<u8> for FrameBuffer {}
impl FrameBufferConv<i16> for FrameBuffer {}
impl FrameBufferConv<f32> for FrameBuffer {}

use std::fmt;

impl fmt::Debug for FrameBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "FrameBuffer")
    }
}

#[derive(Debug)]
pub struct Frame {
    pub kind: MediaKind,
    pub buf: Box<FrameBuffer>,
    pub t: Option<TimeInfo>,
}

const ALIGNMENT: usize = 32;

struct Plane {
    buf: BytesMut,
    linesize: usize,
}

struct DefaultFrameBuffer {
    buf: BytesMut,
    planes: Vec<Plane>,
}

impl FrameBuffer for DefaultFrameBuffer {
    fn linesize(&self, idx: usize) -> Result<usize> {
        match self.planes.get(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(plane.linesize),
        }
    }
    fn count(&self) -> usize {
        self.planes.len()
    }

    fn as_slice_inner<'a>(&'a self, idx: usize) -> Result<&'a [u8]> {
        match self.planes.get(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(&plane.buf),
        }
    }
    fn as_mut_slice_inner<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8]> {
        match self.planes.get_mut(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(&mut plane.buf),
        }
    }
}

impl DefaultFrameBuffer {
    pub fn new<'a>(kind: &'a MediaKind) -> DefaultFrameBuffer {
        match kind {
            &Video(ref video) => {
                let size = video.size(ALIGNMENT);
                let data = unsafe {
                    Heap.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap())
                        .unwrap()
                };
                //let data = unsafe { Heap.alloc_zeroed(Layout::from_size_align(size, ALIGNMENT)) };
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for &component in video.format.iter() {
                    if let Some(c) = component {
                        let planesize = c.get_data_size(video.width, video.height, ALIGNMENT);
                        let linesize = c.get_linesize(video.width, ALIGNMENT);
                        buffer.planes.push(Plane {
                            buf: buffer.buf.split_to(planesize),
                            linesize: linesize,
                        });
                    }
                }
                buffer
            },
            &Audio(ref audio) => {
                let size = audio.size(ALIGNMENT);
                let data = unsafe {
                    Heap.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap())
                        .unwrap()
                };
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for _ in 0..audio.map.len() {
                    let size = audio.format.get_audio_size(audio.samples, ALIGNMENT);
                    buffer.planes.push(Plane {
                        buf: buffer.buf.split_to(size),
                        linesize: size,
                    });
                }
                buffer
            },
        }
    }
}

pub fn new_default_frame<T>(kind: T, t: Option<TimeInfo>) -> Frame
where T: Into<MediaKind> + Clone
{
    let k = kind.into();
    let buf = DefaultFrameBuffer::new(&k);

    Frame {
        kind: k,
        buf: box buf,
        t: t,
    }
}

use std::ptr::copy_nonoverlapping;

fn copy_plane(
    dst: &mut [u8],
    dst_linesize: usize,
    src: &[u8],
    src_linesize: usize,
    w: usize,
    h: usize,
) {
    let dst_chunks = dst.chunks_mut(dst_linesize);
    let src_chunks = src.chunks(src_linesize);

    for (d, s) in dst_chunks.zip(src_chunks).take(h) {
        unsafe {
            copy_nonoverlapping(s.as_ptr(), d.as_mut_ptr(), w);
        }
    }
}

fn copy_image<'a, IM, IU, I>(
    dst: IM,
    dst_linesizes: IU,
    src: I,
    src_linesizes: IU,
    w: usize,
    h: usize,
    fmt: &Formaton,
) where
    IM: Iterator<Item = &'a mut [u8]>,
    I: Iterator<Item = &'a [u8]>,
    IU: Iterator<Item = usize>,
{
    let dst_iter = dst.zip(dst_linesizes);
    let src_iter = src.zip(src_linesizes);
    let iter = dst_iter.zip(src_iter).zip(fmt.iter());

    for (((d, d_linesize), (s, s_linesize)), c) in iter {
        copy_plane(
            d,
            d_linesize,
            s,
            s_linesize,
            c.unwrap().get_width(w),
            c.unwrap().get_height(h),
        );
    }
}

// TODO: Add proper tests
fn copy_to_frame<'a, I, IU>(dst: &mut Frame, mut src: I, mut src_linesize: IU, w: usize, h: usize)
where
    I: Iterator<Item = &'a [u8]>,
    IU: Iterator<Item = usize>,
{
    if let MediaKind::Video(ref fmt) = dst.kind {
        let mut f_iter = fmt.format.iter();
        let w = fmt.width;
        let h = fmt.height;
        for i in 0..dst.buf.count() {
            let d_linesize = dst.buf.linesize(i).unwrap();
            let s_linesize = src_linesize.next().unwrap();
            let d = dst.buf.as_mut_slice(i).unwrap();
            let s = src.next().unwrap();
            let c = f_iter.next().unwrap();
            copy_plane(
                d,
                d_linesize,
                s,
                s_linesize,
                c.unwrap().get_width(w),
                c.unwrap().get_height(h),
            );
        }
    } else {
        unimplemented!();
    }
}

use std::mem;
use std::slice;

// TODO make it a separate trait
impl Frame {
    pub fn copy_from_slice<'a, I, IU>(&mut self, mut src: I, mut src_linesize: IU)
    where
        I: Iterator<Item = &'a [u8]>,
        IU: Iterator<Item = usize>,
    {
        if let MediaKind::Video(ref fmt) = self.kind {
            let mut f_iter = fmt.format.iter();
            let w = fmt.width;
            let h = fmt.height;
            for i in 0..self.buf.count() {
                let d_linesize = self.buf.linesize(i).unwrap();
                let s_linesize = src_linesize.next().unwrap();
                let d = self.buf.as_mut_slice(i).unwrap();
                let s = src.next().unwrap();
                let c = f_iter.next().unwrap();
                copy_plane(
                    d,
                    d_linesize,
                    s,
                    s_linesize,
                    c.unwrap().get_width(w),
                    c.unwrap().get_height(h),
                );
            }
        } else {
            unimplemented!();
        }
    }

    pub fn copy_from_raw_parts<'a, I, IU>(&mut self, mut src: I, mut src_linesize: IU)
    where
        I: Iterator<Item = *const u8>,
        IU: Iterator<Item = usize>,
    {
        if let MediaKind::Video(ref fmt) = self.kind {
            let mut f_iter = fmt.format.iter();
            let w = fmt.width;
            let h = fmt.height;
            for i in 0..self.buf.count() {
                let d_linesize = self.buf.linesize(i).unwrap();
                let s_linesize = src_linesize.next().unwrap();
                let d = self.buf.as_mut_slice(i).unwrap();
                let c = f_iter.next().unwrap();
                let r = src.next().unwrap();
                let hb = c.unwrap().get_height(h);
                let s = unsafe { slice::from_raw_parts(r, hb * s_linesize) };
                copy_plane(d, d_linesize, s, s_linesize, c.unwrap().get_width(w), hb);
                mem::forget(s);
            }
        } else {
            unimplemented!();
        }
    }
}
<|endoftext|>


<commit_before>use serde_json::{Value, from_str};
use serde_json::error::Result as R;
use serde_json::Serializer;
use serde::ser::Serialize;
use serde::ser::Serializer as Ser;

use std::collections::HashMap;
use std::io::stdout;

use super::super::parser::{FileHeaderParser, ParserError};
use super::super::file::{FileHeaderSpec, FileHeaderData};

pub struct JsonHeaderParser {
    spec: Option<FileHeaderSpec>,
}

impl JsonHeaderParser {

    pub fn new(spec: Option<FileHeaderSpec>) -> JsonHeaderParser {
        JsonHeaderParser {
            spec: spec
        }
    }

}

impl FileHeaderParser for JsonHeaderParser {

    fn read(&self, string: Option<String>)
        -> Result<FileHeaderData, ParserError>
    {
        if string.is_some() {
            let s = string.unwrap();
            debug!("Deserializing: {}", s);
            let fromstr : R<Value> = from_str(&s[..]);
            if let Ok(content) = fromstr {
                Ok(visit_json(&content))
            } else {
                Err(ParserError::short("Unknown JSON parser error", s.clone(), 0))
            }
        } else {
            Ok(FileHeaderData::Null)
        }
    }

    fn write(&self, data: &FileHeaderData) -> Result<String, ParserError> {
        let mut s = Vec::<u8>::new();
        {
            let mut ser = Serializer::pretty(&mut s);
            data.serialize(&mut ser);
        }

        String::from_utf8(s).or(
            Err(ParserError::short("Cannot parse utf8 bytes",
                                   String::from("<not printable>"),
                                   0)))
    }

}

// TODO: This function must be able to return a parser error
fn visit_json(v: &Value) -> FileHeaderData {
    match v {
        &Value::Null             => FileHeaderData::Null,
        &Value::Bool(b)          => FileHeaderData::Bool(b),
        &Value::I64(i)           => FileHeaderData::Integer(i),
        &Value::U64(u)           => FileHeaderData::UInteger(u),
        &Value::F64(f)           => FileHeaderData::Float(f),
        &Value::String(ref s)        => FileHeaderData::Text(s.clone()),
        &Value::Array(ref vec)       => {
            FileHeaderData::Array {
                values: Box::new(vec.clone().into_iter().map(|i| visit_json(&i)).collect())
            }
        },
        &Value::Object(ref btree)    => {
            let btree = btree.clone();
            FileHeaderData::Map{
                keys: btree.into_iter().map(|(k, v)|
                    FileHeaderData::Key {
                        name: k,
                        value: Box::new(visit_json(&v)),
                    }
                ).collect()
            }
        }
    }
}

impl Serialize for FileHeaderData {

    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Ser
    {
        match self {
            &FileHeaderData::Null               => {
                let o : Option<bool> = None;
                o.serialize(ser)
            },
            &FileHeaderData::Bool(ref b)            => b.serialize(ser),
            &FileHeaderData::Integer(ref i)         => i.serialize(ser),
            &FileHeaderData::UInteger(ref u)        => u.serialize(ser),
            &FileHeaderData::Float(ref f)           => f.serialize(ser),
            &FileHeaderData::Text(ref s)            => (&s[..]).serialize(ser),
            &FileHeaderData::Array{values: ref vs}  => vs.serialize(ser),
            &FileHeaderData::Map{keys: ref ks}      => {
                let mut hm = HashMap::new();

                for key in ks {
                    if let &FileHeaderData::Key{name: ref n, value: ref v} = key {
                        hm.insert(n, v);
                    } else {
                        panic!("Not a key: {:?}", key);
                    }
                }

                hm.serialize(ser)
            },
            &FileHeaderData::Key{name: ref n, value: ref v} => unreachable!(),

        }
    }

}
<commit_msg>Add test for deserialization<commit_after>use serde_json::{Value, from_str};
use serde_json::error::Result as R;
use serde_json::Serializer;
use serde::ser::Serialize;
use serde::ser::Serializer as Ser;

use std::collections::HashMap;
use std::io::stdout;
use std::error::Error;

use super::super::parser::{FileHeaderParser, ParserError};
use super::super::file::{FileHeaderSpec, FileHeaderData};

pub struct JsonHeaderParser {
    spec: Option<FileHeaderSpec>,
}

impl JsonHeaderParser {

    pub fn new(spec: Option<FileHeaderSpec>) -> JsonHeaderParser {
        JsonHeaderParser {
            spec: spec
        }
    }

}

impl FileHeaderParser for JsonHeaderParser {

    fn read(&self, string: Option<String>)
        -> Result<FileHeaderData, ParserError>
    {
        if string.is_some() {
            let s = string.unwrap();
            debug!("Deserializing: {}", s);
            let fromstr : R<Value> = from_str(&s[..]);
            if let Ok(ref content) = fromstr {
                return Ok(visit_json(&content))
            }
            let oe = fromstr.err().unwrap();
            let s = format!("JSON parser error: {}", oe.description());
            let e = ParserError::short(&s[..], s.clone(), 0);
            Err(e)
        } else {
            Ok(FileHeaderData::Null)
        }
    }

    fn write(&self, data: &FileHeaderData) -> Result<String, ParserError> {
        let mut s = Vec::<u8>::new();
        {
            let mut ser = Serializer::pretty(&mut s);
            data.serialize(&mut ser);
        }

        String::from_utf8(s).or(
            Err(ParserError::short("Cannot parse utf8 bytes",
                                   String::from("<not printable>"),
                                   0)))
    }

}

// TODO: This function must be able to return a parser error
fn visit_json(v: &Value) -> FileHeaderData {
    match v {
        &Value::Null             => FileHeaderData::Null,
        &Value::Bool(b)          => FileHeaderData::Bool(b),
        &Value::I64(i)           => FileHeaderData::Integer(i),
        &Value::U64(u)           => FileHeaderData::UInteger(u),
        &Value::F64(f)           => FileHeaderData::Float(f),
        &Value::String(ref s)        => FileHeaderData::Text(s.clone()),
        &Value::Array(ref vec)       => {
            FileHeaderData::Array {
                values: Box::new(vec.clone().into_iter().map(|i| visit_json(&i)).collect())
            }
        },
        &Value::Object(ref btree)    => {
            let btree = btree.clone();
            FileHeaderData::Map{
                keys: btree.into_iter().map(|(k, v)|
                    FileHeaderData::Key {
                        name: k,
                        value: Box::new(visit_json(&v)),
                    }
                ).collect()
            }
        }
    }
}

impl Serialize for FileHeaderData {

    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Ser
    {
        match self {
            &FileHeaderData::Null               => {
                let o : Option<bool> = None;
                o.serialize(ser)
            },
            &FileHeaderData::Bool(ref b)            => b.serialize(ser),
            &FileHeaderData::Integer(ref i)         => i.serialize(ser),
            &FileHeaderData::UInteger(ref u)        => u.serialize(ser),
            &FileHeaderData::Float(ref f)           => f.serialize(ser),
            &FileHeaderData::Text(ref s)            => (&s[..]).serialize(ser),
            &FileHeaderData::Array{values: ref vs}  => vs.serialize(ser),
            &FileHeaderData::Map{keys: ref ks}      => {
                let mut hm = HashMap::new();

                for key in ks {
                    if let &FileHeaderData::Key{name: ref n, value: ref v} = key {
                        hm.insert(n, v);
                    } else {
                        panic!("Not a key: {:?}", key);
                    }
                }

                hm.serialize(ser)
            },
            &FileHeaderData::Key{name: ref n, value: ref v} => unreachable!(),

        }
    }

}

#[cfg(test)]
mod test {

    use super::JsonHeaderParser;
    use storage::parser::{FileHeaderParser, ParserError};
    use storage::file::{FileHeaderSpec, FileHeaderData};

    #[test]
    fn test_deserialization() {
        use storage::file::FileHeaderData as FHD;
        use storage::file::FileHeaderSpec as FHS;

        let text = String::from("{\"a\": 1, \"b\": -2}");
        let spec = FHS::Map {
            keys: vec![
                FHS::Key {
                    name: String::from("a"),
                    value_type: Box::new(FHS::UInteger)
                },
                FHS::Key {
                    name: String::from("b"),
                    value_type: Box::new(FHS::Integer)
                }
            ]
        };

        let parser = JsonHeaderParser::new(Some(spec));
        let parsed = parser.read(Some(text));
        assert!(parsed.is_ok(), "Parsed is not ok: {:?}", parsed);

        match parsed.ok() {
            Some(FHD::Map{keys: keys}) => {
                for k in keys {
                    match k {
                        FHD::Key{name: name, value: box value} => {
                            assert!(name == "a" || name == "b", "Key unknown");
                            match &value {
                                &FHD::UInteger(u) => assert_eq!(u, 1),
                                &FHD::Integer(i) => assert_eq!(i, -2),
                                _ => assert!(false, "Integers are not here"),
                            }
                        },
                        _ => assert!(false, "Key is not a Key"),
                    }
                }
            },

            _ => assert!(false, "Parsed is not a map"),
        }
    }

}
<|endoftext|>


<commit_before>extern crate eve;

use std::env;
use eve::authenticate::*;
use std::fs::OpenOptions;

#[allow(dead_code)]
fn main() {

	for argument in env::args() {
    	match &*argument {
    		"clean" => {
    			OpenOptions::new().create(true).truncate(true).open("./events").unwrap();
    			()
    		},
    		_ => continue,
    	}
	}

    run()
}<commit_msg>Removed some copied code<commit_after>extern crate eve;

use eve::authenticate::*;

#[allow(dead_code)]
fn main() {

    run()
}<|endoftext|>