<commit_before>use std::{
    collections::VecDeque,
    fmt::{self, Debug},
    hint::unreachable_unchecked,
    mem,
    rc::Rc,
    sync::{
        atomic::{AtomicBool, Ordering},
        Mutex, MutexGuard,
    },
    time::Instant,
};

use cocoa::{appkit::NSApp, base::nil, foundation::NSString};

use crate::{
    event::{Event, StartCause, WindowEvent},
    event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget},
    platform_impl::platform::{observer::EventLoopWaker, util::Never},
    window::WindowId,
};
use objc::runtime::Object;

lazy_static! {
    static ref HANDLER: Handler = Default::default();
}

impl Event<Never> {
    fn userify<T: 'static>(self) -> Event<T> {
        self.map_nonuser_event()
            // `Never` can't be constructed, so the `UserEvent` variant can't
            // be present here.
            .unwrap_or_else(|_| unsafe { unreachable_unchecked() })
    }
}

pub trait EventHandler: Debug {
    fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow);
    fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
}

struct EventLoopHandler<T: 'static> {
    callback: Box<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>,
    will_exit: bool,
    window_target: Rc<RootWindowTarget<T>>,
}

impl<T> Debug for EventLoopHandler<T> {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        formatter
            .debug_struct("EventLoopHandler")
            .field("window_target", &self.window_target)
            .finish()
    }
}

impl<T> EventHandler for EventLoopHandler<T> {
    fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow) {
        (self.callback)(event.userify(), &self.window_target, control_flow);
        self.will_exit |= *control_flow == ControlFlow::Exit;
        if self.will_exit {
            *control_flow = ControlFlow::Exit;
        }
    }

    fn handle_user_events(&mut self, control_flow: &mut ControlFlow) {
        let mut will_exit = self.will_exit;
        for event in self.window_target.p.receiver.try_iter() {
            (self.callback)(Event::UserEvent(event), &self.window_target, control_flow);
            will_exit |= *control_flow == ControlFlow::Exit;
            if will_exit {
                *control_flow = ControlFlow::Exit;
            }
        }
        self.will_exit = will_exit;
    }
}

#[derive(Default)]
struct Handler {
    ready: AtomicBool,
    in_callback: AtomicBool,
    control_flow: Mutex<ControlFlow>,
    control_flow_prev: Mutex<ControlFlow>,
    start_time: Mutex<Option<Instant>>,
    callback: Mutex<Option<Box<dyn EventHandler>>>,
    pending_events: Mutex<VecDeque<Event<Never>>>,
    pending_redraw: Mutex<Vec<WindowId>>,
    waker: Mutex<EventLoopWaker>,
}

unsafe impl Send for Handler {}
unsafe impl Sync for Handler {}

impl Handler {
    fn events<'a>(&'a self) -> MutexGuard<'a, VecDeque<Event<Never>>> {
        self.pending_events.lock().unwrap()
    }

    fn redraw<'a>(&'a self) -> MutexGuard<'a, Vec<WindowId>> {
        self.pending_redraw.lock().unwrap()
    }

    fn waker<'a>(&'a self) -> MutexGuard<'a, EventLoopWaker> {
        self.waker.lock().unwrap()
    }

    fn is_ready(&self) -> bool {
        self.ready.load(Ordering::Acquire)
    }

    fn set_ready(&self) {
        self.ready.store(true, Ordering::Release);
    }

    fn should_exit(&self) -> bool {
        *self.control_flow.lock().unwrap() == ControlFlow::Exit
    }

    fn get_control_flow_and_update_prev(&self) -> ControlFlow {
        let control_flow = self.control_flow.lock().unwrap();
        *self.control_flow_prev.lock().unwrap() = *control_flow;
        *control_flow
    }

    fn get_old_and_new_control_flow(&self) -> (ControlFlow, ControlFlow) {
        let old = *self.control_flow_prev.lock().unwrap();
        let new = *self.control_flow.lock().unwrap();
        (old, new)
    }

    fn get_start_time(&self) -> Option<Instant> {
        *self.start_time.lock().unwrap()
    }

    fn update_start_time(&self) {
        *self.start_time.lock().unwrap() = Some(Instant::now());
    }

    fn take_events(&self) -> VecDeque<Event<Never>> {
        mem::replace(&mut *self.events(), Default::default())
    }

    fn should_redraw(&self) -> Vec<WindowId> {
        mem::replace(&mut *self.redraw(), Default::default())
    }

    fn get_in_callback(&self) -> bool {
        self.in_callback.load(Ordering::Acquire)
    }

    fn set_in_callback(&self, in_callback: bool) {
        self.in_callback.store(in_callback, Ordering::Release);
    }

    fn handle_nonuser_event(&self, event: Event<Never>) {
        if let Some(ref mut callback) = *self.callback.lock().unwrap() {
            callback.handle_nonuser_event(event, &mut *self.control_flow.lock().unwrap());
        }
    }

    fn handle_user_events(&self) {
        if let Some(ref mut callback) = *self.callback.lock().unwrap() {
            callback.handle_user_events(&mut *self.control_flow.lock().unwrap());
        }
    }
}

pub enum AppState {}

impl AppState {
    // This function extends lifetime of `callback` to 'static as its side effect
    pub unsafe fn set_callback<F, T>(callback: F, window_target: Rc<RootWindowTarget<T>>)
    where
        F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
    {
        *HANDLER.callback.lock().unwrap() = Some(Box::new(EventLoopHandler {
            // This transmute is always safe, in case it was reached through `run`, since our
            // lifetime will be already 'static. In other cases caller should ensure that all data
            // they passed to callback will actually outlive it, some apps just can't move
            // everything to event loop, so this is something that they should care about.
            callback: mem::transmute::<
                Box<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>,
                Box<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>,
            >(Box::new(callback)),
            will_exit: false,
            window_target,
        }));
    }

    pub fn exit() {
        HANDLER.set_in_callback(true);
        HANDLER.handle_nonuser_event(Event::LoopDestroyed);
        HANDLER.set_in_callback(false);
        HANDLER.callback.lock().unwrap().take();
    }

    pub fn launched() {
        HANDLER.set_ready();
        HANDLER.waker().start();
        HANDLER.set_in_callback(true);
        HANDLER.handle_nonuser_event(Event::NewEvents(StartCause::Init));
        HANDLER.set_in_callback(false);
    }

    pub fn wakeup() {
        if !HANDLER.is_ready() {
            return;
        }
        let start = HANDLER.get_start_time().unwrap();
        let cause = match HANDLER.get_control_flow_and_update_prev() {
            ControlFlow::Poll => StartCause::Poll,
            ControlFlow::Wait => StartCause::WaitCancelled {
                start,
                requested_resume: None,
            },
            ControlFlow::WaitUntil(requested_resume) => {
                if Instant::now() >= requested_resume {
                    StartCause::ResumeTimeReached {
                        start,
                        requested_resume,
                    }
                } else {
                    StartCause::WaitCancelled {
                        start,
                        requested_resume: Some(requested_resume),
                    }
                }
            }
            ControlFlow::Exit => StartCause::Poll, //panic!("unexpected `ControlFlow::Exit`"),
        };
        HANDLER.set_in_callback(true);
        HANDLER.handle_nonuser_event(Event::NewEvents(cause));
        HANDLER.set_in_callback(false);
    }

    // This is called from multiple threads at present
    pub fn queue_redraw(window_id: WindowId) {
        let mut pending_redraw = HANDLER.redraw();
        if !pending_redraw.contains(&window_id) {
            pending_redraw.push(window_id);
        }
    }

    pub fn queue_event(event: Event<Never>) {
        if !unsafe { msg_send![class!(NSThread), isMainThread] } {
            panic!("Event queued from different thread: {:#?}", event);
        }
        HANDLER.events().push_back(event);
    }

    pub fn queue_events(mut events: VecDeque<Event<Never>>) {
        if !unsafe { msg_send![class!(NSThread), isMainThread] } {
            panic!("Events queued from different thread: {:#?}", events);
        }
        HANDLER.events().append(&mut events);
    }

    pub fn cleared() {
        if !HANDLER.is_ready() {
            return;
        }
        if !HANDLER.get_in_callback() {
            HANDLER.set_in_callback(true);
            HANDLER.handle_user_events();
            for event in HANDLER.take_events() {
                HANDLER.handle_nonuser_event(event);
            }
            for window_id in HANDLER.should_redraw() {
                HANDLER.handle_nonuser_event(Event::WindowEvent {
                    window_id,
                    event: WindowEvent::RedrawRequested,
                });
            }
            HANDLER.handle_nonuser_event(Event::EventsCleared);
            HANDLER.set_in_callback(false);
        }
        if HANDLER.should_exit() {
            unsafe {
                let _: () = msg_send![NSApp(), stop: nil];

                let windows: *const Object = msg_send![NSApp(), windows];
                let window: *const Object = msg_send![windows, objectAtIndex:0];
                assert_ne!(window, nil);

                let title: *const Object = msg_send![window, title];
                assert_ne!(title, nil);
                let postfix = NSString::alloc(nil).init_str("*");
                let some_unique_title: *const Object =
                    msg_send![title, stringByAppendingString: postfix];
                assert_ne!(some_unique_title, nil);

                // To stop event loop immediately, we need to send some UI event here.
                let _: () = msg_send![window, setTitle: some_unique_title];
                // And restore it.
                let _: () = msg_send![window, setTitle: title];
            };
        }
        HANDLER.update_start_time();
        match HANDLER.get_old_and_new_control_flow() {
            (ControlFlow::Exit, _) | (_, ControlFlow::Exit) => (),
            (old, new) if old == new => (),
            (_, ControlFlow::Wait) => HANDLER.waker().stop(),
            (_, ControlFlow::WaitUntil(instant)) => HANDLER.waker().start_at(instant),
            (_, ControlFlow::Poll) => HANDLER.waker().start(),
        }
    }
}
<commit_msg>Implement revamped `RedrawRequested` on macOS (#1235)<commit_after>use std::{
    collections::VecDeque,
    fmt::{self, Debug},
    hint::unreachable_unchecked,
    mem,
    rc::Rc,
    sync::{
        atomic::{AtomicBool, Ordering},
        Mutex, MutexGuard,
    },
    time::Instant,
};

use cocoa::{appkit::NSApp, base::nil, foundation::NSString};

use crate::{
    event::{Event, StartCause, WindowEvent},
    event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget},
    platform_impl::platform::{observer::EventLoopWaker, util::Never},
    window::WindowId,
};
use objc::runtime::Object;

lazy_static! {
    static ref HANDLER: Handler = Default::default();
}

impl Event<Never> {
    fn userify<T: 'static>(self) -> Event<T> {
        self.map_nonuser_event()
            // `Never` can't be constructed, so the `UserEvent` variant can't
            // be present here.
            .unwrap_or_else(|_| unsafe { unreachable_unchecked() })
    }
}

