<commit_before>use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering::*};

fn main() {
    atomic_bool();
    atomic_isize();
}

fn atomic_bool() {
    static mut ATOMIC: AtomicBool = AtomicBool::new(false);

    unsafe {
        assert_eq!(*ATOMIC.get_mut(), false);
        ATOMIC.store(true, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), true);
        ATOMIC.fetch_or(false, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), true);
        ATOMIC.fetch_and(false, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), false);
        ATOMIC.fetch_nand(true, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), true);
        ATOMIC.fetch_xor(true, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), false);
    }
}

fn atomic_isize() {
    static ATOMIC: AtomicIsize = AtomicIsize::new(0);

    // Make sure trans can emit all the intrinsics correctly
    assert_eq!(ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed), Ok(0));
    assert_eq!(ATOMIC.compare_exchange(0, 2, Acquire, Relaxed), Err(1));
    assert_eq!(ATOMIC.compare_exchange(0, 1, Release, Relaxed), Err(1));
    assert_eq!(ATOMIC.compare_exchange(1, 0, AcqRel, Relaxed), Ok(1));
    ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed).ok();
    ATOMIC.compare_exchange(0, 1, Acquire, Acquire).ok();
    ATOMIC.compare_exchange(0, 1, AcqRel, Acquire).ok();
    ATOMIC.compare_exchange(0, 1, SeqCst, Acquire).ok();
    ATOMIC.compare_exchange(0, 1, SeqCst, SeqCst).ok();

    ATOMIC.store(0, SeqCst);

    assert_eq!(ATOMIC.compare_exchange_weak(0, 1, Relaxed, Relaxed), Ok(0));
    assert_eq!(ATOMIC.compare_exchange_weak(0, 2, Acquire, Relaxed), Err(1));
    assert_eq!(ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed), Err(1));
    assert_eq!(ATOMIC.compare_exchange_weak(1, 0, AcqRel, Relaxed), Ok(1));
    ATOMIC.compare_exchange_weak(0, 1, AcqRel, Relaxed).ok();
    ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed).ok();
    ATOMIC.compare_exchange_weak(0, 1, Acquire, Acquire).ok();
    ATOMIC.compare_exchange_weak(0, 1, AcqRel, Acquire).ok();
    ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok();
    ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok();
}
<commit_msg>test AtomicU64<commit_after>use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicU64, Ordering::*};

fn main() {
    atomic_bool();
    atomic_isize();
    atomic_u64();
}

fn atomic_bool() {
    static mut ATOMIC: AtomicBool = AtomicBool::new(false);

    unsafe {
        assert_eq!(*ATOMIC.get_mut(), false);
        ATOMIC.store(true, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), true);
        ATOMIC.fetch_or(false, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), true);
        ATOMIC.fetch_and(false, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), false);
        ATOMIC.fetch_nand(true, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), true);
        ATOMIC.fetch_xor(true, SeqCst);
        assert_eq!(*ATOMIC.get_mut(), false);
    }
}

fn atomic_isize() {
    static ATOMIC: AtomicIsize = AtomicIsize::new(0);

    // Make sure trans can emit all the intrinsics correctly
    assert_eq!(ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed), Ok(0));
    assert_eq!(ATOMIC.compare_exchange(0, 2, Acquire, Relaxed), Err(1));
    assert_eq!(ATOMIC.compare_exchange(0, 1, Release, Relaxed), Err(1));
    assert_eq!(ATOMIC.compare_exchange(1, 0, AcqRel, Relaxed), Ok(1));
    ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed).ok();
    ATOMIC.compare_exchange(0, 1, Acquire, Acquire).ok();
    ATOMIC.compare_exchange(0, 1, AcqRel, Acquire).ok();
    ATOMIC.compare_exchange(0, 1, SeqCst, Acquire).ok();
    ATOMIC.compare_exchange(0, 1, SeqCst, SeqCst).ok();

    ATOMIC.store(0, SeqCst);

    assert_eq!(ATOMIC.compare_exchange_weak(0, 1, Relaxed, Relaxed), Ok(0));
    assert_eq!(ATOMIC.compare_exchange_weak(0, 2, Acquire, Relaxed), Err(1));
    assert_eq!(ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed), Err(1));
    assert_eq!(ATOMIC.compare_exchange_weak(1, 0, AcqRel, Relaxed), Ok(1));
    ATOMIC.compare_exchange_weak(0, 1, AcqRel, Relaxed).ok();
    ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed).ok();
    ATOMIC.compare_exchange_weak(0, 1, Acquire, Acquire).ok();
    ATOMIC.compare_exchange_weak(0, 1, AcqRel, Acquire).ok();
    ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok();
    ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok();
}

fn atomic_u64() {
    static ATOMIC: AtomicU64 = AtomicU64::new(0);

    ATOMIC.store(1, SeqCst);
    assert_eq!(ATOMIC.compare_exchange(0, 0x100, AcqRel, Acquire), Err(1));
    assert_eq!(ATOMIC.compare_exchange_weak(1, 0x100, AcqRel, Acquire), Ok(1));
    assert_eq!(ATOMIC.load(Relaxed), 0x100);
}
<|endoftext|>


<commit_before>//! TODO documentation

use std::ptr;

use wlroots_sys::{wlr_output_cursor, wlr_output_cursor_create, wlr_output_cursor_destroy,
                  wlr_output_cursor_move, wlr_output_cursor_set_image,
                  wlr_output_cursor_set_surface};

use {wlroots_dehandle, render,
     output::{self, Output},
     surface::{self, Surface},
     utils::{Handleable, HandleResult}};

#[derive(Debug, Eq, PartialEq)]
pub struct Cursor {
    cursor: *mut wlr_output_cursor,
    output_handle: output::Handle
}

impl Cursor {
    /// Creates a new `output::Cursor` that's bound to the given `Output`.
    ///
    /// When the `Output` is destroyed each call will return an Error.
    ///
    /// # Ergonomics
    ///
    /// To make this easier for you, I would suggest putting the `output::Cursor` in your
    /// `OutputHandler` implementor's state so that when the `Output` is removed you
    /// just don't have to think about it and it will clean itself up by itself.
    pub fn new(output: &mut Output) -> Option<Cursor> {
        unsafe {
            let output_handle = output.weak_reference();
            let cursor = wlr_output_cursor_create(output.as_ptr());
            if cursor.is_null() {
                None
            } else {
                Some(Cursor { cursor,
                              output_handle })
            }
        }
    }

    /// Sets the hardware cursor's image.
    #[wlroots_dehandle]
    pub fn set_image(&mut self, image: &render::Image) -> HandleResult<bool> {
        unsafe {
            let cursor = self.cursor;
            #[dehandle] let _output = self.output_handle?;
            Ok(wlr_output_cursor_set_image(cursor,
                                           image.pixels.as_ptr(),
                                           image.stride,
                                           image.width,
                                           image.height,
                                           image.hotspot_x,
                                           image.hotspot_y))
        }
    }

    /// Sets the hardware cursor's surface.
    #[wlroots_dehandle]
    pub fn set_surface<'a, T>(&mut self, surface: T, hotspot_x: i32, hotspot_y: i32)
                              -> HandleResult<()>
    where T: Into<Option<&'a Surface>>
    {
        unsafe {
            let surface_ptr = surface.into()
                .map(|surface| surface.as_ptr())
                .unwrap_or_else(|| ptr::null_mut());
            #[dehandle] let _output = self.output_handle?;
            Ok(wlr_output_cursor_set_surface(self.cursor,
                                             surface_ptr,
                                             hotspot_x,
                                             hotspot_y))
        }
    }

    /// Moves the hardware cursor to the desired location
    #[wlroots_dehandle]
    pub fn move_to(&mut self, x: f64, y: f64) -> HandleResult<bool> {
        unsafe {
            #[dehandle] let _output = self.output_handle?;
            Ok(wlr_output_cursor_move(self.cursor, x, y))
        }
    }

    /// Get the coordinates of the cursor.
    ///
    /// Returned value is in (x, y) format.
    pub fn coords(&self) -> (f64, f64) {
        unsafe { ((*self.cursor).x, (*self.cursor).y) }
    }

    /// Determines if the hardware cursor is enabled or not.
    pub fn enabled(&self) -> bool {
        unsafe { (*self.cursor).enabled }
    }

    /// Determines if the hardware cursor is visible or not.
    pub fn visible(&self) -> bool {
        unsafe { (*self.cursor).visible }
    }

    /// Gets the width and height of the hardware cursor.
    ///
    /// Returned value is in (width, height) format.
    pub fn size(&self) -> (u32, u32) {
        unsafe { ((*self.cursor).width, (*self.cursor).height) }
    }

    /// Gets the hotspot coordinates of the hardware cursor.
    ///
    /// Returned value is in (x, y) coordinates.
    pub fn hotspots(&self) -> (i32, i32) {
        unsafe { ((*self.cursor).hotspot_x, (*self.cursor).hotspot_y) }
    }

    /// Gets the texture for the cursor, if a software cursor is used without a
    /// surface.
    pub fn texture<'surface>(&'surface self) -> Option<render::Texture<'surface>> {
        unsafe {
            let texture = (*self.cursor).texture;
            if texture.is_null() {
                None
            } else {
                Some(render::Texture::from_ptr(texture))
            }
        }
    }

    /// Gets the surface for the cursor, if using a cursor surface.
    pub fn surface(&self) -> Option<surface::Handle> {
        unsafe {
            let surface = (*self.cursor).surface;
            if surface.is_null() {
                None
            } else {
                Some(surface::Handle::from_ptr(surface))
            }
        }
    }
}

impl Drop for Cursor {
    fn drop(&mut self) {
        unsafe { wlr_output_cursor_destroy(self.cursor) }
    }
}
<commit_msg>Can get the output handle from the cursor<commit_after>//! TODO documentation

use std::ptr;

use wlroots_sys::{wlr_output_cursor, wlr_output_cursor_create, wlr_output_cursor_destroy,
                  wlr_output_cursor_move, wlr_output_cursor_set_image,
                  wlr_output_cursor_set_surface};

use {wlroots_dehandle, render,
     output::{self, Output},
     surface::{self, Surface},
     utils::{Handleable, HandleResult}};

#[derive(Debug, Eq, PartialEq)]
pub struct Cursor {
    cursor: *mut wlr_output_cursor,
    output_handle: output::Handle
}

impl Cursor {
    /// Creates a new `output::Cursor` that's bound to the given `Output`.
    ///
    /// When the `Output` is destroyed each call will return an Error.
    ///
    /// # Ergonomics
    ///
    /// To make this easier for you, I would suggest putting the `output::Cursor` in your
    /// `OutputHandler` implementor's state so that when the `Output` is removed you
    /// just don't have to think about it and it will clean itself up by itself.
    pub fn new(output: &mut Output) -> Option<Cursor> {
        unsafe {
            let output_handle = output.weak_reference();
            let cursor = wlr_output_cursor_create(output.as_ptr());
            if cursor.is_null() {
                None
            } else {
                Some(Cursor { cursor,
                              output_handle })
            }
        }
    }

    /// Return a copy of the output handle used by this cursor.
    ///
    /// There are no guarantees that it is valid to use.
    pub fn output(&self) -> output::Handle {
        self.output_handle.clone()
    }

    /// Sets the hardware cursor's image.
    #[wlroots_dehandle]
    pub fn set_image(&mut self, image: &render::Image) -> HandleResult<bool> {
        unsafe {
            let cursor = self.cursor;
            #[dehandle] let _output = self.output_handle?;
            Ok(wlr_output_cursor_set_image(cursor,
                                           image.pixels.as_ptr(),
                                           image.stride,
                                           image.width,
                                           image.height,
                                           image.hotspot_x,
                                           image.hotspot_y))
        }
    }

    /// Sets the hardware cursor's surface.
    #[wlroots_dehandle]
    pub fn set_surface<'a, T>(&mut self, surface: T, hotspot_x: i32, hotspot_y: i32)
                              -> HandleResult<()>
    where T: Into<Option<&'a Surface>>
    {
        unsafe {
            let surface_ptr = surface.into()
                .map(|surface| surface.as_ptr())
                .unwrap_or_else(|| ptr::null_mut());
            #[dehandle] let _output = self.output_handle?;
            Ok(wlr_output_cursor_set_surface(self.cursor,
                                             surface_ptr,
                                             hotspot_x,
                                             hotspot_y))
        }
    }

