<commit_before>use std::fmt::Debug;
use std::mem;
use std::sync::mpsc;
use std::sync::RwLock;

use rayon::prelude::*;
use rayon;
use anymap;

#[derive(Clone, Default, Debug)]
pub struct Component {
    data: i32,
}

// #[derive(Clone, Default)]
// pub struct VecResource<T> {
//     data: Vec<T>,
// }

#[derive(Clone, Default, Debug)]
pub struct VecResource<T>
    where T: Debug
{
    data: Vec<T>,
}

impl<T> VecResource<T>
    where T: Debug
{
    pub fn new() -> Self {
        VecResource { data: Vec::new() }
    }
}

pub struct Entity(u32);

pub type InputChannel<T> = Vec<T>;
pub type OutputChannel<T> = mpsc::Sender<T>;

pub struct EventSender<E> {
    channels: Vec<RwLock<Vec<E>>>
}

// We never clone the channel senders, so I'm not sure if this is
// really better than just having a Vec<RwLock<E>>, but...
impl<E> EventSender<E> where E: Send + Sync {
    fn new() -> Self {
        EventSender {
            channels: Vec::new(),
        }
    }

    pub fn send_to_entity(&self, entity: Entity, event: E) {
        let channel = self.channels.get(entity.0 as usize).expect("Sent message to non-existent entity!");
        let channel_write = &mut channel.write().expect("Attempted to write on poisoned RwLock, aiee!");
        channel_write.push(event);
    }

    pub fn clear(&mut self) {
        // Might as well parallelize?
        // Overhead might not make it worth it.
        // Try it later, see if it matters.

        self.channels.par_iter()
            .for_each(|q| {
                // Not sure if this is actually an optimization but it might be?
                // Depends on how expensive getting a write lock is.
                // ...Probably not more expensive than getting a read lock, tbh.
                let to_clear = {
                    let q_read = &mut q.try_read().unwrap();
                    q_read.len() > 0
                };
                if to_clear {
                    let q_write = &mut q.try_write().expect("Tried to clear event queues while in use; should never happen!");
                    q_write.clear();
                }
            });
    }
}

// I feel a little ghetto making one global event type for everything,
// but we'll roll with it for now.
pub struct World<E> where E: Send {
    entities: Vec<Entity>,
    current_components: anymap::AnyMap,
    next_components: anymap::AnyMap,
    current_events: EventSender<E>,
    next_events: EventSender<E>,
}

impl<E> World<E> where E: Send + Sync {
    pub fn new() -> Self {
        World {
            entities: Vec::new(),
            current_components: anymap::AnyMap::new(),
            next_components: anymap::AnyMap::new(),
            current_events: EventSender::new(),
            next_events: EventSender::new(),
        }
    }

    fn register<T>(&mut self)
        where T: Default + 'static
    {
        self.current_components.insert(T::default());
        self.next_components.insert(T::default());
    }

    fn run1<F, C>(&mut self, f: F)
        where F: Fn(&C, &[E], &EventSender<E>) -> C + Sync,
              C: Debug + Send + Sync + 'static
    {
        if let Some(resource) = self.current_components.get::<VecResource<C>>() {
            if let Some(next_components) = self.next_components.get_mut::<VecResource<C>>() {
                let d: &[C] = &resource.data;
                let v = &mut next_components.data;
                let next_events = &self.next_events;
                d.par_iter()
                    .zip(&self.current_events.channels)
                    .map(|(c, e)| {
                        let event_queue = e.read().expect("Aiee event queue is poisoned in World::run()");
                        f(c, &event_queue[..], next_events)
                    })
                    .collect_into(v);
            } else {
                panic!("current_components exists but next_components does not, this should never happen!")
            }
        } else {
            panic!("Tried to run a system on an unknown component type");
        }
    }

    fn run2<F, C1, C2>(&mut self, f: F)
        where F: Fn(&C1, &C2, &[E], &EventSender<E>) -> (C1, C2) + Sync,
              C1: Debug + Send + Sync + 'static,
              C2: Debug + Send + Sync + 'static
    {
        let current1 = self.current_components.get::<VecResource<C1>>().expect("Tried to run a system on an unknown component type");
        let current2 = self.current_components.get::<VecResource<C2>>().expect("Tried to run a system on an unknown component type");
        let c1: &[C1] = &current1.data;
        let c2: &[C2] = &current2.data;

        let next_events = &self.next_events;
        // BUGGO: Aieee, my perfect non-allocating system is now poisoned!
        let mut next_hax: Vec<(C1, C2)> = Vec::with_capacity(c1.len());
        c1.par_iter()
            .zip(c2)
            .zip(&self.current_events.channels)
            .map(|((comp1, comp2), e)| {
                let event_queue = e.read().expect("Aiee event queue is poisoned in World::run(); did a system crash?");
                f(comp1, comp2, &event_queue[..], next_events)
            })
            .collect_into(&mut next_hax);
        //.enumerate()
        // This doesn't seem to work 'cause it gets pesky about the closure altering self,
        // for some reason.  Hmm.
        //.for_each(|(i, (comp1, comp2))| {
            //    next1.data[i] = comp1;
            //});
        //.collect_into(v);
        let (r1, r2): (Vec<C1>, Vec<C2>) = next_hax.into_iter().unzip();
        {
            let next1 = self.next_components.get_mut::<VecResource<C1>>().expect("current_components exists but next_components does not, this should never happen!");
            let n1 = &mut next1.data;
            *n1 = r1;
        }
        {
            let next2 = self.next_components.get_mut::<VecResource<C2>>().expect("current_components exists but next_components does not, this should never happen!");
            let n2 = &mut next2.data;
            *n2 = r2;
        }
    }

    // This function finalizes the end of the frame.
    // Delivers events, flips the current and next components, etc.
    fn finish(&mut self) {
        // Switch components
        {
            let m1 = &mut self.current_components;
            let m2 = &mut self.next_components;
            mem::swap(m1, m2);
        }

        // empty out old events, deliver new ones.
        // Making the iterator work easily takes a little
        // bit of explicit type-mongling
        {
            let e1 = &mut self.current_events;
            let e2 = &mut self.next_events;
            mem::swap(e1, e2);
        }
        self.next_events.clear();
    }

    fn next_entity(&self) -> Entity {
        use std::u32;
        assert!(self.entities.len() < u32::MAX as usize);
        Entity(self.entities.len() as u32)
    }

    fn create_entity<T>(&mut self, component: T) where T: Debug + Send + Sync + Clone + 'static {
        let e = self.next_entity();
        self.entities.push(e);

        let nc: &mut VecResource<T> = self.next_components.entry().or_insert_with(VecResource::new);
        nc.data.push(component.clone());
        let components: &mut VecResource<T> = self.current_components.entry().or_insert_with(VecResource::new);
        components.data.push(component);

        self.current_events.channels.push(RwLock::new(Vec::new()));
        self.next_events.channels.push(RwLock::new(Vec::new()));
    }

    fn send_to_entity(&mut self, entity: Entity, event: E) {
        self.next_events.send_to_entity(entity, event);
    }
}

#[cfg(test)]
mod tests {

    use super::*;
    use rand;

    #[test]
    fn test_world_thingy() {
        let entity_count = 100;
        let message_count = 1000;
        let loops = 100;
        let mut w = World::new();
        for i in 0..entity_count {
            w.create_entity(i as usize);
        }
        for i in 0..message_count {
            let dest = rand::random::<u32>() % (entity_count as u32);
            w.send_to_entity(Entity(dest), 0);
        }
        for _ in 0..loops {
            // Call finish to make the event routing happen.
            w.finish();
            w.run1(|comp: &usize, events: &[usize], writer: &EventSender<usize>| {
                // println!("Component: {} Event: {:?}", comp, events);
                // Just send any event you get to the next entity index;
                // the event number is how many times it's been sent.
                for e in events {
                    writer.send_to_entity(Entity(((*comp+1) % entity_count) as u32), *e + 1);
                }
                *comp
            });
            //println!("Entit are {:?}", results);
        }
        let mut desired_results: Vec<u32> = Vec::new();
        desired_results.extend(&[2, 3, 4, 5, 6, 7, 8, 9, 10, 11][..]);
        assert!(false);
    }
}
<commit_msg>Stubbing out dealing with multiple component types.<commit_after>use std::fmt::Debug;
use std::mem;
use std::sync::mpsc;
use std::sync::RwLock;

use rayon::prelude::*;
use rayon;
use anymap;

#[derive(Clone, Default, Debug)]
pub struct Component {
    data: i32,
}

// #[derive(Clone, Default)]
// pub struct VecResource<T> {
//     data: Vec<T>,
// }

#[derive(Clone, Default, Debug)]
pub struct VecResource<T>
    where T: Debug
{
    data: Vec<T>,
}

impl<T> VecResource<T>
    where T: Debug
{
    pub fn new() -> Self {
        VecResource { data: Vec::new() }
    }
}