pub trait EventHandler: Debug {
    fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow);
    fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
}

struct EventLoopHandler<T: 'static> {
    callback: Box<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>,
    will_exit: bool,
    window_target: Rc<RootWindowTarget<T>>,
}

impl<T> Debug for EventLoopHandler<T> {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        formatter
            .debug_struct("EventLoopHandler")
            .field("window_target", &self.window_target)
            .finish()
    }
}

impl<T> EventHandler for EventLoopHandler<T> {
    fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow) {
        (self.callback)(event.userify(), &self.window_target, control_flow);
        self.will_exit |= *control_flow == ControlFlow::Exit;
        if self.will_exit {
            *control_flow = ControlFlow::Exit;
        }
    }

    fn handle_user_events(&mut self, control_flow: &mut ControlFlow) {
        let mut will_exit = self.will_exit;
        for event in self.window_target.p.receiver.try_iter() {
            (self.callback)(Event::UserEvent(event), &self.window_target, control_flow);
            will_exit |= *control_flow == ControlFlow::Exit;
            if will_exit {
                *control_flow = ControlFlow::Exit;
            }
        }
        self.will_exit = will_exit;
    }
}

#[derive(Default)]
struct Handler {
    ready: AtomicBool,
    in_callback: AtomicBool,
    control_flow: Mutex<ControlFlow>,
    control_flow_prev: Mutex<ControlFlow>,
    start_time: Mutex<Option<Instant>>,
    callback: Mutex<Option<Box<dyn EventHandler>>>,
    pending_events: Mutex<VecDeque<Event<Never>>>,
    pending_redraw: Mutex<Vec<WindowId>>,
    waker: Mutex<EventLoopWaker>,
}

unsafe impl Send for Handler {}
unsafe impl Sync for Handler {}

impl Handler {
    fn events<'a>(&'a self) -> MutexGuard<'a, VecDeque<Event<Never>>> {
        self.pending_events.lock().unwrap()
    }

    fn redraw<'a>(&'a self) -> MutexGuard<'a, Vec<WindowId>> {
        self.pending_redraw.lock().unwrap()
    }

    fn waker<'a>(&'a self) -> MutexGuard<'a, EventLoopWaker> {
        self.waker.lock().unwrap()
    }

    fn is_ready(&self) -> bool {
        self.ready.load(Ordering::Acquire)
    }

    fn set_ready(&self) {
        self.ready.store(true, Ordering::Release);
    }

    fn should_exit(&self) -> bool {
        *self.control_flow.lock().unwrap() == ControlFlow::Exit
    }

    fn get_control_flow_and_update_prev(&self) -> ControlFlow {
        let control_flow = self.control_flow.lock().unwrap();
        *self.control_flow_prev.lock().unwrap() = *control_flow;
        *control_flow
    }

    fn get_old_and_new_control_flow(&self) -> (ControlFlow, ControlFlow) {
        let old = *self.control_flow_prev.lock().unwrap();
        let new = *self.control_flow.lock().unwrap();
        (old, new)
    }

    fn get_start_time(&self) -> Option<Instant> {
        *self.start_time.lock().unwrap()
    }

    fn update_start_time(&self) {
        *self.start_time.lock().unwrap() = Some(Instant::now());
    }

    fn take_events(&self) -> VecDeque<Event<Never>> {
        mem::replace(&mut *self.events(), Default::default())
    }

    fn should_redraw(&self) -> Vec<WindowId> {
        mem::replace(&mut *self.redraw(), Default::default())
    }

    fn get_in_callback(&self) -> bool {
        self.in_callback.load(Ordering::Acquire)
    }

    fn set_in_callback(&self, in_callback: bool) {
        self.in_callback.store(in_callback, Ordering::Release);
    }

    fn handle_nonuser_event(&self, event: Event<Never>) {
        if let Some(ref mut callback) = *self.callback.lock().unwrap() {
            callback.handle_nonuser_event(event, &mut *self.control_flow.lock().unwrap());
        }
    }

    fn handle_user_events(&self) {
        if let Some(ref mut callback) = *self.callback.lock().unwrap() {
            callback.handle_user_events(&mut *self.control_flow.lock().unwrap());
        }
    }
}

pub enum AppState {}

impl AppState {
    // This function extends lifetime of `callback` to 'static as its side effect
    pub unsafe fn set_callback<F, T>(callback: F, window_target: Rc<RootWindowTarget<T>>)
    where
        F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
    {
        *HANDLER.callback.lock().unwrap() = Some(Box::new(EventLoopHandler {
            // This transmute is always safe, in case it was reached through `run`, since our
            // lifetime will be already 'static. In other cases caller should ensure that all data
            // they passed to callback will actually outlive it, some apps just can't move
            // everything to event loop, so this is something that they should care about.
            callback: mem::transmute::<
                Box<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>,
                Box<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>,
            >(Box::new(callback)),
            will_exit: false,
            window_target,
        }));
    }

    pub fn exit() {
        HANDLER.set_in_callback(true);
        HANDLER.handle_nonuser_event(Event::LoopDestroyed);
        HANDLER.set_in_callback(false);
        HANDLER.callback.lock().unwrap().take();
    }

    pub fn launched() {
        HANDLER.set_ready();
        HANDLER.waker().start();
        HANDLER.set_in_callback(true);
        HANDLER.handle_nonuser_event(Event::NewEvents(StartCause::Init));
        HANDLER.set_in_callback(false);
    }

    pub fn wakeup() {
        if !HANDLER.is_ready() {
            return;
        }
        let start = HANDLER.get_start_time().unwrap();
        let cause = match HANDLER.get_control_flow_and_update_prev() {
            ControlFlow::Poll => StartCause::Poll,
            ControlFlow::Wait => StartCause::WaitCancelled {
                start,
                requested_resume: None,
            },
            ControlFlow::WaitUntil(requested_resume) => {
                if Instant::now() >= requested_resume {
                    StartCause::ResumeTimeReached {
                        start,
                        requested_resume,
                    }
                } else {
                    StartCause::WaitCancelled {
                        start,
                        requested_resume: Some(requested_resume),
                    }
                }
            }
            ControlFlow::Exit => StartCause::Poll, //panic!("unexpected `ControlFlow::Exit`"),
        };
        HANDLER.set_in_callback(true);
        HANDLER.handle_nonuser_event(Event::NewEvents(cause));
        HANDLER.set_in_callback(false);
    }

    // This is called from multiple threads at present
    pub fn queue_redraw(window_id: WindowId) {
        let mut pending_redraw = HANDLER.redraw();
        if !pending_redraw.contains(&window_id) {
            pending_redraw.push(window_id);
        }
    }

    pub fn queue_event(event: Event<Never>) {
        if !unsafe { msg_send![class!(NSThread), isMainThread] } {
            panic!("Event queued from different thread: {:#?}", event);
        }
        HANDLER.events().push_back(event);
    }

    pub fn queue_events(mut events: VecDeque<Event<Never>>) {
        if !unsafe { msg_send![class!(NSThread), isMainThread] } {
            panic!("Events queued from different thread: {:#?}", events);
        }
        HANDLER.events().append(&mut events);
    }

    pub fn cleared() {
        if !HANDLER.is_ready() {
            return;
        }
        if !HANDLER.get_in_callback() {
            HANDLER.set_in_callback(true);
            HANDLER.handle_user_events();
            for event in HANDLER.take_events() {
                HANDLER.handle_nonuser_event(event);
            }
            HANDLER.handle_nonuser_event(Event::MainEventsCleared);
            for window_id in HANDLER.should_redraw() {
                HANDLER.handle_nonuser_event(Event::RedrawRequested(window_id));
            }
            HANDLER.handle_nonuser_event(Event::RedrawEventsCleared);
            HANDLER.set_in_callback(false);
        }
        if HANDLER.should_exit() {
            unsafe {
                let _: () = msg_send![NSApp(), stop: nil];

                let windows: *const Object = msg_send![NSApp(), windows];
                let window: *const Object = msg_send![windows, objectAtIndex:0];
                assert_ne!(window, nil);

                let title: *const Object = msg_send![window, title];
                assert_ne!(title, nil);
                let postfix = NSString::alloc(nil).init_str("*");
                let some_unique_title: *const Object =
                    msg_send![title, stringByAppendingString: postfix];
                assert_ne!(some_unique_title, nil);

                // To stop event loop immediately, we need to send some UI event here.
                let _: () = msg_send![window, setTitle: some_unique_title];
                // And restore it.
                let _: () = msg_send![window, setTitle: title];
            };
        }
        HANDLER.update_start_time();
        match HANDLER.get_old_and_new_control_flow() {
            (ControlFlow::Exit, _) | (_, ControlFlow::Exit) => (),
            (old, new) if old == new => (),
            (_, ControlFlow::Wait) => HANDLER.waker().stop(),
            (_, ControlFlow::WaitUntil(instant)) => HANDLER.waker().start_at(instant),
            (_, ControlFlow::Poll) => HANDLER.waker().start(),
        }
    }
}
<|endoftext|>


<commit_before>use error::{Result, Error};

use std::cell::RefCell;
use std::rc::Rc;
use std::net::SocketAddr;
use std::collections::HashMap;
use std::io;

use futures::stream::Stream;
use futures::Sink;
use futures::Future;

use tokio_core::reactor::Core;
use tokio_core::net::TcpListener;
use tokio_io::AsyncRead;

use mqtt3::{Packet, Connack, ConnectReturnCode};

use codec::MqttCodec;
use client::Client;

pub struct Broker {
    clients: Rc<RefCell<HashMap<SocketAddr, Client>>>,
}

impl Broker {
    pub fn new() -> Self {
        Broker { clients: Rc::new(RefCell::new(HashMap::new())) }
    }