    /// Moves the hardware cursor to the desired location
    #[wlroots_dehandle]
    pub fn move_to(&mut self, x: f64, y: f64) -> HandleResult<bool> {
        unsafe {
            #[dehandle] let _output = self.output_handle?;
            Ok(wlr_output_cursor_move(self.cursor, x, y))
        }
    }

    /// Get the coordinates of the cursor.
    ///
    /// Returned value is in (x, y) format.
    pub fn coords(&self) -> (f64, f64) {
        unsafe { ((*self.cursor).x, (*self.cursor).y) }
    }

    /// Determines if the hardware cursor is enabled or not.
    pub fn enabled(&self) -> bool {
        unsafe { (*self.cursor).enabled }
    }

    /// Determines if the hardware cursor is visible or not.
    pub fn visible(&self) -> bool {
        unsafe { (*self.cursor).visible }
    }

    /// Gets the width and height of the hardware cursor.
    ///
    /// Returned value is in (width, height) format.
    pub fn size(&self) -> (u32, u32) {
        unsafe { ((*self.cursor).width, (*self.cursor).height) }
    }

    /// Gets the hotspot coordinates of the hardware cursor.
    ///
    /// Returned value is in (x, y) coordinates.
    pub fn hotspots(&self) -> (i32, i32) {
        unsafe { ((*self.cursor).hotspot_x, (*self.cursor).hotspot_y) }
    }

    /// Gets the texture for the cursor, if a software cursor is used without a
    /// surface.
    pub fn texture<'surface>(&'surface self) -> Option<render::Texture<'surface>> {
        unsafe {
            let texture = (*self.cursor).texture;
            if texture.is_null() {
                None
            } else {
                Some(render::Texture::from_ptr(texture))
            }
        }
    }

    /// Gets the surface for the cursor, if using a cursor surface.
    pub fn surface(&self) -> Option<surface::Handle> {
        unsafe {
            let surface = (*self.cursor).surface;
            if surface.is_null() {
                None
            } else {
                Some(surface::Handle::from_ptr(surface))
            }
        }
    }
}

impl Drop for Cursor {
    fn drop(&mut self) {
        unsafe { wlr_output_cursor_destroy(self.cursor) }
    }
}
<|endoftext|>


<commit_before>use std::process::exit;

use libimagdiary::diary::Diary;
use libimagdiary::diaryid::DiaryId;
use libimagdiary::error::DiaryErrorKind as DEK;
use libimagdiary::error::MapErrInto;
use libimagentryedit::edit::Edit;
use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error;
use libimagdiary::entry::Entry;
use libimagdiary::result::Result;

use util::get_diary_name;

pub fn create(rt: &Runtime) {

    let diaryname = get_diary_name(rt);
    if diaryname.is_none() {
        warn!("No diary selected. Use either the configuration file or the commandline option");
        exit(1);
    }
    let diaryname = diaryname.unwrap();

    let prevent_edit = rt.cli().subcommand_matches("create").unwrap().is_present("no-edit");

    fn create_entry<'a>(diary: &'a Diary, rt: &Runtime) -> Result<Entry<'a>> {
        use std::str::FromStr;

        let create = rt.cli().subcommand_matches("create").unwrap();
        if !create.is_present("timed") {
            debug!("Creating non-timed entry");
            diary.new_entry_today()
        } else {
            let id = match create.value_of("timed") {
                Some("h") | Some("hourly") => {
                    debug!("Creating hourly-timed entry");
                    let time = DiaryId::now(String::from(diary.name()));
                    let hr = create
                        .value_of("hour")
                        .map(|v| { debug!("Creating hourly entry with hour = {:?}", v); v })
                        .and_then(|s| {
                            FromStr::from_str(s)
                                .map_err(|_| warn!("Could not parse hour: '{}'", s))
                                .ok()
                        })
                        .unwrap_or(time.hour());

                    time.with_hour(hr).with_minute(0)
                },

                Some("m") | Some("minutely") => {
                    debug!("Creating minutely-timed entry");
                    let time = DiaryId::now(String::from(diary.name()));
                    let hr = create
                        .value_of("hour")
                        .map(|h| { debug!("hour = {:?}", h); h })
                        .and_then(|s| {
                            FromStr::from_str(s)
                                .map_err(|_| warn!("Could not parse hour: '{}'", s))
                                .ok()
                        })
                        .unwrap_or(time.hour());

                    let min = create
                        .value_of("minute")
                        .map(|m| { debug!("minute = {:?}", m); m })
                        .and_then(|s| {
                            FromStr::from_str(s)
                                .map_err(|_| warn!("Could not parse minute: '{}'", s))
                                .ok()
                        })
                        .unwrap_or(time.minute());

                    time.with_hour(hr).with_minute(min)
                },

                Some(_) => {
                    warn!("Timed creation failed: Unknown spec '{}'",
                          create.value_of("timed").unwrap());
                    exit(1);
                },

                None => {
                    warn!("Unexpected error, cannot continue");
                    exit(1);
                },
            };

            diary.new_entry_by_id(id)
        }
    }

    let diary = Diary::open(rt.store(), &diaryname[..]);
    let res = create_entry(&diary, rt)
        .and_then(|mut entry| {
            if prevent_edit {
                debug!("Not editing new diary entry");
                Ok(())
            } else {
                debug!("Editing new diary entry");
                entry.edit_content(rt).map_err_into(DEK::DiaryEditError)
            }
        });

    if let Err(e) = res {
        trace_error(&e);
    } else {
        info!("Ok!");
    }
}

<commit_msg>Replace is_none() -> unwrap() with unwrap_or_else()<commit_after>use std::process::exit;

use libimagdiary::diary::Diary;
use libimagdiary::diaryid::DiaryId;
use libimagdiary::error::DiaryErrorKind as DEK;
use libimagdiary::error::MapErrInto;
use libimagentryedit::edit::Edit;
use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error;
use libimagdiary::entry::Entry;
use libimagdiary::result::Result;

use util::get_diary_name;

pub fn create(rt: &Runtime) {
    let diaryname = get_diary_name(rt)
        .unwrap_or_else(|| {
            warn!("No diary selected. Use either the configuration file or the commandline option");
            exit(1)
        });

    let prevent_edit = rt.cli().subcommand_matches("create").unwrap().is_present("no-edit");

    fn create_entry<'a>(diary: &'a Diary, rt: &Runtime) -> Result<Entry<'a>> {
        use std::str::FromStr;

        let create = rt.cli().subcommand_matches("create").unwrap();
        if !create.is_present("timed") {
            debug!("Creating non-timed entry");
            diary.new_entry_today()
        } else {
            let id = match create.value_of("timed") {
                Some("h") | Some("hourly") => {
                    debug!("Creating hourly-timed entry");
                    let time = DiaryId::now(String::from(diary.name()));
                    let hr = create
                        .value_of("hour")
                        .map(|v| { debug!("Creating hourly entry with hour = {:?}", v); v })
                        .and_then(|s| {
                            FromStr::from_str(s)
                                .map_err(|_| warn!("Could not parse hour: '{}'", s))
                                .ok()
                        })
                        .unwrap_or(time.hour());

                    time.with_hour(hr).with_minute(0)
                },

                Some("m") | Some("minutely") => {
                    debug!("Creating minutely-timed entry");
                    let time = DiaryId::now(String::from(diary.name()));
                    let hr = create
                        .value_of("hour")
                        .map(|h| { debug!("hour = {:?}", h); h })
                        .and_then(|s| {
                            FromStr::from_str(s)
                                .map_err(|_| warn!("Could not parse hour: '{}'", s))
                                .ok()
                        })
                        .unwrap_or(time.hour());

                    let min = create
                        .value_of("minute")
                        .map(|m| { debug!("minute = {:?}", m); m })
                        .and_then(|s| {
                            FromStr::from_str(s)
                                .map_err(|_| warn!("Could not parse minute: '{}'", s))
                                .ok()
                        })
                        .unwrap_or(time.minute());

                    time.with_hour(hr).with_minute(min)
                },

                Some(_) => {
                    warn!("Timed creation failed: Unknown spec '{}'",
                          create.value_of("timed").unwrap());
                    exit(1);
                },

                None => {
                    warn!("Unexpected error, cannot continue");
                    exit(1);
                },
            };

            diary.new_entry_by_id(id)
        }
    }

    let diary = Diary::open(rt.store(), &diaryname[..]);
    let res = create_entry(&diary, rt)
        .and_then(|mut entry| {
            if prevent_edit {
                debug!("Not editing new diary entry");
                Ok(())
            } else {
                debug!("Editing new diary entry");
                entry.edit_content(rt).map_err_into(DEK::DiaryEditError)
            }
        });

    if let Err(e) = res {
        trace_error(&e);
    } else {
        info!("Ok!");
    }
}

<|endoftext|>


<commit_before>use libimagstore::storeid::build_entry_path;
use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error_exit;

pub fn delete(rt: &Runtime) {
    use std::process::exit;

    rt.cli()
        .subcommand_matches("delete")
        .map(|sub| {
            sub.value_of("id")
                .map(|id| {
                    let path = build_entry_path(rt.store(), id);
                    if path.is_err() {
                        trace_error_exit(&path.unwrap_err(), 1);
                    }
                    let path = path.unwrap();
                    debug!("Deleting file at {:?}", id);

                    rt.store()
                        .delete(path)
                        .map_err(|e| {
                           warn!("Error: {:?}", e);
                           exit(1);
                        })
                })
                .or_else(|| {
                    warn!("No ID passed. Will exit now");
                    exit(1);
                })
        })
        .or_else(|| {
            warn!("No subcommand 'delete'. Will exit now");
            exit(1);
        });
}

<commit_msg>Replace unwrap() with try!()<commit_after>use libimagstore::storeid::build_entry_path;
use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error_exit;

pub fn delete(rt: &Runtime) {
    use std::process::exit;

    rt.cli()
        .subcommand_matches("delete")
        .map(|sub| {
            sub.value_of("id")
                .map(|id| {
                    let path = try!(build_entry_path(rt.store(), id)
                                    .map_err(|e| trace_error_exit(&e, 1)));
                    debug!("Deleting file at {:?}", id);

                    rt.store()
                        .delete(path)
                        .map_err(|e| {
                           warn!("Error: {:?}", e);
                           exit(1);
                        })
                })
                .or_else(|| {
                    warn!("No ID passed. Will exit now");
                    exit(1);
                })
        })
        .or_else(|| {
            warn!("No subcommand 'delete'. Will exit now");
            exit(1);
        });
}

<|endoftext|>


<commit_before>/* automatically generated by rust-bindgen */

use glut::bindgen::{glutCreateWindow, glutDestroyWindow, glutDisplayFunc, glutGet, glutGetWindow};
use glut::bindgen::{glutInit, glutInitDisplayMode, glutPostRedisplay, glutReshapeFunc};
use glut::bindgen::{glutReshapeWindow, glutSetWindow, glutSwapBuffers, glutTimerFunc};
use libc::*;
use dvec::DVec;
use ptr::{null, to_unsafe_ptr};
use str::to_bytes;
use task::local_data::{local_data_get, local_data_set};
use cast::reinterpret_cast;
use vec::raw::to_ptr;

/* FIXME: global variable glutStrokeRoman */

/* FIXME: global variable glutStrokeMonoRoman */

/* FIXME: global variable glutBitmap9By15 */

/* FIXME: global variable glutBitmap8By13 */

/* FIXME: global variable glutBitmapTimesRoman10 */

/* FIXME: global variable glutBitmapTimesRoman24 */

/* FIXME: global variable glutBitmapHelvetica10 */

/* FIXME: global variable glutBitmapHelvetica12 */

/* FIXME: global variable glutBitmapHelvetica18 */

pub type GLenum = i32;
pub type GLint = i32;
pub type GLfloat = f32;
pub type GLdouble = f64;

pub enum Window = c_int;

pub const DOUBLE: c_uint = 2 as c_uint;

const WINDOW_WIDTH: GLenum = 102;
const WINDOW_HEIGHT: GLenum = 103;

pub enum State {
    WindowWidth,
    WindowHeight
}

pub fn destroy<T>(_value: ~[T]) {
    // let it drop
}

pub fn init() {
    unsafe {
        let argc = 0 as c_int;
        let command = to_bytes(~"glut");
        let argv: (*u8, *u8) = (to_ptr(command), null());
        let argv_p = reinterpret_cast(&to_unsafe_ptr(&argv));

        glutInit(to_unsafe_ptr(&argc), argv_p);

        destroy(move command);
    }
}