#[derive(Clone, Debug)]
pub struct Entity(u32);

pub type InputChannel<T> = Vec<T>;
pub type OutputChannel<T> = mpsc::Sender<T>;

pub struct EventSender<E> {
    channels: Vec<RwLock<Vec<E>>>
}

// We never clone the channel senders, so I'm not sure if this is
// really better than just having a Vec<RwLock<E>>, but...
impl<E> EventSender<E> where E: Send + Sync {
    fn new() -> Self {
        EventSender {
            channels: Vec::new(),
        }
    }

    pub fn send_to_entity(&self, entity: Entity, event: E) {
        let channel = self.channels.get(entity.0 as usize).expect("Sent message to non-existent entity!");
        let channel_write = &mut channel.write().expect("Attempted to write on poisoned RwLock, aiee!");
        channel_write.push(event);
    }

    pub fn clear(&mut self) {
        // Might as well parallelize?
        // Overhead might not make it worth it.
        // Try it later, see if it matters.

        self.channels.par_iter()
            .for_each(|q| {
                // Not sure if this is actually an optimization but it might be?
                // Depends on how expensive getting a write lock is.
                // ...Probably not more expensive than getting a read lock, tbh.
                let to_clear = {
                    let q_read = &mut q.try_read().unwrap();
                    q_read.len() > 0
                };
                if to_clear {
                    let q_write = &mut q.try_write().expect("Tried to clear event queues while in use; should never happen!");
                    q_write.clear();
                }
            });
    }
}

// I feel a little ghetto making one global event type for everything,
// but we'll roll with it for now.
pub struct World<E> where E: Send {
    entities: Vec<Entity>,
    current_components: anymap::AnyMap,
    next_components: anymap::AnyMap,
    current_events: EventSender<E>,
    next_events: EventSender<E>,
}

impl<E> World<E> where E: Send + Sync {
    pub fn new() -> Self {
        World {
            entities: Vec::new(),
            current_components: anymap::AnyMap::new(),
            next_components: anymap::AnyMap::new(),
            current_events: EventSender::new(),
            next_events: EventSender::new(),
        }
    }

    fn register<T>(&mut self)
        where T: Default + 'static
    {
        self.current_components.insert(T::default());
        self.next_components.insert(T::default());
    }

    fn run1<F, C>(&mut self, f: F)
        where F: Fn(&C, &[E], &EventSender<E>) -> C + Sync,
              C: Debug + Send + Sync + 'static
    {
        if let Some(resource) = self.current_components.get::<VecResource<C>>() {
            if let Some(next_components) = self.next_components.get_mut::<VecResource<C>>() {
                let d: &[C] = &resource.data;
                let v = &mut next_components.data;
                let next_events = &self.next_events;
                d.par_iter()
                    .zip(&self.current_events.channels)
                    .map(|(c, e)| {
                        let event_queue = e.read().expect("Aiee event queue is poisoned in World::run()");
                        f(c, &event_queue[..], next_events)
                    })
                    .collect_into(v);
            } else {
                panic!("current_components exists but next_components does not, this should never happen!")
            }
        } else {
            panic!("Tried to run a system on an unknown component type");
        }
    }

    fn run2<F, C1, C2>(&mut self, f: F)
        where F: Fn(&C1, &C2, &[E], &EventSender<E>) -> (C1, C2) + Sync,
              C1: Debug + Send + Sync + 'static,
              C2: Debug + Send + Sync + 'static
    {
        let current1 = self.current_components.get::<VecResource<C1>>().expect("Tried to run a system on an unknown component type");
        let current2 = self.current_components.get::<VecResource<C2>>().expect("Tried to run a system on an unknown component type");
        let c1: &[C1] = &current1.data;
        let c2: &[C2] = &current2.data;

        let next_events = &self.next_events;
        // BUGGO: Aieee, my perfect non-allocating system is now poisoned!
        let mut next_hax: Vec<(C1, C2)> = Vec::with_capacity(c1.len());
        c1.par_iter()
            .zip(c2)
            .zip(&self.current_events.channels)
            .map(|((comp1, comp2), e)| {
                let event_queue = e.read().expect("Aiee event queue is poisoned in World::run(); did a system crash?");
                f(comp1, comp2, &event_queue[..], next_events)
            })
            .collect_into(&mut next_hax);
        //.enumerate()
        // This doesn't seem to work 'cause it gets pesky about the closure altering self,
        // for some reason.  Hmm.
        //.for_each(|(i, (comp1, comp2))| {
            //    next1.data[i] = comp1;
            //});
        //.collect_into(v);
        let (r1, r2): (Vec<C1>, Vec<C2>) = next_hax.into_iter().unzip();
        {
            let next1 = self.next_components.get_mut::<VecResource<C1>>().expect("current_components exists but next_components does not, this should never happen!");
            let n1 = &mut next1.data;
            *n1 = r1;
        }
        {
            let next2 = self.next_components.get_mut::<VecResource<C2>>().expect("current_components exists but next_components does not, this should never happen!");
            let n2 = &mut next2.data;
            *n2 = r2;
        }
    }

    // This function finalizes the end of the frame.
    // Delivers events, flips the current and next components, etc.
    fn finish(&mut self) {
        // Switch components
        {
            let m1 = &mut self.current_components;
            let m2 = &mut self.next_components;
            mem::swap(m1, m2);
        }

        // empty out old events, deliver new ones.
        // Making the iterator work easily takes a little
        // bit of explicit type-mongling
        {
            let e1 = &mut self.current_events;
            let e2 = &mut self.next_events;
            mem::swap(e1, e2);
        }
        self.next_events.clear();
    }

    fn next_entity(&self) -> Entity {
        use std::u32;
        assert!(self.entities.len() < u32::MAX as usize);
        Entity(self.entities.len() as u32)
    }

    fn create_entity<C1, C2>(&mut self, component1: C1, component2: C2) -> Entity
        where C1: Debug + Send + Sync + Clone + 'static,
              C2: Debug + Send + Sync + Clone + 'static,
    {
        let e = self.next_entity();
        self.entities.push(e.clone());
        self.current_events.channels.push(RwLock::new(Vec::new()));
        self.next_events.channels.push(RwLock::new(Vec::new()));

        {
            let nc: &mut VecResource<C1> = self.next_components.entry().or_insert_with(VecResource::new);
            nc.data.push(component1.clone());
            let components: &mut VecResource<C1> = self.current_components.entry().or_insert_with(VecResource::new);
            components.data.push(component1);
        }
        {
            let nc: &mut VecResource<C2> = self.next_components.entry().or_insert_with(VecResource::new);
            nc.data.push(component2.clone());
            let components: &mut VecResource<C2> = self.current_components.entry().or_insert_with(VecResource::new);
            components.data.push(component2);
        }

        e
    }

    /*
Uninitialized components makes this tricky,
as does making sure we register all component types
before adding them.
Not impossible, just takes a little finesse.
How does specs do it?
    fn add_component<C>(&mut self, entity: Entity, component: C)
        where C: Debug + Send + Sync + Clone + 'static {
        let nc: &mut VecResource<T> = self.next_components.entry().or_insert_with(VecResource::new);
        nc.data.push(component.clone());
        let components: &mut VecResource<T> = self.current_components.entry().or_insert_with(VecResource::new);
        components.data.push(component);
    }
*/

    fn send_to_entity(&mut self, entity: Entity, event: E) {
        self.next_events.send_to_entity(entity, event);
    }
}

#[cfg(test)]
mod tests {

    use super::*;
    use rand;

    #[test]
    fn test_world_thingy() {
        let entity_count = 100;
        let message_count = 1000;
        let loops = 100;
        let mut w = World::new();
        for i in 0..entity_count {
            w.create_entity(i as usize, ());
        }
        for i in 0..message_count {
            let dest = rand::random::<u32>() % (entity_count as u32);
            w.send_to_entity(Entity(dest), 0);
        }
        for _ in 0..loops {
            // Call finish to make the event routing happen.
            w.finish();
            w.run1(|comp: &usize, events: &[usize], writer: &EventSender<usize>| {
                // println!("Component: {} Event: {:?}", comp, events);
                // Just send any event you get to the next entity index;
                // the event number is how many times it's been sent.
                for e in events {
                    writer.send_to_entity(Entity(((*comp+1) % entity_count) as u32), *e + 1);
                }
                *comp
            });
            //println!("Entit are {:?}", results);
        }
        let mut desired_results: Vec<u32> = Vec::new();
        desired_results.extend(&[2, 3, 4, 5, 6, 7, 8, 9, 10, 11][..]);
        assert!(false);
    }
}
<|endoftext|>


<commit_before>use atom::*;
use symbol;
use errors::*;
use std::fmt;
use std::rc::Rc;
use std::cell::RefCell;