    pub fn start(&mut self) -> Result<()> {
        let mut core = Core::new().unwrap();
        let handle = core.handle();
        let address = "0.0.0.0:1883".parse().unwrap();
        let listener = TcpListener::bind(&address, &core.handle()).unwrap();

        let welcomes = listener.incoming().and_then(|(socket, addr)| {
            let framed = socket.framed(MqttCodec);

            // and_then<F, B>(self, f: F) -> AndThen<Self, B, F>
            // where F: FnOnce(Self::Item) -> B,
            //       B: IntoFuture<Error=Self::Error>, // Error of value returned by 'F' and Error of Self should match
            //       Self: Sized

            // => If Self resolves to Ok(_), Execute 'F' with '_'

            // AndThen<Self, B, F> => F: FnOnce(Self::Item) -> B, B: IntoFuture<Error=Self::Error>, Self: Sized

            /// handshake = AndThen<
            ///                MapErr< Stream<Framed>, closure>, --> Self
            ///                Result<Framed, io::Error>,        --> B (Should be an IntoFuture whose error = Self's error)
            ///                closure >                         --> F (Should be which returns 'B')

            /// Creates a 'Self' from stream, whose error match to that of and_then's closure
            let handshake = framed.into_future().map_err(|(err, _)| err).and_then(|(packet,framed)| {
                if let Some(Packet::Connect(c)) = packet {
                    println!("{:?}", c);
                    Ok(framed)
                } else {
                    Err(io::Error::new(io::ErrorKind::Other, "invalid handshake"))
                }
            });

            handshake
        });

        let server = welcomes.for_each(|framed| {

            let (sender, receiver) = framed.split();

            let connack = Packet::Connack(Connack {
                                              session_present: false,
                                              code: ConnectReturnCode::Accepted,
                                          });
            let sender = sender.send(connack).wait();

            let rx_future = receiver
                .for_each(|msg| {
                              println!("{:?}", msg);
                              Ok(())
                          })
                .then(|_| Ok(()));

            handle.spawn(rx_future);
            Ok(())
        });

        core.run(server)?;
        Ok(())
    }

    pub fn add(&self, addr: SocketAddr, client: Client) {
        self.clients.borrow_mut().insert(addr, client);
    }

    pub fn remove(&self, addr: &SocketAddr) -> Option<Client> {
        self.clients.borrow_mut().remove(addr)
    }
}
<commit_msg>don't stop reactor during errors<commit_after>use error::{Result, Error};

use std::cell::RefCell;
use std::rc::Rc;
use std::net::SocketAddr;
use std::collections::HashMap;
use std::io;
use std::result;

use futures::future;
use futures::stream::Stream;
use futures::Sink;
use futures::Future;

use tokio_core::reactor::Core;
use tokio_core::net::TcpListener;
use tokio_io::AsyncRead;
use tokio_io;

use mqtt3::{Packet, Connack, ConnectReturnCode};

use codec::MqttCodec;
use client::Client;

pub struct Broker {
    clients: Rc<RefCell<HashMap<SocketAddr, Client>>>,
}

impl Broker {
    pub fn new() -> Self {
        Broker { clients: Rc::new(RefCell::new(HashMap::new())) }
    }

    pub fn start(&mut self) -> Result<()> {
        let mut core = Core::new().unwrap();
        let handle = core.handle();
        let address = "0.0.0.0:1883".parse().unwrap();
        let listener = TcpListener::bind(&address, &core.handle()).unwrap();

        let welcomes = listener.incoming().and_then(|(socket, addr)| {
            println!("New connection from: {:?}", addr);
            let framed = socket.framed(MqttCodec);

            // and_then<F, B>(self, f: F) -> AndThen<Self, B, F>
            // where F: FnOnce(Self::Item) -> B,
            //       B: IntoFuture<Error=Self::Error>, // Error of value returned by 'F' and Error of Self should match
            //       Self: Sized

            // => If Self resolves to Ok(_), Execute 'F' with '_'

            // AndThen<Self, B, F> => F: FnOnce(Self::Item) -> B, B: IntoFuture<Error=Self::Error>, Self: Sized

            /// handshake = AndThen<
            ///                MapErr< Stream<Framed>, closure>, --> Self
            ///                Result<Framed, io::Error>,        --> B (Should be an IntoFuture whose error = Self's error)
            ///                closure >                         --> F (Should be which returns 'B')

            /// Creates a 'Self' from stream, whose error match to that of and_then's closure
            let handshake = framed.into_future().map_err(|(err, _)| err).and_then(|(packet,framed)| {
                if let Some(Packet::Connect(c)) = packet {
                    println!("{:?}", c);
                    Ok(framed)
                } else {
                    println!("Not a handshake packet");
                    Err(io::Error::new(io::ErrorKind::Other, "invalid handshake"))
                }
            });

            handshake
        });

        let server = welcomes
            .map(|w| Some(w))
            .or_else(|e| Ok::<_, ()>(None))
            .for_each(|framed| {
                if framed.is_some() {
                    let (sender, receiver) = framed.unwrap().split();

                    let connack = Packet::Connack(Connack {
                                                      session_present: false,
                                                      code: ConnectReturnCode::Accepted,
                                                  });

                    let sender = sender.send(connack).wait();

                    let rx_future = receiver
                        .for_each(|msg| {
                                      println!("{:?}", msg);
                                      Ok(())
                                  })
                        .then(|_| Ok(()));

                    handle.spawn(rx_future);
                }
                Ok(())
            });

        core.run(server);
        Ok(())
    }

    pub fn add(&self, addr: SocketAddr, client: Client) {
        self.clients.borrow_mut().insert(addr, client);
    }

    pub fn remove(&self, addr: &SocketAddr) -> Option<Client> {
        self.clients.borrow_mut().remove(addr)
    }
}
<|endoftext|>


<commit_before>use geometry::Point;
use geometry::Rect;
use geometry::Size;

/**
 Elements that may be contained by a quadtree node.
 Either child nodes, a single rect, or nothing.
 */
enum Elements {
    /// Children are top left, top right, bottom right, and bottom left, respectively.
    Children(~QuadTree, ~QuadTree, ~QuadTree, ~QuadTree),
    /// A single rectangle.
    Member(Rect),
    /// Nothing.
    NoElements,
}

/**
 A quadtree node that can contain either one rectangle,
 or exactly four child nodes.
 */
pub struct QuadTree {
    rect: Rect,
    elements: Elements,
}

impl QuadTree {
    /**
     Create a quadtree with a root node with the given origin and size.
     */
    pub fn new(origin: Point, size: Size, elems: Elements) -> QuadTree {
        let tree =
        match elems {
            Children(tl, tr, br, bl) => QuadTree::newWithChildren(origin, size, tl, tr, br, bl),
            Member(rect) => QuadTree::newWithMember(origin, size, rect),
            NoElements => QuadTree::newWithSize(origin, size),
        };

        tree
    }

    /**
     Create a quadtree with a root node with the same origin and a square
     size with side length matching the longer dimension of `rect`.
     */
    pub fn newAutosized(rect: Rect) -> QuadTree {
        let largerDimen = if rect.size.width > rect.size.height {
            rect.size.width
        } else {
            rect.size.height
        };

        let size = Size { width: largerDimen, height: largerDimen };

        QuadTree::newWithMember(rect.origin, size, rect)
    }

    /**
     Create an empty quadtree with a zero-sized root node.
     */
    pub fn newEmpty() -> QuadTree {
        let origin = Point { x: 0 as f32, y: 0 as f32 };
        let size = Size { width: 0 as f32, height: 0 as f32 };
        let tree = QuadTree::new(origin, size, NoElements);

        tree
    }

    /**
     Create a quadtree with a root node with the given origin, size, and child rectangles.
     Child nodes `tl`, `tr`, `br`, and `bl` should form the rect specified by `origin` and `size`.
     */
    fn newWithChildren(origin: Point, size: Size, tl: ~QuadTree, tr: ~QuadTree, br: ~QuadTree, bl: ~QuadTree) -> QuadTree {
        let nodeRect = Rect { origin: origin, size: size };

        let tree = QuadTree { rect: nodeRect, elements: Children(tl, tr, br, bl) };

        tree
    }

    /**
     Create a quadtree with a root node with the given origin, size, and member rectangle.
     */
    fn newWithMember(origin: Point, size: Size, insertRect: Rect) -> QuadTree {
        let node = QuadTree::newWithSize(origin, size);

        let (success, tree) = node.insertRect(insertRect);
        assert!(success, "Failed inserting a node into an empty quadtree.");

        tree
    }

    /**
     Create a quadtree with only a specified size and position.
     */
    fn newWithSize(origin: Point, size: Size) -> QuadTree {
        let nodeRect = Rect { origin: origin, size: size };
        let tree = QuadTree { rect: nodeRect, elements: NoElements };

        tree
    }

    /**
     Insert a rectangle into the quadtree. If `toInsert` overlaps another rectangle
     already in the tree, the return value will be (false, self).
     If the root node is zero-sized, the resulting tree will have a square root node
     large enough to hold `toInsert`.
     */
    pub fn insertRect(self, toInsert: Rect) -> (bool, QuadTree) {
        if self.rect.size.width == 0.0 {
            return (true, QuadTree::newAutosized(toInsert))
        }

        fail!("insertRect not implemented for non-zero sized trees!");

        (false, self)
    }

    /**
     Find all of the rects in `self`, or its children, that are in nodes
     intersected by the given rect.
     */
    pub fn rectsInChildNodesIntersectedByRect(&self, testRect: &Rect) -> ~[Rect] {
        // If the test rect doesn't intersect us, then it can't intersect
        // any rects that we have.
        match self.rect.intersect(testRect) {
            Some(intersection) => {
                let mut rects = ~[];
                let mut nodesToCheck = ~[self];

                while nodesToCheck.len() > 0 {
                    let mut newNodesToCheck = ~[];

                    for node in nodesToCheck.iter() {
                        match node.elements {
                            Children(~ref tl, ~ref tr, ~ref br, ~ref bl) => {
                                let mut check = ~[];
                                let intersection = &intersection;
                                if tl.rect.intersects(intersection) {
                                    check.push(tl);
                                }
                                if tr.rect.intersects(intersection) {
                                    check.push(tr);
                                }
                                if br.rect.intersects(intersection) {
                                    check.push(br);
                                }
                                if bl.rect.intersects(intersection) {
                                    check.push(bl);
                                }
                                newNodesToCheck.push_all(check);
                            }
                            Member(memberRect) => rects.push(memberRect),
                            NoElements => ()
                        };
                    }

                    nodesToCheck = newNodesToCheck;
                }

                rects
            },
            None => ~[],
        }
    }
}<commit_msg>Add assertions to ensure that child nodes' rects match the parent's rect.<commit_after>use geometry::Point;
use geometry::Rect;
use geometry::Size;

/**
 Elements that may be contained by a quadtree node.
 Either child nodes, a single rect, or nothing.
 */
enum Elements {
    /// Children are top left, top right, bottom right, and bottom left, respectively.
    Children(~QuadTree, ~QuadTree, ~QuadTree, ~QuadTree),
    /// A single rectangle.
    Member(Rect),
    /// Nothing.
    NoElements,
}

/**
 A quadtree node that can contain either one rectangle,
 or exactly four child nodes.
 */
pub struct QuadTree {
    rect: Rect,
    elements: Elements,
}

impl QuadTree {
    /**
     Create a quadtree with a root node with the given origin and size.
     */
    pub fn new(origin: Point, size: Size, elems: Elements) -> QuadTree {
        let tree =
        match elems {
            Children(tl, tr, br, bl) => QuadTree::newWithChildren(origin, size, tl, tr, br, bl),
            Member(rect) => QuadTree::newWithMember(origin, size, rect),
            NoElements => QuadTree::newWithSize(origin, size),
        };

        tree
    }

