<commit_before>// Copyright 2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use bincode::serde::DeserializeError;
use std::sync::mpsc;
use std::sync::{Arc, Mutex};
use std::collections::hash_map::HashMap;
use std::cell::{RefCell};
use std::io::{Error, ErrorKind};
use std::slice;
use std::fmt::{self, Debug, Formatter};
use std::cmp::{PartialEq};
use std::ops::Deref;
use std::mem;
use std::usize;

use uuid::Uuid;

struct ServerRecord {
    sender: OsIpcSender,
    conn_sender: mpsc::Sender<bool>,
    conn_receiver: Mutex<mpsc::Receiver<bool>>,
}

impl ServerRecord {
    fn new(sender: OsIpcSender) -> ServerRecord {
        let (tx, rx) = mpsc::channel::<bool>();
        ServerRecord {
            sender: sender,
            conn_sender: tx,
            conn_receiver: Mutex::new(rx),
        }
    }

    fn accept(&self) {
        self.conn_receiver.lock().unwrap().recv().unwrap();
    }

    fn connect(&self) {
        self.conn_sender.send(true).unwrap();
    }
}

lazy_static! {
    static ref ONE_SHOT_SERVERS: Mutex<HashMap<String,ServerRecord>> = Mutex::new(HashMap::new());
}

struct MpscChannelMessage(Vec<u8>, Vec<OsIpcChannel>, Vec<OsIpcSharedMemory>);

pub fn channel() -> Result<(OsIpcSender, OsIpcReceiver),MpscError> {
    let (base_sender, base_receiver) = mpsc::channel::<MpscChannelMessage>();
    Ok((OsIpcSender::new(base_sender), OsIpcReceiver::new(base_receiver)))
}

pub struct OsIpcReceiver {
    receiver: Arc<Mutex<Option<mpsc::Receiver<MpscChannelMessage>>>>,
}

impl PartialEq for OsIpcReceiver {
    fn eq(&self, other: &OsIpcReceiver) -> bool {
        self.receiver.lock().unwrap().as_ref().map(|rx| rx as *const _) ==
            other.receiver.lock().unwrap().as_ref().map(|rx| rx as *const _)
    }
}

// Can't derive, as mpsc::Receiver doesn't implement Debug.
impl fmt::Debug for OsIpcReceiver {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Not sure there is anything useful we could print here.
        write!(f, "OsIpcReceiver {{ .. }}")
    }
}

impl OsIpcReceiver {
    fn new(receiver: mpsc::Receiver<MpscChannelMessage>) -> OsIpcReceiver {
        OsIpcReceiver {
            receiver: Arc::new(Mutex::new(Some(receiver))),
        }
    }

    pub fn consume(&self) -> OsIpcReceiver {
        let receiver = self.receiver.lock().unwrap().take();
        OsIpcReceiver::new(receiver.unwrap())
    }

    pub fn recv(&self) -> Result<(Vec<u8>, Vec<OsOpaqueIpcChannel>, Vec<OsIpcSharedMemory>),MpscError> {
        let r = self.receiver.lock().unwrap();
        match r.as_ref().unwrap().recv() {
            Ok(MpscChannelMessage(d,c,s)) => Ok((d,
                                                 c.into_iter().map(OsOpaqueIpcChannel::new).collect(),
                                                 s)),
            Err(_) => Err(MpscError::ChannelClosedError),
        }
    }

    pub fn try_recv(&self) -> Result<(Vec<u8>, Vec<OsOpaqueIpcChannel>, Vec<OsIpcSharedMemory>),MpscError> {
        let r = self.receiver.lock().unwrap();
        match r.as_ref().unwrap().try_recv() {
            Ok(MpscChannelMessage(d,c,s)) => Ok((d,
                                                 c.into_iter().map(OsOpaqueIpcChannel::new).collect(),
                                                 s)),
            Err(_) => Err(MpscError::ChannelClosedError),
        }
    }
}

#[derive(Clone)]
pub struct OsIpcSender {
    sender: Arc<Mutex<mpsc::Sender<MpscChannelMessage>>>,
}

impl PartialEq for OsIpcSender {
    fn eq(&self, other: &OsIpcSender) -> bool {
        &*self.sender.lock().unwrap() as *const _ ==
            &*other.sender.lock().unwrap() as *const _
    }
}

// Can't derive, as mpsc::Sender doesn't implement Debug.
impl fmt::Debug for OsIpcSender {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Not sure there is anything useful we could print here.
        write!(f, "OsIpcSender {{ .. }}")
    }
}

impl OsIpcSender {
    fn new(sender: mpsc::Sender<MpscChannelMessage>) -> OsIpcSender {
        OsIpcSender {
            sender: Arc::new(Mutex::new(sender)),
        }
    }

    pub fn connect(name: String) -> Result<OsIpcSender,MpscError> {
        let record = ONE_SHOT_SERVERS.lock().unwrap().remove(&name).unwrap();
        record.connect();
        Ok(record.sender)
    }

    pub fn get_max_fragment_size() -> usize {
        usize::MAX
    }

    pub fn send(&self,
                data: &[u8],
                ports: Vec<OsIpcChannel>,
                shared_memory_regions: Vec<OsIpcSharedMemory>)
                -> Result<(),MpscError>
    {
        match self.sender.lock().unwrap().send(MpscChannelMessage(data.to_vec(), ports, shared_memory_regions)) {
            Err(_) => Err(MpscError::ChannelClosedError),
            Ok(_) => Ok(()),
        }
    }
}

pub struct OsIpcReceiverSet {
    last_index: usize,
    receiver_ids: Vec<usize>,
    receivers: Vec<OsIpcReceiver>,
}

impl OsIpcReceiverSet {
    pub fn new() -> Result<OsIpcReceiverSet,MpscError> {
        Ok(OsIpcReceiverSet {
            last_index: 0,
            receiver_ids: vec![],
            receivers: vec![],
        })
    }

    pub fn add(&mut self, receiver: OsIpcReceiver) -> Result<i64,MpscError> {
        self.last_index += 1;
        self.receiver_ids.push(self.last_index);
        self.receivers.push(receiver.consume());
        Ok(self.last_index as i64)
    }

    pub fn select(&mut self) -> Result<Vec<OsIpcSelectionResult>,MpscError> {
        let mut receivers: Vec<Option<mpsc::Receiver<MpscChannelMessage>>> = Vec::with_capacity(self.receivers.len());
        let mut r_id: i64 = -1;
        let mut r_index: usize = 0;

        {
            let select = mpsc::Select::new();
            // we *must* allocate exact capacity for this, because the Handles *can't move*
            let mut handles: Vec<mpsc::Handle<MpscChannelMessage>> = Vec::with_capacity(self.receivers.len());

            for r in &self.receivers {
                let inner_r = mem::replace(&mut *r.receiver.lock().unwrap(), None);
                receivers.push(inner_r);
            }

            for r in &receivers {
                unsafe {
                    handles.push(select.handle(r.as_ref().unwrap()));
                    handles.last_mut().unwrap().add();
                }
            }

            let id = select.wait();

            for (index,h) in handles.iter().enumerate() {
                if h.id() == id {
                    r_index = index;
                    r_id = self.receiver_ids[index] as i64;
                    break;
                }
            }
        }

        // put the receivers back
        for (index,r) in self.receivers.iter().enumerate() {
            mem::replace(&mut *r.receiver.lock().unwrap(), mem::replace(&mut receivers[index], None));
        }

        if r_id == -1 {
            return Err(MpscError::UnknownError);
        }

        let receivers = &mut self.receivers;
        match receivers[r_index].recv() {
            Ok((data, channels, shmems)) =>
                Ok(vec![OsIpcSelectionResult::DataReceived(r_id, data, channels, shmems)]),
            Err(MpscError::ChannelClosedError) => {
                receivers.remove(r_index);
                self.receiver_ids.remove(r_index);
                Ok(vec![OsIpcSelectionResult::ChannelClosed(r_id)])
            },
            Err(err) => Err(err),
        }
    }
}

pub enum OsIpcSelectionResult {
    DataReceived(i64, Vec<u8>, Vec<OsOpaqueIpcChannel>, Vec<OsIpcSharedMemory>),
    ChannelClosed(i64),
}

impl OsIpcSelectionResult {
    pub fn unwrap(self) -> (i64, Vec<u8>, Vec<OsOpaqueIpcChannel>, Vec<OsIpcSharedMemory>) {
        match self {
            OsIpcSelectionResult::DataReceived(id, data, channels, shared_memory_regions) => {
                (id, data, channels, shared_memory_regions)
            }
            OsIpcSelectionResult::ChannelClosed(id) => {
                panic!("OsIpcSelectionResult::unwrap(): receiver ID {} was closed!", id)
            }
        }
    }
}

pub struct OsIpcOneShotServer {
    receiver: RefCell<Option<OsIpcReceiver>>,
    name: String,
}

impl OsIpcOneShotServer {
    pub fn new() -> Result<(OsIpcOneShotServer, String),MpscError> {
        let (sender, receiver) = match channel() {
            Ok((s,r)) => (s,r),
            Err(err) => return Err(err),
        };

        let name = Uuid::new_v4().to_string();
        let record = ServerRecord::new(sender);
        ONE_SHOT_SERVERS.lock().unwrap().insert(name.clone(), record);
        Ok((OsIpcOneShotServer {
            receiver: RefCell::new(Some(receiver)),
            name: name.clone(),
        },name.clone()))
    }

    pub fn accept(&self) -> Result<(OsIpcReceiver,
                                    Vec<u8>,
                                    Vec<OsOpaqueIpcChannel>,
                                    Vec<OsIpcSharedMemory>),MpscError>
    {
        ONE_SHOT_SERVERS.lock().unwrap().get(&self.name).unwrap().accept();
        let receiver = self.receiver.borrow_mut().take().unwrap();
        let (data, channels, shmems) = receiver.recv().unwrap();
        Ok((receiver, data, channels, shmems))
    }
}