#[derive (Debug, Clone, PartialEq)]
struct Entry {
    key: symbol::InternedStr,
    value: Atom,
}

impl fmt::Display for Entry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} => {}", self.key, self.value)
    }
}

#[derive(Debug,PartialEq)]
struct EnvGeneration {
    value: Vec<Entry>,
    parent: Option<Env>,
}

impl fmt::Display for EnvGeneration {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "EnvGeneration[{:p}]", self));
        for i in &self.value {
            try!(write!(f, "\t{}", i));
        }
        Ok(())
    }
}

impl EnvGeneration {
    fn new(parent: Option<Env>) -> EnvGeneration {
        EnvGeneration {
            value: Vec::new(),
            parent: parent,
        }
    }

    fn find(&self, key: &str) -> Option<&Entry> {
        self.value.iter().rev().find(|entry| entry.key.as_ref() == key)
    }
}

#[derive (Debug, Clone, PartialEq)]
pub struct Env(Rc<RefCell<EnvGeneration>>);

impl Default for Env {
    fn default() -> Env {
        Env::new(None)
    }
}

impl fmt::Display for Env {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let gen = self.0.borrow();
        try!(write!(f, "Top-level: EnvGeneration: {}\n", *gen));

        if let Some(ref parent) = gen.parent {
            try!(write!(f, "parent: {}\n", parent));
        } else {
            try!(write!(f, "no parent\n"));
        }
        Ok(())
    }
}

impl Env {
    pub fn new(parent: Option<Env>) -> Env {
        Env(Rc::new(RefCell::new(EnvGeneration::new(parent))))
    }

    fn find(&self, key: &str) -> Option<Atom> {
        let gen = self.0.borrow();
        let value = &gen.value;
        match value.iter().rev().find(|entry| entry.key.as_ref() == key) {
            Some(ref entry) => Some(entry.value.clone()),
            None => {
                if let Some(ref parent) = gen.parent {
                    parent.find(key)
                } else {
                    None
                }
            }
        }
    }

    #[allow(dead_code)]
    pub fn num_generations(&self) -> usize {
        self.num_gen(1)
    }

    fn num_gen(&self, c: usize) -> usize {
        let gen = self.0.borrow();
        if let Some(ref parent) = gen.parent {
            return parent.num_gen(c + 1)
        }
        else {
            c
        }
    }

    pub fn bind_mut(&mut self, params: &[Atom], args: &[Atom]) {
        let mut params_iter = params.iter();
        let mut args_iter = args.iter();
        while let Some(&Atom::Symbol(ref sym)) = params_iter.next() {
            if sym.as_ref() == "&" {
                if let Some(&Atom::Symbol(ref splat)) = params_iter.next() {
                    let vals = args_iter.cloned().collect();
                    self.0.borrow_mut().value.push(Entry {
                        key: *splat,
                        value: Atom::list(vals),
                    });
                    break;
                }
            } else {
                let arg = args_iter.next().cloned().unwrap_or(Atom::Nil);

                {
                    // tricking the borrow checker here
                    let mut gen = self.0.borrow_mut();

                    if let Some(mut entry) = gen.value.iter_mut().find(|entry| entry.key == *sym) {
                        entry.value = arg;
                        continue;
                    }
                }

                self.0.borrow_mut().value.push(Entry {
                    key: *sym,
                    value: arg,
                });
            }
        }
    }

    pub fn bind(&mut self, params: &[Atom], args: &[Atom]) -> Env {
        let mut arg_map = Vec::with_capacity(params.len());
        let mut params_iter = params.iter();
        let mut args_iter = args.iter();

        while let Some(&Atom::Symbol(ref sym)) = params_iter.next() {
            if sym.as_ref() == "&" {
                if let Some(&Atom::Symbol(ref splat)) = params_iter.next() {
                    let vals = args_iter.cloned().collect();
                    arg_map.push(Entry {
                        key: *splat,
                        value: Atom::list(vals),
                    });
                    break;
                }
            } else {
                let arg = args_iter.next().cloned().unwrap_or(Atom::Nil);

                self.0.borrow_mut().value.push(Entry {
                    key: *sym,
                    value: arg,
                });
            }
        }

        let env_gen = EnvGeneration {
            value: arg_map,
            parent: Some(self.clone()),
        };
        Env(Rc::new(RefCell::new(env_gen)))
    }

    pub fn get(&self, key: &str) -> Option<Atom> {
        self.find(key)
    }

    pub fn define(&mut self, key: symbol::InternedStr, value: Atom) -> Result<Atom, Error> {
        if let Some(_) = self.0.borrow().find(key.as_ref()) {
            // println!("env is: {}", self);
            return Err(invalid_arg(&format!("define has entry already: {}", key.as_ref())));
        }
        self.0.borrow_mut().value.push(Entry {
            key: key,
            value: value,
        });
        Ok(Atom::Symbol(key))
    }

    pub fn set(&mut self, key: symbol::InternedStr, value: Atom) -> Result<Atom, Error> {
        {
            // set in current generation
            let mut gen = self.0.borrow_mut();
            if let Some(mut entry) = gen.value.iter_mut().find(|entry| entry.key == key) {
                entry.value = value;
                return Ok(Atom::Symbol(key));
            }
        }

        if let Some(ref mut parent) = self.0.borrow_mut().parent {
            parent.set(key, value)
        } else {
            Err(invalid_arg("in set"))
        }
    }
}

#[cfg(test)]
mod tests {
    use self::super::*;
    use atom::*;
    use errors::*;
    use symbol::*;

    #[test]
    fn nested_get() {
        let mut env = Env::new(None);

        env.define(intern("foo"), Atom::String("bar".to_owned())).unwrap();

        let env2 = Env::new(Some(env.clone()));

        assert_eq!(Atom::String("bar".to_owned()),
                   env2.get(intern("foo").as_ref()).unwrap());
    }

    #[test]
    fn splat() {
        let mut env = Env::new(None);

        let params = vec![Atom::symbol("&"), Atom::symbol("body")];

        let e = env.bind(&params, &vec![Atom::from(0), Atom::from(1), Atom::from(2)]);

        let body = e.get("body").unwrap();

        assert_eq!(Atom::list(vec![Atom::from(0), Atom::from(1), Atom::from(2)]),
                   body);
    }

    #[test]
    fn define() {
        let mut env = Env::new(None);

        env.define(intern("foo"), Atom::string("bar")).unwrap();

        if let Err(Error::InvalidArguments(_)) = env.set(intern("bar"), Atom::string("foo")) {
            assert!(true);
        } else {
            assert!(false);
        }

        let mut env2 = Env::new(Some(env.clone()));

        env2.set(intern("foo"), Atom::parse("0")).unwrap();

        assert_eq!(Atom::parse("0"), env.get("foo").unwrap());
        assert_eq!(Atom::parse("0"), env2.get("foo").unwrap());

        env2.define(intern("foo"), Atom::string("baz")).unwrap();

        assert_eq!(Atom::string("baz"), env2.get("foo").unwrap());
        assert_eq!(Atom::parse("0"), env.get("foo").unwrap());
    }

    #[test]
    fn bind_mut() {
        let mut env = Env::default();
        let args = vec![Atom::from(0), Atom::from(1)];
        let params = vec![Atom::symbol("a"), Atom::symbol("b")];
        env.bind_mut(&params, &args);

        assert_eq!(env.get("a").unwrap(), Atom::from(0));
        assert_eq!(env.get("b").unwrap(), Atom::from(1));

        env.bind_mut(&params, &vec![Atom::from(2), Atom::from(42)]);

        assert_eq!(env.get("a").unwrap(), Atom::from(2));
        assert_eq!(env.get("b").unwrap(), Atom::from(42));

        assert_eq!(2, env.0.borrow().value.len());
    }

}
<commit_msg>bind now uses bind_mut under the hood<commit_after>use atom::*;
use symbol;
use errors::*;
use std::fmt;
use std::rc::Rc;
use std::cell::RefCell;

#[derive (Debug, Clone, PartialEq)]
struct Entry {
    key: symbol::InternedStr,
    value: Atom,
}

impl fmt::Display for Entry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} => {}", self.key, self.value)
    }
}

#[derive(Debug,PartialEq)]
struct EnvGeneration {
    value: Vec<Entry>,
    parent: Option<Env>,
}

impl fmt::Display for EnvGeneration {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "EnvGeneration[{:p}]", self));
        for i in &self.value {
            try!(write!(f, "\t{}", i));
        }
        Ok(())
    }
}

impl EnvGeneration {
    fn new(parent: Option<Env>) -> EnvGeneration {
        EnvGeneration {
            value: Vec::new(),
            parent: parent,
        }
    }

    fn find(&self, key: &str) -> Option<&Entry> {
        self.value.iter().rev().find(|entry| entry.key.as_ref() == key)
    }
}

#[derive (Debug, Clone, PartialEq)]
pub struct Env(Rc<RefCell<EnvGeneration>>);