    /**
     Create a quadtree with a root node with the same origin and a square
     size with side length matching the longer dimension of `rect`.
     */
    pub fn newAutosized(rect: Rect) -> QuadTree {
        let largerDimen = if rect.size.width > rect.size.height {
            rect.size.width
        } else {
            rect.size.height
        };

        let size = Size { width: largerDimen, height: largerDimen };

        QuadTree::newWithMember(rect.origin, size, rect)
    }

    /**
     Create an empty quadtree with a zero-sized root node.
     */
    pub fn newEmpty() -> QuadTree {
        let origin = Point { x: 0 as f32, y: 0 as f32 };
        let size = Size { width: 0 as f32, height: 0 as f32 };
        let tree = QuadTree::new(origin, size, NoElements);

        tree
    }

    /**
     Create a quadtree with a root node with the given origin, size, and child rectangles.
     Child nodes `tl`, `tr`, `br`, and `bl` should form the rect specified by `origin` and `size`.
     */
    fn newWithChildren(origin: Point, size: Size, tl: ~QuadTree, tr: ~QuadTree, br: ~QuadTree, bl: ~QuadTree) -> QuadTree {
        let nodeRect = Rect { origin: origin, size: size };

        // Assert that our rect and our childrens' rects match up.
        assert!(tl.rect.minX() == bl.rect.minX(), "Top left and bottom left children should have same minX coordinate.");
        assert!(tl.rect.maxX() == bl.rect.maxX(), "Top left and bottom left children should have same maxX coordinate.");
        assert!(tl.rect.maxY() == bl.rect.minY(), "Top left and bottom left children should have same maxY and minY coordinates, respectively.");

        assert!(tl.rect.maxX() == tr.rect.minX(), "Top left and top right children should share their maxX and minX coordinates, respectively.");
        assert!(tl.rect.minY() == tr.rect.minY(), "Top left and top right children should have same minY coordinate.");
        assert!(tl.rect.maxY() == tr.rect.maxY(), "Top left and top right children should have same maxY coordinate.");

        assert!(bl.rect.maxX() == br.rect.minX(), "Bottom left and bottom right children should share their maxX and minX coordinates, respectively.");
        assert!(bl.rect.minY() == br.rect.minY(), "Bottom left and bottom right children should have same minY coordinate.");
        assert!(bl.rect.maxY() == br.rect.maxY(), "Bottom left and bottom right children should have same maxY coordinate.");

        assert!(tr.rect.minX() == br.rect.minX(), "Top right and bottom right children should have same minX coordinate.");
        assert!(tr.rect.maxX() == br.rect.maxX(), "Top right and bottom right children should have same maxX coordinate.");
        assert!(tr.rect.maxY() == br.rect.minY(), "Top right and bottom right children should have same maxY and minY coordinates, respectively.");

        assert!(nodeRect.minX() == tl.rect.minX(), "Tree node's minX should match its top left child's minX coordinate.");
        assert!(nodeRect.maxX() == tr.rect.maxX(), "Tree node's maxX should match its top right child's maxX coordinate.");
        assert!(nodeRect.minY() == tl.rect.minY(), "Tree node's minY should match its top left child's minY coordinate.");
        assert!(nodeRect.maxY() == bl.rect.maxY(), "Tree node's maxY should match its top left child's maxY coordinate.");

        let tree = QuadTree { rect: nodeRect, elements: Children(tl, tr, br, bl) };

        tree
    }

    /**
     Create a quadtree with a root node with the given origin, size, and member rectangle.
     */
    fn newWithMember(origin: Point, size: Size, insertRect: Rect) -> QuadTree {
        let node = QuadTree::newWithSize(origin, size);

        let (success, tree) = node.insertRect(insertRect);
        assert!(success, "Failed inserting a node into an empty quadtree.");

        tree
    }

    /**
     Create a quadtree with only a specified size and position.
     */
    fn newWithSize(origin: Point, size: Size) -> QuadTree {
        let nodeRect = Rect { origin: origin, size: size };
        let tree = QuadTree { rect: nodeRect, elements: NoElements };

        tree
    }

    /**
     Insert a rectangle into the quadtree. If `toInsert` overlaps another rectangle
     already in the tree, the return value will be (false, self).
     If the root node is zero-sized, the resulting tree will have a square root node
     large enough to hold `toInsert`.
     */
    pub fn insertRect(self, toInsert: Rect) -> (bool, QuadTree) {
        if self.rect.size.width == 0.0 {
            return (true, QuadTree::newAutosized(toInsert))
        }

        fail!("insertRect not implemented for non-zero sized trees!");

        (false, self)
    }

    /**
     Find all of the rects in `self`, or its children, that are in nodes
     intersected by the given rect.
     */
    pub fn rectsInChildNodesIntersectedByRect(&self, testRect: &Rect) -> ~[Rect] {
        // If the test rect doesn't intersect us, then it can't intersect
        // any rects that we have.
        match self.rect.intersect(testRect) {
            Some(intersection) => {
                let mut rects = ~[];
                let mut nodesToCheck = ~[self];

                while nodesToCheck.len() > 0 {
                    let mut newNodesToCheck = ~[];

                    for node in nodesToCheck.iter() {
                        match node.elements {
                            Children(~ref tl, ~ref tr, ~ref br, ~ref bl) => {
                                let mut check = ~[];
                                let intersection = &intersection;
                                if tl.rect.intersects(intersection) {
                                    check.push(tl);
                                }
                                if tr.rect.intersects(intersection) {
                                    check.push(tr);
                                }
                                if br.rect.intersects(intersection) {
                                    check.push(br);
                                }
                                if bl.rect.intersects(intersection) {
                                    check.push(bl);
                                }
                                newNodesToCheck.push_all(check);
                            }
                            Member(memberRect) => rects.push(memberRect),
                            NoElements => ()
                        };
                    }

                    nodesToCheck = newNodesToCheck;
                }

                rects
            },
            None => ~[],
        }
    }
}<|endoftext|>


<commit_before>extern crate glutin;
extern crate trdl;

use std::os::raw::c_void;

fn offset(point: (f32, f32), offset: (f32, f32)) -> (f32, f32) {
    (point.0 + offset.0, point.1 + offset.1)
}

fn make_foot(off: (f32, f32), is_right: bool, is_back: bool) -> trdl::Path {
    let mut points = [(0f32, 0f32), (50f32, 50f32), (80f32, 100f32), (100f32, 200f32),
        (0f32, 250f32), (-75f32, 200f32), (-100f32, 100f32), (0f32, 0f32)];
    let stroke = (0f32, 0f32, 0f32, 6);
    let fill_color = (0f32, 1f32, 0f32);
    let mut backwards = false;
    if is_right {
        if is_back {
            for p in &mut points {
                *p = (-p.0 + off.0, -p.1 + off.1);
            }
        } else {
            for p in &mut points {
                *p = (p.0 + off.0, -p.1 + off.1);
            }
            backwards = true;
        }
    } else {
        if is_back {
            for p in &mut points {
                *p = (-p.0 + off.0, p.1 + off.1);
            }
            backwards = true;
        } else {
            for p in &mut points {
                *p = (p.0 + off.0, p.1 + off.1);
            }
        }
    }
    if backwards {
        trdl::Path::new(points[7]).
            line_to(points[6]).
            curve_to(points[5], points[4], points[3]).
            curve_to(points[2], points[1], points[0]).
            close_path().
            set_stroke(stroke.0, stroke.1, stroke.2, stroke.3).
            set_fill_color(fill_color.0, fill_color.1, fill_color.2)
    } else {
        trdl::Path::new(points[0]).
            curve_to(points[1], points[2], points[3]).
            curve_to(points[4], points[5], points[6]).
            line_to(points[7]).
            close_path().
            set_stroke(stroke.0, stroke.1, stroke.2, stroke.3).
            set_fill_color(fill_color.0, fill_color.1, fill_color.2)
    }
}

fn make_shape(off_x: f32, off_y: f32) -> Vec<trdl::Path> {
    let mut paths = Vec::new();
    paths.push(make_foot((off_x + 200f32, off_y + 100_f32), false, false));
    paths.push(make_foot((off_x + 200f32, off_y - 100_f32), true, false));
    paths.push(make_foot((off_x - 200f32, off_y + 80_f32), false, true));
    paths.push(make_foot((off_x - 200f32, off_y - 80_f32), true, true));
    paths
}

struct Window {
    w: glutin::Window
}

impl trdl::Window for Window {
    fn set_context(&self) {
        unsafe { self.w.make_current().unwrap() };
    }
    fn load_fn(&self, addr: &str) -> *const c_void {
        self.w.get_proc_address(addr) as *const c_void
    }
}

fn main() {
    let window_size = (1280, 800);
    let window = Window {
        w: glutin::WindowBuilder::new().
            with_dimensions(window_size.0, window_size.1).
            with_title("TRDL Test").
            build().unwrap() };

    let mut drawing = trdl::Drawing::new(&window, window_size.0, window_size.1,
                                         0.4, 0.5, 0.6).unwrap();

    let mut idx = 0usize;
    let sqrt_size = 1u32;
    let num_shapes = sqrt_size * sqrt_size;
    let wx = window_size.0 as i32 - 300i32;
    let wy = window_size.1 as i32 - 300i32;

    let paths = make_shape(600f32, 400f32);
    for p in paths {
        drawing.add_path(p).unwrap();
    }

    drawing.draw();
    window.w.swap_buffers().unwrap();
    for event in window.w.wait_events() {
        if let glutin::Event::Closed = event {
            break;
        }
    }
}<commit_msg>main now draws a turtle!<commit_after>extern crate glutin;
extern crate trdl;

use std::f32;
use std::os::raw::c_void;

fn offset(point: (f32, f32), offset: (f32, f32)) -> (f32, f32) {
    (point.0 + offset.0, point.1 + offset.1)
}