#[derive(PartialEq, Debug)]
pub enum OsIpcChannel {
    Sender(OsIpcSender),
    Receiver(OsIpcReceiver),
}

#[derive(PartialEq, Debug)]
pub struct OsOpaqueIpcChannel {
    channel: RefCell<Option<OsIpcChannel>>,
}

impl OsOpaqueIpcChannel {
    fn new(channel: OsIpcChannel) -> OsOpaqueIpcChannel {
        OsOpaqueIpcChannel {
            channel: RefCell::new(Some(channel))
        }
    }

    pub fn to_receiver(&self) -> OsIpcReceiver {
        match self.channel.borrow_mut().take().unwrap() {
            OsIpcChannel::Sender(_) => panic!("Opaque channel is not a receiver!"),
            OsIpcChannel::Receiver(r) => r
        }
    }

    pub fn to_sender(&self) -> OsIpcSender {
        match self.channel.borrow_mut().take().unwrap() {
            OsIpcChannel::Sender(s) => s,
            OsIpcChannel::Receiver(_) => panic!("Opaque channel is not a sender!"),
        }
    }
}

pub struct OsIpcSharedMemory {
    ptr: *mut u8,
    length: usize,
    data: Arc<Vec<u8>>,
}

unsafe impl Send for OsIpcSharedMemory {}
unsafe impl Sync for OsIpcSharedMemory {}

impl Clone for OsIpcSharedMemory {
    fn clone(&self) -> OsIpcSharedMemory {
        OsIpcSharedMemory {
            ptr: self.ptr,
            length: self.length,
            data: self.data.clone(),
        }
    }
}

impl PartialEq for OsIpcSharedMemory {
    fn eq(&self, other: &OsIpcSharedMemory) -> bool {
        **self == **other
    }
}

impl Debug for OsIpcSharedMemory {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        (**self).fmt(formatter)
    }
}

impl Deref for OsIpcSharedMemory {
    type Target = [u8];

    #[inline]
    fn deref(&self) -> &[u8] {
        if self.ptr.is_null() {
            panic!("attempted to access a consumed `OsIpcSharedMemory`")
        }
        unsafe {
            slice::from_raw_parts(self.ptr, self.length)
        }
    }
}

impl OsIpcSharedMemory {
    pub fn from_byte(byte: u8, length: usize) -> OsIpcSharedMemory {
        let mut v = Arc::new(vec![byte; length]);
        OsIpcSharedMemory {
            ptr: Arc::get_mut(&mut v).unwrap().as_mut_ptr(),
            length: length,
            data: v
        }
    }

    pub fn from_bytes(bytes: &[u8]) -> OsIpcSharedMemory {
        let mut v = Arc::new(bytes.to_vec());
        OsIpcSharedMemory {
            ptr: Arc::get_mut(&mut v).unwrap().as_mut_ptr(),
            length: v.len(),
            data: v
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum MpscError {
    ChannelClosedError,
    UnknownError,
}

impl MpscError {
    #[allow(dead_code)]
    pub fn channel_is_closed(&self) -> bool {
        *self == MpscError::ChannelClosedError
    }
}

impl From<MpscError> for DeserializeError {
    fn from(mpsc_error: MpscError) -> DeserializeError {
        DeserializeError::IoError(mpsc_error.into())
    }
}

impl From<MpscError> for Error {
    fn from(mpsc_error: MpscError) -> Error {
        match mpsc_error {
            MpscError::ChannelClosedError => {
                Error::new(ErrorKind::BrokenPipe, "MPSC channel closed")
            }
            MpscError::UnknownError => Error::new(ErrorKind::Other, "Other MPSC channel error"),
        }
    }
}

<commit_msg>Make inprocess::OsIpcSender::to_sender take &mut self<commit_after>// Copyright 2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use bincode::serde::DeserializeError;
use std::sync::mpsc;
use std::sync::{Arc, Mutex};
use std::collections::hash_map::HashMap;
use std::cell::{RefCell};
use std::io::{Error, ErrorKind};
use std::slice;
use std::fmt::{self, Debug, Formatter};
use std::cmp::{PartialEq};
use std::ops::Deref;
use std::mem;
use std::usize;

use uuid::Uuid;

struct ServerRecord {
    sender: OsIpcSender,
    conn_sender: mpsc::Sender<bool>,
    conn_receiver: Mutex<mpsc::Receiver<bool>>,
}

impl ServerRecord {
    fn new(sender: OsIpcSender) -> ServerRecord {
        let (tx, rx) = mpsc::channel::<bool>();
        ServerRecord {
            sender: sender,
            conn_sender: tx,
            conn_receiver: Mutex::new(rx),
        }
    }

    fn accept(&self) {
        self.conn_receiver.lock().unwrap().recv().unwrap();
    }

    fn connect(&self) {
        self.conn_sender.send(true).unwrap();
    }
}

lazy_static! {
    static ref ONE_SHOT_SERVERS: Mutex<HashMap<String,ServerRecord>> = Mutex::new(HashMap::new());
}

struct MpscChannelMessage(Vec<u8>, Vec<OsIpcChannel>, Vec<OsIpcSharedMemory>);

pub fn channel() -> Result<(OsIpcSender, OsIpcReceiver),MpscError> {
    let (base_sender, base_receiver) = mpsc::channel::<MpscChannelMessage>();
    Ok((OsIpcSender::new(base_sender), OsIpcReceiver::new(base_receiver)))
}

pub struct OsIpcReceiver {
    receiver: Arc<Mutex<Option<mpsc::Receiver<MpscChannelMessage>>>>,
}

impl PartialEq for OsIpcReceiver {
    fn eq(&self, other: &OsIpcReceiver) -> bool {
        self.receiver.lock().unwrap().as_ref().map(|rx| rx as *const _) ==
            other.receiver.lock().unwrap().as_ref().map(|rx| rx as *const _)
    }
}

// Can't derive, as mpsc::Receiver doesn't implement Debug.
impl fmt::Debug for OsIpcReceiver {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Not sure there is anything useful we could print here.
        write!(f, "OsIpcReceiver {{ .. }}")
    }
}

impl OsIpcReceiver {
    fn new(receiver: mpsc::Receiver<MpscChannelMessage>) -> OsIpcReceiver {
        OsIpcReceiver {
            receiver: Arc::new(Mutex::new(Some(receiver))),
        }
    }

    pub fn consume(&self) -> OsIpcReceiver {
        let receiver = self.receiver.lock().unwrap().take();
        OsIpcReceiver::new(receiver.unwrap())
    }

    pub fn recv(&self) -> Result<(Vec<u8>, Vec<OsOpaqueIpcChannel>, Vec<OsIpcSharedMemory>),MpscError> {
        let r = self.receiver.lock().unwrap();
        match r.as_ref().unwrap().recv() {
            Ok(MpscChannelMessage(d,c,s)) => Ok((d,
                                                 c.into_iter().map(OsOpaqueIpcChannel::new).collect(),
                                                 s)),
            Err(_) => Err(MpscError::ChannelClosedError),
        }
    }

    pub fn try_recv(&self) -> Result<(Vec<u8>, Vec<OsOpaqueIpcChannel>, Vec<OsIpcSharedMemory>),MpscError> {
        let r = self.receiver.lock().unwrap();
        match r.as_ref().unwrap().try_recv() {
            Ok(MpscChannelMessage(d,c,s)) => Ok((d,
                                                 c.into_iter().map(OsOpaqueIpcChannel::new).collect(),
                                                 s)),
            Err(_) => Err(MpscError::ChannelClosedError),
        }
    }
}

#[derive(Clone)]
pub struct OsIpcSender {
    sender: Arc<Mutex<mpsc::Sender<MpscChannelMessage>>>,
}

impl PartialEq for OsIpcSender {
    fn eq(&self, other: &OsIpcSender) -> bool {
        &*self.sender.lock().unwrap() as *const _ ==
            &*other.sender.lock().unwrap() as *const _
    }
}

// Can't derive, as mpsc::Sender doesn't implement Debug.
impl fmt::Debug for OsIpcSender {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Not sure there is anything useful we could print here.
        write!(f, "OsIpcSender {{ .. }}")
    }
}

impl OsIpcSender {
    fn new(sender: mpsc::Sender<MpscChannelMessage>) -> OsIpcSender {
        OsIpcSender {
            sender: Arc::new(Mutex::new(sender)),
        }
    }

    pub fn connect(name: String) -> Result<OsIpcSender,MpscError> {
        let record = ONE_SHOT_SERVERS.lock().unwrap().remove(&name).unwrap();
        record.connect();
        Ok(record.sender)
    }

    pub fn get_max_fragment_size() -> usize {
        usize::MAX
    }

    pub fn send(&self,
                data: &[u8],
                ports: Vec<OsIpcChannel>,
                shared_memory_regions: Vec<OsIpcSharedMemory>)
                -> Result<(),MpscError>
    {
        match self.sender.lock().unwrap().send(MpscChannelMessage(data.to_vec(), ports, shared_memory_regions)) {
            Err(_) => Err(MpscError::ChannelClosedError),
            Ok(_) => Ok(()),
        }
    }
}

pub struct OsIpcReceiverSet {
    last_index: usize,
    receiver_ids: Vec<usize>,
    receivers: Vec<OsIpcReceiver>,
}

impl OsIpcReceiverSet {
    pub fn new() -> Result<OsIpcReceiverSet,MpscError> {
        Ok(OsIpcReceiverSet {
            last_index: 0,
            receiver_ids: vec![],
            receivers: vec![],
        })
    }

    pub fn add(&mut self, receiver: OsIpcReceiver) -> Result<i64,MpscError> {
        self.last_index += 1;
        self.receiver_ids.push(self.last_index);
        self.receivers.push(receiver.consume());
        Ok(self.last_index as i64)
    }