impl Default for Env {
    fn default() -> Env {
        Env::new(None)
    }
}

impl fmt::Display for Env {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let gen = self.0.borrow();
        try!(write!(f, "Top-level: EnvGeneration: {}\n", *gen));

        if let Some(ref parent) = gen.parent {
            try!(write!(f, "parent: {}\n", parent));
        } else {
            try!(write!(f, "no parent\n"));
        }
        Ok(())
    }
}

impl Env {
    pub fn new(parent: Option<Env>) -> Env {
        Env(Rc::new(RefCell::new(EnvGeneration::new(parent))))
    }

    fn find(&self, key: &str) -> Option<Atom> {
        let gen = self.0.borrow();
        let value = &gen.value;
        match value.iter().rev().find(|entry| entry.key.as_ref() == key) {
            Some(ref entry) => Some(entry.value.clone()),
            None => {
                if let Some(ref parent) = gen.parent {
                    parent.find(key)
                } else {
                    None
                }
            }
        }
    }

    #[allow(dead_code)]
    pub fn num_generations(&self) -> usize {
        self.num_gen(1)
    }

    fn num_gen(&self, c: usize) -> usize {
        let gen = self.0.borrow();
        if let Some(ref parent) = gen.parent {
            return parent.num_gen(c + 1);
        } else {
            c
        }
    }

    pub fn bind_mut(&mut self, params: &[Atom], args: &[Atom]) {
        let mut params_iter = params.iter();
        let mut args_iter = args.iter();
        while let Some(&Atom::Symbol(ref sym)) = params_iter.next() {
            if sym.as_ref() == "&" {
                if let Some(&Atom::Symbol(ref splat)) = params_iter.next() {
                    let vals = args_iter.cloned().collect();
                    self.0.borrow_mut().value.push(Entry {
                        key: *splat,
                        value: Atom::list(vals),
                    });
                    break;
                }
            } else {
                let arg = args_iter.next().cloned().unwrap_or(Atom::Nil);

                {
                    // tricking the borrow checker here
                    let mut gen = self.0.borrow_mut();

                    if let Some(mut entry) = gen.value.iter_mut().find(|entry| entry.key == *sym) {
                        entry.value = arg;
                        continue;
                    }
                }

                self.0.borrow_mut().value.push(Entry {
                    key: *sym,
                    value: arg,
                });
            }
        }
    }

    pub fn bind(&self, params: &[Atom], args: &[Atom]) -> Env {
        let mut e = Env::new(Some(self.clone()));
        e.bind_mut(params, args);
        e
    }

    pub fn get(&self, key: &str) -> Option<Atom> {
        self.find(key)
    }

    pub fn define(&mut self, key: symbol::InternedStr, value: Atom) -> Result<Atom, Error> {
        if let Some(_) = self.0.borrow().find(key.as_ref()) {
            // println!("env is: {}", self);
            return Err(invalid_arg(&format!("define has entry already: {}", key.as_ref())));
        }
        self.0.borrow_mut().value.push(Entry {
            key: key,
            value: value,
        });
        Ok(Atom::Symbol(key))
    }

    pub fn set(&mut self, key: symbol::InternedStr, value: Atom) -> Result<Atom, Error> {
        {
            // set in current generation
            let mut gen = self.0.borrow_mut();
            if let Some(mut entry) = gen.value.iter_mut().find(|entry| entry.key == key) {
                entry.value = value;
                return Ok(Atom::Symbol(key));
            }
        }

        if let Some(ref mut parent) = self.0.borrow_mut().parent {
            parent.set(key, value)
        } else {
            Err(invalid_arg("in set"))
        }
    }
}

#[cfg(test)]
mod tests {
    use self::super::*;
    use atom::*;
    use errors::*;
    use symbol::*;

    #[test]
    fn nested_get() {
        let mut env = Env::new(None);

        env.define(intern("foo"), Atom::String("bar".to_owned())).unwrap();

        let env2 = Env::new(Some(env.clone()));

        assert_eq!(Atom::String("bar".to_owned()),
                   env2.get(intern("foo").as_ref()).unwrap());
    }

    #[test]
    fn splat() {
        let env = Env::new(None);

        let params = vec![Atom::symbol("&"), Atom::symbol("body")];

        let e = env.bind(&params, &vec![Atom::from(0), Atom::from(1), Atom::from(2)]);

        let body = e.get("body").unwrap();

        assert_eq!(Atom::list(vec![Atom::from(0), Atom::from(1), Atom::from(2)]),
                   body);
    }

    #[test]
    fn define() {
        let mut env = Env::new(None);

        env.define(intern("foo"), Atom::string("bar")).unwrap();

        if let Err(Error::InvalidArguments(_)) = env.set(intern("bar"), Atom::string("foo")) {
            assert!(true);
        } else {
            assert!(false);
        }

        let mut env2 = Env::new(Some(env.clone()));

        env2.set(intern("foo"), Atom::parse("0")).unwrap();

        assert_eq!(Atom::parse("0"), env.get("foo").unwrap());
        assert_eq!(Atom::parse("0"), env2.get("foo").unwrap());

        env2.define(intern("foo"), Atom::string("baz")).unwrap();

        assert_eq!(Atom::string("baz"), env2.get("foo").unwrap());
        assert_eq!(Atom::parse("0"), env.get("foo").unwrap());
    }

    #[test]
    fn bind_mut() {
        let mut env = Env::default();
        let args = vec![Atom::from(0), Atom::from(1)];
        let params = vec![Atom::symbol("a"), Atom::symbol("b")];
        env.bind_mut(&params, &args);

        assert_eq!(env.get("a").unwrap(), Atom::from(0));
        assert_eq!(env.get("b").unwrap(), Atom::from(1));

        env.bind_mut(&params, &vec![Atom::from(2), Atom::from(42)]);

        assert_eq!(env.get("a").unwrap(), Atom::from(2));
        assert_eq!(env.get("b").unwrap(), Atom::from(42));

        assert_eq!(2, env.0.borrow().value.len());
    }

}
<|endoftext|>


<commit_before>use std::error;
use std::fmt;

/// An error returned from the [`Sender::send`] method.
///
/// A send operation can only fail if the receiving end of a channel is disconnected, implying that
/// the data could never be received. The error contains the data being sent as a payload so it can
/// be recovered.
///
/// [`Sender::send`]: struct.Sender.html#method.send
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct SendError<T>(pub T);

/// This enumeration is the list of the possible error outcomes for the [`try_send`] method.
///
/// [`try_send`]: struct.Sender.html#method.try_send
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum TrySendError<T> {
    /// The data could not be sent on the channel because it would require that the callee block to
    /// send the data.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no receiver
    /// available to receive the message at the time.
    Full(T),

    /// This channel's receiving half has disconnected, so the data could not be sent. The data is
    /// returned back to the callee in this case.
    Disconnected(T),
}

/// This enumeration is the list of possible errors that made [`send_timeout`] unable to return
/// data when called. This can occur with bounded channels only.
///
/// [`send_timeout`]: struct.Sender.html#method.send_timeout
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum SendTimeoutError<T> {
    /// This channel is currently full, but the receivers have not yet disconnected.
    Timeout(T),

    /// The channel's receiving half has become disconnected.
    Disconnected(T),
}

/// An error returned from the [`Select::send`] method.
///
/// This error occurs when the selection case doesn't send a message into the channel. Note that
/// cases enumerated in a selection loop are sometimes simply skipped, so they might fail even if
/// the channel is currently not full.
///
/// [`Select::send`]: struct.Select.html#method.send
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct SelectSendError<T>(pub T);

/// An error returned from the [`Receiver::recv`] method.
///
/// The [`recv`] operation can only fail if the sending half of a channel is disconnected and the
/// channel is empty, implying that no further messages will ever be received.
///
/// [`Receiver::recv`]: struct.Receiver.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct RecvError;

/// This enumeration is the list of the possible reasons that [`try_recv`] could not return data
/// when called. This can occur with both bounded and unbounded channels.
///
/// [`try_recv`]: struct.Receiver.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum TryRecvError {
    /// This channel is currently empty, but the senders have not yet disconnected, so data may yet
    /// become available.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no sender
    /// available to at the time.
    Empty,

    /// The channel's sending half has become disconnected, and there will never be any more data
    /// received on it.
    Disconnected,
}

/// This enumeration is the list of possible errors that made [`recv_timeout`] unable to return
/// data when called. This can occur with both bounded and unbounded channels.
///
/// [`recv_timeout`]: struct.Receiver.html#method.recv_timeout
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum RecvTimeoutError {
    /// This channel is currently empty, but the senders have not yet disconnected, so data may yet
    /// become available.
    Timeout,

    /// The channel's sending half has become disconnected, and there will never be any more data
    /// received on it.
    Disconnected,
}