fn make_foot(off: (f32, f32), is_right: bool, is_back: bool) -> Vec<trdl::Path> {
    let mut foot_points = [(0f32, 0f32), (50f32, 50f32), (80f32, 100f32), (100f32, 200f32),
        (0f32, 250f32), (-75f32, 200f32), (-100f32, 100f32), (0f32, 0f32)];
    let mut toe_points = [(100f32, 200f32), (75f32, 210f32), (50f32, 215f32)];

    let stroke = (0f32, 0f32, 0f32, 6);
    let fill_color = (0.684f32, 0.765f32, 0f32);
    let mut backwards = false;
    if is_right {
        if is_back {
            for p in &mut foot_points {
                *p = (-p.0 + off.0, -p.1 + off.1);
            }
            for p in &mut toe_points {
                *p = (-p.0 + off.0, -p.1 + off.1);
            }
        } else {
            for p in &mut foot_points {
                *p = (p.0 + off.0, -p.1 + off.1);
            }
            for p in &mut toe_points {
                *p = (p.0 + off.0, -p.1 + off.1);
            }
            backwards = true;
        }
    } else {
        if is_back {
            for p in &mut foot_points {
                *p = (-p.0 + off.0, p.1 + off.1);
            }
            for p in &mut toe_points {
                *p = (-p.0 + off.0, p.1 + off.1);
            }
            backwards = true;
        } else {
            for p in &mut foot_points {
                *p = (p.0 + off.0, p.1 + off.1);
            }
            for p in &mut toe_points {
                *p = (p.0 + off.0, p.1 + off.1);
            }
        }
    }
    if backwards {
        vec![trdl::Path::new(foot_points[7]).
             line_to(foot_points[6]).
             curve_to(foot_points[5], foot_points[4], foot_points[3]).
             curve_to(foot_points[2], foot_points[1], foot_points[0]).
             close_path().
             set_stroke(stroke.0, stroke.1, stroke.2, stroke.3).
             set_fill_color(fill_color.0, fill_color.1, fill_color.2),
             trdl::Path::ellipse(toe_points[0], 10f32, 10f32, 0f32).
                 set_fill_color(0.718f32, 0.51f32, 0f32).set_stroke(0f32, 0f32, 0f32, 2),
             trdl::Path::ellipse(toe_points[1], 10f32, 10f32, 0f32).
                 set_fill_color(0.718f32, 0.51f32, 0f32).set_stroke(0f32, 0f32, 0f32, 2),
             trdl::Path::ellipse(toe_points[2], 10f32, 10f32, 0f32).
                 set_fill_color(0.718f32, 0.51f32, 0f32).set_stroke(0f32, 0f32, 0f32, 2)]
    } else {
        vec![trdl::Path::new(foot_points[0]).
             curve_to(foot_points[1], foot_points[2], foot_points[3]).
             curve_to(foot_points[4], foot_points[5], foot_points[6]).
             line_to(foot_points[7]).
             close_path().
             set_stroke(stroke.0, stroke.1, stroke.2, stroke.3).
             set_fill_color(fill_color.0, fill_color.1, fill_color.2),
             trdl::Path::ellipse(toe_points[0], 10f32, 10f32, 0f32).
                 set_fill_color(0.718f32, 0.51f32, 0f32).set_stroke(0f32, 0f32, 0f32, 2),
             trdl::Path::ellipse(toe_points[1], 10f32, 10f32, 0f32).
                 set_fill_color(0.718f32, 0.51f32, 0f32).set_stroke(0f32, 0f32, 0f32, 2),
             trdl::Path::ellipse(toe_points[2], 10f32, 10f32, 0f32).
                 set_fill_color(0.718f32, 0.51f32, 0f32).set_stroke(0f32, 0f32, 0f32, 2)]
    }
}

fn make_head(off: (f32, f32)) -> Vec<trdl::Path> {
    vec![trdl::Path::ellipse(off, 135f32, 90f32, 0f32).
            set_fill_color(0.684f32, 0.765f32, 0f32).set_stroke(0f32, 0f32, 0f32, 6),
         trdl::Path::ellipse((off.0 + 100f32, off.1 + 55f32), 10f32, 10f32, 0f32).
             set_fill_color(0f32, 0f32, 0f32),
         trdl::Path::ellipse((off.0 + 100f32, off.1 - 55f32), 10f32, 10f32, 0f32).
             set_fill_color(0f32, 0f32, 0f32)]
}

fn make_tail(off: (f32, f32)) -> trdl::Path {
    trdl::Path::new(offset((50f32, 20f32), off)).
        curve_to(offset((0f32, 20f32), off), offset((-50f32, 80f32), off),
                 offset((-100f32, 80f32), off)).
        curve_to(offset((-50f32, 50f32), off), offset((-50f32, -30f32), off),
                 offset((50f32, -20f32), off)).close_path().
        set_fill_color(0.684f32, 0.765f32, 0f32).set_stroke(0f32, 0f32, 0f32, 6)
}

fn make_shell(off: (f32, f32)) -> Vec<trdl::Path> {
    let radius = 250f32;
    let c = f32::consts::FRAC_PI_3.cos();
    let s = f32::consts::FRAC_PI_3.sin();
    let cr = c * radius;
    let sr = s * radius;
    let hex_rad = 175f32;
    let chr = c * hex_rad;
    let shr = s * hex_rad;
    vec![trdl::Path::ellipse(off, radius, radius, 0f32).
         set_fill_color(0.454f32, 0.522f32, 0f32).set_stroke(0f32, 0f32, 0f32, 6),
         trdl::Path::new((off.0, off.1 + radius)).line_to((off.0, off.1 - radius)).
             set_stroke(0f32, 0f32, 0f32, 6),
         trdl::Path::new((off.0 + sr, off.1 + cr)).line_to((off.0 - sr, off.1 - cr)).
             set_stroke(0f32, 0f32, 0f32, 6),
         trdl::Path::new((off.0 + sr, off.1 - cr)).line_to((off.0 - sr, off.1 + cr)).
             set_stroke(0f32, 0f32, 0f32, 6),
         trdl::Path::new((off.0, off.1 - hex_rad)).
             line_to((off.0 + shr, off.1 - chr)).
             line_to((off.0 + shr, off.1 + chr)).
             line_to((off.0, off.1 + hex_rad)).
             line_to((off.0 - shr, off.1 + chr)).
             line_to((off.0 - shr, off.1 - chr)).close_path().
             set_fill_color(0.454f32, 0.682f32, 0f32).set_stroke(0f32, 0f32, 0f32, 6)]

}

fn make_shape(off_x: f32, off_y: f32) -> Vec<trdl::Path> {
    let mut paths = Vec::new();
    paths.append(&mut make_foot((off_x + 220f32, off_y + 100_f32), false, false));
    paths.append(&mut make_foot((off_x + 220f32, off_y - 100_f32), true, false));
    paths.append(&mut make_foot((off_x - 200f32, off_y + 80_f32), false, true));
    paths.append(&mut make_foot((off_x - 200f32, off_y - 80_f32), true, true));
    paths.append(&mut make_head((off_x + 320f32, off_y)));
    paths.push(make_tail((off_x - 275f32, off_y)));
    paths.append(&mut make_shell((off_x, off_y)));
    paths
}

struct Window {
    w: glutin::Window
}

impl trdl::Window for Window {
    fn set_context(&self) {
        unsafe { self.w.make_current().unwrap() };
    }
    fn load_fn(&self, addr: &str) -> *const c_void {
        self.w.get_proc_address(addr) as *const c_void
    }
}

fn main() {
    let window_size = (1280, 800);
    let window = Window {
        w: glutin::WindowBuilder::new().
            with_dimensions(window_size.0, window_size.1).
            with_title("TRDL Test").
            build().unwrap() };

    let mut drawing = trdl::Drawing::new(&window, window_size.0, window_size.1,
                                         0.4, 0.5, 0.6).unwrap();

    let mut idx = 0usize;
    let sqrt_size = 1u32;
    let num_shapes = sqrt_size * sqrt_size;
    let wx = window_size.0 as i32 - 300i32;
    let wy = window_size.1 as i32 - 300i32;

    let paths = make_shape(600f32, 400f32);
    for p in paths {
        drawing.add_path(p).unwrap();
    }

    drawing.draw();
    window.w.swap_buffers().unwrap();
    for event in window.w.wait_events() {
        if let glutin::Event::Closed = event {
            break;
        }
    }
}<|endoftext|>


<commit_before>use crate::query::{AutomatonWeight, Query, Weight};
use crate::schema::Term;
use crate::Searcher;
use crate::TantivyError::InvalidArgument;
use levenshtein_automata::{LevenshteinAutomatonBuilder, DFA};
use once_cell::sync::Lazy;
use std::collections::HashMap;
use std::ops::Range;

/// A range of Levenshtein distances that we will build DFAs for our terms
/// The computation is exponential, so best keep it to low single digits
const VALID_LEVENSHTEIN_DISTANCE_RANGE: Range<u8> = (0..3);

static LEV_BUILDER: Lazy<HashMap<(u8, bool), LevenshteinAutomatonBuilder>> = Lazy::new(|| {
    let mut lev_builder_cache = HashMap::new();
    // TODO make population lazy on a `(distance, val)` basis
    for distance in VALID_LEVENSHTEIN_DISTANCE_RANGE {
        for &transposition in &[false, true] {
            let lev_automaton_builder = LevenshteinAutomatonBuilder::new(distance, transposition);
            lev_builder_cache.insert((distance, transposition), lev_automaton_builder);
        }
    }
    lev_builder_cache
});

/// A Fuzzy Query matches all of the documents
/// containing a specific term that is within
/// Levenshtein distance
/// ```rust
/// use tantivy::collector::{Count, TopDocs};
/// use tantivy::query::FuzzyTermQuery;
/// use tantivy::schema::{Schema, TEXT};
/// use tantivy::{doc, Index, Term};
///
/// fn example() -> tantivy::Result<()> {
///     let mut schema_builder = Schema::builder();
///     let title = schema_builder.add_text_field("title", TEXT);
///     let schema = schema_builder.build();
///     let index = Index::create_in_ram(schema);
///     {
///         let mut index_writer = index.writer(3_000_000)?;
///         index_writer.add_document(doc!(
///             title => "The Name of the Wind",
///         ));
///         index_writer.add_document(doc!(
///             title => "The Diary of Muadib",
///         ));
///         index_writer.add_document(doc!(
///             title => "A Dairy Cow",
///         ));
///         index_writer.add_document(doc!(
///             title => "The Diary of a Young Girl",
///         ));
///         index_writer.commit().unwrap();
///     }
///     let reader = index.reader()?;
///     let searcher = reader.searcher();
///
///     {
///         let term = Term::from_field_text(title, "Diary");
///         let query = FuzzyTermQuery::new(term, 1, true);
///         let (top_docs, count) = searcher.search(&query, &(TopDocs::with_limit(2), Count)).unwrap();
///         assert_eq!(count, 2);
///         assert_eq!(top_docs.len(), 2);
///     }
///
///     Ok(())
/// }
/// # assert!(example().is_ok());
/// ```
#[derive(Debug, Clone)]
pub struct FuzzyTermQuery {
    /// What term are we searching
    term: Term,
    /// How many changes are we going to allow
    distance: u8,
    /// Should a transposition cost 1 or 2?
    transposition_cost_one: bool,
    ///
    prefix: bool,
}

impl FuzzyTermQuery {
    /// Creates a new Fuzzy Query
    pub fn new(term: Term, distance: u8, transposition_cost_one: bool) -> FuzzyTermQuery {
        FuzzyTermQuery {
            term,
            distance,
            transposition_cost_one,
            prefix: false,
        }
    }