    pub fn select(&mut self) -> Result<Vec<OsIpcSelectionResult>,MpscError> {
        let mut receivers: Vec<Option<mpsc::Receiver<MpscChannelMessage>>> = Vec::with_capacity(self.receivers.len());
        let mut r_id: i64 = -1;
        let mut r_index: usize = 0;

        {
            let select = mpsc::Select::new();
            // we *must* allocate exact capacity for this, because the Handles *can't move*
            let mut handles: Vec<mpsc::Handle<MpscChannelMessage>> = Vec::with_capacity(self.receivers.len());

            for r in &self.receivers {
                let inner_r = mem::replace(&mut *r.receiver.lock().unwrap(), None);
                receivers.push(inner_r);
            }

            for r in &receivers {
                unsafe {
                    handles.push(select.handle(r.as_ref().unwrap()));
                    handles.last_mut().unwrap().add();
                }
            }

            let id = select.wait();

            for (index,h) in handles.iter().enumerate() {
                if h.id() == id {
                    r_index = index;
                    r_id = self.receiver_ids[index] as i64;
                    break;
                }
            }
        }

        // put the receivers back
        for (index,r) in self.receivers.iter().enumerate() {
            mem::replace(&mut *r.receiver.lock().unwrap(), mem::replace(&mut receivers[index], None));
        }

        if r_id == -1 {
            return Err(MpscError::UnknownError);
        }

        let receivers = &mut self.receivers;
        match receivers[r_index].recv() {
            Ok((data, channels, shmems)) =>
                Ok(vec![OsIpcSelectionResult::DataReceived(r_id, data, channels, shmems)]),
            Err(MpscError::ChannelClosedError) => {
                receivers.remove(r_index);
                self.receiver_ids.remove(r_index);
                Ok(vec![OsIpcSelectionResult::ChannelClosed(r_id)])
            },
            Err(err) => Err(err),
        }
    }
}

pub enum OsIpcSelectionResult {
    DataReceived(i64, Vec<u8>, Vec<OsOpaqueIpcChannel>, Vec<OsIpcSharedMemory>),
    ChannelClosed(i64),
}

impl OsIpcSelectionResult {
    pub fn unwrap(self) -> (i64, Vec<u8>, Vec<OsOpaqueIpcChannel>, Vec<OsIpcSharedMemory>) {
        match self {
            OsIpcSelectionResult::DataReceived(id, data, channels, shared_memory_regions) => {
                (id, data, channels, shared_memory_regions)
            }
            OsIpcSelectionResult::ChannelClosed(id) => {
                panic!("OsIpcSelectionResult::unwrap(): receiver ID {} was closed!", id)
            }
        }
    }
}

pub struct OsIpcOneShotServer {
    receiver: RefCell<Option<OsIpcReceiver>>,
    name: String,
}

impl OsIpcOneShotServer {
    pub fn new() -> Result<(OsIpcOneShotServer, String),MpscError> {
        let (sender, receiver) = match channel() {
            Ok((s,r)) => (s,r),
            Err(err) => return Err(err),
        };

        let name = Uuid::new_v4().to_string();
        let record = ServerRecord::new(sender);
        ONE_SHOT_SERVERS.lock().unwrap().insert(name.clone(), record);
        Ok((OsIpcOneShotServer {
            receiver: RefCell::new(Some(receiver)),
            name: name.clone(),
        },name.clone()))
    }

    pub fn accept(&self) -> Result<(OsIpcReceiver,
                                    Vec<u8>,
                                    Vec<OsOpaqueIpcChannel>,
                                    Vec<OsIpcSharedMemory>),MpscError>
    {
        ONE_SHOT_SERVERS.lock().unwrap().get(&self.name).unwrap().accept();
        let receiver = self.receiver.borrow_mut().take().unwrap();
        let (data, channels, shmems) = receiver.recv().unwrap();
        Ok((receiver, data, channels, shmems))
    }
}

#[derive(PartialEq, Debug)]
pub enum OsIpcChannel {
    Sender(OsIpcSender),
    Receiver(OsIpcReceiver),
}

#[derive(PartialEq, Debug)]
pub struct OsOpaqueIpcChannel {
    channel: RefCell<Option<OsIpcChannel>>,
}

impl OsOpaqueIpcChannel {
    fn new(channel: OsIpcChannel) -> OsOpaqueIpcChannel {
        OsOpaqueIpcChannel {
            channel: RefCell::new(Some(channel))
        }
    }

    pub fn to_receiver(&self) -> OsIpcReceiver {
        match self.channel.borrow_mut().take().unwrap() {
            OsIpcChannel::Sender(_) => panic!("Opaque channel is not a receiver!"),
            OsIpcChannel::Receiver(r) => r
        }
    }

    pub fn to_sender(&mut self) -> OsIpcSender {
        match self.channel.borrow_mut().take().unwrap() {
            OsIpcChannel::Sender(s) => s,
            OsIpcChannel::Receiver(_) => panic!("Opaque channel is not a sender!"),
        }
    }
}

pub struct OsIpcSharedMemory {
    ptr: *mut u8,
    length: usize,
    data: Arc<Vec<u8>>,
}

unsafe impl Send for OsIpcSharedMemory {}
unsafe impl Sync for OsIpcSharedMemory {}

impl Clone for OsIpcSharedMemory {
    fn clone(&self) -> OsIpcSharedMemory {
        OsIpcSharedMemory {
            ptr: self.ptr,
            length: self.length,
            data: self.data.clone(),
        }
    }
}

impl PartialEq for OsIpcSharedMemory {
    fn eq(&self, other: &OsIpcSharedMemory) -> bool {
        **self == **other
    }
}

impl Debug for OsIpcSharedMemory {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        (**self).fmt(formatter)
    }
}

impl Deref for OsIpcSharedMemory {
    type Target = [u8];

    #[inline]
    fn deref(&self) -> &[u8] {
        if self.ptr.is_null() {
            panic!("attempted to access a consumed `OsIpcSharedMemory`")
        }
        unsafe {
            slice::from_raw_parts(self.ptr, self.length)
        }
    }
}

impl OsIpcSharedMemory {
    pub fn from_byte(byte: u8, length: usize) -> OsIpcSharedMemory {
        let mut v = Arc::new(vec![byte; length]);
        OsIpcSharedMemory {
            ptr: Arc::get_mut(&mut v).unwrap().as_mut_ptr(),
            length: length,
            data: v
        }
    }