/// An error returned from the [`Select::recv`] method.
///
/// This error occurs when the selection case doesn't receive a message from the channel. Note that
/// cases enumerated in a selection loop are sometimes simply skipped, so they might fail even if
/// the channel is currently not empty.
///
/// [`Select::recv`]: struct.Select.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct SelectRecvError;

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

impl<T> fmt::Display for SendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "sending on a closed channel".fmt(f)
    }
}

impl<T: Send> error::Error for SendError<T> {
    fn description(&self) -> &str {
        "sending on a closed channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> SendError<T> {
    /// Unwraps the value.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::unbounded;
    ///
    /// let (tx, rx) = unbounded();
    /// drop(rx);
    ///
    /// if let Err(err) = tx.send("foo") {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl<T> fmt::Debug for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TrySendError::Full(..) => "Full(..)".fmt(f),
            TrySendError::Disconnected(..) => "Disconnected(..)".fmt(f),
        }
    }
}

impl<T> fmt::Display for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TrySendError::Full(..) => "sending on a full channel".fmt(f),
            TrySendError::Disconnected(..) => "sending on a closed channel".fmt(f),
        }
    }
}

impl<T: Send> error::Error for TrySendError<T> {
    fn description(&self) -> &str {
        match *self {
            TrySendError::Full(..) => "sending on a full channel",
            TrySendError::Disconnected(..) => "sending on a closed channel",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> TrySendError<T> {
    /// Unwraps the value.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::bounded;
    ///
    /// let (tx, rx) = bounded(0);
    ///
    /// if let Err(err) = tx.try_send("foo") {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        match self {
            TrySendError::Full(v) => v,
            TrySendError::Disconnected(v) => v,
        }
    }
}

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

impl<T> fmt::Display for SendTimeoutError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            SendTimeoutError::Timeout(..) => "timed out waiting on channel".fmt(f),
            SendTimeoutError::Disconnected(..) => "sending on a closed channel".fmt(f),
        }
    }
}

impl<T: Send> error::Error for SendTimeoutError<T> {
    fn description(&self) -> &str {
        "sending on a closed channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> SendTimeoutError<T> {
    /// Unwraps the value.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::time::Duration;
    /// use crossbeam_channel::unbounded;
    ///
    /// let (tx, rx) = unbounded();
    ///
    /// if let Err(err) = tx.send_timeout("foo", Duration::from_secs(0)) {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        match self {
            SendTimeoutError::Timeout(v) => v,
            SendTimeoutError::Disconnected(v) => v,
        }
    }
}

impl<T: Send> fmt::Debug for SelectSendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "SelectSendError(..)".fmt(f)
    }
}

impl<T: Send> fmt::Display for SelectSendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "selection `send` case is not ready".fmt(f)
    }
}

impl<T: Send> error::Error for SelectSendError<T> {
    fn description(&self) -> &str {
        "selection `send` case is not ready"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> SelectSendError<T> {
    /// Unwraps the value.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::{unbounded, Select};
    ///
    /// let (tx, rx) = unbounded();
    ///
    /// let mut msg = "message".to_string();
    /// let mut sel = Select::new();
    /// loop {
    ///     if let Err(err) = sel.send(&tx, msg) {
    ///         msg = err.into_inner();
    ///     } else {
    ///         break;
    ///     }
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl fmt::Display for RecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "receiving on a closed channel".fmt(f)
    }
}

impl error::Error for RecvError {
    fn description(&self) -> &str {
        "receiving on a closed channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl fmt::Display for TryRecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TryRecvError::Empty => "receiving on an empty channel".fmt(f),
            TryRecvError::Disconnected => "receiving on a closed channel".fmt(f),
        }
    }
}

impl error::Error for TryRecvError {
    fn description(&self) -> &str {
        match *self {
            TryRecvError::Empty => "receiving on an empty channel",
            TryRecvError::Disconnected => "receiving on a closed channel",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl fmt::Display for RecvTimeoutError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            RecvTimeoutError::Timeout => "timed out waiting on channel".fmt(f),
            RecvTimeoutError::Disconnected => "channel is empty and sending half is closed".fmt(f),
        }
    }
}

impl error::Error for RecvTimeoutError {
    fn description(&self) -> &str {
        match *self {
            RecvTimeoutError::Timeout => "timed out waiting on channel",
            RecvTimeoutError::Disconnected => "channel is empty and sending half is closed",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl fmt::Display for SelectRecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "selection `recv` case is not ready".fmt(f)
    }
}

impl error::Error for SelectRecvError {
    fn description(&self) -> &str {
        "selection `recv` case is not ready"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}
<commit_msg>From<RecvError> for {TryRecv,RecvTimeout}Error<commit_after>use std::error;
use std::fmt;

/// An error returned from the [`Sender::send`] method.
///
/// A send operation can only fail if the receiving end of a channel is disconnected, implying that
/// the data could never be received. The error contains the data being sent as a payload so it can
/// be recovered.
///
/// [`Sender::send`]: struct.Sender.html#method.send
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct SendError<T>(pub T);

/// This enumeration is the list of the possible error outcomes for the [`try_send`] method.
///
/// [`try_send`]: struct.Sender.html#method.try_send
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum TrySendError<T> {
    /// The data could not be sent on the channel because it would require that the callee block to
    /// send the data.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no receiver
    /// available to receive the message at the time.
    Full(T),

    /// This channel's receiving half has disconnected, so the data could not be sent. The data is
    /// returned back to the callee in this case.
    Disconnected(T),
}

/// This enumeration is the list of possible errors that made [`send_timeout`] unable to return
/// data when called. This can occur with bounded channels only.
///
/// [`send_timeout`]: struct.Sender.html#method.send_timeout
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum SendTimeoutError<T> {
    /// This channel is currently full, but the receivers have not yet disconnected.
    Timeout(T),

    /// The channel's receiving half has become disconnected.
    Disconnected(T),
}

/// An error returned from the [`Select::send`] method.
///
/// This error occurs when the selection case doesn't send a message into the channel. Note that
/// cases enumerated in a selection loop are sometimes simply skipped, so they might fail even if
/// the channel is currently not full.
///
/// [`Select::send`]: struct.Select.html#method.send
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct SelectSendError<T>(pub T);

/// An error returned from the [`Receiver::recv`] method.
///
/// The [`recv`] operation can only fail if the sending half of a channel is disconnected and the
/// channel is empty, implying that no further messages will ever be received.
///
/// [`Receiver::recv`]: struct.Receiver.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct RecvError;

/// This enumeration is the list of the possible reasons that [`try_recv`] could not return data
/// when called. This can occur with both bounded and unbounded channels.
///
/// [`try_recv`]: struct.Receiver.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum TryRecvError {
    /// This channel is currently empty, but the senders have not yet disconnected, so data may yet
    /// become available.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no sender
    /// available to at the time.
    Empty,

    /// The channel's sending half has become disconnected, and there will never be any more data
    /// received on it.
    Disconnected,
}

/// This enumeration is the list of possible errors that made [`recv_timeout`] unable to return
/// data when called. This can occur with both bounded and unbounded channels.
///
/// [`recv_timeout`]: struct.Receiver.html#method.recv_timeout
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum RecvTimeoutError {
    /// This channel is currently empty, but the senders have not yet disconnected, so data may yet
    /// become available.
    Timeout,

    /// The channel's sending half has become disconnected, and there will never be any more data
    /// received on it.
    Disconnected,
}

/// An error returned from the [`Select::recv`] method.
///
/// This error occurs when the selection case doesn't receive a message from the channel. Note that
/// cases enumerated in a selection loop are sometimes simply skipped, so they might fail even if
/// the channel is currently not empty.
///
/// [`Select::recv`]: struct.Select.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct SelectRecvError;

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

impl<T> fmt::Display for SendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "sending on a closed channel".fmt(f)
    }
}

impl<T: Send> error::Error for SendError<T> {
    fn description(&self) -> &str {
        "sending on a closed channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> SendError<T> {
    /// Unwraps the value.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::unbounded;
    ///
    /// let (tx, rx) = unbounded();
    /// drop(rx);
    ///
    /// if let Err(err) = tx.send("foo") {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl<T> fmt::Debug for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TrySendError::Full(..) => "Full(..)".fmt(f),
            TrySendError::Disconnected(..) => "Disconnected(..)".fmt(f),
        }
    }
}

impl<T> fmt::Display for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TrySendError::Full(..) => "sending on a full channel".fmt(f),
            TrySendError::Disconnected(..) => "sending on a closed channel".fmt(f),
        }
    }
}