    /// Creates a new Fuzzy Query that treats transpositions as cost one rather than two
    pub fn new_prefix(term: Term, distance: u8, transposition_cost_one: bool) -> FuzzyTermQuery {
        FuzzyTermQuery {
            term,
            distance,
            transposition_cost_one,
            prefix: true,
        }
    }

    fn specialized_weight(&self) -> crate::Result<AutomatonWeight<DFA>> {
        // LEV_BUILDER is a HashMap, whose `get` method returns an Option
        match LEV_BUILDER.get(&(self.distance, false)) {
            // Unwrap the option and build the Ok(AutomatonWeight)
            Some(automaton_builder) => {
                let automaton = automaton_builder.build_dfa(self.term.text());
                Ok(AutomatonWeight::new(self.term.field(), automaton))
            }
            None => Err(InvalidArgument(format!(
                "Levenshtein distance of {} is not allowed. Choose a value in the {:?} range",
                self.distance, VALID_LEVENSHTEIN_DISTANCE_RANGE
            ))),
        }
    }
}

impl Query for FuzzyTermQuery {
    fn weight(
        &self,
        _searcher: &Searcher,
        _scoring_enabled: bool,
    ) -> crate::Result<Box<dyn Weight>> {
        Ok(Box::new(self.specialized_weight()?))
    }
}

#[cfg(test)]
mod test {
    use super::FuzzyTermQuery;
    use crate::collector::TopDocs;
    use crate::schema::Schema;
    use crate::schema::TEXT;
    use crate::tests::assert_nearly_equals;
    use crate::Index;
    use crate::Term;

    #[test]
    pub fn test_fuzzy_term() {
        let mut schema_builder = Schema::builder();
        let country_field = schema_builder.add_text_field("country", TEXT);
        let schema = schema_builder.build();
        let index = Index::create_in_ram(schema);
        {
            let mut index_writer = index.writer_with_num_threads(1, 10_000_000).unwrap();
            index_writer.add_document(doc!(
                country_field => "japan",
            ));
            index_writer.add_document(doc!(
                country_field => "korea",
            ));
            index_writer.commit().unwrap();
        }
        let reader = index.reader().unwrap();
        let searcher = reader.searcher();
        {
            let term = Term::from_field_text(country_field, "japon");

            let fuzzy_query = FuzzyTermQuery::new(term, 1, true);
            let top_docs = searcher
                .search(&fuzzy_query, &TopDocs::with_limit(2))
                .unwrap();
            assert_eq!(top_docs.len(), 1, "Expected only 1 document");
            let (score, _) = top_docs[0];
            assert_nearly_equals(1f32, score);
        }
    }
}
<commit_msg>Removing parenthesis.<commit_after>use crate::query::{AutomatonWeight, Query, Weight};
use crate::schema::Term;
use crate::Searcher;
use crate::TantivyError::InvalidArgument;
use levenshtein_automata::{LevenshteinAutomatonBuilder, DFA};
use once_cell::sync::Lazy;
use std::collections::HashMap;
use std::ops::Range;

/// A range of Levenshtein distances that we will build DFAs for our terms
/// The computation is exponential, so best keep it to low single digits
const VALID_LEVENSHTEIN_DISTANCE_RANGE: Range<u8> = 0..3;

static LEV_BUILDER: Lazy<HashMap<(u8, bool), LevenshteinAutomatonBuilder>> = Lazy::new(|| {
    let mut lev_builder_cache = HashMap::new();
    // TODO make population lazy on a `(distance, val)` basis
    for distance in VALID_LEVENSHTEIN_DISTANCE_RANGE {
        for &transposition in &[false, true] {
            let lev_automaton_builder = LevenshteinAutomatonBuilder::new(distance, transposition);
            lev_builder_cache.insert((distance, transposition), lev_automaton_builder);
        }
    }
    lev_builder_cache
});

/// A Fuzzy Query matches all of the documents
/// containing a specific term that is within
/// Levenshtein distance
/// ```rust
/// use tantivy::collector::{Count, TopDocs};
/// use tantivy::query::FuzzyTermQuery;
/// use tantivy::schema::{Schema, TEXT};
/// use tantivy::{doc, Index, Term};
///
/// fn example() -> tantivy::Result<()> {
///     let mut schema_builder = Schema::builder();
///     let title = schema_builder.add_text_field("title", TEXT);
///     let schema = schema_builder.build();
///     let index = Index::create_in_ram(schema);
///     {
///         let mut index_writer = index.writer(3_000_000)?;
///         index_writer.add_document(doc!(
///             title => "The Name of the Wind",
///         ));
///         index_writer.add_document(doc!(
///             title => "The Diary of Muadib",
///         ));
///         index_writer.add_document(doc!(
///             title => "A Dairy Cow",
///         ));
///         index_writer.add_document(doc!(
///             title => "The Diary of a Young Girl",
///         ));
///         index_writer.commit().unwrap();
///     }
///     let reader = index.reader()?;
///     let searcher = reader.searcher();
///
///     {
///         let term = Term::from_field_text(title, "Diary");
///         let query = FuzzyTermQuery::new(term, 1, true);
///         let (top_docs, count) = searcher.search(&query, &(TopDocs::with_limit(2), Count)).unwrap();
///         assert_eq!(count, 2);
///         assert_eq!(top_docs.len(), 2);
///     }
///
///     Ok(())
/// }
/// # assert!(example().is_ok());
/// ```
#[derive(Debug, Clone)]
pub struct FuzzyTermQuery {
    /// What term are we searching
    term: Term,
    /// How many changes are we going to allow
    distance: u8,
    /// Should a transposition cost 1 or 2?
    transposition_cost_one: bool,
    ///
    prefix: bool,
}

impl FuzzyTermQuery {
    /// Creates a new Fuzzy Query
    pub fn new(term: Term, distance: u8, transposition_cost_one: bool) -> FuzzyTermQuery {
        FuzzyTermQuery {
            term,
            distance,
            transposition_cost_one,
            prefix: false,
        }
    }

    /// Creates a new Fuzzy Query that treats transpositions as cost one rather than two
    pub fn new_prefix(term: Term, distance: u8, transposition_cost_one: bool) -> FuzzyTermQuery {
        FuzzyTermQuery {
            term,
            distance,
            transposition_cost_one,
            prefix: true,
        }
    }

    fn specialized_weight(&self) -> crate::Result<AutomatonWeight<DFA>> {
        // LEV_BUILDER is a HashMap, whose `get` method returns an Option
        match LEV_BUILDER.get(&(self.distance, false)) {
            // Unwrap the option and build the Ok(AutomatonWeight)
            Some(automaton_builder) => {
                let automaton = automaton_builder.build_dfa(self.term.text());
                Ok(AutomatonWeight::new(self.term.field(), automaton))
            }
            None => Err(InvalidArgument(format!(
                "Levenshtein distance of {} is not allowed. Choose a value in the {:?} range",
                self.distance, VALID_LEVENSHTEIN_DISTANCE_RANGE
            ))),
        }
    }
}

impl Query for FuzzyTermQuery {
    fn weight(
        &self,
        _searcher: &Searcher,
        _scoring_enabled: bool,
    ) -> crate::Result<Box<dyn Weight>> {
        Ok(Box::new(self.specialized_weight()?))
    }
}

#[cfg(test)]
mod test {
    use super::FuzzyTermQuery;
    use crate::collector::TopDocs;
    use crate::schema::Schema;
    use crate::schema::TEXT;
    use crate::tests::assert_nearly_equals;
    use crate::Index;
    use crate::Term;