pub fn create_window(name: ~str) -> Window {
    unsafe {
        let bytes = to_bytes(name);
        return Window(glutCreateWindow(to_ptr(bytes) as *c_char));
    }
}

pub fn destroy_window(window: Window) {
    unsafe {
        glutDestroyWindow(*window);
    }
}

pub fn reshape_window(window: Window, width: c_int, height: c_int) {
    unsafe {
        let current_window = glutGetWindow();
        glutSetWindow(*window);
        glutReshapeWindow(width, height);
        glutSetWindow(current_window);
    }
}

pub fn display_callback_tls_key(_callback: @@fn()) {
    // Empty.
}

pub extern fn display_callback() {
    unsafe {
        let callback = local_data_get(display_callback_tls_key).get();
        (*callback)();
    }
}

pub fn display_func(callback: @fn()) {
    unsafe {
        local_data_set(display_callback_tls_key, @callback);
        glutDisplayFunc(display_callback);
    }
}

pub fn timer_callback_tls_key(_callback: @DVec<@fn()>) {
    // Empty.
}

pub extern fn timer_callback(index: int) {
    unsafe {
        let callbacks = local_data_get(timer_callback_tls_key).get();
        ((*callbacks)[index as uint])();
    }
}

pub fn timer_func(msecs: u32, callback: @fn()) {
    unsafe {
        let callbacks;
        match local_data_get(timer_callback_tls_key) {
            None => {
                callbacks = @DVec();
                local_data_set(timer_callback_tls_key, copy callbacks);
            }
            Some(existing_callbacks) => {
                callbacks = existing_callbacks;
            }
        }

        callbacks.push(callback);
        let index = (callbacks.len() - 1) as c_int;
        glutTimerFunc(msecs, timer_callback, index);
    }
}

pub fn reshape_callback_tls_key(_callback: @@fn(x: c_int, y: c_int)) {
    // Empty.
}

pub extern fn reshape_callback(++width: c_int, ++height: c_int) {
    unsafe {
        let callback = local_data_get(reshape_callback_tls_key).get();
        (*callback)(width, height);
    }
}

pub fn reshape_func(_window: Window, callback: @fn(x: c_int, y: c_int)) {
    unsafe {
        local_data_set(reshape_callback_tls_key, @callback);
        glutReshapeFunc(reshape_callback);
    }
}

#[cfg(target_os="macos")]
pub fn check_loop() {
    unsafe {
        ext::glutCheckLoop();
    }
}

#[cfg(target_os="linux")]
pub fn check_loop() {
    unsafe {
        ext::glutMainLoopEvent();
    }
}

pub fn init_display_mode(mode: c_uint) {
    unsafe {
        glutInitDisplayMode(mode);
    }
}

pub fn swap_buffers() {
    unsafe {
        glutSwapBuffers();
    }
}

pub fn post_redisplay() {
    unsafe {
        glutPostRedisplay();
    }
}

pub fn get(state: State) -> c_int {
    unsafe {
        let glut_state;
        match state {
            WindowWidth => glut_state = WINDOW_WIDTH,
            WindowHeight => glut_state = WINDOW_HEIGHT
        }
        glutGet(glut_state)
    }
}

#[cfg(target_os="macos")]
#[nolink]
#[link_args="-framework GLUT"]
pub extern mod dummy {
}

#[cfg(target_os="linux")]
#[link_name="glut"]
pub extern mod dummy {
}

#[cfg(target_os="macos")]
#[nolink]
pub extern mod ext {
    // Mac GLUT extension.
    fn glutCheckLoop();
}

#[cfg(target_os="linux")]
#[nolink]
pub extern mod ext {
    // freeglut extension.
    fn glutMainLoopEvent();
}