impl<T: Send> error::Error for TrySendError<T> {
    fn description(&self) -> &str {
        match *self {
            TrySendError::Full(..) => "sending on a full channel",
            TrySendError::Disconnected(..) => "sending on a closed channel",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> TrySendError<T> {
    /// Unwraps the value.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::bounded;
    ///
    /// let (tx, rx) = bounded(0);
    ///
    /// if let Err(err) = tx.try_send("foo") {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        match self {
            TrySendError::Full(v) => v,
            TrySendError::Disconnected(v) => v,
        }
    }
}

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

impl<T> fmt::Display for SendTimeoutError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            SendTimeoutError::Timeout(..) => "timed out waiting on channel".fmt(f),
            SendTimeoutError::Disconnected(..) => "sending on a closed channel".fmt(f),
        }
    }
}

impl<T: Send> error::Error for SendTimeoutError<T> {
    fn description(&self) -> &str {
        "sending on a closed channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> SendTimeoutError<T> {
    /// Unwraps the value.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::time::Duration;
    /// use crossbeam_channel::unbounded;
    ///
    /// let (tx, rx) = unbounded();
    ///
    /// if let Err(err) = tx.send_timeout("foo", Duration::from_secs(0)) {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        match self {
            SendTimeoutError::Timeout(v) => v,
            SendTimeoutError::Disconnected(v) => v,
        }
    }
}

impl<T: Send> fmt::Debug for SelectSendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "SelectSendError(..)".fmt(f)
    }
}

impl<T: Send> fmt::Display for SelectSendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "selection `send` case is not ready".fmt(f)
    }
}

impl<T: Send> error::Error for SelectSendError<T> {
    fn description(&self) -> &str {
        "selection `send` case is not ready"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> SelectSendError<T> {
    /// Unwraps the value.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::{unbounded, Select};
    ///
    /// let (tx, rx) = unbounded();
    ///
    /// let mut msg = "message".to_string();
    /// let mut sel = Select::new();
    /// loop {
    ///     if let Err(err) = sel.send(&tx, msg) {
    ///         msg = err.into_inner();
    ///     } else {
    ///         break;
    ///     }
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl fmt::Display for RecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "receiving on a closed channel".fmt(f)
    }
}

impl error::Error for RecvError {
    fn description(&self) -> &str {
        "receiving on a closed channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl fmt::Display for TryRecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TryRecvError::Empty => "receiving on an empty channel".fmt(f),
            TryRecvError::Disconnected => "receiving on a closed channel".fmt(f),
        }
    }
}

impl error::Error for TryRecvError {
    fn description(&self) -> &str {
        match *self {
            TryRecvError::Empty => "receiving on an empty channel",
            TryRecvError::Disconnected => "receiving on a closed channel",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl From<RecvError> for TryRecvError {
    fn from(err: RecvError) -> TryRecvError {
        match err {
            RecvError => TryRecvError::Disconnected,
        }
    }
}

impl fmt::Display for RecvTimeoutError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            RecvTimeoutError::Timeout => "timed out waiting on channel".fmt(f),
            RecvTimeoutError::Disconnected => "channel is empty and sending half is closed".fmt(f),
        }
    }
}

impl error::Error for RecvTimeoutError {
    fn description(&self) -> &str {
        match *self {
            RecvTimeoutError::Timeout => "timed out waiting on channel",
            RecvTimeoutError::Disconnected => "channel is empty and sending half is closed",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl From<RecvError> for RecvTimeoutError {
    fn from(err: RecvError) -> RecvTimeoutError {
        match err {
            RecvError => RecvTimeoutError::Disconnected,
        }
    }
}

impl fmt::Display for SelectRecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "selection `recv` case is not ready".fmt(f)
    }
}

impl error::Error for SelectRecvError {
    fn description(&self) -> &str {
        "selection `recv` case is not ready"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}
<|endoftext|>


<commit_before>
#![allow(dead_code,
         non_camel_case_types,
         non_upper_case_globals,
         non_snake_case)]

use std::os::raw::{c_int, c_void, c_uchar, c_char};
use std::{};

pub type uint8_t = u8;
pub type uint16_t = u16;
pub type uint32_t = u32;

pub enum rtlsdr_dev { }
pub type rtlsdr_dev_t = rtlsdr_dev;

#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum rtlsdr_tuner {
    RTLSDR_TUNER_UNKNOWN = 0,
    RTLSDR_TUNER_E4000   = 1,
    RTLSDR_TUNER_FC0012  = 2,
    RTLSDR_TUNER_FC0013  = 3,
    RTLSDR_TUNER_FC2580  = 4,
    RTLSDR_TUNER_R820T   = 5,
    RTLSDR_TUNER_R828D   = 6,
}
pub type rtlsdr_read_async_cb_t = ::std::option::Option<unsafe extern "C" fn(buf: *mut c_uchar, len: uint32_t, ctx: *mut c_void)>;

#[link(name = "rtlsdr")]
extern "C" {
    pub fn rtlsdr_get_device_count() -> uint32_t;
    pub fn rtlsdr_get_device_name(index: uint32_t) -> *const c_char;
    pub fn rtlsdr_get_device_usb_strings(index: uint32_t, manufact: *mut c_char, product: *mut c_char, serial: *mut c_char) -> c_int;
    pub fn rtlsdr_get_index_by_serial(serial: *const c_char) -> c_int;
    pub fn rtlsdr_open(dev: *mut *mut rtlsdr_dev_t, index: uint32_t) -> c_int;
    pub fn rtlsdr_close(dev: *mut rtlsdr_dev_t) -> c_int;
    pub fn rtlsdr_set_xtal_freq(dev: *mut rtlsdr_dev_t, rtl_freq: uint32_t, tuner_freq: uint32_t) -> c_int;
    pub fn rtlsdr_get_xtal_freq(dev: *mut rtlsdr_dev_t, rtl_freq: *mut uint32_t, tuner_freq: *mut uint32_t) -> c_int;
    pub fn rtlsdr_get_usb_strings(dev: *mut rtlsdr_dev_t, manufact: *mut c_char, product: *mut c_char, serial: *mut c_char) -> c_int;
    pub fn rtlsdr_write_eeprom(dev: *mut rtlsdr_dev_t, data: *mut uint8_t, offset: uint8_t, len: uint16_t) -> c_int;
    pub fn rtlsdr_read_eeprom(dev: *mut rtlsdr_dev_t, data: *mut uint8_t, offset: uint8_t, len: uint16_t) -> c_int;
    pub fn rtlsdr_set_center_freq(dev: *mut rtlsdr_dev_t, freq: uint32_t) -> c_int;
    pub fn rtlsdr_get_center_freq(dev: *mut rtlsdr_dev_t) -> c_int;
    pub fn rtlsdr_set_freq_correction(dev: *mut rtlsdr_dev_t, ppm: c_int) -> c_int;
    pub fn rtlsdr_get_freq_correction(dev: *mut rtlsdr_dev_t) -> c_int;
    pub fn rtlsdr_get_tuner_type(dev: *mut rtlsdr_dev_t) -> rtlsdr_tuner;
    pub fn rtlsdr_get_tuner_gains(dev: *mut rtlsdr_dev_t, gains: *mut c_int) -> c_int;
    pub fn rtlsdr_set_tuner_gain(dev: *mut rtlsdr_dev_t, gain: c_int) -> c_int;
    pub fn rtlsdr_set_tuner_bandwidth(dev: *mut rtlsdr_dev_t, bw: uint32_t) -> c_int;
    pub fn rtlsdr_get_tuner_gain(dev: *mut rtlsdr_dev_t) -> c_int;
    pub fn rtlsdr_set_tuner_if_gain(dev: *mut rtlsdr_dev_t, stage: c_int, gain: c_int) -> c_int;
    pub fn rtlsdr_set_tuner_gain_mode(dev: *mut rtlsdr_dev_t, manual: c_int) -> c_int;
    pub fn rtlsdr_set_sample_rate(dev: *mut rtlsdr_dev_t, rate: uint32_t) -> c_int;
    pub fn rtlsdr_get_sample_rate(dev: *mut rtlsdr_dev_t) -> c_int;
    pub fn rtlsdr_set_testmode(dev: *mut rtlsdr_dev_t, on: c_int) -> c_int;
    pub fn rtlsdr_set_agc_mode(dev: *mut rtlsdr_dev_t, on: c_int) -> c_int;
    pub fn rtlsdr_set_direct_sampling(dev: *mut rtlsdr_dev_t, on: c_int) -> c_int;
    pub fn rtlsdr_get_direct_sampling(dev: *mut rtlsdr_dev_t) -> c_int;
    pub fn rtlsdr_set_offset_tuning(dev: *mut rtlsdr_dev_t, on: c_int) -> c_int;
    pub fn rtlsdr_get_offset_tuning(dev: *mut rtlsdr_dev_t) -> c_int;
    pub fn rtlsdr_reset_buffer(dev: *mut rtlsdr_dev_t) -> c_int;
    pub fn rtlsdr_read_sync(dev: *mut rtlsdr_dev_t, buf: *mut c_void, len: c_int, n_read: *mut c_int) -> c_int;
    pub fn rtlsdr_wait_async(dev: *mut rtlsdr_dev_t, cb: rtlsdr_read_async_cb_t, ctx: *mut c_void) -> c_int;
    pub fn rtlsdr_read_async(dev: *mut rtlsdr_dev_t, cb: rtlsdr_read_async_cb_t, ctx: *mut c_void, buf_num: uint32_t, buf_len: uint32_t) -> c_int;
    pub fn rtlsdr_cancel_async(dev: *mut rtlsdr_dev_t) -> c_int;
}
<commit_msg>ongoing dev, working open and close functions<commit_after>
#![allow(dead_code,
         non_camel_case_types,
         non_upper_case_globals,
         non_snake_case)]