    #[test]
    pub fn test_fuzzy_term() {
        let mut schema_builder = Schema::builder();
        let country_field = schema_builder.add_text_field("country", TEXT);
        let schema = schema_builder.build();
        let index = Index::create_in_ram(schema);
        {
            let mut index_writer = index.writer_with_num_threads(1, 10_000_000).unwrap();
            index_writer.add_document(doc!(
                country_field => "japan",
            ));
            index_writer.add_document(doc!(
                country_field => "korea",
            ));
            index_writer.commit().unwrap();
        }
        let reader = index.reader().unwrap();
        let searcher = reader.searcher();
        {
            let term = Term::from_field_text(country_field, "japon");

            let fuzzy_query = FuzzyTermQuery::new(term, 1, true);
            let top_docs = searcher
                .search(&fuzzy_query, &TopDocs::with_limit(2))
                .unwrap();
            assert_eq!(top_docs.len(), 1, "Expected only 1 document");
            let (score, _) = top_docs[0];
            assert_nearly_equals(1f32, score);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>boost base mutation rate back to 1.0<commit_after><|endoftext|>


<commit_before>use std;
use std::sync::Arc;
use smallvec::SmallVec;

use rope::Rope;
use str_utils::{is_grapheme_boundary, nearest_internal_grapheme_boundary, next_grapheme_boundary,
                prev_grapheme_boundary};
use tree::{Node, NodeChildren, NodeText, MAX_BYTES, MAX_CHILDREN};

/// An incremental `Rope` builder.
///
/// `RopeBuilder` is used to efficiently build `Rope`s from sequences
/// of text chunks.  It is useful for situations such as:
///
/// - Creating a rope from a large text file without pre-loading the
///   entire contents of the file into memory (but see
///   `Rope::from_reader()` which uses `RopeBuilder` internally for
///   precisely this use-case).
/// - Creating a rope from a streaming data source.
/// - Loading a non-utf8 text source into a rope, doing the encoding
///   conversion incrementally as you go.
///
/// Unlike repeatedly calling `Rope::insert()` on the end of a rope,
/// this API runs in time linear to the amount of data fed to it, and
/// is overall much faster.  It also creates more memory-compact ropes.
///
/// (The converse of this API is the [`Chunks`](iter/struct.Chunks.html)
/// iterator.)
///
/// # Example
/// ```
/// # use ropey::RopeBuilder;
/// #
/// let mut builder = RopeBuilder::new();
///
/// builder.append("Hello ");
/// builder.append("world!\n");
/// builder.append("How's ");
/// builder.append("it goin");
/// builder.append("g?");
///
/// let rope = builder.finish();
///
/// assert_eq!(rope, "Hello world!\nHow's it going?");
/// ```
#[derive(Debug, Clone)]
pub struct RopeBuilder {
    stack: SmallVec<[Arc<Node>; 4]>,
    buffer: String,
}

impl RopeBuilder {
    /// Creates a new RopeBuilder, ready for input.
    pub fn new() -> RopeBuilder {
        RopeBuilder {
            stack: {
                let mut stack = SmallVec::new();
                stack.push(Arc::new(Node::new()));
                stack
            },
            buffer: String::new(),
        }
    }

    /// Appends `chunk` to the end of the in-progress `Rope`.
    ///
    /// This method is called repeatedly to incrementally build up a
    /// `Rope`.  The passed text chunk can be as large or small as
    /// desired, but larger chunks are more efficient.
    ///
    /// `chunk` must be valid utf8 text.
    pub fn append(&mut self, chunk: &str) {
        self.append_internal(chunk, false);
    }

    /// Finishes the build, and returns the `Rope`.
    ///
    /// Note: this method consumes the builder.  If you want to continue
    /// building other ropes with the same prefix, you can clone the builder
    /// before calling `finish()`.
    pub fn finish(mut self) -> Rope {
        // Append the last leaf
        self.append_internal("", true);
        self.finish_internal()
    }

    /// Builds a rope all at once from a single string slice.
    ///
    /// This avoids the creation and use of the internal buffer.  This is
    /// for internal use only, because the public-facing API has
    /// Rope::from_str(), which actually uses this for its implementation.
    pub(crate) fn build_at_once(mut self, chunk: &str) -> Rope {
        self.append_internal(chunk, true);
        self.finish_internal()
    }

    //-----------------------------------------------------------------

    // Internal workings of `append()`.
    fn append_internal(&mut self, chunk: &str, last_chunk: bool) {
        let mut chunk = chunk;

        // Repeatedly chop text off the end of the input, creating
        // leaf nodes out of them and appending them to the tree.
        while !chunk.is_empty() || (!self.buffer.is_empty() && last_chunk) {
            // Get the text for the next leaf
            let (leaf_text, remainder) = self.get_next_leaf_text(chunk, last_chunk);
            chunk = remainder;

            // Append the leaf to the rope
            match leaf_text {
                NextText::None => break,
                NextText::UseBuffer => {
                    let string = NodeText::from_str(&self.buffer);
                    self.append_leaf_node(Arc::new(Node::Leaf(string)));
                    self.buffer.clear();
                }
                NextText::String(s) => {
                    self.append_leaf_node(Arc::new(Node::Leaf(NodeText::from_str(s))));
                }
            }
        }
    }

    // Internal workings of `finish()`.
    fn finish_internal(mut self) -> Rope {
        // Zip up all the remaining nodes on the stack
        let mut stack_idx = self.stack.len() - 1;
        while stack_idx >= 1 {
            let node = self.stack.pop().unwrap();
            if let Node::Internal(ref mut children) = *Arc::make_mut(&mut self.stack[stack_idx - 1])
            {
                children.push((node.text_info(), node));
            } else {
                unreachable!();
            }
            stack_idx -= 1;
        }

        // Get root and fix any right-side nodes with too few children.
        let mut root = self.stack.pop().unwrap();
        Arc::make_mut(&mut root).zip_fix_right();

        // Create the rope, make sure it's well-formed, and return it.
        let mut rope = Rope { root: root };
        rope.pull_up_singular_nodes();
        return rope;
    }

    // Returns (next_leaf_text, remaining_text)
    fn get_next_leaf_text<'a>(
        &mut self,
        text: &'a str,
        last_chunk: bool,
    ) -> (NextText<'a>, &'a str) {
        if self.buffer.is_empty() {
            if text.len() > MAX_BYTES {
                // Simplest case: just chop off the end of `text`
                let split_idx = find_good_split_idx(text, MAX_BYTES);
                if (split_idx == 0 || split_idx == text.len()) && !last_chunk {
                    self.buffer.push_str(text);
                    return (NextText::None, "");
                } else {
                    return (NextText::String(&text[..split_idx]), &text[split_idx..]);
                }
            } else if !last_chunk {
                self.buffer.push_str(text);
                return (NextText::None, "");
            } else {
                return (NextText::String(text), "");
            }
        } else if (text.len() + self.buffer.len()) > MAX_BYTES {
            let split_idx = if self.buffer.len() < MAX_BYTES {
                nearest_internal_grapheme_boundary(text, MAX_BYTES - self.buffer.len())
            } else {
                nearest_internal_grapheme_boundary(text, 0)
            };

            if (split_idx == 0 || split_idx == text.len()) && !last_chunk {
                self.buffer.push_str(text);
                return (NextText::None, "");
            } else {
                self.buffer.push_str(&text[..split_idx]);
                return (NextText::UseBuffer, &text[split_idx..]);
            }
        } else if !last_chunk {
            self.buffer.push_str(text);
            return (NextText::None, "");
        } else {
            self.buffer.push_str(text);
            return (NextText::UseBuffer, "");
        }
    }

    fn append_leaf_node(&mut self, leaf: Arc<Node>) {
        let last = self.stack.pop().unwrap();
        match *last {
            Node::Leaf(_) => {
                if last.leaf_text().is_empty() {
                    self.stack.push(leaf);
                } else {
                    let mut children = NodeChildren::new();
                    children.push((last.text_info(), last));
                    children.push((leaf.text_info(), leaf));
                    self.stack.push(Arc::new(Node::Internal(children)));
                }
            }

            Node::Internal(_) => {
                self.stack.push(last);
                let mut left = leaf;
                let mut stack_idx = (self.stack.len() - 1) as isize;
                loop {
                    if stack_idx < 0 {
                        // We're above the root, so do a root split.
                        let mut children = NodeChildren::new();
                        children.push((left.text_info(), left));
                        self.stack.insert(0, Arc::new(Node::Internal(children)));
                        break;
                    } else if self.stack[stack_idx as usize].child_count() < (MAX_CHILDREN - 1) {
                        // There's room to add a child, so do that.
                        Arc::make_mut(&mut self.stack[stack_idx as usize])
                            .children()
                            .push((left.text_info(), left));
                        break;
                    } else {
                        // Not enough room to fit a child, so split.
                        left = Arc::new(Node::Internal(
                            Arc::make_mut(&mut self.stack[stack_idx as usize])
                                .children()
                                .push_split((left.text_info(), left)),
                        ));
                        std::mem::swap(&mut left, &mut self.stack[stack_idx as usize]);
                        stack_idx -= 1;
                    }
                }
            }
        }
    }
}

enum NextText<'a> {
    None,
    UseBuffer,
    String(&'a str),
}

fn find_good_split_idx(text: &str, idx: usize) -> usize {
    if is_grapheme_boundary(text, idx) {
        idx
    } else {
        let prev = prev_grapheme_boundary(text, idx);
        let next = next_grapheme_boundary(text, idx);
        if prev > 0 {
            prev
        } else {
            next
        }
    }
}
<commit_msg>Added test for RopeBuilder.<commit_after>use std;
use std::sync::Arc;
use smallvec::SmallVec;

use rope::Rope;
use str_utils::{is_grapheme_boundary, nearest_internal_grapheme_boundary, next_grapheme_boundary,
                prev_grapheme_boundary};
use tree::{Node, NodeChildren, NodeText, MAX_BYTES, MAX_CHILDREN};

/// An incremental `Rope` builder.
///
/// `RopeBuilder` is used to efficiently build `Rope`s from sequences
/// of text chunks.  It is useful for situations such as:
///
/// - Creating a rope from a large text file without pre-loading the
///   entire contents of the file into memory (but see
///   `Rope::from_reader()` which uses `RopeBuilder` internally for
///   precisely this use-case).
/// - Creating a rope from a streaming data source.
/// - Loading a non-utf8 text source into a rope, doing the encoding
///   conversion incrementally as you go.
///
/// Unlike repeatedly calling `Rope::insert()` on the end of a rope,
/// this API runs in time linear to the amount of data fed to it, and
/// is overall much faster.  It also creates more memory-compact ropes.
///
/// (The converse of this API is the [`Chunks`](iter/struct.Chunks.html)
/// iterator.)
///
/// # Example
/// ```
/// # use ropey::RopeBuilder;
/// #
/// let mut builder = RopeBuilder::new();
///
/// builder.append("Hello ");
/// builder.append("world!\n");
/// builder.append("How's ");
/// builder.append("it goin");
/// builder.append("g?");
///
/// let rope = builder.finish();
///
/// assert_eq!(rope, "Hello world!\nHow's it going?");
/// ```
#[derive(Debug, Clone)]
pub struct RopeBuilder {
    stack: SmallVec<[Arc<Node>; 4]>,
    buffer: String,
}

impl RopeBuilder {
    /// Creates a new RopeBuilder, ready for input.
    pub fn new() -> RopeBuilder {
        RopeBuilder {
            stack: {
                let mut stack = SmallVec::new();
                stack.push(Arc::new(Node::new()));
                stack
            },
            buffer: String::new(),
        }
    }

    /// Appends `chunk` to the end of the in-progress `Rope`.
    ///
    /// This method is called repeatedly to incrementally build up a
    /// `Rope`.  The passed text chunk can be as large or small as
    /// desired, but larger chunks are more efficient.
    ///
    /// `chunk` must be valid utf8 text.
    pub fn append(&mut self, chunk: &str) {
        self.append_internal(chunk, false);
    }

    /// Finishes the build, and returns the `Rope`.
    ///
    /// Note: this method consumes the builder.  If you want to continue
    /// building other ropes with the same prefix, you can clone the builder
    /// before calling `finish()`.
    pub fn finish(mut self) -> Rope {
        // Append the last leaf
        self.append_internal("", true);
        self.finish_internal()
    }

    /// Builds a rope all at once from a single string slice.
    ///
    /// This avoids the creation and use of the internal buffer.  This is
    /// for internal use only, because the public-facing API has
    /// Rope::from_str(), which actually uses this for its implementation.
    pub(crate) fn build_at_once(mut self, chunk: &str) -> Rope {
        self.append_internal(chunk, true);
        self.finish_internal()
    }

    //-----------------------------------------------------------------

    // Internal workings of `append()`.
    fn append_internal(&mut self, chunk: &str, last_chunk: bool) {
        let mut chunk = chunk;

        // Repeatedly chop text off the end of the input, creating
        // leaf nodes out of them and appending them to the tree.
        while !chunk.is_empty() || (!self.buffer.is_empty() && last_chunk) {
            // Get the text for the next leaf
            let (leaf_text, remainder) = self.get_next_leaf_text(chunk, last_chunk);
            chunk = remainder;

            // Append the leaf to the rope
            match leaf_text {
                NextText::None => break,
                NextText::UseBuffer => {
                    let string = NodeText::from_str(&self.buffer);
                    self.append_leaf_node(Arc::new(Node::Leaf(string)));
                    self.buffer.clear();
                }
                NextText::String(s) => {
                    self.append_leaf_node(Arc::new(Node::Leaf(NodeText::from_str(s))));
                }
            }
        }
    }

    // Internal workings of `finish()`.
    fn finish_internal(mut self) -> Rope {
        // Zip up all the remaining nodes on the stack
        let mut stack_idx = self.stack.len() - 1;
        while stack_idx >= 1 {
            let node = self.stack.pop().unwrap();
            if let Node::Internal(ref mut children) = *Arc::make_mut(&mut self.stack[stack_idx - 1])
            {
                children.push((node.text_info(), node));
            } else {
                unreachable!();
            }
            stack_idx -= 1;
        }

        // Get root and fix any right-side nodes with too few children.
        let mut root = self.stack.pop().unwrap();
        Arc::make_mut(&mut root).zip_fix_right();

        // Create the rope, make sure it's well-formed, and return it.
        let mut rope = Rope { root: root };
        rope.pull_up_singular_nodes();
        return rope;
    }

    // Returns (next_leaf_text, remaining_text)
    fn get_next_leaf_text<'a>(
        &mut self,
        text: &'a str,
        last_chunk: bool,
    ) -> (NextText<'a>, &'a str) {
        if self.buffer.is_empty() {
            if text.len() > MAX_BYTES {
                // Simplest case: just chop off the end of `text`
                let split_idx = find_good_split_idx(text, MAX_BYTES);
                if (split_idx == 0 || split_idx == text.len()) && !last_chunk {
                    self.buffer.push_str(text);
                    return (NextText::None, "");
                } else {
                    return (NextText::String(&text[..split_idx]), &text[split_idx..]);
                }
            } else if !last_chunk {
                self.buffer.push_str(text);
                return (NextText::None, "");
            } else {
                return (NextText::String(text), "");
            }
        } else if (text.len() + self.buffer.len()) > MAX_BYTES {
            let split_idx = if self.buffer.len() < MAX_BYTES {
                nearest_internal_grapheme_boundary(text, MAX_BYTES - self.buffer.len())
            } else {
                nearest_internal_grapheme_boundary(text, 0)
            };

            if (split_idx == 0 || split_idx == text.len()) && !last_chunk {
                self.buffer.push_str(text);
                return (NextText::None, "");
            } else {
                self.buffer.push_str(&text[..split_idx]);
                return (NextText::UseBuffer, &text[split_idx..]);
            }
        } else if !last_chunk {
            self.buffer.push_str(text);
            return (NextText::None, "");
        } else {
            self.buffer.push_str(text);
            return (NextText::UseBuffer, "");
        }
    }

    fn append_leaf_node(&mut self, leaf: Arc<Node>) {
        let last = self.stack.pop().unwrap();
        match *last {
            Node::Leaf(_) => {
                if last.leaf_text().is_empty() {
                    self.stack.push(leaf);
                } else {
                    let mut children = NodeChildren::new();
                    children.push((last.text_info(), last));
                    children.push((leaf.text_info(), leaf));
                    self.stack.push(Arc::new(Node::Internal(children)));
                }
            }

            Node::Internal(_) => {
                self.stack.push(last);
                let mut left = leaf;
                let mut stack_idx = (self.stack.len() - 1) as isize;
                loop {
                    if stack_idx < 0 {
                        // We're above the root, so do a root split.
                        let mut children = NodeChildren::new();
                        children.push((left.text_info(), left));
                        self.stack.insert(0, Arc::new(Node::Internal(children)));
                        break;
                    } else if self.stack[stack_idx as usize].child_count() < (MAX_CHILDREN - 1) {
                        // There's room to add a child, so do that.
                        Arc::make_mut(&mut self.stack[stack_idx as usize])
                            .children()
                            .push((left.text_info(), left));
                        break;
                    } else {
                        // Not enough room to fit a child, so split.
                        left = Arc::new(Node::Internal(
                            Arc::make_mut(&mut self.stack[stack_idx as usize])
                                .children()
                                .push_split((left.text_info(), left)),
                        ));
                        std::mem::swap(&mut left, &mut self.stack[stack_idx as usize]);
                        stack_idx -= 1;
                    }
                }
            }
        }
    }
}

enum NextText<'a> {
    None,
    UseBuffer,
    String(&'a str),
}

fn find_good_split_idx(text: &str, idx: usize) -> usize {
    if is_grapheme_boundary(text, idx) {
        idx
    } else {
        let prev = prev_grapheme_boundary(text, idx);
        let next = next_grapheme_boundary(text, idx);
        if prev > 0 {
            prev
        } else {
            next
        }
    }
}

//===========================================================================

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