    pub fn from_bytes(bytes: &[u8]) -> OsIpcSharedMemory {
        let mut v = Arc::new(bytes.to_vec());
        OsIpcSharedMemory {
            ptr: Arc::get_mut(&mut v).unwrap().as_mut_ptr(),
            length: v.len(),
            data: v
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum MpscError {
    ChannelClosedError,
    UnknownError,
}

impl MpscError {
    #[allow(dead_code)]
    pub fn channel_is_closed(&self) -> bool {
        *self == MpscError::ChannelClosedError
    }
}

impl From<MpscError> for DeserializeError {
    fn from(mpsc_error: MpscError) -> DeserializeError {
        DeserializeError::IoError(mpsc_error.into())
    }
}

impl From<MpscError> for Error {
    fn from(mpsc_error: MpscError) -> Error {
        match mpsc_error {
            MpscError::ChannelClosedError => {
                Error::new(ErrorKind::BrokenPipe, "MPSC channel closed")
            }
            MpscError::UnknownError => Error::new(ErrorKind::Other, "Other MPSC channel error"),
        }
    }
}

<|endoftext|>


<commit_before>use std::char;
use std::cell::Cell;
use std::fmt;

pub struct Lexer {
    input: String,
    position: Cell<usize>,
    read_position: Cell<usize>,
    ch: Cell<char>
}

impl Lexer {
    pub fn new(input: String) -> Lexer {
        let l = Lexer {
            input: input,
            position: Cell::new(0),
            read_position: Cell::new(0),
            ch: Cell::new(' ')
        };
        l.read_char();
        l
    }

    pub fn read_char(&self) {
        if self.read_position.get() >= self.input.len() {
            self.ch.set('\0');
        } else {
            let c = self.input.chars().nth(self.read_position.get()).unwrap();
            self.ch.set(c);
        }
        self.position.set(self.read_position.get());
        self.read_position.set(self.read_position.get() + 1);
    }

    pub fn next_token(&self) -> Token {
        self.skip_white_space();
        self.get_token(self.ch.get())
    }

    pub fn get_token(&self, s: char) -> Token {
        let token = match s {
            '=' => {
                if self.peek_char() == '=' {
                    self.read_char();
                    Token {
                        token_type: TokenType::Eq,
                        value: Some(Value::Str(String::from("==")))
                    }
                } else {
                    Token {
                        token_type: TokenType::Assign,
                        value: Some(Value::Str(String::from("=")))
                    }
                }
            }
            '+' => {
                Token {
                    token_type: TokenType::Plus,
                    value: Some(Value::Str(String::from("+")))
                }
            }
            '-' => {
                Token {
                    token_type: TokenType::Minus,
                    value: Some(Value::Str(String::from("-")))
                }
            }
            '!' => {
                if self.peek_char() == '=' {
                    self.read_char();
                    Token {
                        token_type: TokenType::NotEq,
                        value: Some(Value::Str(String::from("!=")))
                    }
                } else {
                    Token {
                        token_type: TokenType::Bang,
                        value: Some(Value::Str(String::from("!")))
                    }
                }
            }
            '/' => {
                Token {
                    token_type: TokenType::Slash,
                    value: Some(Value::Str(String::from("/")))
                }
            }
            '*' => {
                Token {
                    token_type: TokenType::Asterisk,
                    value: Some(Value::Str(String::from("*")))
                }
            }
            '<' => {
                Token {
                    token_type: TokenType::Lt,
                    value: Some(Value::Str(String::from("<")))
                }
            }
            '>' => {
                Token {
                    token_type: TokenType::Gt,
                    value: Some(Value::Str(String::from(">")))
                }
            }
            ';' => {
                Token {
                    token_type: TokenType::Semicolon,
                    value: Some(Value::Str(String::from(";")))
                }
            }
            '(' => {
                Token {
                    token_type: TokenType::Lparen,
                    value: Some(Value::Str(String::from("(")))
                }
            }
            ')' => {
                Token {
                    token_type: TokenType::Rparen,
                    value: Some(Value::Str(String::from(")")))
                }
            }
            ',' => {
                Token {
                    token_type: TokenType::Comma,
                    value: Some(Value::Str(String::from(",")))
                }
            }
            '{' => {
                Token {
                    token_type: TokenType::Lbrace,
                    value: Some(Value::Str(String::from("{")))
                }
            }
            '}' => {
                Token {
                    token_type: TokenType::Rbrace,
                    value: Some(Value::Str(String::from("}")))
                }
            }
            '\0' => {
                Token {
                    token_type: TokenType::Eof,
                    value: Some(Value::Str(String::from("\0")))
                }
            }
            c => {
                if is_letter(c) {
                    let identifier = unsafe {self.read_identifier()};
                    Token {
                        token_type: unsafe {self.lookup_ident(&identifier)},
                        value: Some(Value::Str(identifier))
                    }
                } else if is_digit(c) {
                    Token {
                        token_type: TokenType::Int,
                        value: Some(Value::Str(unsafe { self.read_number()}))
                    }
                } else {
                    Token {
                        token_type: TokenType::Illegal,
                        value: None
                    }
                }
            }
        };
        self.read_char();
        token
    }

    pub unsafe fn read_identifier(&self) -> String {
        let start_position = self.position.get();
        while is_letter(self.ch.get()) {
            self.read_char();
        }
        let end_position = self.position.get();
        let s = self.input.slice_unchecked(start_position, end_position);
        s.to_string()
    }

    pub unsafe fn lookup_ident(&self, s: &str) -> TokenType {
        match s {
            "fn" => TokenType::Function,
            "let" => TokenType::Let,
            "true" => TokenType::True,
            "false" => TokenType::False,
            "if" => TokenType::If,
            "else" => TokenType::Else,
            "return" => TokenType::Return,
            _ => TokenType::Ident
        }
    }

    pub unsafe fn read_number(&self) -> String {
        let start_position = self.position.get();
        while is_digit(self.ch.get()) {
            self.read_char();
        }
        let end_position = self.position.get();
        let s = self.input.slice_unchecked(start_position, end_position);
        s.to_string()
    }

    pub fn skip_white_space(&self) {
        while self.ch.get() == ' ' || self.ch.get() == '\t' || self.ch.get() == '\n' || self.ch.get() == '\r' {
            self.read_char();
        }
    }

    pub fn peek_char(&self) -> char {
        if self.read_position.get() >= self.input.len() {
            '0'
        } else {
            self.input.chars().nth(self.read_position.get()).unwrap()
        }
    }
}

fn is_letter(ch: char) -> bool {
    'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_'
}

fn is_digit(ch: char) -> bool {
    '0' <= ch && ch <= '9'
}

#[derive(Debug)]
pub enum Value {
    Str(String),
}

impl PartialEq for Value {
    fn eq(&self, other: &Value) -> bool {
        match *self {
            Value::Str(ref s) => {
                match *other {
                    Value::Str(ref o) => {
                        *s == *o
                    },
                    _ => false
                }
            }
            _ => false
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum TokenType {
    Illegal,
    Eof,

    Ident,
    Int,

    Assign,
    Plus,
    Minus,
    Bang,
    Asterisk,
    Slash,
    Eq,
    NotEq,

    Lt,
    Gt,

    Comma,
    Semicolon,

    Lparen,
    Rparen,
    Lbrace,
    Rbrace,

    Function,
    Let,
    True,
    False,
    If,
    Else,
    Return
}

#[derive(Debug)]
pub struct Token {
    pub token_type: TokenType,
    pub value: Option<Value>,
}

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

// Test
#[test]
fn peek_char() {
    let input = String::from("!=");
    let l = &Lexer::new(input);
    assert_eq!('=', l.peek_char());
    assert_eq!('=', l.peek_char());
}

#[test]
fn next_token_base() {
    let input = String::from("=()");
    let l = &Lexer::new(input);
    assert_eq!(l.next_token().token_type, TokenType::Assign);
    assert_eq!(l.next_token().token_type, TokenType::Lparen);
    assert_eq!(l.next_token().token_type, TokenType::Rparen);
}

#[test]
fn test_is_digit() {
    assert_eq!(is_digit('0'), true);
    assert_eq!(is_digit('1'), true);
    assert_eq!(is_digit('8'), true);
    assert_eq!(is_digit('9'), true);
}

#[test]
fn test_is_letter() {
    assert_eq!(is_letter('_'), true);
    assert_eq!(is_letter('a'), true);
    assert_eq!(is_letter('b'), true);
    assert_eq!(is_letter('y'), true);
    assert_eq!(is_letter('z'), true);
    assert_eq!(is_letter('A'), true);
    assert_eq!(is_letter('B'), true);
    assert_eq!(is_letter('Y'), true);
    assert_eq!(is_letter('Z'), true);
}

#[test]
fn next_token() {
    let input = String::from("let five = 5;
let ten = 10;

let add = fn(x, y) {
    x + y;
};

let result = add(five, ten);
!-/*5;
5 < 10 > 5;

if (5 < 10) {
    return true;
} else {
    return false;
}

10 == 10;
10 != 9;");
    let tests = vec![
        (TokenType::Let, Value::Str(String::from("let"))),
        (TokenType::Ident, Value::Str(String::from("five"))),
        (TokenType::Assign, Value::Str(String::from("="))),
        (TokenType::Int, Value::Str(String::from("5"))),
//        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Let, Value::Str(String::from("let"))),
        (TokenType::Ident, Value::Str(String::from("ten"))),
        (TokenType::Assign, Value::Str(String::from("="))),
        (TokenType::Int, Value::Str(String::from("10"))),
//        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Let, Value::Str(String::from("let"))),
        (TokenType::Ident, Value::Str(String::from("add"))),
        (TokenType::Assign, Value::Str(String::from("="))),
        (TokenType::Function, Value::Str(String::from("fn"))),
//        (TokenType::Lparen, Value::Str(String::from("("))),
        (TokenType::Ident, Value::Str(String::from("x"))),
//        (TokenType::Comma, Value::Str(String::from(","))),
        (TokenType::Ident, Value::Str(String::from("y"))),
//        (TokenType::Rparen, Value::Str(String::from(")"))),
        (TokenType::Lbrace, Value::Str(String::from("{"))),
        (TokenType::Ident, Value::Str(String::from("x"))),
        (TokenType::Plus, Value::Str(String::from("+"))),
        (TokenType::Ident, Value::Str(String::from("y"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Rbrace, Value::Str(String::from("}"))),
        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Let, Value::Str(String::from("let"))),
        (TokenType::Ident, Value::Str(String::from("result"))),
        (TokenType::Assign, Value::Str(String::from("="))),
        (TokenType::Ident, Value::Str(String::from("add"))),
//        (TokenType::Lparen, Value::Str(String::from("("))),
        (TokenType::Ident, Value::Str(String::from("five"))),
        //        (TokenType::Comma, Value::Str(String::from(","))),
        (TokenType::Ident, Value::Str(String::from("ten"))),
        //        (TokenType::Rparen, Value::Str(String::from(")"))),
        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Bang, Value::Str(String::from("!"))),
        (TokenType::Minus, Value::Str(String::from("-"))),
        (TokenType::Slash, Value::Str(String::from("/"))),
        (TokenType::Asterisk, Value::Str(String::from("*"))),
        (TokenType::Int, Value::Str(String::from("5"))),
//        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Int, Value::Str(String::from("5"))),
        (TokenType::Lt, Value::Str(String::from("<"))),
        (TokenType::Int, Value::Str(String::from("10"))),
        (TokenType::Gt, Value::Str(String::from(">"))),
        (TokenType::Int, Value::Str(String::from("5"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::If, Value::Str(String::from("if"))),
        (TokenType::Lparen, Value::Str(String::from("("))),
        (TokenType::Int, Value::Str(String::from("5"))),
        (TokenType::Lt, Value::Str(String::from("<"))),
        (TokenType::Int, Value::Str(String::from("10"))),
//        (TokenType::Rparen, Value::Str(String::from(")"))),
        (TokenType::Lbrace, Value::Str(String::from("{"))),
        (TokenType::Return, Value::Str(String::from("return"))),
        (TokenType::True, Value::Str(String::from("true"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Rbrace, Value::Str(String::from("}"))),
        (TokenType::Else, Value::Str(String::from("else"))),
        (TokenType::Lbrace, Value::Str(String::from("{"))),
        (TokenType::Return, Value::Str(String::from("return"))),
        (TokenType::False, Value::Str(String::from("false"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Rbrace, Value::Str(String::from("}"))),
        (TokenType::Int, Value::Str(String::from("10"))),
        (TokenType::Eq, Value::Str(String::from("=="))),
        (TokenType::Int, Value::Str(String::from("10"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Int, Value::Str(String::from("10"))),
        (TokenType::NotEq, Value::Str(String::from("!="))),
        (TokenType::Int, Value::Str(String::from("9"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Eof, Value::Str(String::from("\0"))),
    ];

    let l = &Lexer::new(input);
    for e in &tests {
        let t = l.next_token();
        assert_eq!(t.token_type, e.0);
        assert_eq!(t.value.unwrap(), e.1);
    }
}
<commit_msg>refactor code<commit_after>use std::char;
use std::cell::Cell;
use std::fmt;

pub struct Lexer {
    input: String,
    position: Cell<usize>,
    read_position: Cell<usize>,
    ch: Cell<char>
}

impl Lexer {
    pub fn new(input: String) -> Lexer {
        let l = Lexer {
            input: input,
            position: Cell::new(0),
            read_position: Cell::new(0),
            ch: Cell::new(' ')
        };
        l.read_char();
        l
    }

    pub fn read_char(&self) {
        if self.read_position.get() >= self.input.len() {
            self.ch.set('\0');
        } else {
            let c = self.input.chars().nth(self.read_position.get()).unwrap();
            self.ch.set(c);
        }
        self.position.set(self.read_position.get());
        self.read_position.set(self.read_position.get() + 1);
    }

    pub fn next_token(&self) -> Token {
        self.skip_white_space();
        self.get_token(self.ch.get())
    }

    pub fn get_token(&self, s: char) -> Token {
        let token = match s {
            '=' => {
                if self.peek_char() == '=' {
                    self.read_char();
                    Token {
                        token_type: TokenType::Eq,
                        value: Some(Value::Str(String::from("==")))
                    }
                } else {
                    Token {
                        token_type: TokenType::Assign,
                        value: Some(Value::Str(String::from("=")))
                    }
                }
            }
            '+' => {
                Token {
                    token_type: TokenType::Plus,
                    value: Some(Value::Str(String::from("+")))
                }
            }
            '-' => {
                Token {
                    token_type: TokenType::Minus,
                    value: Some(Value::Str(String::from("-")))
                }
            }
            '!' => {
                if self.peek_char() == '=' {
                    self.read_char();
                    Token {
                        token_type: TokenType::NotEq,
                        value: Some(Value::Str(String::from("!=")))
                    }
                } else {
                    Token {
                        token_type: TokenType::Bang,
                        value: Some(Value::Str(String::from("!")))
                    }
                }
            }
            '/' => {
                Token {
                    token_type: TokenType::Slash,
                    value: Some(Value::Str(String::from("/")))
                }
            }
            '*' => {
                Token {
                    token_type: TokenType::Asterisk,
                    value: Some(Value::Str(String::from("*")))
                }
            }
            '<' => {
                Token {
                    token_type: TokenType::Lt,
                    value: Some(Value::Str(String::from("<")))
                }
            }
            '>' => {
                Token {
                    token_type: TokenType::Gt,
                    value: Some(Value::Str(String::from(">")))
                }
            }
            ';' => {
                Token {
                    token_type: TokenType::Semicolon,
                    value: Some(Value::Str(String::from(";")))
                }
            }
            '(' => {
                Token {
                    token_type: TokenType::Lparen,
                    value: Some(Value::Str(String::from("(")))
                }
            }
            ')' => {
                Token {
                    token_type: TokenType::Rparen,
                    value: Some(Value::Str(String::from(")")))
                }
            }
            ',' => {
                Token {
                    token_type: TokenType::Comma,
                    value: Some(Value::Str(String::from(",")))
                }
            }
            '{' => {
                Token {
                    token_type: TokenType::Lbrace,
                    value: Some(Value::Str(String::from("{")))
                }
            }
            '}' => {
                Token {
                    token_type: TokenType::Rbrace,
                    value: Some(Value::Str(String::from("}")))
                }
            }
            '\0' => {
                Token {
                    token_type: TokenType::Eof,
                    value: Some(Value::Str(String::from("\0")))
                }
            }
            c => {
                if is_letter(c) {
                    let identifier = self.read_identifier();
                    Token {
                        token_type: self.lookup_ident(&identifier),
                        value: Some(Value::Str(identifier))
                    }
                } else if is_digit(c) {
                    Token {
                        token_type: TokenType::Int,
                        value: Some(Value::Str(self.read_number()))
                    }
                } else {
                    Token {
                        token_type: TokenType::Illegal,
                        value: None
                    }
                }
            }
        };
        self.read_char();
        token
    }

    pub fn read_identifier(&self) -> String {
        let start_position = self.position.get();
        while is_letter(self.ch.get()) {
            self.read_char();
        }
        let end_position = self.position.get();
        let s = &(self.input)[start_position..end_position];
        s.to_string()
    }

    pub fn lookup_ident(&self, s: &str) -> TokenType {
        match s {
            "fn" => TokenType::Function,
            "let" => TokenType::Let,
            "true" => TokenType::True,
            "false" => TokenType::False,
            "if" => TokenType::If,
            "else" => TokenType::Else,
            "return" => TokenType::Return,
            _ => TokenType::Ident
        }
    }

    pub fn read_number(&self) -> String {
        let start_position = self.position.get();
        while is_digit(self.ch.get()) {
            self.read_char();
        }
        let end_position = self.position.get();
        let s = &(self.input)[start_position..end_position];
        s.to_string()
    }

    pub fn skip_white_space(&self) {
        while self.ch.get() == ' ' || self.ch.get() == '\t' || self.ch.get() == '\n' || self.ch.get() == '\r' {
            self.read_char();
        }
    }

    pub fn peek_char(&self) -> char {
        if self.read_position.get() >= self.input.len() {
            '\0'
        } else {
            self.input.chars().nth(self.read_position.get()).unwrap()
        }
    }
}

fn is_letter(ch: char) -> bool {
    'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_'
}

fn is_digit(ch: char) -> bool {
    '0' <= ch && ch <= '9'
}

#[derive(Debug)]
pub enum Value {
    Str(String),
}

impl PartialEq for Value {
    fn eq(&self, other: &Value) -> bool {
        match *self {
            Value::Str(ref s) => {
                match *other {
                    Value::Str(ref o) => {
                        *s == *o
                    }
                }
            }
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum TokenType {
    Illegal,
    Eof,

    Ident,
    Int,

    Assign,
    Plus,
    Minus,
    Bang,
    Asterisk,
    Slash,
    Eq,
    NotEq,

    Lt,
    Gt,

    Comma,
    Semicolon,

    Lparen,
    Rparen,
    Lbrace,
    Rbrace,

    Function,
    Let,
    True,
    False,
    If,
    Else,
    Return
}

#[derive(Debug)]
pub struct Token {
    pub token_type: TokenType,
    pub value: Option<Value>,
}

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

#[test]
fn peek_char() {
    let input = String::from("!=");
    let l = &Lexer::new(input);
    assert_eq!('=', l.peek_char());
    assert_eq!('=', l.peek_char());
}

#[test]
fn test_is_digit() {
    assert_eq!(is_digit('0'), true);
    assert_eq!(is_digit('1'), true);
    assert_eq!(is_digit('8'), true);
    assert_eq!(is_digit('9'), true);
}

#[test]
fn test_is_letter() {
    assert_eq!(is_letter('_'), true);
    assert_eq!(is_letter('a'), true);
    assert_eq!(is_letter('b'), true);
    assert_eq!(is_letter('y'), true);
    assert_eq!(is_letter('z'), true);
    assert_eq!(is_letter('A'), true);
    assert_eq!(is_letter('B'), true);
    assert_eq!(is_letter('Y'), true);
    assert_eq!(is_letter('Z'), true);
}

#[test]
fn next_token() {
    let input = String::from("let five = 5;
let ten = 10;

let add = fn(x, y) {
    x + y;
};

let result = add(five, ten);
!-/*5;
5 < 10 > 5;

if (5 < 10) {
    return true;
} else {
    return false;
}

10 == 10;
10 != 9;");
    let tests = vec![
        (TokenType::Let, Value::Str(String::from("let"))),
        (TokenType::Ident, Value::Str(String::from("five"))),
        (TokenType::Assign, Value::Str(String::from("="))),
        (TokenType::Int, Value::Str(String::from("5"))),
//        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Let, Value::Str(String::from("let"))),
        (TokenType::Ident, Value::Str(String::from("ten"))),
        (TokenType::Assign, Value::Str(String::from("="))),
        (TokenType::Int, Value::Str(String::from("10"))),
//        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Let, Value::Str(String::from("let"))),
        (TokenType::Ident, Value::Str(String::from("add"))),
        (TokenType::Assign, Value::Str(String::from("="))),
        (TokenType::Function, Value::Str(String::from("fn"))),
//        (TokenType::Lparen, Value::Str(String::from("("))),
        (TokenType::Ident, Value::Str(String::from("x"))),
//        (TokenType::Comma, Value::Str(String::from(","))),
        (TokenType::Ident, Value::Str(String::from("y"))),
//        (TokenType::Rparen, Value::Str(String::from(")"))),
        (TokenType::Lbrace, Value::Str(String::from("{"))),
        (TokenType::Ident, Value::Str(String::from("x"))),
        (TokenType::Plus, Value::Str(String::from("+"))),
        (TokenType::Ident, Value::Str(String::from("y"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Rbrace, Value::Str(String::from("}"))),
        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Let, Value::Str(String::from("let"))),
        (TokenType::Ident, Value::Str(String::from("result"))),
        (TokenType::Assign, Value::Str(String::from("="))),
        (TokenType::Ident, Value::Str(String::from("add"))),
//        (TokenType::Lparen, Value::Str(String::from("("))),
        (TokenType::Ident, Value::Str(String::from("five"))),
        //        (TokenType::Comma, Value::Str(String::from(","))),
        (TokenType::Ident, Value::Str(String::from("ten"))),
        //        (TokenType::Rparen, Value::Str(String::from(")"))),
        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Bang, Value::Str(String::from("!"))),
        (TokenType::Minus, Value::Str(String::from("-"))),
        (TokenType::Slash, Value::Str(String::from("/"))),
        (TokenType::Asterisk, Value::Str(String::from("*"))),
        (TokenType::Int, Value::Str(String::from("5"))),
//        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Int, Value::Str(String::from("5"))),
        (TokenType::Lt, Value::Str(String::from("<"))),
        (TokenType::Int, Value::Str(String::from("10"))),
        (TokenType::Gt, Value::Str(String::from(">"))),
        (TokenType::Int, Value::Str(String::from("5"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::If, Value::Str(String::from("if"))),
        (TokenType::Lparen, Value::Str(String::from("("))),
        (TokenType::Int, Value::Str(String::from("5"))),
        (TokenType::Lt, Value::Str(String::from("<"))),
        (TokenType::Int, Value::Str(String::from("10"))),
//        (TokenType::Rparen, Value::Str(String::from(")"))),
        (TokenType::Lbrace, Value::Str(String::from("{"))),
        (TokenType::Return, Value::Str(String::from("return"))),
        (TokenType::True, Value::Str(String::from("true"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Rbrace, Value::Str(String::from("}"))),
        (TokenType::Else, Value::Str(String::from("else"))),
        (TokenType::Lbrace, Value::Str(String::from("{"))),
        (TokenType::Return, Value::Str(String::from("return"))),
        (TokenType::False, Value::Str(String::from("false"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Rbrace, Value::Str(String::from("}"))),
        (TokenType::Int, Value::Str(String::from("10"))),
        (TokenType::Eq, Value::Str(String::from("=="))),
        (TokenType::Int, Value::Str(String::from("10"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Int, Value::Str(String::from("10"))),
        (TokenType::NotEq, Value::Str(String::from("!="))),
        (TokenType::Int, Value::Str(String::from("9"))),
        //        (TokenType::Semicolon, Value::Str(String::from(";"))),
        (TokenType::Eof, Value::Str(String::from("\0"))),
    ];

    let l = &Lexer::new(input);
    for e in &tests {
        let t = l.next_token();
        assert_eq!(t.token_type, e.0);
        assert_eq!(t.value.unwrap(), e.1);
    }
}
<|endoftext|>


<commit_before>#![allow(unstable)]

use std::io::{self, fs};
use std::io::process::{Command, InheritFd};
use std::os;

fn run(cmd: &mut Command) {
    println!("running: {}", cmd);
    assert!(cmd.stdout(InheritFd(1))
            .stderr(InheritFd(2))
            .status()
            .unwrap()
            .success());
}

fn main() {
    let cwd = os::getcwd().unwrap();

    let root_dir = Path::new(os::getenv("CARGO_MANIFEST_DIR").unwrap());
    let out_dir = Path::new(os::getenv("OUT_DIR").expect("out dir must be specified"));

    let build_dir = out_dir.join("build");
    assert!(fs::mkdir_recursive(&build_dir, io::USER_DIR).is_ok());
    assert!(os::change_dir(&build_dir).is_ok());

    let lib_dir = out_dir.join("lib");
    assert!(fs::mkdir_recursive(&lib_dir, io::USER_DIR).is_ok());

    run(Command::new("cmake")
        .arg(root_dir.join("forestdb"))
        .arg("-DCMAKE_BUILD_TYPE=Release") // FIXME: use env for determine type
        .arg(format!("-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}", lib_dir.display()))
        .arg("-DSNAPPY_OPTION=Disable"));

    run(Command::new("make")
        .arg("forestdb")
        .arg("-j")
        .arg("2")); // -j 2 is probably minimum

    let _ = os::change_dir(&cwd);

    println!("cargo:rustc-flags=-l forestdb -L {}", lib_dir.display());
}
<commit_msg>Build fixes<commit_after>#![allow(unstable)]

use std::io::{self, fs};
use std::io::process::{Command, InheritFd};
use std::os;

fn run(cmd: &mut Command) {
    println!("running: {}", cmd);
    assert!(cmd.stdout(InheritFd(1))
            .stderr(InheritFd(2))
            .status()
            .unwrap()
            .success());
}

fn main() {
    let root_dir = Path::new(os::getenv("CARGO_MANIFEST_DIR").unwrap());
    let out_dir = Path::new(os::getenv("OUT_DIR").expect("out dir must be specified"));

    let build_dir = out_dir.join("build");
    assert!(fs::mkdir_recursive(&build_dir, io::USER_DIR).is_ok());
    assert!(os::change_dir(&build_dir).is_ok());

    let lib_dir = out_dir.join("lib");
    assert!(fs::mkdir_recursive(&lib_dir, io::USER_DIR).is_ok());

    let profile = match os::getenv("PROFILE").unwrap().as_slice() {
        "bench" | "release" => "Release",
        // FIXME: it should be Debug, but might fail as debug requires gcov/lcov to be installed
        _ => "RelWithDebugInfo",
    };

    run(Command::new("cmake")
        .arg(root_dir.join("forestdb"))
        .arg(format!("-DCMAKE_BUILD_TYPE={}", profile))
        .arg(format!("-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}", lib_dir.display()))
        .arg("-DSNAPPY_OPTION=Disable")
        .cwd(&build_dir));

    run(Command::new("cmake")
        .arg("--build").arg(".")
        .arg("--target").arg("forestdb")
        .cwd(&build_dir));

    println!("cargo:rustc-flags=-l forestdb -L {}", lib_dir.display());
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;

use std::collections::BTreeMap;

use rustc_serialize::json::{Json, ToJson};

/// An Optional value can contain Optional::Some<T> or Optional::Absent.
/// It is similar to an Option, but Optional::Absent means it will be
/// omitted when serialized.
pub enum Optional<T> {
    Value(T),
    Absent,
}

impl<T> Optional<T> {
    pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
        match self {
            Optional::Value(v) => f(v),
            Optional::Absent => def,
        }
    }
}

pub struct Location {
    pub address: Optional<String>,
    pub lat: f64,
    pub lon: f64,
}

pub struct Spacefed {
    pub spacenet: bool,
    pub spacesaml: bool,
    pub spacephone: bool,
}

pub struct Icon {
    pub open: String,
    pub close: String,
}

pub struct State {
    pub open: Option<bool>,
    pub lastchange: Optional<u64>,
    pub trigger_person: Optional<String>,
    pub message: Optional<String>,
    pub icon: Optional<Icon>,
}

pub struct Event {
    pub name: String,
    pub _type: String,
    pub timestamp: u64,
    pub extra: Optional<String>,
}

pub struct Contact {
    pub irc: Optional<String>,
    pub twitter: Optional<String>,
    pub foursquare: Optional<String>,
    pub email: Optional<String>,
}

pub struct Feed {
    pub _type: Optional<String>,
    pub url: String,
}

pub struct Feeds {
    pub blog: Optional<Feed>,
    pub wiki: Optional<Feed>,
    pub calendar: Optional<Feed>,
    pub flickr: Optional<Feed>,
}

pub struct Sensors {
    pub people_now_present: Optional<Vec<PeopleNowPresentSensor>>,
    pub temperature: Optional<Vec<TemperatureSensor>>,
}

pub struct PeopleNowPresentSensor {
    pub value: u32,
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
}

pub struct TemperatureSensor {
    pub value: f32,
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
}

pub struct Cache {
    pub schedule: String,
}

pub struct RadioShow {
    pub name: String,
    pub url: String,
    pub _type: String,
    pub start: String,
    pub end: String,
}

pub struct Status {

    // Hackerspace properties
    pub api: String,
    pub space: String,
    pub logo: String,
    pub url: String,
    pub location: Location,
    pub contact: Contact,

    // Hackerspace features / projects
    pub spacefed: Optional<Spacefed>,
    pub projects: Optional<Vec<String>>,
    pub cam: Optional<Vec<String>>,
    pub feeds: Optional<Feeds>,
    pub events: Optional<Vec<Event>>,
    pub radio_show: Optional<Vec<RadioShow>>,

    // SpaceAPI internal usage
    pub cache: Optional<Cache>,
    pub issue_report_channels: Vec<String>,

    // Mutable data
    pub state: State,
    pub sensors: Optional<Sensors>,

}

impl Status {

    /// Create a new Status object with only the minimum amount of fields
    pub fn new(space: String, logo: String, url: String, location: Location, contact: Contact, issue_report_channels: Vec<String>) -> Status {
        Status {
            api: "0.13".to_string(),
            space: space,
            logo: logo,
            url: url,
            location: location,
            contact: contact,

            spacefed: Optional::Absent,
            projects: Optional::Absent,
            cam: Optional::Absent,
            feeds: Optional::Absent,
            events: Optional::Absent,
            radio_show: Optional::Absent,

            cache: Optional::Absent,
            issue_report_channels: issue_report_channels,

            state: State {
                open: None,
                lastchange: Optional::Absent,
                trigger_person: Optional::Absent,
                message: Optional::Absent,
                icon: Optional::Absent,
            },
            sensors: Optional::Absent,
        }
    }

}

impl ToJson for Status {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();

        d.insert("api".to_string(), self.api.to_json());
        d.insert("space".to_string(), self.space.to_json());
        d.insert("logo".to_string(), self.logo.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("location".to_string(), self.location.to_json());
        d.insert("contact".to_string(), self.contact.to_json());

        match self.spacefed {
            Optional::Value(ref spacefed) => { d.insert("spacefed".to_string(), spacefed.to_json()); },
            Optional::Absent => (),
        };
        match self.projects {
            Optional::Value(ref projects) => { d.insert("projects".to_string(), projects.to_json()); },
            Optional::Absent => (),
        };
        match self.cam {
            Optional::Value(ref cam) => { d.insert("cam".to_string(), cam.to_json()); },
            Optional::Absent => (),
        };
        match self.feeds {
            Optional::Value(ref feeds) => { d.insert("feeds".to_string(), feeds.to_json()); },
            Optional::Absent => (),
        };
        match self.events {
            Optional::Value(ref events) => { d.insert("events".to_string(), events.to_json()); },
            Optional::Absent => (),
        };
        match self.radio_show {
            Optional::Value(ref radio_show) => { d.insert("radio_show".to_string(), radio_show.to_json()); },
            Optional::Absent => (),
        };

        match self.cache {
            Optional::Value(ref cache) => { d.insert("cache".to_string(), cache.to_json()); },
            Optional::Absent => (),
        };
        d.insert("issue_report_channels".to_string(), self.issue_report_channels.to_json());

        d.insert("state".to_string(), self.state.to_json());
        match self.sensors {
            Optional::Value(ref sensors) => { d.insert("sensors".to_string(), sensors.to_json()); },
            Optional::Absent => (),
        };

        Json::Object(d)
    }
}

impl ToJson for Location {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("lat".to_string(), self.lat.to_json());
        d.insert("lon".to_string(), self.lon.to_json());
        match self.address {
            Optional::Value(ref address) => {
                d.insert("address".to_string(), address.to_json());
            },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Spacefed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("spacenet".to_string(), self.spacenet.to_json());
        d.insert("spacesaml".to_string(), self.spacesaml.to_json());
        d.insert("spacephone".to_string(), self.spacephone.to_json());
        Json::Object(d)
    }
}

impl ToJson for Icon {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        d.insert("close".to_string(), self.close.to_json());
        Json::Object(d)
    }
}

impl ToJson for State {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        match self.lastchange {
            Optional::Value(ref lastchange) => { d.insert("lastchange".to_string(), lastchange.to_json()); },
            Optional::Absent => (),
        };
        match self.trigger_person {
            Optional::Value(ref trigger_person) => { d.insert("trigger_person".to_string(), trigger_person.to_json()); },
            Optional::Absent => (),
        };
        match self.message {
            Optional::Value(ref message) => { d.insert("message".to_string(), message.to_json()); },
            Optional::Absent => (),
        };
        match self.icon {
            Optional::Value(ref icon) => { d.insert("icon".to_string(), icon.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Event {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("timestamp".to_string(), self.timestamp.to_json());
        match self.extra {
            Optional::Value(ref extra) => { d.insert("extra".to_string(), extra.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Contact {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.irc {
            Optional::Value(ref irc) => { d.insert("irc".to_string(), irc.to_json()); },
            Optional::Absent => (),
        };
        match self.twitter {
            Optional::Value(ref twitter) => { d.insert("twitter".to_string(), twitter.to_json()); },
            Optional::Absent => (),
        };
        match self.foursquare {
            Optional::Value(ref foursquare) => { d.insert("foursquare".to_string(), foursquare.to_json()); },
            Optional::Absent => (),
        };
        match self.email {
            Optional::Value(ref email) => { d.insert("email".to_string(), email.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("url".to_string(), self.url.to_json());
        match self._type {
            Optional::Value(ref _type) => { d.insert("type".to_string(), _type.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feeds {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.blog {
            Optional::Value(ref blog) => { d.insert("blog".to_string(), blog.to_json()); },
            Optional::Absent => (),
        };
        match self.wiki {
            Optional::Value(ref wiki) => { d.insert("wiki".to_string(), wiki.to_json()); },
            Optional::Absent => (),
        };
        match self.calendar {
            Optional::Value(ref calendar) => { d.insert("calendar".to_string(), calendar.to_json()); },
            Optional::Absent => (),
        };
        match self.flickr {
            Optional::Value(ref flickr) => { d.insert("flickr".to_string(), flickr.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Sensors {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.people_now_present {
            Optional::Value(ref people_now_present) => { d.insert("people_now_present".to_string(), people_now_present.to_json()); },
            Optional::Absent => (),
        };
        match self.temperature {
            Optional::Value(ref temperature) => { d.insert("temperature".to_string(), temperature.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for PeopleNowPresentSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        match self.location {
            Optional::Value(ref location) => { d.insert("location".to_string(), location.to_json()); },
            Optional::Absent => (),
        };
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.names {
            Optional::Value(ref names) => { d.insert("names".to_string(), names.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for TemperatureSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        d.insert("unit".to_string(), self.unit.to_json());
        d.insert("location".to_string(), self.location.to_json());
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Cache {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("schedule".to_string(), self.schedule.to_json());
        Json::Object(d)
    }
}

impl ToJson for RadioShow {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("start".to_string(), self.start.to_json());
        d.insert("end".to_string(), self.end.to_json());
        Json::Object(d)
    }
}
<commit_msg>spaceapi: derive Debug, Copy and Clone for Optional<commit_after>extern crate rustc_serialize;

use std::collections::BTreeMap;

use rustc_serialize::json::{Json, ToJson};

/// An Optional value can contain Optional::Some<T> or Optional::Absent.
/// It is similar to an Option, but Optional::Absent means it will be
/// omitted when serialized.
#[derive(Debug, Copy, Clone)]
pub enum Optional<T> {
    Value(T),
    Absent,
}

impl<T> Optional<T> {
    pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
        match self {
            Optional::Value(v) => f(v),
            Optional::Absent => def,
        }
    }
}

pub struct Location {
    pub address: Optional<String>,
    pub lat: f64,
    pub lon: f64,
}

pub struct Spacefed {
    pub spacenet: bool,
    pub spacesaml: bool,
    pub spacephone: bool,
}

pub struct Icon {
    pub open: String,
    pub close: String,
}

pub struct State {
    pub open: Option<bool>,
    pub lastchange: Optional<u64>,
    pub trigger_person: Optional<String>,
    pub message: Optional<String>,
    pub icon: Optional<Icon>,
}

pub struct Event {
    pub name: String,
    pub _type: String,
    pub timestamp: u64,
    pub extra: Optional<String>,
}

pub struct Contact {
    pub irc: Optional<String>,
    pub twitter: Optional<String>,
    pub foursquare: Optional<String>,
    pub email: Optional<String>,
}

pub struct Feed {
    pub _type: Optional<String>,
    pub url: String,
}

pub struct Feeds {
    pub blog: Optional<Feed>,
    pub wiki: Optional<Feed>,
    pub calendar: Optional<Feed>,
    pub flickr: Optional<Feed>,
}

pub struct Sensors {
    pub people_now_present: Optional<Vec<PeopleNowPresentSensor>>,
    pub temperature: Optional<Vec<TemperatureSensor>>,
}

pub struct PeopleNowPresentSensor {
    pub value: u32,
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
}

pub struct TemperatureSensor {
    pub value: f32,
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
}

pub struct Cache {
    pub schedule: String,
}

pub struct RadioShow {
    pub name: String,
    pub url: String,
    pub _type: String,
    pub start: String,
    pub end: String,
}

pub struct Status {

    // Hackerspace properties
    pub api: String,
    pub space: String,
    pub logo: String,
    pub url: String,
    pub location: Location,
    pub contact: Contact,

    // Hackerspace features / projects
    pub spacefed: Optional<Spacefed>,
    pub projects: Optional<Vec<String>>,
    pub cam: Optional<Vec<String>>,
    pub feeds: Optional<Feeds>,
    pub events: Optional<Vec<Event>>,
    pub radio_show: Optional<Vec<RadioShow>>,

    // SpaceAPI internal usage
    pub cache: Optional<Cache>,
    pub issue_report_channels: Vec<String>,

    // Mutable data
    pub state: State,
    pub sensors: Optional<Sensors>,

}

impl Status {

    /// Create a new Status object with only the minimum amount of fields
    pub fn new(space: String, logo: String, url: String, location: Location, contact: Contact, issue_report_channels: Vec<String>) -> Status {
        Status {
            api: "0.13".to_string(),
            space: space,
            logo: logo,
            url: url,
            location: location,
            contact: contact,

            spacefed: Optional::Absent,
            projects: Optional::Absent,
            cam: Optional::Absent,
            feeds: Optional::Absent,
            events: Optional::Absent,
            radio_show: Optional::Absent,

            cache: Optional::Absent,
            issue_report_channels: issue_report_channels,

            state: State {
                open: None,
                lastchange: Optional::Absent,
                trigger_person: Optional::Absent,
                message: Optional::Absent,
                icon: Optional::Absent,
            },
            sensors: Optional::Absent,
        }
    }

}

impl ToJson for Status {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();

        d.insert("api".to_string(), self.api.to_json());
        d.insert("space".to_string(), self.space.to_json());
        d.insert("logo".to_string(), self.logo.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("location".to_string(), self.location.to_json());
        d.insert("contact".to_string(), self.contact.to_json());

        match self.spacefed {
            Optional::Value(ref spacefed) => { d.insert("spacefed".to_string(), spacefed.to_json()); },
            Optional::Absent => (),
        };
        match self.projects {
            Optional::Value(ref projects) => { d.insert("projects".to_string(), projects.to_json()); },
            Optional::Absent => (),
        };
        match self.cam {
            Optional::Value(ref cam) => { d.insert("cam".to_string(), cam.to_json()); },
            Optional::Absent => (),
        };
        match self.feeds {
            Optional::Value(ref feeds) => { d.insert("feeds".to_string(), feeds.to_json()); },
            Optional::Absent => (),
        };
        match self.events {
            Optional::Value(ref events) => { d.insert("events".to_string(), events.to_json()); },
            Optional::Absent => (),
        };
        match self.radio_show {
            Optional::Value(ref radio_show) => { d.insert("radio_show".to_string(), radio_show.to_json()); },
            Optional::Absent => (),
        };

        match self.cache {
            Optional::Value(ref cache) => { d.insert("cache".to_string(), cache.to_json()); },
            Optional::Absent => (),
        };
        d.insert("issue_report_channels".to_string(), self.issue_report_channels.to_json());

        d.insert("state".to_string(), self.state.to_json());
        match self.sensors {
            Optional::Value(ref sensors) => { d.insert("sensors".to_string(), sensors.to_json()); },
            Optional::Absent => (),
        };

        Json::Object(d)
    }
}

impl ToJson for Location {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("lat".to_string(), self.lat.to_json());
        d.insert("lon".to_string(), self.lon.to_json());
        match self.address {
            Optional::Value(ref address) => {
                d.insert("address".to_string(), address.to_json());
            },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Spacefed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("spacenet".to_string(), self.spacenet.to_json());
        d.insert("spacesaml".to_string(), self.spacesaml.to_json());
        d.insert("spacephone".to_string(), self.spacephone.to_json());
        Json::Object(d)
    }
}

impl ToJson for Icon {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        d.insert("close".to_string(), self.close.to_json());
        Json::Object(d)
    }
}

impl ToJson for State {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        match self.lastchange {
            Optional::Value(ref lastchange) => { d.insert("lastchange".to_string(), lastchange.to_json()); },
            Optional::Absent => (),
        };
        match self.trigger_person {
            Optional::Value(ref trigger_person) => { d.insert("trigger_person".to_string(), trigger_person.to_json()); },
            Optional::Absent => (),
        };
        match self.message {
            Optional::Value(ref message) => { d.insert("message".to_string(), message.to_json()); },
            Optional::Absent => (),
        };
        match self.icon {
            Optional::Value(ref icon) => { d.insert("icon".to_string(), icon.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Event {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("timestamp".to_string(), self.timestamp.to_json());
        match self.extra {
            Optional::Value(ref extra) => { d.insert("extra".to_string(), extra.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Contact {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.irc {
            Optional::Value(ref irc) => { d.insert("irc".to_string(), irc.to_json()); },
            Optional::Absent => (),
        };
        match self.twitter {
            Optional::Value(ref twitter) => { d.insert("twitter".to_string(), twitter.to_json()); },
            Optional::Absent => (),
        };
        match self.foursquare {
            Optional::Value(ref foursquare) => { d.insert("foursquare".to_string(), foursquare.to_json()); },
            Optional::Absent => (),
        };
        match self.email {
            Optional::Value(ref email) => { d.insert("email".to_string(), email.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("url".to_string(), self.url.to_json());
        match self._type {
            Optional::Value(ref _type) => { d.insert("type".to_string(), _type.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feeds {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.blog {
            Optional::Value(ref blog) => { d.insert("blog".to_string(), blog.to_json()); },
            Optional::Absent => (),
        };
        match self.wiki {
            Optional::Value(ref wiki) => { d.insert("wiki".to_string(), wiki.to_json()); },
            Optional::Absent => (),
        };
        match self.calendar {
            Optional::Value(ref calendar) => { d.insert("calendar".to_string(), calendar.to_json()); },
            Optional::Absent => (),
        };
        match self.flickr {
            Optional::Value(ref flickr) => { d.insert("flickr".to_string(), flickr.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Sensors {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.people_now_present {
            Optional::Value(ref people_now_present) => { d.insert("people_now_present".to_string(), people_now_present.to_json()); },
            Optional::Absent => (),
        };
        match self.temperature {
            Optional::Value(ref temperature) => { d.insert("temperature".to_string(), temperature.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for PeopleNowPresentSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        match self.location {
            Optional::Value(ref location) => { d.insert("location".to_string(), location.to_json()); },
            Optional::Absent => (),
        };
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.names {
            Optional::Value(ref names) => { d.insert("names".to_string(), names.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for TemperatureSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        d.insert("unit".to_string(), self.unit.to_json());
        d.insert("location".to_string(), self.location.to_json());
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Cache {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("schedule".to_string(), self.schedule.to_json());
        Json::Object(d)
    }
}

impl ToJson for RadioShow {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("start".to_string(), self.start.to_json());
        d.insert("end".to_string(), self.end.to_json());
        Json::Object(d)
    }
}
<|endoftext|>


<commit_before>fn main() {

// this is simple formatting
println!("Today is {} ", "Tuesday");

println!("{0}, this is {1} and {1}, this is {0}", "Raj" , "Kiran");

println!("{arg1} {arg2} {arg3}", arg1="This is arg1", arg2="This is arg2", arg3="This is arg3");

println!("{string:>width$}", string="hello", width=10);

}
<commit_msg>formatting example<commit_after>struct emp {
name: string,
no: u32,
}

fn main() {

// this is simple formatting
println!("Today is {} ", "Tuesday");

println!("{0}, this is {1} and {1}, this is {0}", "Raj" , "Kiran");

println!("{arg1} {arg2} {arg3}", arg1="This is arg1", arg2="This is arg2", arg3="This is arg3");

println!("{string:>width$}", string="hello", width=10);
let employee =  emp{ name: "rk", no: 10};

let (x,y) = employee;
println!(x);

}
<|endoftext|>


<commit_before>// Anima Engine. The quirky game engine
// Copyright (C) 2016  Dragoș Tiselice
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use super::game::Game;

use std::time::Instant;

/// A `struct` that helps you create a very simple game loop.
///
/// # Examples
///
/// ```
/// # use std::time::Duration;
/// # use anima_engine::game::Game;
/// # use anima_engine::game::GameLoop;
/// pub struct MyGame;
///
/// impl Game for MyGame {
///     fn update(&self, dt: Duration) -> bool {
///         // Update game state.
///         // Return `false` when game needs to stop.
///         false
///     }
/// }
///
/// GameLoop::new(MyGame).run();
/// ```
pub struct GameLoop<T: Game> {
    pub game: T
}

impl<T: Game> GameLoop<T> {
    /// Creates a `GameLoop`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::time::Duration;
    /// # use anima_engine::game::Game;
    /// # use anima_engine::game::GameLoop;
    /// pub struct MyGame;
    ///
    /// impl Game for MyGame {
    ///     fn update(&self, dt: Duration) -> bool {
    ///         // Update game state.
    ///         // Return `false` when game needs to stop.
    ///         false
    ///     }
    /// }
    ///
    /// GameLoop::new(MyGame);
    /// ```
    pub fn new(game: T) -> GameLoop<T> {
        GameLoop { game: game }
    }

    /// Runs `GameLoop`'s `Game` in a loop while feeding the time between frames to the `Game`'s
    /// `update`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::time::Duration;
    /// # use anima_engine::game::Game;
    /// # use anima_engine::game::GameLoop;
    /// pub struct MyGame;
    ///
    /// impl Game for MyGame {
    ///     fn update(&self, dt: Duration) -> bool {
    ///         // Update game state.
    ///         // Return `false` when game needs to stop.
    ///         false
    ///     }
    /// }
    ///
    /// GameLoop::new(MyGame).run();
    /// ```
    pub fn run(&self) {
        let mut last = Instant::now();

        while self.game.update(last.elapsed()) {
            last = Instant::now();
        }
    }
}
<commit_msg>Fix regression in game_loop<commit_after>// Anima Engine. The quirky game engine
// Copyright (C) 2016  Dragoș Tiselice
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use super::game::Game;

use std::time::Instant;

/// A `struct` that helps you create a very simple game loop.
///
/// # Examples
///
/// ```
/// # use std::time::Duration;
/// # use anima_engine::game::Game;
/// # use anima_engine::game::GameLoop;
/// pub struct MyGame;
///
/// impl Game for MyGame {
///     fn update(&self, dt: Duration) -> bool {
///         // Update game state.
///         // Return `false` when game needs to stop.
///         false
///     }
/// }
///
/// GameLoop::new(MyGame).run();
/// ```
pub struct GameLoop<T: Game> {
    pub game: T
}

impl<T: Game> GameLoop<T> {
    /// Creates a `GameLoop`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::time::Duration;
    /// # use anima_engine::game::Game;
    /// # use anima_engine::game::GameLoop;
    /// pub struct MyGame;
    ///
    /// impl Game for MyGame {
    ///     fn update(&self, dt: Duration) -> bool {
    ///         // Update game state.
    ///         // Return `false` when game needs to stop.
    ///         false
    ///     }
    /// }
    ///
    /// GameLoop::new(MyGame);
    /// ```
    pub fn new(game: T) -> GameLoop<T> {
        GameLoop { game: game }
    }

    /// Runs `GameLoop`'s `Game` in a loop while feeding the time between frames to the `Game`'s
    /// `update`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::time::Duration;
    /// # use anima_engine::game::Game;
    /// # use anima_engine::game::GameLoop;
    /// pub struct MyGame;
    ///
    /// impl Game for MyGame {
    ///     fn update(&self, dt: Duration) -> bool {
    ///         // Update game state.
    ///         // Return `false` when game needs to stop.
    ///         false
    ///     }
    /// }
    ///
    /// GameLoop::new(MyGame).run();
    /// ```
    pub fn run(&self) {
        let mut last = Instant::now();

        loop {
            let start = Instant::now();

            if !self.game.update(start - last) {
                break;
            }

            last = start;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>How to deal with init, when type-inference doesn't work<commit_after><|endoftext|>


<commit_before>//! Common HTTP functionality for the Teepee project.
//!
//! Anything shared between both client and server belongs in here, but this crate is not expected
//! to be used directly.
//!
//! Any crate using types from this crate should re‐export them. For example, the ``status`` module
//! should be exported in the root of the HTTP client crate ``httpc`` so that people can write
//! ``httpc::status`` instead of ``httpcommon::status``.

#![crate_id = "httpcommon#0.1-pre"]
#![comment = "Common HTTP functionality for the Teepee project"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![doc(html_root_url = "http://www.rust-ci.org/teepee/httpcommon/doc/")]

#![deny(unnecessary_qualification)]
#![deny(non_uppercase_statics)]
#![deny(unnecessary_typecast)]
#![deny(missing_doc)]
//#![deny(unstable)]
#![deny(unused_result)]
#![deny(deprecated_owned_vector)]

pub mod status;
<commit_msg>Account for renamed repository.<commit_after>//! Common HTTP functionality for the Teepee project.
//!
//! Anything shared between both client and server belongs in here, but this crate is not expected
//! to be used directly.
//!
//! Any crate using types from this crate should re‐export them. For example, the ``status`` module
//! should be exported in the root of the HTTP client crate ``httpc`` so that people can write
//! ``httpc::status`` instead of ``httpcommon::status``.

#![crate_id = "httpcommon#0.1-pre"]
#![comment = "Common HTTP functionality for the Teepee project"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![doc(html_root_url = "http://www.rust-ci.org/teepee/teepee/doc/")]

#![deny(unnecessary_qualification)]
#![deny(non_uppercase_statics)]
#![deny(unnecessary_typecast)]
#![deny(missing_doc)]
//#![deny(unstable)]
#![deny(unused_result)]
#![deny(deprecated_owned_vector)]

pub mod status;
<|endoftext|>