// extern crate libc;
// use libc::{c_int, c_void, c_uchar, c_char};

use std::os::raw::{c_int, c_void, c_uchar, c_char};
use std::option::Option;

pub type uint8_t = u8;
pub type uint16_t = u16;
pub type uint32_t = u32;

pub enum rtlsdr_dev { }
type rtlsdr_dev_t = rtlsdr_dev;

pub struct Device {
    dev: *mut rtlsdr_dev_t,
}

#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum rtlsdr_tuner {
    RTLSDR_TUNER_UNKNOWN = 0,
    RTLSDR_TUNER_E4000 = 1,
    RTLSDR_TUNER_FC0012 = 2,
    RTLSDR_TUNER_FC0013 = 3,
    RTLSDR_TUNER_FC2580 = 4,
    RTLSDR_TUNER_R820T = 5,
    RTLSDR_TUNER_R828D = 6,
}

#[derive(Copy, Clone)]
#[derive(Debug)]
pub enum Error {
    NoError,
    Io,
    InvalidParam,
    Access,
    NoDevice,
    NotFound,
    Busy,
    Timeout,
    Overflow,
    Pipe,
    Interrupted,
    NoMem,
    NotSupported,
    Other,
}

pub type rtlsdr_read_async_cb_t = Option<unsafe extern "C" fn(buf: *mut c_uchar,
                                                              len: uint32_t,
                                                              ctx: *mut c_void)>;

#[link(name = "rtlsdr")]
extern "C" {
    fn rtlsdr_get_device_count() -> uint32_t;
    fn rtlsdr_get_device_name(index: uint32_t) -> *const c_char;
    fn rtlsdr_get_device_usb_strings(index: uint32_t,
                                     manufact: *mut c_char,
                                     product: *mut c_char,
                                     serial: *mut c_char)
                                     -> c_int;
    fn rtlsdr_get_index_by_serial(serial: *const c_char) -> c_int;

    fn rtlsdr_open(dev: *mut *mut rtlsdr_dev_t, index: uint32_t) -> c_int;
    fn rtlsdr_close(dev: *mut rtlsdr_dev_t) -> c_int;
    fn rtlsdr_set_xtal_freq(dev: *mut rtlsdr_dev_t,
                            rtl_freq: uint32_t,
                            tuner_freq: uint32_t)
                            -> c_int;
    fn rtlsdr_get_xtal_freq(dev: *mut rtlsdr_dev_t,
                            rtl_freq: *mut uint32_t,
                            tuner_freq: *mut uint32_t)
                            -> c_int;
    fn rtlsdr_get_usb_strings(dev: *mut rtlsdr_dev_t,
                              manufact: *mut c_char,
                              product: *mut c_char,
                              serial: *mut c_char)
                              -> c_int;
    fn rtlsdr_write_eeprom(dev: *mut rtlsdr_dev_t,
                           data: *mut uint8_t,
                           offset: uint8_t,
                           len: uint16_t)
                           -> c_int;
    fn rtlsdr_read_eeprom(dev: *mut rtlsdr_dev_t,
                          data: *mut uint8_t,
                          offset: uint8_t,
                          len: uint16_t)
                          -> c_int;
    fn rtlsdr_set_center_freq(dev: *mut rtlsdr_dev_t, freq: uint32_t) -> c_int;
    fn rtlsdr_get_center_freq(dev: *mut rtlsdr_dev_t) -> c_int;
    fn rtlsdr_set_freq_correction(dev: *mut rtlsdr_dev_t, ppm: c_int) -> c_int;
    fn rtlsdr_get_freq_correction(dev: *mut rtlsdr_dev_t) -> c_int;
    fn rtlsdr_get_tuner_type(dev: *mut rtlsdr_dev_t) -> rtlsdr_tuner;
    fn rtlsdr_get_tuner_gains(dev: *mut rtlsdr_dev_t, gains: *mut c_int) -> c_int;
    fn rtlsdr_set_tuner_gain(dev: *mut rtlsdr_dev_t, gain: c_int) -> c_int;
    fn rtlsdr_set_tuner_bandwidth(dev: *mut rtlsdr_dev_t, bw: uint32_t) -> c_int;
    fn rtlsdr_get_tuner_gain(dev: *mut rtlsdr_dev_t) -> c_int;
    fn rtlsdr_set_tuner_if_gain(dev: *mut rtlsdr_dev_t, stage: c_int, gain: c_int) -> c_int;
    fn rtlsdr_set_tuner_gain_mode(dev: *mut rtlsdr_dev_t, manual: c_int) -> c_int;
    fn rtlsdr_set_sample_rate(dev: *mut rtlsdr_dev_t, rate: uint32_t) -> c_int;
    fn rtlsdr_get_sample_rate(dev: *mut rtlsdr_dev_t) -> c_int;
    fn rtlsdr_set_testmode(dev: *mut rtlsdr_dev_t, on: c_int) -> c_int;
    fn rtlsdr_set_agc_mode(dev: *mut rtlsdr_dev_t, on: c_int) -> c_int;
    fn rtlsdr_set_direct_sampling(dev: *mut rtlsdr_dev_t, on: c_int) -> c_int;
    fn rtlsdr_get_direct_sampling(dev: *mut rtlsdr_dev_t) -> c_int;
    fn rtlsdr_set_offset_tuning(dev: *mut rtlsdr_dev_t, on: c_int) -> c_int;
    fn rtlsdr_get_offset_tuning(dev: *mut rtlsdr_dev_t) -> c_int;
    fn rtlsdr_reset_buffer(dev: *mut rtlsdr_dev_t) -> c_int;
    fn rtlsdr_read_sync(dev: *mut rtlsdr_dev_t,
                        buf: *mut c_void,
                        len: c_int,
                        n_read: *mut c_int)
                        -> c_int;
    fn rtlsdr_wait_async(dev: *mut rtlsdr_dev_t,
                         cb: rtlsdr_read_async_cb_t,
                         ctx: *mut c_void)
                         -> c_int;
    fn rtlsdr_read_async(dev: *mut rtlsdr_dev_t,
                         cb: rtlsdr_read_async_cb_t,
                         ctx: *mut c_void,
                         buf_num: uint32_t,
                         buf_len: uint32_t)
                         -> c_int;
    fn rtlsdr_cancel_async(dev: *mut rtlsdr_dev_t) -> c_int;
}

fn get_err_msg(e: c_int) -> Error {
    use Error::*;
    match e {
        0 => NoError,
        -1 => Io,
        -2 => InvalidParam,
        -3 => Access,
        -4 => NoDevice,
        -5 => NotFound,
        -6 => Busy,
        -7 => Timeout,
        -8 => Overflow,
        -9 => Pipe,
        -10 => Interrupted,
        -11 => NoMem,
        -12 => NotSupported,
        _ => Other,
    }
}

// pub fn get_device_count() -> i32 {}
// pub fn get_device_name(index: ) ->  {}
// pub fn get_device_usb_strings( ) ->  i32 {}
// pub fn get_index_by_serial( ) ->  {}

pub fn open(index: i32) -> (Device, Error) {
    let mut d: *mut rtlsdr_dev_t = std::ptr::null_mut();
    unsafe {
        let e = rtlsdr_open(&mut d as *mut *mut rtlsdr_dev_t, index as uint32_t);
        return (Device {dev: d}, get_err_msg(e));
    }
}

impl Device {
    pub fn close(&self) -> Error {
        unsafe {
            return get_err_msg(rtlsdr_close(self.dev));
        }
    }
//     pub fn set_xtal_freq() -> Error {}
//     pub fn get_xtal_freq() -> Error {}
//     pub fn get_usb_strings() -> Error {}
//     pub fn write_eeprom() -> Error {}
//     pub fn read_eeprom() -> Error {}
//     pub fn set_center_freq() -> Error {}
//     pub fn get_center_freq() -> Error {}
//     pub fn set_freq_correction() -> Error {}
//     pub fn get_freq_correction() -> Error {}
//     pub fn get_tuner_type() -> rtlsdr_tuner {}
//     pub fn get_tuner_gains() -> Error {}
//     pub fn set_tuner_gain() -> Error {}
//     pub fn set_tuner_bandwidth() -> Error {}
//     pub fn get_tuner_gain() -> Error {}
//     pub fn set_tuner_if_gain() -> Error {}
//     pub fn set_tuner_gain_mode() -> Error {}
//     pub fn set_sample_rate() -> Error {}
//     pub fn get_sample_rate() -> Error {}
//     pub fn set_testmode() -> Error {}
//     pub fn set_agc_mode() -> Error {}
//     pub fn set_direct_sampling() -> Error {}
//     pub fn get_direct_sampling() -> Error {}
//     pub fn set_offset_tuning() -> Error {}
//     pub fn get_offset_tuning() -> Error {}
//     pub fn reset_buffer() -> Error {}
//     pub fn read_sync() -> Error {}
//     pub fn wait_async() -> Error {}
//     pub fn read_async() -> Error {}
//     pub fn cancel_async() -> Error {}
}