    // 127 bytes, 103 chars, 4 lines
    const TEXT: &str = "Hello there!  How're you doing?\r\nIt's \
                        a fine day, isn't it?\r\nAren't you glad \
                        we're alive?\r\nこんにちは、みんなさん！";

    #[test]
    fn rope_builder_01() {
        let mut b = RopeBuilder::new();

        b.append("Hello there!  How're you doing?\r");
        b.append("\nIt's a fine ");
        b.append("d");
        b.append("a");
        b.append("y,");
        b.append(" ");
        b.append("isn't it?");
        b.append("\r");
        b.append("\nAren't you ");
        b.append("glad we're alive?\r");
        b.append("\n");
        b.append("こんにち");
        b.append("は、みんなさ");
        b.append("ん！");

        let r = b.finish();

        assert_eq!(r, TEXT);

        r.assert_integrity();
        r.assert_invariants();
    }
}
<|endoftext|>


<commit_before>use std::io::Command;
use regex::Regex;
use common:: { LogEntry, Feature, Fix, Unknown };

#[deriving(Show)]
pub struct LogReaderConfig {
    pub grep: String,
    pub format: String,
    pub from: Option<String>,
    pub to: String
}

pub fn get_latest_tag () -> String {

    Command::new("git")
            .arg("rev-list")
            .arg("--tags")
            .arg("--max-count=1")
            .spawn()
            .ok().expect("failed to invoke ref-list")
            .stdout.get_mut_ref().read_to_string()
            .ok().expect("failed to get latest git log")
            .as_slice().trim_chars('\n')
            .to_string()
}

pub fn get_last_commit () -> String {
    Command::new("git")
            .arg("rev-parse")
            .arg("HEAD")
            .spawn()
            .ok().expect("failed to invoke rev-parse")
            .stdout.get_mut_ref().read_to_string()
            .ok().expect("failed to get last commit")
}

pub fn get_log_entries (config:LogReaderConfig) -> Vec<LogEntry>{

    let range = match config.from {
        Some(ref from) => format!("{}..{}", from, config.to),
        None => "HEAD".to_string()
    };

    Command::new("git")
            .arg("log")
            .arg("-E")
            .arg(format!("--grep={}",config.grep))
            .arg(format!("--format={}", "%H%n%s%n%b%n==END=="))
            .arg(range)
            .spawn()
            .ok().expect("failed to invoke `git log`")
            .stdout.get_mut_ref().read_to_string()
            .ok().expect("failed to read git log")
            .as_slice()
            .split_str("\n==END==\n")
            .map(|commit_str| { parse_raw_commit(commit_str) })
            .filter(| entry| entry.commit_type != Unknown)
            .collect()
}

static COMMIT_PATTERN: Regex = regex!(r"^(.*)\((.*)\):(.*)");
static CLOSES_PATTERN: Regex = regex!(r"(?:Closes|Fixes|Resolves)\s((?:#(\d+)(?:,\s)?)+)");

fn parse_raw_commit(commit_str:&str) -> LogEntry {
    let mut lines = commit_str.split('\n');

    let hash = lines.next().unwrap_or("").to_string();

    let (subject, component, commit_type) =
        match lines.next().and_then(|s| COMMIT_PATTERN.captures(s)) {
            Some(caps) => {
                let commit_type = match caps.at(1) {
                    "feat" => Feature,
                    "fix"  => Fix,
                    _      => Unknown
                };
                let component = caps.at(2).to_string();
                let subject = caps.at(3).to_string();
                (subject, component, commit_type)
           },
           None => ("".to_string(), "".to_string(), Unknown)
        };
    let closes = lines.filter_map(|line| CLOSES_PATTERN.captures(line))
                      .map(|caps| caps.at(2).to_string())
                      .collect();

    LogEntry {
        hash: hash,
        subject: subject,
        component: component,
        closes: closes,
        breaks: vec!(),
        commit_type: commit_type
    }
}
<commit_msg>fix(git): get_mut_ref() was deprecated, use as_mut().unwrap()<commit_after>use std::io::Command;
use regex::Regex;
use common:: { LogEntry, Feature, Fix, Unknown };

#[deriving(Show)]
pub struct LogReaderConfig {
    pub grep: String,
    pub format: String,
    pub from: Option<String>,
    pub to: String
}

pub fn get_latest_tag () -> String {

    Command::new("git")
            .arg("rev-list")
            .arg("--tags")
            .arg("--max-count=1")
            .spawn()
            .ok().expect("failed to invoke ref-list")
            .stdout.as_mut().unwrap().read_to_string()
            .ok().expect("failed to get latest git log")
            .as_slice().trim_chars('\n')
            .to_string()
}

pub fn get_last_commit () -> String {
    Command::new("git")
            .arg("rev-parse")
            .arg("HEAD")
            .spawn()
            .ok().expect("failed to invoke rev-parse")
            .stdout.as_mut().unwrap().read_to_string()
            .ok().expect("failed to get last commit")
}

pub fn get_log_entries (config:LogReaderConfig) -> Vec<LogEntry>{

    let range = match config.from {
        Some(ref from) => format!("{}..{}", from, config.to),
        None => "HEAD".to_string()
    };

    Command::new("git")
            .arg("log")
            .arg("-E")
            .arg(format!("--grep={}",config.grep))
            .arg(format!("--format={}", "%H%n%s%n%b%n==END=="))
            .arg(range)
            .spawn()
            .ok().expect("failed to invoke `git log`")
            .stdout.as_mut().unwrap().read_to_string()
            .ok().expect("failed to read git log")
            .as_slice()
            .split_str("\n==END==\n")
            .map(|commit_str| { parse_raw_commit(commit_str) })
            .filter(| entry| entry.commit_type != Unknown)
            .collect()
}

static COMMIT_PATTERN: Regex = regex!(r"^(.*)\((.*)\):(.*)");
static CLOSES_PATTERN: Regex = regex!(r"(?:Closes|Fixes|Resolves)\s((?:#(\d+)(?:,\s)?)+)");

fn parse_raw_commit(commit_str:&str) -> LogEntry {
    let mut lines = commit_str.split('\n');

    let hash = lines.next().unwrap_or("").to_string();

    let (subject, component, commit_type) =
        match lines.next().and_then(|s| COMMIT_PATTERN.captures(s)) {
            Some(caps) => {
                let commit_type = match caps.at(1) {
                    "feat" => Feature,
                    "fix"  => Fix,
                    _      => Unknown
                };
                let component = caps.at(2).to_string();
                let subject = caps.at(3).to_string();
                (subject, component, commit_type)
           },
           None => ("".to_string(), "".to_string(), Unknown)
        };
    let closes = lines.filter_map(|line| CLOSES_PATTERN.captures(line))
                      .map(|caps| caps.at(2).to_string())
                      .collect();

    LogEntry {
        hash: hash,
        subject: subject,
        component: component,
        closes: closes,
        breaks: vec!(),
        commit_type: commit_type
    }
}
<|endoftext|>