#[nolink]
pub extern mod bindgen {

pub fn glutInit(++argcp: *c_int, ++argv: **c_char);

pub fn glutInitDisplayMode(++mode: c_uint);

pub fn glutInitDisplayString(++string: *c_char);

pub fn glutInitWindowPosition(++x: c_int, ++y: c_int);

pub fn glutInitWindowSize(++width: c_int, ++height: c_int);

pub fn glutMainLoop();

pub fn glutCreateWindow(++title: *c_char) -> c_int;

pub fn glutCreateSubWindow(++win: c_int, ++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int) -> c_int;

pub fn glutDestroyWindow(++win: c_int);

pub fn glutPostRedisplay();

pub fn glutPostWindowRedisplay(++win: c_int);

pub fn glutSwapBuffers();

pub fn glutGetWindow() -> c_int;

pub fn glutSetWindow(++win: c_int);

pub fn glutSetWindowTitle(++title: *c_char);

pub fn glutSetIconTitle(++title: *c_char);

pub fn glutPositionWindow(++x: c_int, ++y: c_int);

pub fn glutReshapeWindow(++width: c_int, ++height: c_int);

pub fn glutPopWindow();

pub fn glutPushWindow();

pub fn glutIconifyWindow();

pub fn glutShowWindow();

pub fn glutHideWindow();

pub fn glutFullScreen();

pub fn glutSetCursor(++cursor: c_int);

pub fn glutWarpPointer(++x: c_int, ++y: c_int);

pub fn glutEstablishOverlay();

pub fn glutRemoveOverlay();

pub fn glutUseLayer(++layer: GLenum);

pub fn glutPostOverlayRedisplay();

pub fn glutPostWindowOverlayRedisplay(++win: c_int);

pub fn glutShowOverlay();

pub fn glutHideOverlay();

pub fn glutCreateMenu(++arg1: *u8) -> c_int;

pub fn glutDestroyMenu(++menu: c_int);

pub fn glutGetMenu() -> c_int;

pub fn glutSetMenu(++menu: c_int);

pub fn glutAddMenuEntry(++label: *c_char, ++value: c_int);

pub fn glutAddSubMenu(++label: *c_char, ++submenu: c_int);

pub fn glutChangeToMenuEntry(++item: c_int, ++label: *c_char, ++value: c_int);

pub fn glutChangeToSubMenu(++item: c_int, ++label: *c_char, ++submenu: c_int);

pub fn glutRemoveMenuItem(++item: c_int);

pub fn glutAttachMenu(++button: c_int);

pub fn glutDetachMenu(++button: c_int);

pub fn glutDisplayFunc(++func: *u8);

pub fn glutReshapeFunc(++func: *u8);

pub fn glutKeyboardFunc(++func: *u8);

pub fn glutMouseFunc(++func: *u8);

pub fn glutMotionFunc(++func: *u8);

pub fn glutPassiveMotionFunc(++func: *u8);

pub fn glutEntryFunc(++func: *u8);

pub fn glutVisibilityFunc(++func: *u8);

pub fn glutIdleFunc(++func: *u8);

pub fn glutTimerFunc(++millis: c_uint, ++func: *u8, ++value: c_int);

pub fn glutMenuStateFunc(++func: *u8);

pub fn glutSpecialFunc(++func: *u8);

pub fn glutSpaceballMotionFunc(++func: *u8);

pub fn glutSpaceballRotateFunc(++func: *u8);

pub fn glutSpaceballButtonFunc(++func: *u8);

pub fn glutButtonBoxFunc(++func: *u8);

pub fn glutDialsFunc(++func: *u8);

pub fn glutTabletMotionFunc(++func: *u8);

pub fn glutTabletButtonFunc(++func: *u8);

pub fn glutMenuStatusFunc(++func: *u8);

pub fn glutOverlayDisplayFunc(++func: *u8);

pub fn glutWindowStatusFunc(++func: *u8);

pub fn glutKeyboardUpFunc(++func: *u8);

pub fn glutSpecialUpFunc(++func: *u8);

pub fn glutJoystickFunc(++func: *u8, ++pollInterval: c_int);

pub fn glutSetColor(++arg1: c_int, ++red: GLfloat, ++green: GLfloat, ++blue: GLfloat);

pub fn glutGetColor(++ndx: c_int, ++component: c_int) -> GLfloat;

pub fn glutCopyColormap(++win: c_int);

pub fn glutGet(++_type: GLenum) -> c_int;

pub fn glutDeviceGet(++_type: GLenum) -> c_int;

pub fn glutExtensionSupported(++name: *c_char) -> c_int;

pub fn glutGetModifiers() -> c_int;

pub fn glutLayerGet(++_type: GLenum) -> c_int;

pub fn glutGetProcAddress(++procName: *c_char) -> *c_void;

pub fn glutBitmapCharacter(++font: *c_void, ++character: c_int);

pub fn glutBitmapWidth(++font: *c_void, ++character: c_int) -> c_int;

pub fn glutStrokeCharacter(++font: *c_void, ++character: c_int);

pub fn glutStrokeWidth(++font: *c_void, ++character: c_int) -> c_int;

pub fn glutBitmapLength(++font: *c_void, ++string: *c_uchar) -> c_int;

pub fn glutStrokeLength(++font: *c_void, ++string: *c_uchar) -> c_int;

pub fn glutWireSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutSolidSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutWireCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutSolidCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutWireCube(++size: GLdouble);

pub fn glutSolidCube(++size: GLdouble);

pub fn glutWireTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

pub fn glutSolidTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

pub fn glutWireDodecahedron();

pub fn glutSolidDodecahedron();

pub fn glutWireTeapot(++size: GLdouble);

pub fn glutSolidTeapot(++size: GLdouble);

pub fn glutWireOctahedron();

pub fn glutSolidOctahedron();

pub fn glutWireTetrahedron();

pub fn glutSolidTetrahedron();

pub fn glutWireIcosahedron();

pub fn glutSolidIcosahedron();

pub fn glutVideoResizeGet(++param: GLenum) -> c_int;

pub fn glutSetupVideoResizing();

pub fn glutStopVideoResizing();

pub fn glutVideoResize(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

pub fn glutVideoPan(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

pub fn glutReportErrors();

pub fn glutIgnoreKeyRepeat(++ignore: c_int);

pub fn glutSetKeyRepeat(++repeatMode: c_int);

pub fn glutForceJoystickFunc();

pub fn glutGameModeString(++string: *c_char);

pub fn glutEnterGameMode() -> c_int;

pub fn glutLeaveGameMode();

pub fn glutGameModeGet(++mode: GLenum) -> c_int;

}
<commit_msg>Update for language changes<commit_after>/* automatically generated by rust-bindgen */

use glut::bindgen::{glutCreateWindow, glutDestroyWindow, glutDisplayFunc, glutGet, glutGetWindow};
use glut::bindgen::{glutInit, glutInitDisplayMode, glutPostRedisplay, glutReshapeFunc};
use glut::bindgen::{glutReshapeWindow, glutSetWindow, glutSwapBuffers, glutTimerFunc};
use libc::*;
use dvec::DVec;
use ptr::{null, to_unsafe_ptr};
use str::to_bytes;
use task::local_data::{local_data_get, local_data_set};
use cast::reinterpret_cast;
use vec::raw::to_ptr;

/* FIXME: global variable glutStrokeRoman */

/* FIXME: global variable glutStrokeMonoRoman */

/* FIXME: global variable glutBitmap9By15 */

/* FIXME: global variable glutBitmap8By13 */

/* FIXME: global variable glutBitmapTimesRoman10 */

/* FIXME: global variable glutBitmapTimesRoman24 */

/* FIXME: global variable glutBitmapHelvetica10 */

/* FIXME: global variable glutBitmapHelvetica12 */

/* FIXME: global variable glutBitmapHelvetica18 */

pub type GLenum = i32;
pub type GLint = i32;
pub type GLfloat = f32;
pub type GLdouble = f64;

pub enum Window = c_int;

pub const DOUBLE: c_uint = 2 as c_uint;

const WINDOW_WIDTH: GLenum = 102;
const WINDOW_HEIGHT: GLenum = 103;

pub enum State {
    WindowWidth,
    WindowHeight
}

pub fn destroy<T>(_value: ~[T]) {
    // let it drop
}

pub fn init() {
    unsafe {
        let argc = 0 as c_int;
        let command = to_bytes(~"glut");
        let argv: (*u8, *u8) = (to_ptr(command), null());
        let argv_p = reinterpret_cast(&to_unsafe_ptr(&argv));

        glutInit(to_unsafe_ptr(&argc), argv_p);

        destroy(command);
    }
}

pub fn create_window(name: ~str) -> Window {
    unsafe {
        let bytes = to_bytes(name);
        return Window(glutCreateWindow(to_ptr(bytes) as *c_char));
    }
}

pub fn destroy_window(window: Window) {
    unsafe {
        glutDestroyWindow(*window);
    }
}

pub fn reshape_window(window: Window, width: c_int, height: c_int) {
    unsafe {
        let current_window = glutGetWindow();
        glutSetWindow(*window);
        glutReshapeWindow(width, height);
        glutSetWindow(current_window);
    }
}

pub fn display_callback_tls_key(_callback: @@fn()) {
    // Empty.
}

pub extern fn display_callback() {
    unsafe {
        let callback = local_data_get(display_callback_tls_key).get();
        (*callback)();
    }
}

pub fn display_func(callback: @fn()) {
    unsafe {
        local_data_set(display_callback_tls_key, @callback);
        glutDisplayFunc(display_callback);
    }
}

pub fn timer_callback_tls_key(_callback: @DVec<@fn()>) {
    // Empty.
}

pub extern fn timer_callback(index: int) {
    unsafe {
        let callbacks = local_data_get(timer_callback_tls_key).get();
        ((*callbacks)[index as uint])();
    }
}

pub fn timer_func(msecs: u32, callback: @fn()) {
    unsafe {
        let callbacks;
        match local_data_get(timer_callback_tls_key) {
            None => {
                callbacks = @DVec();
                local_data_set(timer_callback_tls_key, copy callbacks);
            }
            Some(existing_callbacks) => {
                callbacks = existing_callbacks;
            }
        }

        callbacks.push(callback);
        let index = (callbacks.len() - 1) as c_int;
        glutTimerFunc(msecs, timer_callback, index);
    }
}

pub fn reshape_callback_tls_key(_callback: @@fn(x: c_int, y: c_int)) {
    // Empty.
}

pub extern fn reshape_callback(++width: c_int, ++height: c_int) {
    unsafe {
        let callback = local_data_get(reshape_callback_tls_key).get();
        (*callback)(width, height);
    }
}

pub fn reshape_func(_window: Window, callback: @fn(x: c_int, y: c_int)) {
    unsafe {
        local_data_set(reshape_callback_tls_key, @callback);
        glutReshapeFunc(reshape_callback);
    }
}

#[cfg(target_os="macos")]
pub fn check_loop() {
    unsafe {
        ext::glutCheckLoop();
    }
}

#[cfg(target_os="linux")]
pub fn check_loop() {
    unsafe {
        ext::glutMainLoopEvent();
    }
}

pub fn init_display_mode(mode: c_uint) {
    unsafe {
        glutInitDisplayMode(mode);
    }
}

pub fn swap_buffers() {
    unsafe {
        glutSwapBuffers();
    }
}

pub fn post_redisplay() {
    unsafe {
        glutPostRedisplay();
    }
}

pub fn get(state: State) -> c_int {
    unsafe {
        let glut_state;
        match state {
            WindowWidth => glut_state = WINDOW_WIDTH,
            WindowHeight => glut_state = WINDOW_HEIGHT
        }
        glutGet(glut_state)
    }
}

#[cfg(target_os="macos")]
#[nolink]
#[link_args="-framework GLUT"]
pub extern mod dummy {
}

#[cfg(target_os="linux")]
#[link_name="glut"]
pub extern mod dummy {
}

#[cfg(target_os="macos")]
#[nolink]
pub extern mod ext {
    // Mac GLUT extension.
    fn glutCheckLoop();
}

#[cfg(target_os="linux")]
#[nolink]
pub extern mod ext {
    // freeglut extension.
    fn glutMainLoopEvent();
}

#[nolink]
pub extern mod bindgen {

pub fn glutInit(++argcp: *c_int, ++argv: **c_char);

pub fn glutInitDisplayMode(++mode: c_uint);

pub fn glutInitDisplayString(++string: *c_char);

pub fn glutInitWindowPosition(++x: c_int, ++y: c_int);

pub fn glutInitWindowSize(++width: c_int, ++height: c_int);

pub fn glutMainLoop();

pub fn glutCreateWindow(++title: *c_char) -> c_int;

pub fn glutCreateSubWindow(++win: c_int, ++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int) -> c_int;

pub fn glutDestroyWindow(++win: c_int);

pub fn glutPostRedisplay();

pub fn glutPostWindowRedisplay(++win: c_int);

pub fn glutSwapBuffers();

pub fn glutGetWindow() -> c_int;

pub fn glutSetWindow(++win: c_int);

pub fn glutSetWindowTitle(++title: *c_char);

pub fn glutSetIconTitle(++title: *c_char);

pub fn glutPositionWindow(++x: c_int, ++y: c_int);

pub fn glutReshapeWindow(++width: c_int, ++height: c_int);

pub fn glutPopWindow();

pub fn glutPushWindow();

pub fn glutIconifyWindow();

pub fn glutShowWindow();

pub fn glutHideWindow();

pub fn glutFullScreen();

pub fn glutSetCursor(++cursor: c_int);

pub fn glutWarpPointer(++x: c_int, ++y: c_int);

pub fn glutEstablishOverlay();

pub fn glutRemoveOverlay();

pub fn glutUseLayer(++layer: GLenum);

pub fn glutPostOverlayRedisplay();

pub fn glutPostWindowOverlayRedisplay(++win: c_int);

pub fn glutShowOverlay();

pub fn glutHideOverlay();

pub fn glutCreateMenu(++arg1: *u8) -> c_int;

pub fn glutDestroyMenu(++menu: c_int);

pub fn glutGetMenu() -> c_int;

pub fn glutSetMenu(++menu: c_int);

pub fn glutAddMenuEntry(++label: *c_char, ++value: c_int);

pub fn glutAddSubMenu(++label: *c_char, ++submenu: c_int);

pub fn glutChangeToMenuEntry(++item: c_int, ++label: *c_char, ++value: c_int);

pub fn glutChangeToSubMenu(++item: c_int, ++label: *c_char, ++submenu: c_int);

pub fn glutRemoveMenuItem(++item: c_int);

pub fn glutAttachMenu(++button: c_int);

pub fn glutDetachMenu(++button: c_int);

pub fn glutDisplayFunc(++func: *u8);

pub fn glutReshapeFunc(++func: *u8);

pub fn glutKeyboardFunc(++func: *u8);

pub fn glutMouseFunc(++func: *u8);

pub fn glutMotionFunc(++func: *u8);

pub fn glutPassiveMotionFunc(++func: *u8);

pub fn glutEntryFunc(++func: *u8);

pub fn glutVisibilityFunc(++func: *u8);

pub fn glutIdleFunc(++func: *u8);

pub fn glutTimerFunc(++millis: c_uint, ++func: *u8, ++value: c_int);

pub fn glutMenuStateFunc(++func: *u8);

pub fn glutSpecialFunc(++func: *u8);

pub fn glutSpaceballMotionFunc(++func: *u8);

pub fn glutSpaceballRotateFunc(++func: *u8);

pub fn glutSpaceballButtonFunc(++func: *u8);

pub fn glutButtonBoxFunc(++func: *u8);

pub fn glutDialsFunc(++func: *u8);

pub fn glutTabletMotionFunc(++func: *u8);

pub fn glutTabletButtonFunc(++func: *u8);

pub fn glutMenuStatusFunc(++func: *u8);

pub fn glutOverlayDisplayFunc(++func: *u8);

pub fn glutWindowStatusFunc(++func: *u8);

pub fn glutKeyboardUpFunc(++func: *u8);

pub fn glutSpecialUpFunc(++func: *u8);

pub fn glutJoystickFunc(++func: *u8, ++pollInterval: c_int);

pub fn glutSetColor(++arg1: c_int, ++red: GLfloat, ++green: GLfloat, ++blue: GLfloat);

pub fn glutGetColor(++ndx: c_int, ++component: c_int) -> GLfloat;

pub fn glutCopyColormap(++win: c_int);

pub fn glutGet(++_type: GLenum) -> c_int;

pub fn glutDeviceGet(++_type: GLenum) -> c_int;

pub fn glutExtensionSupported(++name: *c_char) -> c_int;

pub fn glutGetModifiers() -> c_int;

pub fn glutLayerGet(++_type: GLenum) -> c_int;

pub fn glutGetProcAddress(++procName: *c_char) -> *c_void;

pub fn glutBitmapCharacter(++font: *c_void, ++character: c_int);

pub fn glutBitmapWidth(++font: *c_void, ++character: c_int) -> c_int;

pub fn glutStrokeCharacter(++font: *c_void, ++character: c_int);

pub fn glutStrokeWidth(++font: *c_void, ++character: c_int) -> c_int;

pub fn glutBitmapLength(++font: *c_void, ++string: *c_uchar) -> c_int;

pub fn glutStrokeLength(++font: *c_void, ++string: *c_uchar) -> c_int;

pub fn glutWireSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutSolidSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutWireCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutSolidCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutWireCube(++size: GLdouble);

pub fn glutSolidCube(++size: GLdouble);

pub fn glutWireTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

pub fn glutSolidTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

pub fn glutWireDodecahedron();

pub fn glutSolidDodecahedron();

pub fn glutWireTeapot(++size: GLdouble);

pub fn glutSolidTeapot(++size: GLdouble);

pub fn glutWireOctahedron();

pub fn glutSolidOctahedron();

pub fn glutWireTetrahedron();

pub fn glutSolidTetrahedron();

pub fn glutWireIcosahedron();

pub fn glutSolidIcosahedron();

pub fn glutVideoResizeGet(++param: GLenum) -> c_int;

pub fn glutSetupVideoResizing();

pub fn glutStopVideoResizing();

pub fn glutVideoResize(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

pub fn glutVideoPan(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

pub fn glutReportErrors();

pub fn glutIgnoreKeyRepeat(++ignore: c_int);

pub fn glutSetKeyRepeat(++repeatMode: c_int);

pub fn glutForceJoystickFunc();

pub fn glutGameModeString(++string: *c_char);

pub fn glutEnterGameMode() -> c_int;

pub fn glutLeaveGameMode();

pub fn glutGameModeGet(++mode: GLenum) -> c_int;

}
<|endoftext|>


<commit_before>//
// rslex - a lexer generator for rust
//
// regexp.rs
// Regexp parsing and representation
//
// Andrei de A. Formiga, 2013-08-09
//

extern mod std;

use parser::LookaheadBuffer;
use parser::skip_whitespace;
use parser::EOF;

#[deriving(Eq)]
enum Token { LBrack, RBrack, Id(~str), LParen, RParen, Asterisk,
             Plus, Bar, Dash, String(~str), Eof }

enum Ast { Symb(~str), Union(~Ast, ~Ast),
           Conc(~Ast, ~Ast), Star(~Ast), CharClass(char, char), Epsilon }

fn parse_string(buffer: &mut LookaheadBuffer, delim: char) -> ~str {
    let mut res : ~str = ~"";
    let mut c = buffer.next_char();
    while c != delim {
        if (c == EOF) {
            fail!(fmt!("Unexpected end of file. Expected closing %c", delim));
        }
        res.push_char(c);
        c = buffer.next_char();
    }
    res
}

#[test]
fn test_parse_string() {
    let mut b1 = std::io::with_str_reader("abc'* ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_string(&mut b1, '\''), &~"abc"));
    assert!(b1.next_char() == '*');

    let mut b2 = std::io::with_str_reader("abc'def\"  ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_string(&mut b2, '"'), &~"abc'def"));
    assert!(b2.next_char() == ' ');
}

#[test]
#[should_fail]
fn unclosed_string() {
    let mut b1 = std::io::with_str_reader("abc'def  ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_string(&mut b1, '"'), &~"abc'def"));
}

#[inline]
fn is_id_char(c: char) -> bool {
    std::char::is_alphanumeric(c) || c == '_'
}

fn parse_id(buffer: &mut LookaheadBuffer, first: char) -> ~str {
    let mut res : ~str = ~"";
    res.push_char(first);
    let mut c = buffer.next_char();
    while is_id_char(c) {
        res.push_char(c);
        c = buffer.next_char();
    }
    buffer.return_char(c);
    res
}

#[test]
fn test_parse_id() {
    let mut b1 = std::io::with_str_reader("abc'* ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_id(&mut b1, 'x'), &~"xabc"));
    assert!(b1.next_char() == '\'');

    let mut b2 = std::io::with_str_reader("bc_def   ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_id(&mut b2, 'a'), &~"abc_def"));

    let mut b3 = std::io::with_str_reader("_times|'xy')*   ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_id(&mut b3, 'n'), &~"n_times"));
    assert!(b3.next_char() == '|');

    let mut b4 = std::io::with_str_reader(" +xy)*   ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_id(&mut b4, 'n'), &~"n"));
    assert!(b4.next_char() == ' ');
    assert!(b4.next_char() == '+');
    assert!(b4.next_char() == 'x');
    assert!(std::str::eq(&parse_id(&mut b4, 'x'), &~"xy"));
}

fn get_next_token(buffer: &mut LookaheadBuffer) -> ~Token {
    skip_whitespace(buffer);
    match buffer.next_char() {
        '[' => ~LBrack,
        ']' => ~RBrack,
        '(' => ~LParen,
        ')' => ~RParen,
        '*' => ~Asterisk,
        '+' => ~Plus,
        '|' => ~Bar,
        '-' => ~Dash,
        '\'' => ~String(parse_string(buffer, '\'')),
        '"' => ~String(parse_string(buffer, '"')),
        c if std::char::is_alphabetic(c) => ~Id(parse_id(buffer, c)),
        EOF => ~Eof,
        c => fail!(fmt!("Unexpected character: %c\n", c))
    }
}

#[test]
fn test_get_next_token() {
    let mut b1 = std::io::with_str_reader("'return'", LookaheadBuffer::new);
    assert!(get_next_token(&mut b1) == ~String(~"return"));

    let mut b2 = std::io::with_str_reader("return", LookaheadBuffer::new);
    assert!(get_next_token(&mut b2) == ~Id(~"return"));

    let mut b3 = std::io::with_str_reader("(['a'-'z'])(['A'-'Z'])*", LookaheadBuffer::new);
    assert!(get_next_token(&mut b3) == ~LParen);
    assert!(get_next_token(&mut b3) == ~LBrack);
    assert!(get_next_token(&mut b3) == ~String(~"a"));
    assert!(get_next_token(&mut b3) == ~Dash);
    assert!(get_next_token(&mut b3) == ~String(~"z"));
    assert!(get_next_token(&mut b3) == ~RBrack);
    assert!(get_next_token(&mut b3) == ~RParen);
    assert!(get_next_token(&mut b3) == ~LParen);
    assert!(get_next_token(&mut b3) == ~LBrack);
    assert!(get_next_token(&mut b3) == ~String(~"A"));
    assert!(get_next_token(&mut b3) == ~Dash);
    assert!(get_next_token(&mut b3) == ~String(~"Z"));
    assert!(get_next_token(&mut b3) == ~RBrack);
    assert!(get_next_token(&mut b3) == ~RParen);
    assert!(get_next_token(&mut b3) == ~Asterisk);

    let mut b4 = std::io::with_str_reader("letter (letter | digit)*", LookaheadBuffer::new);
    assert!(get_next_token(&mut b4) == ~Id(~"letter"));
    assert!(get_next_token(&mut b4) == ~LParen);
    assert!(get_next_token(&mut b4) == ~Id(~"letter"));
    assert!(get_next_token(&mut b4) == ~Bar);
    assert!(get_next_token(&mut b4) == ~Id(~"digit"));
    assert!(get_next_token(&mut b4) == ~RParen);
    assert!(get_next_token(&mut b4) == ~Asterisk);
}

fn parse_regexp(buffer: &mut LookaheadBuffer) {
    skip_whitespace(buffer);
    let c = buffer.next_char();
}

<commit_msg>Skeleton for parsing functions.<commit_after>//
// rslex - a lexer generator for rust
//
// regexp.rs
// Regexp parsing and representation
//
// Andrei de A. Formiga, 2013-08-09
//

extern mod std;

use parser::LookaheadBuffer;
use parser::skip_whitespace;
use parser::EOF;

#[deriving(Eq)]
enum Token { LBrack, RBrack, Id(~str), LParen, RParen, Asterisk,
             Plus, Bar, Dash, String(~str), Eof }

enum Ast { Symb(~str), Union(~Ast, ~Ast),
           Conc(~Ast, ~Ast), Star(~Ast), CharClass(char, char), Epsilon }

fn parse_string(buffer: &mut LookaheadBuffer, delim: char) -> ~str {
    let mut res : ~str = ~"";
    let mut c = buffer.next_char();
    while c != delim {
        if (c == EOF) {
            fail!(fmt!("Unexpected end of file. Expected closing %c", delim));
        }
        res.push_char(c);
        c = buffer.next_char();
    }
    res
}

#[test]
fn test_parse_string() {
    let mut b1 = std::io::with_str_reader("abc'* ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_string(&mut b1, '\''), &~"abc"));
    assert!(b1.next_char() == '*');

    let mut b2 = std::io::with_str_reader("abc'def\"  ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_string(&mut b2, '"'), &~"abc'def"));
    assert!(b2.next_char() == ' ');
}

#[test]
#[should_fail]
fn unclosed_string() {
    let mut b1 = std::io::with_str_reader("abc'def  ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_string(&mut b1, '"'), &~"abc'def"));
}

#[inline]
fn is_id_char(c: char) -> bool {
    std::char::is_alphanumeric(c) || c == '_'
}

fn parse_id(buffer: &mut LookaheadBuffer, first: char) -> ~str {
    let mut res : ~str = ~"";
    res.push_char(first);
    let mut c = buffer.next_char();
    while is_id_char(c) {
        res.push_char(c);
        c = buffer.next_char();
    }
    buffer.return_char(c);
    res
}

#[test]
fn test_parse_id() {
    let mut b1 = std::io::with_str_reader("abc'* ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_id(&mut b1, 'x'), &~"xabc"));
    assert!(b1.next_char() == '\'');

    let mut b2 = std::io::with_str_reader("bc_def   ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_id(&mut b2, 'a'), &~"abc_def"));

    let mut b3 = std::io::with_str_reader("_times|'xy')*   ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_id(&mut b3, 'n'), &~"n_times"));
    assert!(b3.next_char() == '|');

    let mut b4 = std::io::with_str_reader(" +xy)*   ", LookaheadBuffer::new);
    assert!(std::str::eq(&parse_id(&mut b4, 'n'), &~"n"));
    assert!(b4.next_char() == ' ');
    assert!(b4.next_char() == '+');
    assert!(b4.next_char() == 'x');
    assert!(std::str::eq(&parse_id(&mut b4, 'x'), &~"xy"));
}

#[inline]
fn match_next_token(buffer: &mut LookaheadBuffer, t: ~Token) {
    let rt = get_next_token(buffer);
    if rt != t {
        fail!(fmt!("Unexpeced token: expected %?, got %?\n", t, rt));
    }
}

fn get_next_token(buffer: &mut LookaheadBuffer) -> ~Token {
    skip_whitespace(buffer);
    match buffer.next_char() {
        '[' => ~LBrack,
        ']' => ~RBrack,
        '(' => ~LParen,
        ')' => ~RParen,
        '*' => ~Asterisk,
        '+' => ~Plus,
        '|' => ~Bar,
        '-' => ~Dash,
        '\'' => ~String(parse_string(buffer, '\'')),
        '"' => ~String(parse_string(buffer, '"')),
        c if std::char::is_alphabetic(c) => ~Id(parse_id(buffer, c)),
        EOF => ~Eof,
        c => fail!(fmt!("Unexpected character: %c\n", c))
    }
}

#[test]
fn test_get_next_token() {
    let mut b1 = std::io::with_str_reader("'return'", LookaheadBuffer::new);
    assert!(get_next_token(&mut b1) == ~String(~"return"));

    let mut b2 = std::io::with_str_reader("return", LookaheadBuffer::new);
    assert!(get_next_token(&mut b2) == ~Id(~"return"));

    let mut b3 = std::io::with_str_reader("(['a'-'z'])(['A'-'Z'])*", LookaheadBuffer::new);
    assert!(get_next_token(&mut b3) == ~LParen);
    assert!(get_next_token(&mut b3) == ~LBrack);
    assert!(get_next_token(&mut b3) == ~String(~"a"));
    assert!(get_next_token(&mut b3) == ~Dash);
    assert!(get_next_token(&mut b3) == ~String(~"z"));
    assert!(get_next_token(&mut b3) == ~RBrack);
    assert!(get_next_token(&mut b3) == ~RParen);
    assert!(get_next_token(&mut b3) == ~LParen);
    assert!(get_next_token(&mut b3) == ~LBrack);
    assert!(get_next_token(&mut b3) == ~String(~"A"));
    assert!(get_next_token(&mut b3) == ~Dash);
    assert!(get_next_token(&mut b3) == ~String(~"Z"));
    assert!(get_next_token(&mut b3) == ~RBrack);
    assert!(get_next_token(&mut b3) == ~RParen);
    assert!(get_next_token(&mut b3) == ~Asterisk);

    let mut b4 = std::io::with_str_reader("letter (letter | digit)*", LookaheadBuffer::new);
    assert!(get_next_token(&mut b4) == ~Id(~"letter"));
    assert!(get_next_token(&mut b4) == ~LParen);
    assert!(get_next_token(&mut b4) == ~Id(~"letter"));
    assert!(get_next_token(&mut b4) == ~Bar);
    assert!(get_next_token(&mut b4) == ~Id(~"digit"));
    assert!(get_next_token(&mut b4) == ~RParen);
    assert!(get_next_token(&mut b4) == ~Asterisk);
}

// regexp := union
// union  := union '|' concat | concat
// concat := concat factor | factor
// factor := (regexp) | regexp'*' | regexp'+' | class | id | str
// class  := '[' (char | range)* ']'
// range  := char'-'char

// parse a regexp from buffer until one of the terminators in term occurs
pub fn parse_regexp(buffer: &mut LookaheadBuffer, term: &[~str]) -> ~Ast {
    parse_union(buffer, term)
}

fn parse_union(buffer: &mut LookaheadBuffer, term: &[~str]) -> ~Ast {
    let left = parse_concat(buffer, term);
    if get_next_token(buffer) == ~Bar {
        let right = parse_union(buffer, term);
        ~Union(left, right)
    }
    else {
        left
    }
}

fn parse_concat(buffer: &mut LookaheadBuffer, term: &[~str]) -> ~Ast {
    ~Epsilon
}

fn parse_factor(buffer: &mut LookaheadBuffer, term: &[~str]) -> ~Ast {
    let pre = match get_next_token(buffer) {
        ~LParen => { let e = parse_regexp(buffer, term);
                     match_next_token(buffer, ~RParen);
                     e }
        _ => ~Epsilon
    };
    pre
}
<|endoftext|>


<commit_before>
use geometry::Point;
use core::rand::RngUtil;
use core::float::{pow,ln};
mod geometry;

//
// Cellule
//
#[deriving(Clone)]
struct Cell {
    center: Point,
    id: uint,
    radius: f64,
    velocity: Point,
    acc: Point,
    generation: uint,
    age: f64,
    t_dup: f64
}

pub impl Cell {
    fn new(ident: uint, t_curr: f64) -> Cell {
        let radius = 5e-5f64;
        //let r=rand::random::<float>();
        let center : Point =rand::random();

        Cell{ center: center, id: ident, radius: radius, velocity: Point::new(), acc: Point::new(), generation: 0, age:0f64, t_dup: t_curr+calc_dup_time()}
    }

    fn move(&self, tumeur: &Crowd, dt: f64) -> Cell {

        // Nouvelle position
        let new_center=self.center+self.velocity+self.acc*(0.5*pow(dt,2.0) as f64);

        // Nouvelle accélération
        let new_acc=self.calc_forces(tumeur)+Point::new_dir()*1e-5f64;

        // Nouvelle vitesse ( + frottement)
        let lambda : f64=100.0;
        let denom : f64 = 1.0/(1.0+lambda*dt/2.0);
        let new_velocity=(self.velocity*(1.0-lambda*dt/2.0)+(self.acc+new_acc)*dt/(2.0 as f64))*denom;

        Cell{center: new_center, id: self.id, radius: self.radius, velocity: new_velocity, acc: new_acc, generation: self.generation, age: self.age+dt, t_dup: self.t_dup}
    }

    fn replicate(&self, tumeur: &Crowd, dt: f64) -> Option<~Cell> {
        if(self.t_dup<=tumeur.time) {
            let new_center=self.center + Point::new_dir()*2.2f64*self.radius;
            //self.t_dup=tumeur.time+calc_dup_time();
            Some(~Cell{center: new_center, id: tumeur.size()+1, radius: self.radius, velocity: Point::new(), acc: Point::new(), generation: self.generation+1, age:0f64, t_dup: tumeur.time+calc_dup_time() })
        }
        else {
            None
        }
    }

    fn calc_forces(&self, tumeur: &Crowd) -> Point {
        let seuil=3.0*self.radius;
        let mut force = Point::new();
        for tumeur.cells.each |&cell| {
            if(cell.id != self.id) {
                let dist_cells=f64::max((self.dist(cell)-2.0*self.radius),0.0f64)+1e-6f64;
                if(dist_cells <= 20f64*self.radius) {
                   let factor_rep =  1.0/pow(dist_cells/seuil,3.0)*1e-7f64 ;
                    let factor_attract = -1.0/pow(dist_cells/(3.0*seuil),2.0)*1e-7f64;
                    force += (self.center-cell.center)*(factor_rep+factor_attract);
                }
            }
        }
        force
    }

    fn should_die(&self) -> bool {
        self.age > 5.0f64+rand::random::<f64>()
    }

    #[inline(always)]
    fn x(&self) -> f64 {
        self.center.x
    }

    #[inline(always)]
    fn y(&self) -> f64 {
        self.center.y
    }

    fn dist(&self, other: &Cell) -> f64 {
        self.center.dist(&other.center)
    }

}

impl ToStr for Cell {
    fn to_str(&self) -> ~str {
        fmt!("%d @ (%f, %f)", self.id as int, self.center.x as float, self.center.y as float)
    }
}

/// Calcul du temps de mutation
fn calc_dup_time() -> f64 {
    let lambda=1.0/(2.0*ln(2f64));
    let ord=rand::random::<f64>();

    0.2+ln(1f64-ord)/(-lambda)
}

#[test]
fn test_dup_time() {
    let dup1=calc_dup_time();
    assert!(dup1 >= 0.0f64);
    let dup2=calc_dup_time();
    assert!(dup2!=dup1);
}

#[test]
fn test_new() {
    let cell1=Cell::new(0,0f64);
    let cell2=Cell::new(1,0f64);
    assert!(cell1.center != cell2.center);
}

//
// Population
//

struct Crowd {
    cells : ~[~Cell],
    time : f64
}

pub impl Crowd {
    fn new(init_pop : uint) -> Crowd {

        let mut pop : ~[~Cell]=~[];
        for uint::range(1,init_pop+1) |num| {
            let lonely_one = ~Cell::new(num, 0.0f64);
            pop.push(copy lonely_one);
        }
        Crowd{ cells : pop, time: 0.0}
    }

    fn size(&self) -> uint {
        self.cells.len()
    }

    fn evolve(&self, dt: f64) -> Crowd {
        let mut new_crowd : ~[~Cell] = ~[];
        for self.cells.each |cell| {
            if(!cell.should_die()) {
                // Mouvement
                new_crowd.push(~cell.move(self, dt));

                // Prolifération
                match cell.replicate(self, dt) {
                    None => (),
                    Some(new_born) => new_crowd.push(new_born)
                }

            }
        }

        Crowd{cells: new_crowd, time: self.time+dt}
    }
}

impl ToStr for Crowd {
    fn to_str(&self) -> ~str {
        let mut desc =~"";
        for self.cells.each |cell| {
            let mut lcell_desc=~"";
            lcell_desc.push_str(cell.to_str()); lcell_desc.push_str("\n");
            desc.push_str(lcell_desc);
        }
        desc
    }
}

#[test]
fn test_size() {
    let crowd=Crowd::new(13);
    assert!(crowd.size()==13);
}
<commit_msg>Prise en compte du temps de mutation en supposant un comportement go or grow.<commit_after>
use geometry::Point;
use core::rand::RngUtil;
use core::float::{pow,ln};
mod geometry;

//
// Cellule
//
#[deriving(Clone)]
struct Cell {
    center: Point,
    id: uint,
    radius: f64,
    velocity: Point,
    acc: Point,
    generation: uint,
    age: f64,
    t_dup: f64
}

pub impl Cell {
    fn new(ident: uint, t_curr: f64) -> Cell {
        let radius = 5e-5f64;
        //let r=rand::random::<float>();
        let center : Point =rand::random();

        Cell{ center: center, id: ident, radius: radius, velocity: Point::new(), acc: Point::new(), generation: 0, age:0f64, t_dup: t_curr+calc_dup_time()}
    }

    fn move(&self, tumeur: &Crowd, dt: f64) -> Cell {

        // Nouvelle position
        let new_center=self.center+self.velocity+self.acc*(0.5*pow(dt,2.0) as f64);

        // Nouvelle accélération
        let new_acc=self.calc_forces(tumeur)+Point::new_dir()*1e-5f64;

        // Nouvelle vitesse ( + frottement)
        let lambda : f64=100.0;
        let denom : f64 = 1.0/(1.0+lambda*dt/2.0);
        let new_velocity=(self.velocity*(1.0-lambda*dt/2.0)+(self.acc+new_acc)*dt/(2.0 as f64))*denom;

        Cell{center: new_center, id: self.id, radius: self.radius, velocity: new_velocity, acc: new_acc, generation: self.generation, age: self.age+dt, t_dup: self.t_dup}
    }

    fn replicate(&self, tumeur: &Crowd, dt: f64) -> Option<~Cell> {
        if(self.t_dup<=tumeur.time) {
            let new_center=self.center + Point::new_dir()*2.2f64*self.radius;
            //self.t_dup=tumeur.time+calc_dup_time();
            Some(~Cell{center: new_center, id: tumeur.size()+1, radius: self.radius, velocity: Point::new(), acc: Point::new(), generation: self.generation+1, age:0f64, t_dup: tumeur.time+calc_dup_time() })
        }
        else {
            None
        }
    }

    fn calc_forces(&self, tumeur: &Crowd) -> Point {
        let seuil=3.0*self.radius;
        let mut force = Point::new();
        for tumeur.cells.each |&cell| {
            if(cell.id != self.id) {
                let dist_cells=f64::max((self.dist(cell)-2.0*self.radius),0.0f64)+1e-6f64;
                if(dist_cells <= 20f64*self.radius) {
                   let factor_rep =  1.0/pow(dist_cells/seuil,3.0)*1e-7f64 ;
                    let factor_attract = -1.0/pow(dist_cells/(3.0*seuil),2.0)*1e-7f64;
                    force += (self.center-cell.center)*(factor_rep+factor_attract);
                }
            }
        }
        force
    }

    fn should_die(&self) -> bool {
        self.age > 5.0f64+rand::random::<f64>()
    }

    #[inline(always)]
    fn x(&self) -> f64 {
        self.center.x
    }

    #[inline(always)]
    fn y(&self) -> f64 {
        self.center.y
    }

    fn dist(&self, other: &Cell) -> f64 {
        self.center.dist(&other.center)
    }

}

impl ToStr for Cell {
    fn to_str(&self) -> ~str {
        fmt!("%d @ (%f, %f)", self.id as int, self.center.x as float, self.center.y as float)
    }
}

/// Calcul du temps de mutation
fn calc_dup_time() -> f64 {
    let lambda=1.0/(2.0*ln(2f64));
    let ord=rand::random::<f64>();

    0.2+ln(1f64-ord)/(-lambda)
}

#[test]
fn test_dup_time() {
    let dup1=calc_dup_time();
    assert!(dup1 >= 0.0f64);
    let dup2=calc_dup_time();
    assert!(dup2!=dup1);
}

#[test]
fn test_new() {
    let cell1=Cell::new(0,0f64);
    let cell2=Cell::new(1,0f64);
    assert!(cell1.center != cell2.center);
}

//
// Population
//

struct Crowd {
    cells : ~[~Cell],
    time : f64
}

pub impl Crowd {
    fn new(init_pop : uint) -> Crowd {

        let mut pop : ~[~Cell]=~[];
        for uint::range(1,init_pop+1) |num| {
            let lonely_one = ~Cell::new(num, 0.0f64);
            pop.push(copy lonely_one);
        }
        Crowd{ cells : pop, time: 0.0}
    }

    fn size(&self) -> uint {
        self.cells.len()
    }

    fn evolve(&self, dt: f64) -> Crowd {
        let mut new_crowd : ~[~Cell] = ~[];
        for self.cells.each |cell| {
            if(!cell.should_die()) {

                // Prolifération
                match cell.replicate(self, dt) {
                    None => {new_crowd.push(~cell.move(self, dt));}, // Mouvement
                    Some(new_born) => {
                        new_crowd.push(new_born);
                        new_crowd.push(~Cell{center: cell.center, id: cell.id, radius: cell.radius, velocity: cell.velocity, acc: cell.acc, generation: cell.generation, age: cell.age+dt, t_dup: self.time+calc_dup_time()});
                    }
                }

            }
        }

        Crowd{cells: new_crowd, time: self.time+dt}
    }
}

impl ToStr for Crowd {
    fn to_str(&self) -> ~str {
        let mut desc =~"";
        for self.cells.each |cell| {
            let mut lcell_desc=~"";
            lcell_desc.push_str(cell.to_str()); lcell_desc.push_str("\n");
            desc.push_str(lcell_desc);
        }
        desc
    }
}

#[test]
fn test_size() {
    let crowd=Crowd::new(13);
    assert!(crowd.size()==13);
}
<|endoftext|>


<commit_before>use regex::Regex;
use super::formatter::FormatStr;

pub struct TagFormatter;

impl FormatStr for TagFormatter {
    fn format(&self, s: &str) -> String {
        let mut r = self.format_paragraphs(s);
        // currently no special formatting for links so just format like other tags (remove)
        r = self.format_code_tags(&r);
        self.format_tags(&r)
    }
}

impl TagFormatter {
    pub fn format_paragraphs(&self, s: &str) -> String {
        // todo split
        let mut r = self.replace_paragraphs_opening_tags(&s, "\n");
        r = self.replace_paragraphs_closing_tags(&r, "");
        r
    }

    pub fn format_links(&self, s: &str) -> String {
        let mut r = self.replace_link_opening_tags(s, "");
        r = self.replace_link_closing_tags(&r, "");
        r
    }

    pub fn format_tags(&self, s: &str) -> String {
        self.replace_tags(s, "")
    }

    pub fn format_code_tags(&self, s:&str) -> String {
        let mut r = self.replace_opening_code_tags(s, "\n");
        self.replace_closing_code_tags(&r, "\n") // make code blocks stand out
    }

    fn replace_paragraphs_closing_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *
 *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_paragraphs_opening_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *
 *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_link_opening_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_link_closing_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( * *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_tags(&self, s: &str, replacement: &str) -> String {
        // will just replace all tags and should be called after other methods have run before
        let re = Regex::new(r"(</?\w+((\s+\w+(\s*=\s*(?:\x22.*?\x22|'.*?'|[\^'\x22>\s]+))?)+\s*|\s*)/?>)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_closing_code_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_opening_code_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }
}
#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_replace_paragraphs() {
        let tag_formatter = TagFormatter;
        let mut s: String = format!("aaaaaa zzz zzaaa

");
        s = tag_formatter.format_paragraphs(&s);
        assert_eq!("aaaaaa zzz zzaaa\n", s);

        s = format!("
 para
 ");
        s = tag_formatter.format_paragraphs(&s);
        assert_eq!("\npara", s);
    }

    #[test]
    fn test_replace_codetags() {
        let tag_formatter = TagFormatter;
        let mut s = format!(" System.out.println(\"Hello world\"); ");
        s = tag_formatter.format_code_tags(&s);
        assert_eq!("\n\tSystem.out.println(\"Hello world\");", s);
    }
    #[test]
    fn test_replace_links() {
        let tag_formatter = TagFormatter;
        let mut s: String = format!("this is  \
                                     http://www.link.com ");
        s = tag_formatter.format_links(&s);
        assert_eq!("this is http://www.link.com", s);
    }

    #[test]
    fn test_replace_tags() {
        let tag_formatter = TagFormatter;
        let mut s: String = format!("this is http://www.link.com");
        s = tag_formatter.format_tags(&s);
        assert_eq!("this is http://www.link.com", s);
        s = format!("
para

div

heading
");
        s = tag_formatter.format_tags(&s);
        assert_eq!("para div heading ", s);
    }
    #[test]
    fn test_formatting_with_item() {
        use helpers::io_utils::read_file;
        use serde_json;
        use core::models::HnItem;

        let tag_formatter = TagFormatter;

        let unformatted_item:HnItem =  read_file("res/test/item-with-html.json")
            .and_then(|content| Some(serde_json::from_str(&content).unwrap()))
            .unwrap();
        let formatted_text = read_file("res/test/formatted-item-with-html.txt").unwrap();
        assert_eq!(formatted_text, tag_formatter.format(unformatted_item.text.as_ref().unwrap()));
        // ;
    }

}<commit_msg>Altered formatting a bit<commit_after>use regex::Regex;
use super::formatter::FormatStr;

pub struct TagFormatter;

impl FormatStr for TagFormatter {
    fn format(&self, s: &str) -> String {
        let mut r = self.format_paragraphs(s);
        // currently no special formatting for links so just format like other tags (remove)
        r = self.format_code_tags(&r);
        self.format_tags(&r)
    }
}

impl TagFormatter {
    pub fn format_paragraphs(&self, s: &str) -> String {
        // todo split
        let mut r = self.replace_paragraphs_opening_tags(&s, "\n");
        r = self.replace_paragraphs_closing_tags(&r, "");
        r
    }

    pub fn format_links(&self, s: &str) -> String {
        let mut r = self.replace_link_opening_tags(s, "");
        r = self.replace_link_closing_tags(&r, "");
        r
    }

    pub fn format_tags(&self, s: &str) -> String {
        self.replace_tags(s, "")
    }

    pub fn format_code_tags(&self, s:&str) -> String {
        let mut r = self.replace_opening_code_tags(s, "\n");
        self.replace_closing_code_tags(&r, "\n") // make code blocks stand out
    }

    fn replace_paragraphs_closing_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *
 *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_paragraphs_opening_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *
 *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_link_opening_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_link_closing_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( * *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_tags(&self, s: &str, replacement: &str) -> String {
        // will just replace all tags and should be called after other methods have run before
        let re = Regex::new(r"(</?\w+((\s+\w+(\s*=\s*(?:\x22.*?\x22|'.*?'|[\^'\x22>\s]+))?)+\s*|\s*)/?>)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_closing_code_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }

    fn replace_opening_code_tags(&self, s: &str, replacement: &str) -> String {
        let re = Regex::new(r"( *)").unwrap();
        re.replace_all(s, replacement).into_owned()
    }
}
#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_replace_paragraphs() {
        let tag_formatter = TagFormatter;
        let mut s: String = format!("aaaaaa zzz zzaaa

");
        s = tag_formatter.format_paragraphs(&s);
        assert_eq!("aaaaaa zzz zzaaa\n", s);

        s = format!("
 para
 ");
        s = tag_formatter.format_paragraphs(&s);
        assert_eq!("\npara", s);
    }

    #[test]
    fn test_replace_codetags() {
        let tag_formatter = TagFormatter;
        let mut s = format!("System.out.println(\"Hello world\");");
        s = tag_formatter.format_code_tags(&s);
        assert_eq!("\nSystem.out.println(\"Hello world\");\n", s);
    }
    #[test]
    fn test_replace_links() {
        let tag_formatter = TagFormatter;
        let mut s: String = format!("this is  \
                                     http://www.link.com ");
        s = tag_formatter.format_links(&s);
        assert_eq!("this is http://www.link.com", s);
    }

    #[test]
    fn test_replace_tags() {
        let tag_formatter = TagFormatter;
        let mut s: String = format!("this is http://www.link.com");
        s = tag_formatter.format_tags(&s);
        assert_eq!("this is http://www.link.com", s);
        s = format!("
para

div

heading
");
        s = tag_formatter.format_tags(&s);
        assert_eq!("para div heading ", s);
    }
    #[test]
    fn test_formatting_with_item() {
        use helpers::io_utils::read_file;
        use serde_json;
        use core::models::HnItem;

        let tag_formatter = TagFormatter;

        let unformatted_item:HnItem =  read_file("res/test/item-with-html.json")
            .and_then(|content| Some(serde_json::from_str(&content).unwrap()))
            .unwrap();
        let formatted_text = read_file("res/test/formatted-item-with-html.txt").unwrap();
        assert_eq!(formatted_text, tag_formatter.format(unformatted_item.text.as_ref().unwrap()));
        // ;
    }

}<|endoftext|>


<commit_before>extern crate permutohedron;
use permutohedron::Heap;

pub fn chain(input: &[(usize, usize)]) -> Option<Vec<(usize, usize)>> {
    if input.is_empty() {
        return Some(vec![]);
    }

    let mut cell_and_inv_cell_vec = input.iter()
                                         .map(|&(x, y)| ((x, y), (y, x)))
                                         .collect::<Vec<_>>();

    let heap = Heap::new(&mut cell_and_inv_cell_vec);
    let mut solution = Vec::new();
    for o in heap {
        let mut cur_cell = o[0].0;
        let first_cell = cur_cell;
        solution.push(cur_cell);
        for &(cell, inv_cell) in o.iter().skip(1) {
            if cur_cell.1 == cell.0 {
                cur_cell = cell;
                solution.push(cell);
            } else if cur_cell.1 == inv_cell.0 {
                cur_cell = inv_cell;
                solution.push(inv_cell);
            }
        }
        // if len of solution is the same as the len of input we need to check if
        // the first digit is the same as the last one
        if solution.len() == input.len() {
            if first_cell.0 == cur_cell.1 {
                // found the solution, just return and ignore the other solutions
                return Some(solution);
            }
        }
        solution.clear();
    }
    None
}
<commit_msg>Optimized a little bit the Dominoes exercise<commit_after>extern crate permutohedron;
use permutohedron::Heap;

pub fn chain(input: &[(usize, usize)]) -> Option<Vec<(usize, usize)>> {
    if input.is_empty() {
        return Some(vec![]);
    }

    let mut input_as_vec = input.iter().cloned().collect::<Vec<_>>();
    let input_permutations = Heap::new(&mut input_as_vec);
    let mut solution = Vec::new();
    for permutation in input_permutations {
        let mut cur_cell = permutation[0];
        let first_cell = cur_cell;
        solution.push(cur_cell);
        for &(x, y) in permutation.iter().skip(1) {
            if cur_cell.1 == x {
                cur_cell = (x, y);
                solution.push(cur_cell);
            } else if cur_cell.1 == y {
                cur_cell = (y, x);
                solution.push(cur_cell);
            }
        }
        // if len of solution is the same as the len of input we need to check if
        // the first digit is the same as the last one
        if solution.len() == input.len() {
            if first_cell.0 == cur_cell.1 {
                // found the solution, just return and ignore the other solutions
                return Some(solution);
            }
        }
        solution.clear();
    }
    None
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use mouros_rust_bindings::mailbox;

#[allow(non_snake_case)]
pub mod BoardLed {
    pub const LED1: i32 = 0;
    pub const LED2: i32 = 1;
    pub const LED3: i32 = 2;
    pub const LED4: i32 = 3;
}

extern "C" {
    fn bsp_led_get_state(led: i32) -> u8;
    fn bsp_led_on(led: i32);
    fn bsp_led_off(led: i32);
    fn bsp_led_toggle(led: i32);
}

pub fn led_get_state(led: i32) -> bool {
    unsafe { bsp_led_get_state(led) != 0 }
}

pub fn led_on(led: i32) {
    unsafe { bsp_led_on(led) }
}

pub fn led_off(led: i32) {
    unsafe { bsp_led_off(led) }
}

pub fn led_toggle(led: i32) {
    unsafe { bsp_led_toggle(led) }
}
<commit_msg>Removed unnecessary module import<commit_after>#![allow(dead_code)]

#[allow(non_snake_case)]
pub mod BoardLed {
    pub const LED1: i32 = 0;
    pub const LED2: i32 = 1;
    pub const LED3: i32 = 2;
    pub const LED4: i32 = 3;
}

extern "C" {
    fn bsp_led_get_state(led: i32) -> u8;
    fn bsp_led_on(led: i32);
    fn bsp_led_off(led: i32);
    fn bsp_led_toggle(led: i32);
}

pub fn led_get_state(led: i32) -> bool {
    unsafe { bsp_led_get_state(led) != 0 }
}

pub fn led_on(led: i32) {
    unsafe { bsp_led_on(led) }
}

pub fn led_off(led: i32) {
    unsafe { bsp_led_off(led) }
}

pub fn led_toggle(led: i32) {
    unsafe { bsp_led_toggle(led) }
}
<|endoftext|>


<commit_before>//! There are many AstNodes, but only a few tokens, so we hand-write them here.

use crate::{
    SyntaxToken,
    SyntaxKind::{COMMENT, WHITESPACE},
    ast::AstToken,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Comment<'a>(SyntaxToken<'a>);

impl<'a> AstToken<'a> for Comment<'a> {
    fn cast(token: SyntaxToken<'a>) -> Option<Self> {
        if token.kind() == COMMENT {
            Some(Comment(token))
        } else {
            None
        }
    }
    fn syntax(&self) -> SyntaxToken<'a> {
        self.0
    }
}

impl<'a> Comment<'a> {
    pub fn kind(&self) -> CommentKind {
        kind_by_prefix(self.text())
    }

    pub fn prefix(&self) -> &'static str {
        prefix_by_kind(self.kind())
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct CommentKind {
    pub shape: CommentShape,
    pub doc: Option<CommentPlacement>,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CommentShape {
    Line,
    Block,
}

impl CommentShape {
    pub fn is_line(self) -> bool {
        self == CommentShape::Line
    }

    pub fn is_block(self) -> bool {
        self == CommentShape::Block
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CommentPlacement {
    Inner,
    Outer,
}

const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = {
    use {CommentShape::*, CommentPlacement::*};
    &[
        ("///", CommentKind { shape: Line, doc: Some(Outer) }),
        ("//!", CommentKind { shape: Line, doc: Some(Inner) }),
        ("/**", CommentKind { shape: Block, doc: Some(Outer) }),
        ("/**", CommentKind { shape: Block, doc: Some(Inner) }),
        ("//", CommentKind { shape: Line, doc: None }),
        ("/*", CommentKind { shape: Block, doc: None }),
    ]
};

fn kind_by_prefix(text: &str) -> CommentKind {
    for (prefix, kind) in COMMENT_PREFIX_TO_KIND.iter() {
        if text.starts_with(prefix) {
            return *kind;
        }
    }
    panic!("bad comment text: {:?}", text)
}

fn prefix_by_kind(kind: CommentKind) -> &'static str {
    for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() {
        if *k == kind {
            return prefix;
        }
    }
    unreachable!()
}

pub struct Whitespace<'a>(SyntaxToken<'a>);

impl<'a> AstToken<'a> for Whitespace<'a> {
    fn cast(token: SyntaxToken<'a>) -> Option<Self> {
        if token.kind() == WHITESPACE {
            Some(Whitespace(token))
        } else {
            None
        }
    }
    fn syntax(&self) -> SyntaxToken<'a> {
        self.0
    }
}

impl<'a> Whitespace<'a> {
    pub fn spans_multiple_lines(&self) -> bool {
        let text = self.text();
        text.find('\n').map_or(false, |idx| text[idx + 1..].contains('\n'))
    }
}
<commit_msg>fix inner block doc comments<commit_after>//! There are many AstNodes, but only a few tokens, so we hand-write them here.

use crate::{
    SyntaxToken,
    SyntaxKind::{COMMENT, WHITESPACE},
    ast::AstToken,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Comment<'a>(SyntaxToken<'a>);

impl<'a> AstToken<'a> for Comment<'a> {
    fn cast(token: SyntaxToken<'a>) -> Option<Self> {
        if token.kind() == COMMENT {
            Some(Comment(token))
        } else {
            None
        }
    }
    fn syntax(&self) -> SyntaxToken<'a> {
        self.0
    }
}

impl<'a> Comment<'a> {
    pub fn kind(&self) -> CommentKind {
        kind_by_prefix(self.text())
    }

    pub fn prefix(&self) -> &'static str {
        prefix_by_kind(self.kind())
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct CommentKind {
    pub shape: CommentShape,
    pub doc: Option<CommentPlacement>,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CommentShape {
    Line,
    Block,
}

impl CommentShape {
    pub fn is_line(self) -> bool {
        self == CommentShape::Line
    }

    pub fn is_block(self) -> bool {
        self == CommentShape::Block
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CommentPlacement {
    Inner,
    Outer,
}

const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = {
    use {CommentShape::*, CommentPlacement::*};
    &[
        ("///", CommentKind { shape: Line, doc: Some(Outer) }),
        ("//!", CommentKind { shape: Line, doc: Some(Inner) }),
        ("/**", CommentKind { shape: Block, doc: Some(Outer) }),
        ("/*!", CommentKind { shape: Block, doc: Some(Inner) }),
        ("//", CommentKind { shape: Line, doc: None }),
        ("/*", CommentKind { shape: Block, doc: None }),
    ]
};

fn kind_by_prefix(text: &str) -> CommentKind {
    for (prefix, kind) in COMMENT_PREFIX_TO_KIND.iter() {
        if text.starts_with(prefix) {
            return *kind;
        }
    }
    panic!("bad comment text: {:?}", text)
}

fn prefix_by_kind(kind: CommentKind) -> &'static str {
    for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() {
        if *k == kind {
            return prefix;
        }
    }
    unreachable!()
}

pub struct Whitespace<'a>(SyntaxToken<'a>);

impl<'a> AstToken<'a> for Whitespace<'a> {
    fn cast(token: SyntaxToken<'a>) -> Option<Self> {
        if token.kind() == WHITESPACE {
            Some(Whitespace(token))
        } else {
            None
        }
    }
    fn syntax(&self) -> SyntaxToken<'a> {
        self.0
    }
}

impl<'a> Whitespace<'a> {
    pub fn spans_multiple_lines(&self) -> bool {
        let text = self.text();
        text.find('\n').map_or(false, |idx| text[idx + 1..].contains('\n'))
    }
}
<|endoftext|>


<commit_before>//! Representation of a `TextEdit`.
//!
//! `rust-analyzer` never mutates text itself and only sends diffs to clients,
//! so `TextEdit` is the ultimate representation of the work done by
//! rust-analyzer.
pub use text_size::{TextRange, TextSize};

/// `InsertDelete` -- a single "atomic" change to text
///
/// Must not overlap with other `InDel`s
#[derive(Debug, Clone)]
pub struct Indel {
    pub insert: String,
    /// Refers to offsets in the original text
    pub delete: TextRange,
}

#[derive(Default, Debug, Clone)]
pub struct TextEdit {
    indels: Vec<Indel>,
}

#[derive(Debug, Default, Clone)]
pub struct TextEditBuilder {
    indels: Vec<Indel>,
}

impl Indel {
    pub fn insert(offset: TextSize, text: String) -> Indel {
        Indel::replace(TextRange::empty(offset), text)
    }
    pub fn delete(range: TextRange) -> Indel {
        Indel::replace(range, String::new())
    }
    pub fn replace(range: TextRange, replace_with: String) -> Indel {
        Indel { delete: range, insert: replace_with }
    }

    pub fn apply(&self, text: &mut String) {
        let start: usize = self.delete.start().into();
        let end: usize = self.delete.end().into();
        text.replace_range(start..end, &self.insert);
    }
}

impl TextEdit {
    pub fn builder() -> TextEditBuilder {
        TextEditBuilder::default()
    }

    pub fn insert(offset: TextSize, text: String) -> TextEdit {
        let mut builder = TextEdit::builder();
        builder.insert(offset, text);
        builder.finish()
    }

    pub fn delete(range: TextRange) -> TextEdit {
        let mut builder = TextEdit::builder();
        builder.delete(range);
        builder.finish()
    }

    pub fn replace(range: TextRange, replace_with: String) -> TextEdit {
        let mut builder = TextEdit::builder();
        builder.replace(range, replace_with);
        builder.finish()
    }

    pub fn len(&self) -> usize {
        self.indels.len()
    }

    pub fn is_empty(&self) -> bool {
        self.indels.is_empty()
    }

    pub fn iter(&self) -> std::slice::Iter<'_, Indel> {
        self.into_iter()
    }

    pub fn apply(&self, text: &mut String) {
        match self.len() {
            0 => return,
            1 => {
                self.indels[0].apply(text);
                return;
            }
            _ => (),
        }

        let mut total_len = TextSize::of(&*text);
        for indel in self.indels.iter() {
            total_len += TextSize::of(&indel.insert);
            total_len -= indel.delete.end() - indel.delete.start();
        }
        let mut buf = String::with_capacity(total_len.into());
        let mut prev = 0;
        for indel in self.indels.iter() {
            let start: usize = indel.delete.start().into();
            let end: usize = indel.delete.end().into();
            if start > prev {
                buf.push_str(&text[prev..start]);
            }
            buf.push_str(&indel.insert);
            prev = end;
        }
        buf.push_str(&text[prev..text.len()]);
        assert_eq!(TextSize::of(&buf), total_len);

        // FIXME: figure out a way to mutate the text in-place or reuse the
        // memory in some other way
        *text = buf
    }

    pub fn union(&mut self, other: TextEdit) -> Result<(), TextEdit> {
        // FIXME: can be done without allocating intermediate vector
        let mut all = self.iter().chain(other.iter()).collect::<Vec<_>>();
        if !check_disjoint(&mut all) {
            return Err(other);
        }
        self.indels.extend(other.indels);
        assert!(check_disjoint(&mut self.indels));
        Ok(())
    }

    pub fn apply_to_offset(&self, offset: TextSize) -> Option<TextSize> {
        let mut res = offset;
        for indel in self.indels.iter() {
            if indel.delete.start() >= offset {
                break;
            }
            if offset < indel.delete.end() {
                return None;
            }
            res += TextSize::of(&indel.insert);
            res -= indel.delete.len();
        }
        Some(res)
    }
}

impl IntoIterator for TextEdit {
    type Item = Indel;
    type IntoIter = std::vec::IntoIter<Indel>;

    fn into_iter(self) -> Self::IntoIter {
        self.indels.into_iter()
    }
}

impl<'a> IntoIterator for &'a TextEdit {
    type Item = &'a Indel;
    type IntoIter = std::slice::Iter<'a, Indel>;

    fn into_iter(self) -> Self::IntoIter {
        self.indels.iter()
    }
}

impl TextEditBuilder {
    pub fn replace(&mut self, range: TextRange, replace_with: String) {
        self.indel(Indel::replace(range, replace_with))
    }
    pub fn delete(&mut self, range: TextRange) {
        self.indel(Indel::delete(range))
    }
    pub fn insert(&mut self, offset: TextSize, text: String) {
        self.indel(Indel::insert(offset, text))
    }
    pub fn finish(self) -> TextEdit {
        let mut indels = self.indels;
        assert!(check_disjoint(&mut indels));
        TextEdit { indels }
    }
    pub fn invalidates_offset(&self, offset: TextSize) -> bool {
        self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset))
    }
    fn indel(&mut self, indel: Indel) {
        self.indels.push(indel);
        if self.indels.len() <= 16 {
            check_disjoint(&mut self.indels);
        }
    }
}

fn check_disjoint(indels: &mut [impl std::borrow::Borrow<Indel>]) -> bool {
    indels.sort_by_key(|indel| (indel.borrow().delete.start(), indel.borrow().delete.end()));
    indels
        .iter()
        .zip(indels.iter().skip(1))
        .all(|(l, r)| l.borrow().delete.end() <= r.borrow().delete.start())
}
<commit_msg>Actually assert disjointness<commit_after>//! Representation of a `TextEdit`.
//!
//! `rust-analyzer` never mutates text itself and only sends diffs to clients,
//! so `TextEdit` is the ultimate representation of the work done by
//! rust-analyzer.
pub use text_size::{TextRange, TextSize};

/// `InsertDelete` -- a single "atomic" change to text
///
/// Must not overlap with other `InDel`s
#[derive(Debug, Clone)]
pub struct Indel {
    pub insert: String,
    /// Refers to offsets in the original text
    pub delete: TextRange,
}

#[derive(Default, Debug, Clone)]
pub struct TextEdit {
    indels: Vec<Indel>,
}

#[derive(Debug, Default, Clone)]
pub struct TextEditBuilder {
    indels: Vec<Indel>,
}

impl Indel {
    pub fn insert(offset: TextSize, text: String) -> Indel {
        Indel::replace(TextRange::empty(offset), text)
    }
    pub fn delete(range: TextRange) -> Indel {
        Indel::replace(range, String::new())
    }
    pub fn replace(range: TextRange, replace_with: String) -> Indel {
        Indel { delete: range, insert: replace_with }
    }

    pub fn apply(&self, text: &mut String) {
        let start: usize = self.delete.start().into();
        let end: usize = self.delete.end().into();
        text.replace_range(start..end, &self.insert);
    }
}

impl TextEdit {
    pub fn builder() -> TextEditBuilder {
        TextEditBuilder::default()
    }

    pub fn insert(offset: TextSize, text: String) -> TextEdit {
        let mut builder = TextEdit::builder();
        builder.insert(offset, text);
        builder.finish()
    }

    pub fn delete(range: TextRange) -> TextEdit {
        let mut builder = TextEdit::builder();
        builder.delete(range);
        builder.finish()
    }

    pub fn replace(range: TextRange, replace_with: String) -> TextEdit {
        let mut builder = TextEdit::builder();
        builder.replace(range, replace_with);
        builder.finish()
    }

    pub fn len(&self) -> usize {
        self.indels.len()
    }

    pub fn is_empty(&self) -> bool {
        self.indels.is_empty()
    }

    pub fn iter(&self) -> std::slice::Iter<'_, Indel> {
        self.into_iter()
    }

    pub fn apply(&self, text: &mut String) {
        match self.len() {
            0 => return,
            1 => {
                self.indels[0].apply(text);
                return;
            }
            _ => (),
        }

        let mut total_len = TextSize::of(&*text);
        for indel in self.indels.iter() {
            total_len += TextSize::of(&indel.insert);
            total_len -= indel.delete.end() - indel.delete.start();
        }
        let mut buf = String::with_capacity(total_len.into());
        let mut prev = 0;
        for indel in self.indels.iter() {
            let start: usize = indel.delete.start().into();
            let end: usize = indel.delete.end().into();
            if start > prev {
                buf.push_str(&text[prev..start]);
            }
            buf.push_str(&indel.insert);
            prev = end;
        }
        buf.push_str(&text[prev..text.len()]);
        assert_eq!(TextSize::of(&buf), total_len);

        // FIXME: figure out a way to mutate the text in-place or reuse the
        // memory in some other way
        *text = buf
    }

    pub fn union(&mut self, other: TextEdit) -> Result<(), TextEdit> {
        // FIXME: can be done without allocating intermediate vector
        let mut all = self.iter().chain(other.iter()).collect::<Vec<_>>();
        if !check_disjoint(&mut all) {
            return Err(other);
        }
        self.indels.extend(other.indels);
        assert_disjoint(&mut self.indels);
        Ok(())
    }

    pub fn apply_to_offset(&self, offset: TextSize) -> Option<TextSize> {
        let mut res = offset;
        for indel in self.indels.iter() {
            if indel.delete.start() >= offset {
                break;
            }
            if offset < indel.delete.end() {
                return None;
            }
            res += TextSize::of(&indel.insert);
            res -= indel.delete.len();
        }
        Some(res)
    }
}

impl IntoIterator for TextEdit {
    type Item = Indel;
    type IntoIter = std::vec::IntoIter<Indel>;

    fn into_iter(self) -> Self::IntoIter {
        self.indels.into_iter()
    }
}

impl<'a> IntoIterator for &'a TextEdit {
    type Item = &'a Indel;
    type IntoIter = std::slice::Iter<'a, Indel>;

    fn into_iter(self) -> Self::IntoIter {
        self.indels.iter()
    }
}

impl TextEditBuilder {
    pub fn replace(&mut self, range: TextRange, replace_with: String) {
        self.indel(Indel::replace(range, replace_with))
    }
    pub fn delete(&mut self, range: TextRange) {
        self.indel(Indel::delete(range))
    }
    pub fn insert(&mut self, offset: TextSize, text: String) {
        self.indel(Indel::insert(offset, text))
    }
    pub fn finish(self) -> TextEdit {
        let mut indels = self.indels;
        assert_disjoint(&mut indels);
        TextEdit { indels }
    }
    pub fn invalidates_offset(&self, offset: TextSize) -> bool {
        self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset))
    }
    fn indel(&mut self, indel: Indel) {
        self.indels.push(indel);
        if self.indels.len() <= 16 {
            assert_disjoint(&mut self.indels);
        }
    }
}

fn assert_disjoint(indels: &mut [impl std::borrow::Borrow<Indel>]) {
    assert!(check_disjoint(indels));
}
fn check_disjoint(indels: &mut [impl std::borrow::Borrow<Indel>]) -> bool {
    indels.sort_by_key(|indel| (indel.borrow().delete.start(), indel.borrow().delete.end()));
    indels
        .iter()
        .zip(indels.iter().skip(1))
        .all(|(l, r)| l.borrow().delete.end() <= r.borrow().delete.start())
}
<|endoftext|>