fn main() {
    println!("opening...");
    let (dev, err) = open(0);
    match err {
        Error::NoError => println!("open successful"),
        _ => return,
    }
    let e = dev.close();
    println!("dev close status: {:?}", e);
}
<|endoftext|>


<commit_before>
use edit::Editor;

use gtk::{self, Widget, Window, Frame, EventBox, DrawingArea, WindowPosition};
use gtk::signal::Inhibit;
use gtk::traits::*;
use gdk::EventType;
use cairo::{Context, Antialias};

pub struct Gui {
	#[allow(dead_code)]
	win: &'static mut Window,
	edit: Editor,
}
impl Gui {
	pub fn new(win: &'static mut Window) -> Gui {
		win.set_title("Propositional Logic Calculator");
		win.set_border_width(10);
		win.set_window_position(WindowPosition::Center);
		win.set_double_buffered(true);
		win.set_default_size(350, 70);

		win.connect_delete_event(|_, _| {
			gtk::main_quit();
			Inhibit(true)
		});

		let da_frame = Frame::new(None).unwrap();
		{
			let eb = EventBox::new().unwrap();
			win.connect_key_press_event(|_, e| {
				if e._type == EventType::KeyPress {
					let ih = ::get_gui().edit.handle_input(e);
					if ih == Inhibit(true) {
						::get_gui().dirty();
					}
					ih
				} else {
					Inhibit(false)
				}
			});
			let da = DrawingArea::new().unwrap();
			da.connect_draw(|w: Widget, c: Context| {
				::get_gui().render(w, c);

				Inhibit(false)
			});
			eb.add(&da);
			da_frame.add(&eb);
		}
		win.add(&da_frame);

		win.show_all();

		Gui {
			win: win,
			edit: Editor::new(),
		}
	}

	pub fn dirty(&self) {
		self.win.queue_draw();
	}

	pub fn render(&self, w: Widget, c: Context) {
		let (_alloc_w, _alloc_h) = (w.get_allocated_width(), w.get_allocated_height());

		c.set_antialias(Antialias::Best);
		c.new_path();

		for l in self.edit.lines().iter() {
			let s = format!("{:#}", l);
			c.text_path(&s);
			let p = c.copy_path();
			let ex = c.fill_extents();
			c.translate(-ex.0, -ex.1);
			c.new_path();
			c.append_path(&p);
			c.fill();
		}
	}
}
<commit_msg>Change dimensions<commit_after>
use edit::Editor;

use gtk::{self, Widget, Window, Frame, EventBox, DrawingArea, WindowPosition};
use gtk::signal::Inhibit;
use gtk::traits::*;
use gdk::EventType;
use cairo::{Context, Antialias};
use cairo::enums::{FontSlant, FontWeight};

pub struct Gui {
	#[allow(dead_code)]
	win: &'static mut Window,
	edit: Editor,
}
impl Gui {
	pub fn new(win: &'static mut Window) -> Gui {
		win.set_title("Propositional Logic Calculator");
		win.set_border_width(10);
		win.set_window_position(WindowPosition::Center);
		win.set_double_buffered(true);
		win.set_default_size(600, 500);

		win.connect_delete_event(|_, _| {
			gtk::main_quit();
			Inhibit(true)
		});

		let da_frame = Frame::new(None).unwrap();
		{
			let eb = EventBox::new().unwrap();
			win.connect_key_press_event(|_, e| {
				if e._type == EventType::KeyPress {
					let ih = ::get_gui().edit.handle_input(e);
					if ih == Inhibit(true) {
						::get_gui().dirty();
					}
					ih
				} else {
					Inhibit(false)
				}
			});
			let da = DrawingArea::new().unwrap();
			da.connect_draw(|w: Widget, c: Context| {
				::get_gui().render(w, c);

				Inhibit(false)
			});
			eb.add(&da);
			da_frame.add(&eb);
		}
		win.add(&da_frame);

		win.show_all();

		Gui {
			win: win,
			edit: Editor::new(),
		}
	}

	pub fn dirty(&self) {
		self.win.queue_draw();
	}

	pub fn render(&self, w: Widget, c: Context) {
		let (_alloc_w, _alloc_h) = (w.get_allocated_width(), w.get_allocated_height());

		c.select_font_face("CMU Serif", FontSlant::Normal, FontWeight::Normal);
		c.set_antialias(Antialias::Best);
		c.set_font_size(24.0);
		c.new_path();

		{
			c.text_path("H");
			let p = c.copy_path();
			let ex = c.fill_extents();
			println!("extent: {:?}", ex);
			c.translate(- ex.0 - 10.0, - ex.1 - 10.0);
		}

		for l in self.edit.lines().iter() {
			let s = format!("{:#}", l);
			c.text_path(&s);
			let p = c.copy_path();
			let ex = c.fill_extents();
			c.translate(-ex.0, -ex.1);
			c.new_path();
			c.append_path(&p);
			c.fill();
			break;
		}
	}
}
<|endoftext|>


<commit_before>extern crate liner;

use liner::Context;
use liner::KeyBindings;

fn main() {
    let mut con = Context::new();

    loop {
        let res = con.read_line("[prompt]$ ", &mut |_| {}).unwrap();

        if res.is_empty() {
            break;
        }

        match res.as_str() {
            "emacs" => {
                con.key_bindings = KeyBindings::Emacs;
                println!("emacs mode");
            }
            "vi" =>  {
                con.key_bindings = KeyBindings::Vi;
                println!("vi mode");
            }
            _ => {}
        }

        con.history.push(res.into()).unwrap();
    }
}
<commit_msg>update the example code with ctrl-c and ctrl-d handling<commit_after>extern crate liner;

use liner::Context;
use liner::KeyBindings;
use std::io::ErrorKind;

fn main() {
    let mut con = Context::new();

    loop {
        let res = con.read_line("[prompt]$ ", &mut |_| {});

        match res {
            Ok(res) => {
                match res.as_str() {
                    "emacs" => {
                        con.key_bindings = KeyBindings::Emacs;
                        println!("emacs mode");
                    }
                    "vi" =>  {
                        con.key_bindings = KeyBindings::Vi;
                        println!("vi mode");
                    }
                    "exit" =>  {
                        println!("exiting...");
                        break;
                    }
                    _ => {}
                }

                con.history.push(res.into()).unwrap();
            }
            Err(e) => {
                match e.kind() {
                    // ctrl-c pressed
                    ErrorKind::Interrupted => {}
                    // ctrl-d pressed
                    ErrorKind::UnexpectedEof => {
                        println!("exiting...");
                        break;
                    }
                    _ => panic!("error: {:?}", e),
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// This example demonstrates use of the `FutureResolver`.
extern crate c_ares;
extern crate c_ares_resolver;
extern crate futures;
extern crate tokio;

use std::error::Error;

use c_ares_resolver::FutureResolver;
use futures::future::Future;

fn main() {
    // Create Resolver and make a query.
    let query = {
        let resolver = FutureResolver::new().expect("Failed to create resolver");
        resolver
            .query_mx("gmail.com")
            .map_err(|e| println!("MX lookup failed with error '{}'", e.description()))
            .map(|results| {
                for result in &results {
                    println!("host {}, priority {}", result.host(), result.priority());
                }
            })
    };

    // Run the query to completion.
    tokio::run(query);
}
<commit_msg>Tweak the futures example<commit_after>// This example demonstrates use of the `FutureResolver`.
extern crate c_ares;
extern crate c_ares_resolver;
extern crate futures;
extern crate tokio;

use std::error::Error;

use c_ares_resolver::FutureResolver;
use futures::future::Future;

fn main() {
    // Create Resolver and make a query.
    let resolver = FutureResolver::new().expect("Failed to create resolver");
    let query = resolver
        .query_mx("gmail.com")
        .map_err(|e| println!("MX lookup failed with error '{}'", e.description()))
        .map(|results| {
            for result in &results {
                println!("host {}, priority {}", result.host(), result.priority());
            }
        });

    // NB Dropping a FutureResolver does *not* cause outstanding requests to fail.
    std::mem::drop(resolver);

    // Run the query to completion.
    tokio::run(query);
}
<|endoftext|>