<commit_before>/// This row implementation is basically based on Pax,
/// but it has a variation in terms of variable-length blocks.

use alloc::heap;
use std::marker;

use types::Type;

pub static ALIGNED_SIZE: usize = 16;

pub type ColumnId = u16;

pub fn compute_aligned_size(size: usize) -> usize {
  let remain = size % ALIGNED_SIZE;

  if remain > 0 {
    size + (ALIGNED_SIZE - remain)
  } else {
    size
  }
}

pub trait PageBuilder {
  fn get_Vector(&self, cid: ColumnId) -> &Vector;
  fn build(&mut self) -> &mut Page;
}

pub struct DefaultPageBuilder {
  page : Page
}

impl DefaultPageBuilder
{
  pub fn new(types: &Vec<Box<Type>>) -> DefaultPageBuilder {

    let mini_pages = types
      .iter()
      .map(|ty| {
        ty.create_vector()
      })
      .collect::<Vec<Box<Vector>>>();

    DefaultPageBuilder {
      page: Page { mini_pages: mini_pages }
    }
  }
}

impl PageBuilder for DefaultPageBuilder {
  fn get_Vector(&self, cid: ColumnId) -> &Vector {
    &*self.page.mini_pages[cid as usize]
  }

  fn build(&mut self) -> &mut Page {
    &mut self.page
  }
}

pub struct Page {
  mini_pages: Vec<Box<Vector>>
}

impl Page {
  fn column_num(&self) -> u32 { self.mini_pages.len() as u32 }
}

pub trait Vector {
  fn size_in_bytes(&self) -> u32;
}

pub struct FixedLenVector<'a> {
  ptr: *mut u8,
  len: u32,
  _marker: marker::PhantomData<&'a ()>
}

impl<'a> FixedLenVector<'a> {
  pub fn new(ty: Box<Type>) -> FixedLenVector<'a> {
    let alloc_size = compute_aligned_size(4 as usize * 1024);

    let ptr = unsafe { heap::allocate(alloc_size, 16) };

    FixedLenVector {
      ptr: ptr,
      len: alloc_size as u32,
      _marker: marker::PhantomData
    }
  }
}

impl<'a> Drop for FixedLenVector<'a> {
  fn drop(&mut self) {
    unsafe {
      heap::deallocate(self.ptr as *mut u8, self.len as usize, 16);
    }
  }
}

impl<'a> Vector for FixedLenVector<'a> {
  fn size_in_bytes(&self) -> u32 {
    self.len
  }
}<commit_msg>Add FixedLenVectorBuilder.<commit_after>/// This row implementation is basically based on Pax,
/// but it has a variation in terms of variable-length blocks.

use alloc::heap;
use std::marker;

use types::Type;

pub static ALIGNED_SIZE : usize = 16;
pub static ROWBATCH_SIZE: usize = 1024;

pub type ColumnId = u16;

pub fn compute_aligned_size(size: usize) -> usize {
  let remain = size % ALIGNED_SIZE;

  if remain > 0 {
    size + (ALIGNED_SIZE - remain)
  } else {
    size
  }
}

pub trait PageBuilder {
  fn get_Vector(&self, cid: ColumnId) -> &Vector;
  fn build(&mut self) -> &mut Page;
}

pub struct DefaultPageBuilder {
  page : Page
}

impl DefaultPageBuilder
{
  pub fn new(types: &Vec<Box<Type>>) -> DefaultPageBuilder {

    let mini_pages = types
      .iter()
      .map(|ty| {
        ty.create_vector()
      })
      .collect::<Vec<Box<Vector>>>();

    DefaultPageBuilder {
      page: Page { mini_pages: mini_pages }
    }
  }
}

impl PageBuilder for DefaultPageBuilder {
  fn get_Vector(&self, cid: ColumnId) -> &Vector {
    &*self.page.mini_pages[cid as usize]
  }

  fn build(&mut self) -> &mut Page {
    &mut self.page
  }
}

pub struct Page {
  mini_pages: Vec<Box<Vector>>
}

impl Page {
  fn column_num(&self) -> u32 { self.mini_pages.len() as u32 }
}

pub trait Vector {
  fn size_in_bytes(&self) -> u32;
}

pub trait VectorBuilder {
  fn write_i8(&mut self, v: i8);

  fn write_i16(&mut self, v: i16);

  fn write_i32(&mut self, v: i32);

  fn write_i64(&mut self, v: i64);

  fn write_f32(&mut self, v: f32);

  fn write_f64(&mut self, v: f64);

  fn write_bytes(&mut self, v: &[u8]);

  fn reset(&mut self);

  fn build(&mut self) -> &Vector;
}

pub struct FixedLenVector<'a> {
  ptr: *mut u8,
  size: u32,
  _marker: marker::PhantomData<&'a ()>
}

impl<'a> FixedLenVector<'a> {
  pub fn new(fixed_len: usize) -> FixedLenVector<'a> {
    let alloc_size = compute_aligned_size(fixed_len * ROWBATCH_SIZE);

    let ptr = unsafe { heap::allocate(alloc_size, 16) };

    FixedLenVector {
      ptr: ptr,
      size: alloc_size as u32,
      _marker: marker::PhantomData
    }
  }

  #[inline]
  pub fn as_ptr(&self) -> *const u8 {
    self.ptr
  }

  #[inline]
  pub fn as_mut_ptr(&mut self) -> *mut u8 {
    self.ptr
  }
}

impl<'a> Drop for FixedLenVector<'a> {
  fn drop(&mut self) {
    unsafe {
      heap::deallocate(self.ptr as *mut u8, self.size as usize, 16);
    }
  }
}

impl<'a> Vector for FixedLenVector<'a> {
  fn size_in_bytes(&self) -> u32 {
    self.size
  }
}

pub struct FixedLenVectorBuilder<'a> {
  fixed_len: usize,
  pos : usize,
  vector: FixedLenVector<'a>
}

impl<'a> FixedLenVectorBuilder<'a>
{
  fn new(fixed_len: usize) -> FixedLenVectorBuilder<'a> {

    FixedLenVectorBuilder {
      fixed_len: fixed_len,
      pos: 0,
      vector: FixedLenVector::new(fixed_len)
    }
  }
}

use std::slice;

#[inline]
fn as_array<'a, T>(v: &FixedLenVector<'a>) -> &'a [T] {
  unsafe {
    slice::from_raw_parts(v.as_ptr() as *const T, 1024)
  }
}

#[inline]
pub fn as_mut_array<'a, T>(v: &mut FixedLenVector<'a>) -> &'a mut [T] {
  unsafe {
    slice::from_raw_parts_mut(v.as_mut_ptr() as *mut T, 1024)
  }
}

#[inline]
fn write_fixed_value<T>(vec: &mut FixedLenVector, pos: usize, val: T) {
  unsafe {
    let array: &mut [T] = slice::from_raw_parts_mut(vec.as_mut_ptr() as *mut T, 1024);
    (*array.get_unchecked_mut(pos)) = val;
  }
}

impl<'a> VectorBuilder for FixedLenVectorBuilder<'a>
{
  #[inline]
  fn write_i8(&mut self, v: i8) {
    write_fixed_value(&mut self.vector, self.pos, v);
    self.pos = self.pos + 1;
  }

  #[inline]
  fn write_i16(&mut self, v: i16) {
    write_fixed_value(&mut self.vector, self.pos, v);
    self.pos = self.pos + 1;
  }

  #[inline]
  fn write_i32(&mut self, v: i32) {
    write_fixed_value(&mut self.vector, self.pos, v);
    self.pos = self.pos + 1;
  }

  #[inline]
  fn write_i64(&mut self, v: i64) {
    write_fixed_value(&mut self.vector, self.pos, v);
    self.pos = self.pos + 1;
  }

  #[inline]
  fn write_f32(&mut self, v: f32) {
    write_fixed_value(&mut self.vector, self.pos, v);
    self.pos = self.pos + 1;
  }

  #[inline]
  fn write_f64(&mut self, v: f64) {
    write_fixed_value(&mut self.vector, self.pos, v);
    self.pos = self.pos + 1;
  }

  #[inline]
  fn write_bytes(&mut self, v: &[u8]) {
  }

  #[inline]
  fn reset(&mut self) {
    self.pos = 0;
  }

  #[inline]
  fn build(&mut self) -> &Vector {
    &self.vector
  }
}<|endoftext|>


<commit_before>use std::io::File;
use std::path::posix::Path;
use std::os::{homedir};

pub fn new<'r>(name: &str) {
    let home_unwrap = homedir().unwrap();
    let path = format!("{}/.muxed/{}", home_unwrap.display(), name);
    File::create(&Path::new(path));
}

#[test]
fn new_writes_file_to_muxed_dir() {
    let name = "test_project";
    let home_unwrap = homedir().unwrap();
    let path = &Path::new(format!("{}/.muxed/{}", home_unwrap.display(), name));
    new(name);
    assert!(path.exists());
}
<commit_msg>Ensure random test values.<commit_after>use std::io::File;
use std::path::posix::Path;
use std::os::{homedir};

pub fn new<'r>(name: &str) {
    let home_unwrap = homedir().unwrap();
    let path = format!("{}/.muxed/{}", home_unwrap.display(), name);
    File::create(&Path::new(path));
}

#[test]
fn new_writes_file_to_muxed_dir() {
    let name = format!("test_project_{}", random::<f64>());
    let home_unwrap = homedir().unwrap();
    let path = &Path::new(format!("{}/.muxed/{}", home_unwrap.display(), name));
    new(name);
    new(name.as_slice());
    assert!(path.exists());
    fs::unlink(path);
}
<|endoftext|>


<commit_before>extern mod extra;
use std::os;
use std::path;
use std::io;
use std::int;
use extra::getopts::*;

fn print_usage(program_name: &str, _opts: &[Opt]) {
	println(fmt!("Usage: %s [options]", program_name));
	println("  -i\t\t-> Path to input file");
	println("  -h | -help\t-> Print this help message");
}

/**
* Loads the input grid file.
* File format is line delmited '0's and '1's.
* 1 = The square is true|on in the game of life.
* 0 = The square is false|off in the game of life.
**/
fn load(file: &path::Path) -> ~[~[bool]] {

	let read_result = io::file_reader(file);

	let lines = match read_result {
		Ok(file) => file.read_lines(),
		Err(e) => {
			fail!(fmt!("Error reading input grid file: %?", e))
		}
	};

	let mut grid: ~[~[bool]] = ~[];

	for lines.iter().advance() |line: &~str| {
		let mut next: ~[bool] = ~[];
		for line.iter().advance() |c| {
			let b: bool = match c {
				'0' => false,
				'1' => true,
				_ => fail!(fmt!("Error parsing input grid file: %c is not valid, 0 or 1 only.", c))
			};
			next.push(b)
		}
		grid.push(next);
	}

	return grid;
}

fn print_grid(grid: &[~[bool]]) {
	for grid.iter().advance() |row| {
		for row.iter().advance() |b| {
			print(fmt!("%c", match b {
				&false => '0',
				&true => '1'
			}));
		}
		println("");
	}
}

fn copy_grid(src: &mut[~[bool]], dst: &mut[~[bool]]) {
	for int::range(0, src.len() as int) |i| {
		for int::range(0, src[i].len() as int) |j| {
			dst[i][j] = src[i][j];
		}
	}
}

fn alive(currently_alive: bool, neighbours_alive: int) -> bool {

	match currently_alive {
		true => match neighbours_alive {
			2 | 3 => true,	// Rule #2
			_ => false		// Rules #1, #3
		},
		false => match neighbours_alive {
			3 => true,		// Rule #4
			_ => false
		}
	}
}

fn game_of_life(grid: &mut[~[bool]],  next: &mut[~[bool]]) {
	/*
	* Rules
	* 1) Any live cell with fewer than two live neighbours dies.
	* 2) Any live cell with two or three live neighbours lives.
	* 3) Any live cell with more than three live neighbours dies.
	* 4) Any dead cell with exactly three live neighbours becomes a live cell.
	*/

	let neighbours = ~[
		[-1, -1],
		[ 0, -1],
		[ 1, -1],
		[-1,  0],
		[ 1,  0],
		[-1,  1],
		[ 0,  1],
		[ 1,  1]
	];

	let mut col = 0;
	while col < grid.len() {

		let mut row = 0;
		while row < grid[col].len() {

			let mut n = 0;
			let mut count = 0;
			// check all neighbors
			while(n < neighbours.len()) {

				let x = neighbours[n][0] + col;
				let y = neighbours[n][1] + row;

				// check boundaries, if the cell is alive up the count
				if x > 0 && x < grid.len() && y > 0 && y < grid[col].len() {
					count += match grid[x][y] {
						true => 1,
						false => 0
					};
				}

				// stop counting, the cell is dead
				if count >= 4 {
					break;
				}

				n += 1;
			}

			next[col][row] = alive(grid[col][row], count);

			row += 1;
		}
		col += 1;
	}
}

fn main() {

	let args : ~[~str] = os::args();

	let opts = ~[
		reqopt("i"),
		optflag("h"),
		optflag("help")
	];

	let program_name: ~str = args[0].clone();

	let opt_matches = match getopts(args.tail(), opts) {
		Ok(m) => { m }
		Err(f) => {
			print_usage(program_name, opts);
			println("");
			fail!(fail_str(f))
		}
	};

	if opt_present(&opt_matches, "h") || opt_present(&opt_matches, "help") {
		print_usage(program_name, opts);
		return;
	}

	let input: &str = opt_str(&opt_matches, "i");
	let input_path = ~path::Path(input);
	let mut grid: ~[~[bool]] = load(input_path);
	let mut next: ~[~[bool]] = grid.clone();

	print_grid(grid);
	println("");

	loop {
		let user = io::stdin();
		game_of_life(grid, next);
		print_grid(next);
		copy_grid(next, grid);
		user.read_line();
	}
}

<commit_msg>Updated main algorithm to use for loops<commit_after>extern mod extra;
use std::os;
use std::path;
use std::io;
use std::int;
use extra::getopts::*;

fn print_usage(program_name: &str, _opts: &[Opt]) {
	println(fmt!("Usage: %s [options]", program_name));
	println("  -i\t\t-> Path to input file");
	println("  -h | -help\t-> Print this help message");
}

/**
* Loads the input grid file.
* File format is line delmited '0's and '1's.
* 1 = The square is true|on in the game of life.
* 0 = The square is false|off in the game of life.
**/
fn load(file: &path::Path) -> ~[~[bool]] {

	let read_result = io::file_reader(file);

	let lines = match read_result {
		Ok(file) => file.read_lines(),
		Err(e) => {
			fail!(fmt!("Error reading input grid file: %?", e))
		}
	};

	let mut grid: ~[~[bool]] = ~[];

	for lines.iter().advance() |line: &~str| {
		let mut next: ~[bool] = ~[];
		for line.iter().advance() |c| {
			let b: bool = match c {
				'0' => false,
				'1' => true,
				_ => fail!(fmt!("Error parsing input grid file: %c is not valid, 0 or 1 only.", c))
			};
			next.push(b)
		}
		grid.push(next);
	}

	return grid;
}

fn print_grid(grid: &[~[bool]]) {
	for grid.iter().advance() |row| {
		for row.iter().advance() |b| {
			print(fmt!("%c", match b {
				&false => '0',
				&true => '1'
			}));
		}
		println("");
	}
}

fn copy_grid(src: &mut[~[bool]], dst: &mut[~[bool]]) {
	for int::range(0, src.len() as int) |i| {
		for int::range(0, src[i].len() as int) |j| {
			dst[i][j] = src[i][j];
		}
	}
}

fn alive(currently_alive: bool, neighbours_alive: int) -> bool {

	match currently_alive {
		true => match neighbours_alive {
			2 | 3 => true,	// Rule #2
			_ => false		// Rules #1, #3
		},
		false => match neighbours_alive {
			3 => true,		// Rule #4
			_ => false
		}
	}
}

fn in_bounds(x: int, y: int, width: int, height: int) -> bool {
	if x >= 0 && x < width && y >= 0 && y < height { true } else { false }
}

fn game_of_life(grid: &mut[~[bool]],  next: &mut[~[bool]]) {
	/*
	* Rules
	* 1) Any live cell with fewer than two live neighbours dies.
	* 2) Any live cell with two or three live neighbours lives.
	* 3) Any live cell with more than three live neighbours dies.
	* 4) Any dead cell with exactly three live neighbours becomes a live cell.
	*/

	let neighbours = [
		[-1, -1],
		[ 0, -1],
		[ 1, -1],
		[-1,  0],
		[ 1,  0],
		[-1,  1],
		[ 0,  1],
		[ 1,  1]
	];

	for int::range(0, grid.len() as int) |row| {
		for int::range(0, grid[row].len() as int) |col| {
			let mut count = 0;

			for int::range(0, neighbours.len() as int) |n| {
				let x = neighbours[n][0] + row;
				let y = neighbours[n][1] + col;

				if in_bounds(x, y, grid.len() as int, grid[row].len() as int) {
					count +=  match grid[x][y] {
						true => 1,
						false => 0
					};
				}

				// stop counting, the cell is dead
				if count >= 4 { break; }
			}
			next[row][col] = alive(grid[row][col], count);
		}
	}
}

fn main() {

	let args : ~[~str] = os::args();

	let opts = ~[
		reqopt("i"),
		optflag("h"),
		optflag("help")
	];

	let program_name: ~str = args[0].clone();

	let opt_matches = match getopts(args.tail(), opts) {
		Ok(m) => { m }
		Err(f) => {
			print_usage(program_name, opts);
			println("");
			fail!(fail_str(f))
		}
	};

	if opt_present(&opt_matches, "h") || opt_present(&opt_matches, "help") {
		print_usage(program_name, opts);
		return;
	}

	let input: &str = opt_str(&opt_matches, "i");
	let input_path = ~path::Path(input);
	let mut grid: ~[~[bool]] = load(input_path);
	let mut next: ~[~[bool]] = grid.clone();

	print_grid(grid);
	println("");

	loop {
		let user = io::stdin();
		game_of_life(grid, next);
		print_grid(next);
		copy_grid(next, grid);
		user.read_line();
	}
}

<|endoftext|>


<commit_before>use Module;
use socket::Socket;

pub trait Pin : ::std::convert::Into<String> {
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Gpio {
    DIO0_N,
    DIO0_P,
    DIO1_N,
    DIO1_P,
    DIO2_N,
    DIO2_P,
    DIO3_N,
    DIO3_P,
    DIO4_N,
    DIO4_P,
    DIO5_N,
    DIO5_P,
    DIO6_N,
    DIO6_P,
    DIO7_N,
    DIO7_P,
}

impl Pin for Gpio {
}

impl ::std::convert::Into<String> for Gpio {
    fn into(self) -> String {
        let s = match self {
            Gpio::DIO0_N => "DIO0_N",
            Gpio::DIO0_P => "DIO0_P",
            Gpio::DIO1_N => "DIO1_N",
            Gpio::DIO1_P => "DIO1_P",
            Gpio::DIO2_N => "DIO2_N",
            Gpio::DIO2_P => "DIO2_P",
            Gpio::DIO3_N => "DIO3_N",
            Gpio::DIO3_P => "DIO3_P",
            Gpio::DIO4_N => "DIO4_N",
            Gpio::DIO4_P => "DIO4_P",
            Gpio::DIO5_N => "DIO5_N",
            Gpio::DIO5_P => "DIO5_P",
            Gpio::DIO6_N => "DIO6_N",
            Gpio::DIO6_P => "DIO6_P",
            Gpio::DIO7_N => "DIO7_N",
            Gpio::DIO7_P => "DIO7_P",
        };

        String::from(s)
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Led {
    LED0,
    LED1,
    LED2,
    LED3,
    LED4,
    LED5,
    LED6,
    LED7,
    LED8,
}

impl Pin for Led {
}

impl ::std::convert::Into<String> for Led {
    fn into(self) -> String {
        let s = match self {
            Led::LED0 => "LED0",
            Led::LED1 => "LED1",
            Led::LED2 => "LED2",
            Led::LED3 => "LED3",
            Led::LED4 => "LED4",
            Led::LED5 => "LED5",
            Led::LED6 => "LED6",
            Led::LED7 => "LED7",
            Led::LED8 => "LED8",
        };

        String::from(s)
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum State {
    LOW,
    HIGH,
}

impl ::std::convert::Into<String> for State {
    fn into(self) -> String {
        let s = match self {
            State::LOW => "0",
            State::HIGH => "1",
        };

        String::from(s)
    }
}

impl ::std::str::FromStr for State {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "0" => Ok(State::LOW),
            "1" => Ok(State::HIGH),
            state => Err(format!("Unknow state '{}'", state)),
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Direction {
    OUT,
    IN,
}

impl ::std::convert::Into<String> for Direction {
    fn into(self) -> String {
        let s = match self {
            Direction::OUT => "OUT",
            Direction::IN => "IN",
        };

        String::from(s)
    }
}

#[derive(Clone)]
pub struct Digital {
    socket: Socket,
}

impl ::Module for Digital {
    fn new(socket: Socket) -> Self {
        Digital {
            socket,
        }
    }
}

impl Digital {
    /**
     * Sets digital pins to default values.
     *
     * Pins DIO1_P - DIO7_P, RP_DIO0_N - RP_DIO7_N are set al OUTPUT and to LOW.
     * LEDs are set to LOW/OFF
     */
    pub fn reset(&self) {
        self.socket.send("DIG:RST");
    }

    /**
     * Set direction of digital pins to output or input.
     */
    pub fn set_direction<P>(&self, pin: P, direction: Direction)
        where P: Pin
    {
        self.socket.send(format!("DIG:PIN:DIR {},{}", Into::<String>::into(direction), Into::<String>::into(pin)));
    }

    /**
     * Set state of digital outputs to 1 (HIGH) or 0 (LOW).
     */
    pub fn set_state<P>(&self, pin: P, state: State)
        where P: Pin
    {
        self.socket.send(format!("DIG:PIN {},{}", Into::<String>::into(pin), Into::<String>::into(state)));
    }

    /**
     * Get state of digital inputs and outputs.
     */
    pub fn get_state<P>(&self, pin: P) -> Result<State, <State as ::std::str::FromStr>::Err>
        where P: Pin
    {
        self.socket.send(format!("DIG:PIN? {}", Into::<String>::into(pin)))
            .unwrap()
            .parse()
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_reset() {
        let (rx, rp) = ::test::create_client();

        rp.digital.reset();
        assert_eq!("DIG:RST\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_direction_in() {
        let (rx, rp) = ::test::create_client();

        rp.digital.set_direction(::digital::Gpio::DIO0_N, ::digital::Direction::IN);
        assert_eq!("DIG:PIN:DIR IN,DIO0_N\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_direction_out() {
        let (rx, rp) = ::test::create_client();

        rp.digital.set_direction(::digital::Led::LED0, ::digital::Direction::OUT);
        assert_eq!("DIG:PIN:DIR OUT,LED0\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_state() {
        let (rx, rp) = ::test::create_client();

        rp.digital.set_state(::digital::Gpio::DIO0_N, ::digital::State::HIGH);
        assert_eq!("DIG:PIN DIO0_N,1\r\n", rx.recv().unwrap());

        assert_eq!(rp.digital.get_state(::digital::Gpio::DIO0_N), Ok(::digital::State::HIGH));
    }
}
<commit_msg>Fix digital::test::test_state<commit_after>use Module;
use socket::Socket;

pub trait Pin : ::std::convert::Into<String> {
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Gpio {
    DIO0_N,
    DIO0_P,
    DIO1_N,
    DIO1_P,
    DIO2_N,
    DIO2_P,
    DIO3_N,
    DIO3_P,
    DIO4_N,
    DIO4_P,
    DIO5_N,
    DIO5_P,
    DIO6_N,
    DIO6_P,
    DIO7_N,
    DIO7_P,
}

impl Pin for Gpio {
}

impl ::std::convert::Into<String> for Gpio {
    fn into(self) -> String {
        let s = match self {
            Gpio::DIO0_N => "DIO0_N",
            Gpio::DIO0_P => "DIO0_P",
            Gpio::DIO1_N => "DIO1_N",
            Gpio::DIO1_P => "DIO1_P",
            Gpio::DIO2_N => "DIO2_N",
            Gpio::DIO2_P => "DIO2_P",
            Gpio::DIO3_N => "DIO3_N",
            Gpio::DIO3_P => "DIO3_P",
            Gpio::DIO4_N => "DIO4_N",
            Gpio::DIO4_P => "DIO4_P",
            Gpio::DIO5_N => "DIO5_N",
            Gpio::DIO5_P => "DIO5_P",
            Gpio::DIO6_N => "DIO6_N",
            Gpio::DIO6_P => "DIO6_P",
            Gpio::DIO7_N => "DIO7_N",
            Gpio::DIO7_P => "DIO7_P",
        };

        String::from(s)
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Led {
    LED0,
    LED1,
    LED2,
    LED3,
    LED4,
    LED5,
    LED6,
    LED7,
    LED8,
}

impl Pin for Led {
}

impl ::std::convert::Into<String> for Led {
    fn into(self) -> String {
        let s = match self {
            Led::LED0 => "LED0",
            Led::LED1 => "LED1",
            Led::LED2 => "LED2",
            Led::LED3 => "LED3",
            Led::LED4 => "LED4",
            Led::LED5 => "LED5",
            Led::LED6 => "LED6",
            Led::LED7 => "LED7",
            Led::LED8 => "LED8",
        };

        String::from(s)
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum State {
    LOW,
    HIGH,
}

impl ::std::convert::Into<String> for State {
    fn into(self) -> String {
        let s = match self {
            State::LOW => "0",
            State::HIGH => "1",
        };

        String::from(s)
    }
}

impl ::std::str::FromStr for State {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "0" => Ok(State::LOW),
            "1" => Ok(State::HIGH),
            state => Err(format!("Unknow state '{}'", state)),
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Direction {
    OUT,
    IN,
}

impl ::std::convert::Into<String> for Direction {
    fn into(self) -> String {
        let s = match self {
            Direction::OUT => "OUT",
            Direction::IN => "IN",
        };

        String::from(s)
    }
}

#[derive(Clone)]
pub struct Digital {
    socket: Socket,
}

impl ::Module for Digital {
    fn new(socket: Socket) -> Self {
        Digital {
            socket,
        }
    }
}

impl Digital {
    /**
     * Sets digital pins to default values.
     *
     * Pins DIO1_P - DIO7_P, RP_DIO0_N - RP_DIO7_N are set al OUTPUT and to LOW.
     * LEDs are set to LOW/OFF
     */
    pub fn reset(&self) {
        self.socket.send("DIG:RST");
    }

    /**
     * Set direction of digital pins to output or input.
     */
    pub fn set_direction<P>(&self, pin: P, direction: Direction)
        where P: Pin
    {
        self.socket.send(format!("DIG:PIN:DIR {},{}", Into::<String>::into(direction), Into::<String>::into(pin)));
    }

    /**
     * Set state of digital outputs to 1 (HIGH) or 0 (LOW).
     */
    pub fn set_state<P>(&self, pin: P, state: State)
        where P: Pin
    {
        self.socket.send(format!("DIG:PIN {},{}", Into::<String>::into(pin), Into::<String>::into(state)));
    }

    /**
     * Get state of digital inputs and outputs.
     */
    pub fn get_state<P>(&self, pin: P) -> Result<State, <State as ::std::str::FromStr>::Err>
        where P: Pin
    {
        self.socket.send(format!("DIG:PIN? {}", Into::<String>::into(pin)))
            .unwrap()
            .parse()
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_reset() {
        let (rx, rp) = ::test::create_client();

        rp.digital.reset();
        assert_eq!("DIG:RST\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_direction_in() {
        let (rx, rp) = ::test::create_client();

        rp.digital.set_direction(::digital::Gpio::DIO0_N, ::digital::Direction::IN);
        assert_eq!("DIG:PIN:DIR IN,DIO0_N\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_direction_out() {
        let (rx, rp) = ::test::create_client();

        rp.digital.set_direction(::digital::Led::LED0, ::digital::Direction::OUT);
        assert_eq!("DIG:PIN:DIR OUT,LED0\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_state() {
        let (rx, rp) = ::test::create_client();

        rp.digital.set_direction(::digital::Gpio::DIO0_N, ::digital::Direction::OUT);
        assert_eq!("DIG:PIN:DIR OUT,DIO0_N\r\n", rx.recv().unwrap());

        rp.digital.set_state(::digital::Gpio::DIO0_N, ::digital::State::HIGH);
        assert_eq!("DIG:PIN DIO0_N,1\r\n", rx.recv().unwrap());

        assert_eq!(rp.digital.get_state(::digital::Gpio::DIO0_N), Ok(::digital::State::HIGH));
    }
}
<|endoftext|>


<commit_before>//! Handles the `Enter` key press. At the momently, this only continues
//! comments, but should handle indent some time in the future as well.

use ide_db::base_db::{FilePosition, SourceDatabase};
use ide_db::RootDatabase;
use syntax::{
    algo::find_node_at_offset,
    ast::{self, edit::IndentLevel, AstToken},
    AstNode, SmolStr, SourceFile,
    SyntaxKind::*,
    SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset,
};

use text_edit::TextEdit;

// Feature: On Enter
//
// rust-analyzer can override kbd:[Enter] key to make it smarter:
//
// - kbd:[Enter] inside triple-slash comments automatically inserts `///`
// - kbd:[Enter] in the middle or after a trailing space in `//` inserts `//`
// - kbd:[Enter] inside `//!` doc comments automatically inserts `//!`
// - kbd:[Enter] after `{` indents contents and closing `}` of single-line block
//
// This action needs to be assigned to shortcut explicitly.
//
// VS Code::
//
// Add the following to `keybindings.json`:
// [source,json]
// ----
// {
//   "key": "Enter",
//   "command": "rust-analyzer.onEnter",
//   "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust"
// }
// ----
//
// image::https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif[]
pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<TextEdit> {
    let parse = db.parse(position.file_id);
    let file = parse.tree();
    let token = file.syntax().token_at_offset(position.offset).left_biased()?;

    if let Some(comment) = ast::Comment::cast(token.clone()) {
        return on_enter_in_comment(&comment, &file, position.offset);
    }

    if token.kind() == L_CURLY {
        // Typing enter after the `{` of a block expression, where the `}` is on the same line
        if let Some(edit) = find_node_at_offset(file.syntax(), position.offset - TextSize::of('{'))
            .and_then(|block| on_enter_in_block(block, position))
        {
            cov_mark::hit!(indent_block_contents);
            return Some(edit);
        }
    }

    None
}

fn on_enter_in_comment(
    comment: &ast::Comment,
    file: &ast::SourceFile,
    offset: TextSize,
) -> Option<TextEdit> {
    if comment.kind().shape.is_block() {
        return None;
    }

    let prefix = comment.prefix();
    let comment_range = comment.syntax().text_range();
    if offset < comment_range.start() + TextSize::of(prefix) {
        return None;
    }

    let mut remove_trailing_whitespace = false;
    // Continuing single-line non-doc comments (like this one :) ) is annoying
    if prefix == "//" && comment_range.end() == offset {
        if comment.text().ends_with(' ') {
            cov_mark::hit!(continues_end_of_line_comment_with_space);
            remove_trailing_whitespace = true;
        } else if !followed_by_comment(&comment) {
            return None;
        }
    }

    let indent = node_indent(&file, comment.syntax())?;
    let inserted = format!("\n{}{} $0", indent, prefix);
    let delete = if remove_trailing_whitespace {
        let trimmed_len = comment.text().trim_end().len() as u32;
        let trailing_whitespace_len = comment.text().len() as u32 - trimmed_len;
        TextRange::new(offset - TextSize::from(trailing_whitespace_len), offset)
    } else {
        TextRange::empty(offset)
    };
    let edit = TextEdit::replace(delete, inserted);
    Some(edit)
}

fn on_enter_in_block(block: ast::BlockExpr, position: FilePosition) -> Option<TextEdit> {
    let contents = block_contents(&block)?;

    if block.syntax().text().contains_char('\n') {
        return None;
    }

    let indent = IndentLevel::from_node(block.syntax());
    let mut edit = TextEdit::insert(position.offset, format!("\n{}$0", indent + 1));
    edit.union(TextEdit::insert(contents.text_range().end(), format!("\n{}", indent))).ok()?;
    Some(edit)
}

fn block_contents(block: &ast::BlockExpr) -> Option<SyntaxNode> {
    let mut node = block.tail_expr().map(|e| e.syntax().clone());

    for stmt in block.statements() {
        if node.is_some() {
            // More than 1 node in the block
            return None;
        }

        node = Some(stmt.syntax().clone());
    }

    node
}

fn followed_by_comment(comment: &ast::Comment) -> bool {
    let ws = match comment.syntax().next_token().and_then(ast::Whitespace::cast) {
        Some(it) => it,
        None => return false,
    };
    if ws.spans_multiple_lines() {
        return false;
    }
    ws.syntax().next_token().and_then(ast::Comment::cast).is_some()
}

fn node_indent(file: &SourceFile, token: &SyntaxToken) -> Option<SmolStr> {
    let ws = match file.syntax().token_at_offset(token.text_range().start()) {
        TokenAtOffset::Between(l, r) => {
            assert!(r == *token);
            l
        }
        TokenAtOffset::Single(n) => {
            assert!(n == *token);
            return Some("".into());
        }
        TokenAtOffset::None => unreachable!(),
    };
    if ws.kind() != WHITESPACE {
        return None;
    }
    let text = ws.text();
    let pos = text.rfind('\n').map(|it| it + 1).unwrap_or(0);
    Some(text[pos..].into())
}

#[cfg(test)]
mod tests {
    use stdx::trim_indent;
    use test_utils::assert_eq_text;

    use crate::fixture;

    fn apply_on_enter(before: &str) -> Option<String> {
        let (analysis, position) = fixture::position(&before);
        let result = analysis.on_enter(position).unwrap()?;

        let mut actual = analysis.file_text(position.file_id).unwrap().to_string();
        result.apply(&mut actual);
        Some(actual)
    }

    fn do_check(ra_fixture_before: &str, ra_fixture_after: &str) {
        let ra_fixture_after = &trim_indent(ra_fixture_after);
        let actual = apply_on_enter(ra_fixture_before).unwrap();
        assert_eq_text!(ra_fixture_after, &actual);
    }

    fn do_check_noop(ra_fixture_text: &str) {
        assert!(apply_on_enter(ra_fixture_text).is_none())
    }

    #[test]
    fn continues_doc_comment() {
        do_check(
            r"
/// Some docs$0
fn foo() {
}
",
            r"
/// Some docs
/// $0
fn foo() {
}
",
        );

        do_check(
            r"
impl S {
    /// Some$0 docs.
    fn foo() {}
}
",
            r"
impl S {
    /// Some
    /// $0 docs.
    fn foo() {}
}
",
        );

        do_check(
            r"
///$0 Some docs
fn foo() {
}
",
            r"
///
/// $0 Some docs
fn foo() {
}
",
        );
    }

    #[test]
    fn does_not_continue_before_doc_comment() {
        do_check_noop(r"$0//! docz");
    }

    #[test]
    fn continues_another_doc_comment() {
        do_check(
            r#"
fn main() {
    //! Documentation for$0 on enter
    let x = 1 + 1;
}
"#,
            r#"
fn main() {
    //! Documentation for
    //! $0 on enter
    let x = 1 + 1;
}
"#,
        );
    }

    #[test]
    fn continues_code_comment_in_the_middle_of_line() {
        do_check(
            r"
fn main() {
    // Fix$0 me
    let x = 1 + 1;
}
",
            r"
fn main() {
    // Fix
    // $0 me
    let x = 1 + 1;
}
",
        );
    }

    #[test]
    fn continues_code_comment_in_the_middle_several_lines() {
        do_check(
            r"
fn main() {
    // Fix$0
    // me
    let x = 1 + 1;
}
",
            r"
fn main() {
    // Fix
    // $0
    // me
    let x = 1 + 1;
}
",
        );
    }

    #[test]
    fn does_not_continue_end_of_line_comment() {
        do_check_noop(
            r"
fn main() {
    // Fix me$0
    let x = 1 + 1;
}
",
        );
    }

    #[test]
    fn continues_end_of_line_comment_with_space() {
        cov_mark::check!(continues_end_of_line_comment_with_space);
        do_check(
            r#"
fn main() {
    // Fix me $0
    let x = 1 + 1;
}
"#,
            r#"
fn main() {
    // Fix me
    // $0
    let x = 1 + 1;
}
"#,
        );
    }

    #[test]
    fn trims_all_trailing_whitespace() {
        do_check(
            "
fn main() {
    // Fix me  \t\t   $0
    let x = 1 + 1;
}
",
            "
fn main() {
    // Fix me
    // $0
    let x = 1 + 1;
}
",
        );
    }

    #[test]
    fn indents_fn_body_block() {
        cov_mark::check!(indent_block_contents);
        do_check(
            r#"
fn f() {$0()}
        "#,
            r#"
fn f() {
    $0()
}
        "#,
        );
    }

    #[test]
    fn indents_block_expr() {
        do_check(
            r#"
fn f() {
    let x = {$0()};
}
        "#,
            r#"
fn f() {
    let x = {
        $0()
    };
}
        "#,
        );
    }

    #[test]
    fn indents_match_arm() {
        do_check(
            r#"
fn f() {
    match 6 {
        1 => {$0f()},
        _ => (),
    }
}
        "#,
            r#"
fn f() {
    match 6 {
        1 => {
            $0f()
        },
        _ => (),
    }
}
        "#,
        );
    }

    #[test]
    fn indents_block_with_statement() {
        do_check(
            r#"
fn f() {$0a = b}
        "#,
            r#"
fn f() {
    $0a = b
}
        "#,
        );
        do_check(
            r#"
fn f() {$0fn f() {}}
        "#,
            r#"
fn f() {
    $0fn f() {}
}
        "#,
        );
    }

    #[test]
    fn indents_nested_blocks() {
        do_check(
            r#"
fn f() {$0{}}
        "#,
            r#"
fn f() {
    $0{}
}
        "#,
        );
    }

    #[test]
    fn does_not_indent_empty_block() {
        do_check_noop(
            r#"
fn f() {$0}
        "#,
        );
        do_check_noop(
            r#"
fn f() {{$0}}
        "#,
        );
    }

    #[test]
    fn does_not_indent_block_with_too_much_content() {
        do_check_noop(
            r#"
fn f() {$0 a = b; ()}
        "#,
        );
        do_check_noop(
            r#"
fn f() {$0 a = b; a = b; }
        "#,
        );
    }

    #[test]
    fn does_not_indent_multiline_block() {
        do_check_noop(
            r#"
fn f() {$0
}
        "#,
        );
        do_check_noop(
            r#"
fn f() {$0

}
        "#,
        );
    }
}
<commit_msg>feat: auto-indent use tree lists<commit_after>//! Handles the `Enter` key press. At the momently, this only continues
//! comments, but should handle indent some time in the future as well.

use ide_db::base_db::{FilePosition, SourceDatabase};
use ide_db::RootDatabase;
use syntax::{
    algo::find_node_at_offset,
    ast::{self, edit::IndentLevel, AstToken},
    AstNode, SmolStr, SourceFile,
    SyntaxKind::*,
    SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset,
};

use text_edit::TextEdit;

// Feature: On Enter
//
// rust-analyzer can override kbd:[Enter] key to make it smarter:
//
// - kbd:[Enter] inside triple-slash comments automatically inserts `///`
// - kbd:[Enter] in the middle or after a trailing space in `//` inserts `//`
// - kbd:[Enter] inside `//!` doc comments automatically inserts `//!`
// - kbd:[Enter] after `{` indents contents and closing `}` of single-line block
//
// This action needs to be assigned to shortcut explicitly.
//
// VS Code::
//
// Add the following to `keybindings.json`:
// [source,json]
// ----
// {
//   "key": "Enter",
//   "command": "rust-analyzer.onEnter",
//   "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust"
// }
// ----
//
// image::https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif[]
pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<TextEdit> {
    let parse = db.parse(position.file_id);
    let file = parse.tree();
    let token = file.syntax().token_at_offset(position.offset).left_biased()?;

    if let Some(comment) = ast::Comment::cast(token.clone()) {
        return on_enter_in_comment(&comment, &file, position.offset);
    }

    if token.kind() == L_CURLY {
        // Typing enter after the `{` of a block expression, where the `}` is on the same line
        if let Some(edit) = find_node_at_offset(file.syntax(), position.offset - TextSize::of('{'))
            .and_then(|block| on_enter_in_block(block, position))
        {
            cov_mark::hit!(indent_block_contents);
            return Some(edit);
        }

        // Typing enter after the `{` of a use tree list.
        if let Some(edit) = find_node_at_offset(file.syntax(), position.offset - TextSize::of('{'))
            .and_then(|list| on_enter_in_use_tree_list(list, position))
        {
            cov_mark::hit!(indent_block_contents);
            return Some(edit);
        }
    }

    None
}

fn on_enter_in_comment(
    comment: &ast::Comment,
    file: &ast::SourceFile,
    offset: TextSize,
) -> Option<TextEdit> {
    if comment.kind().shape.is_block() {
        return None;
    }

    let prefix = comment.prefix();
    let comment_range = comment.syntax().text_range();
    if offset < comment_range.start() + TextSize::of(prefix) {
        return None;
    }

    let mut remove_trailing_whitespace = false;
    // Continuing single-line non-doc comments (like this one :) ) is annoying
    if prefix == "//" && comment_range.end() == offset {
        if comment.text().ends_with(' ') {
            cov_mark::hit!(continues_end_of_line_comment_with_space);
            remove_trailing_whitespace = true;
        } else if !followed_by_comment(&comment) {
            return None;
        }
    }

    let indent = node_indent(&file, comment.syntax())?;
    let inserted = format!("\n{}{} $0", indent, prefix);
    let delete = if remove_trailing_whitespace {
        let trimmed_len = comment.text().trim_end().len() as u32;
        let trailing_whitespace_len = comment.text().len() as u32 - trimmed_len;
        TextRange::new(offset - TextSize::from(trailing_whitespace_len), offset)
    } else {
        TextRange::empty(offset)
    };
    let edit = TextEdit::replace(delete, inserted);
    Some(edit)
}

fn on_enter_in_block(block: ast::BlockExpr, position: FilePosition) -> Option<TextEdit> {
    let contents = block_contents(&block)?;

    if block.syntax().text().contains_char('\n') {
        return None;
    }

    let indent = IndentLevel::from_node(block.syntax());
    let mut edit = TextEdit::insert(position.offset, format!("\n{}$0", indent + 1));
    edit.union(TextEdit::insert(contents.text_range().end(), format!("\n{}", indent))).ok()?;
    Some(edit)
}

fn on_enter_in_use_tree_list(list: ast::UseTreeList, position: FilePosition) -> Option<TextEdit> {
    if list.syntax().text().contains_char('\n') {
        return None;
    }

    let indent = IndentLevel::from_node(list.syntax());
    let mut edit = TextEdit::insert(position.offset, format!("\n{}$0", indent + 1));
    edit.union(TextEdit::insert(
        list.r_curly_token()?.text_range().start(),
        format!("\n{}", indent),
    ))
    .ok()?;
    Some(edit)
}

fn block_contents(block: &ast::BlockExpr) -> Option<SyntaxNode> {
    let mut node = block.tail_expr().map(|e| e.syntax().clone());

    for stmt in block.statements() {
        if node.is_some() {
            // More than 1 node in the block
            return None;
        }

        node = Some(stmt.syntax().clone());
    }

    node
}

fn followed_by_comment(comment: &ast::Comment) -> bool {
    let ws = match comment.syntax().next_token().and_then(ast::Whitespace::cast) {
        Some(it) => it,
        None => return false,
    };
    if ws.spans_multiple_lines() {
        return false;
    }
    ws.syntax().next_token().and_then(ast::Comment::cast).is_some()
}

fn node_indent(file: &SourceFile, token: &SyntaxToken) -> Option<SmolStr> {
    let ws = match file.syntax().token_at_offset(token.text_range().start()) {
        TokenAtOffset::Between(l, r) => {
            assert!(r == *token);
            l
        }
        TokenAtOffset::Single(n) => {
            assert!(n == *token);
            return Some("".into());
        }
        TokenAtOffset::None => unreachable!(),
    };
    if ws.kind() != WHITESPACE {
        return None;
    }
    let text = ws.text();
    let pos = text.rfind('\n').map(|it| it + 1).unwrap_or(0);
    Some(text[pos..].into())
}

#[cfg(test)]
mod tests {
    use stdx::trim_indent;
    use test_utils::assert_eq_text;

    use crate::fixture;

    fn apply_on_enter(before: &str) -> Option<String> {
        let (analysis, position) = fixture::position(&before);
        let result = analysis.on_enter(position).unwrap()?;

        let mut actual = analysis.file_text(position.file_id).unwrap().to_string();
        result.apply(&mut actual);
        Some(actual)
    }

    fn do_check(ra_fixture_before: &str, ra_fixture_after: &str) {
        let ra_fixture_after = &trim_indent(ra_fixture_after);
        let actual = apply_on_enter(ra_fixture_before).unwrap();
        assert_eq_text!(ra_fixture_after, &actual);
    }

    fn do_check_noop(ra_fixture_text: &str) {
        assert!(apply_on_enter(ra_fixture_text).is_none())
    }

    #[test]
    fn continues_doc_comment() {
        do_check(
            r"
/// Some docs$0
fn foo() {
}
",
            r"
/// Some docs
/// $0
fn foo() {
}
",
        );

        do_check(
            r"
impl S {
    /// Some$0 docs.
    fn foo() {}
}
",
            r"
impl S {
    /// Some
    /// $0 docs.
    fn foo() {}
}
",
        );

        do_check(
            r"
///$0 Some docs
fn foo() {
}
",
            r"
///
/// $0 Some docs
fn foo() {
}
",
        );
    }

    #[test]
    fn does_not_continue_before_doc_comment() {
        do_check_noop(r"$0//! docz");
    }

    #[test]
    fn continues_another_doc_comment() {
        do_check(
            r#"
fn main() {
    //! Documentation for$0 on enter
    let x = 1 + 1;
}
"#,
            r#"
fn main() {
    //! Documentation for
    //! $0 on enter
    let x = 1 + 1;
}
"#,
        );
    }

    #[test]
    fn continues_code_comment_in_the_middle_of_line() {
        do_check(
            r"
fn main() {
    // Fix$0 me
    let x = 1 + 1;
}
",
            r"
fn main() {
    // Fix
    // $0 me
    let x = 1 + 1;
}
",
        );
    }

    #[test]
    fn continues_code_comment_in_the_middle_several_lines() {
        do_check(
            r"
fn main() {
    // Fix$0
    // me
    let x = 1 + 1;
}
",
            r"
fn main() {
    // Fix
    // $0
    // me
    let x = 1 + 1;
}
",
        );
    }

    #[test]
    fn does_not_continue_end_of_line_comment() {
        do_check_noop(
            r"
fn main() {
    // Fix me$0
    let x = 1 + 1;
}
",
        );
    }

    #[test]
    fn continues_end_of_line_comment_with_space() {
        cov_mark::check!(continues_end_of_line_comment_with_space);
        do_check(
            r#"
fn main() {
    // Fix me $0
    let x = 1 + 1;
}
"#,
            r#"
fn main() {
    // Fix me
    // $0
    let x = 1 + 1;
}
"#,
        );
    }

    #[test]
    fn trims_all_trailing_whitespace() {
        do_check(
            "
fn main() {
    // Fix me  \t\t   $0
    let x = 1 + 1;
}
",
            "
fn main() {
    // Fix me
    // $0
    let x = 1 + 1;
}
",
        );
    }

    #[test]
    fn indents_fn_body_block() {
        cov_mark::check!(indent_block_contents);
        do_check(
            r#"
fn f() {$0()}
        "#,
            r#"
fn f() {
    $0()
}
        "#,
        );
    }

    #[test]
    fn indents_block_expr() {
        do_check(
            r#"
fn f() {
    let x = {$0()};
}
        "#,
            r#"
fn f() {
    let x = {
        $0()
    };
}
        "#,
        );
    }

    #[test]
    fn indents_match_arm() {
        do_check(
            r#"
fn f() {
    match 6 {
        1 => {$0f()},
        _ => (),
    }
}
        "#,
            r#"
fn f() {
    match 6 {
        1 => {
            $0f()
        },
        _ => (),
    }
}
        "#,
        );
    }

    #[test]
    fn indents_block_with_statement() {
        do_check(
            r#"
fn f() {$0a = b}
        "#,
            r#"
fn f() {
    $0a = b
}
        "#,
        );
        do_check(
            r#"
fn f() {$0fn f() {}}
        "#,
            r#"
fn f() {
    $0fn f() {}
}
        "#,
        );
    }

    #[test]
    fn indents_nested_blocks() {
        do_check(
            r#"
fn f() {$0{}}
        "#,
            r#"
fn f() {
    $0{}
}
        "#,
        );
    }

    #[test]
    fn does_not_indent_empty_block() {
        do_check_noop(
            r#"
fn f() {$0}
        "#,
        );
        do_check_noop(
            r#"
fn f() {{$0}}
        "#,
        );
    }

    #[test]
    fn does_not_indent_block_with_too_much_content() {
        do_check_noop(
            r#"
fn f() {$0 a = b; ()}
        "#,
        );
        do_check_noop(
            r#"
fn f() {$0 a = b; a = b; }
        "#,
        );
    }

    #[test]
    fn does_not_indent_multiline_block() {
        do_check_noop(
            r#"
fn f() {$0
}
        "#,
        );
        do_check_noop(
            r#"
fn f() {$0

}
        "#,
        );
    }

    #[test]
    fn indents_use_tree_list() {
        do_check(
            r#"
use crate::{$0};
            "#,
            r#"
use crate::{
    $0
};
            "#,
        );
        do_check(
            r#"
use crate::{$0Object, path::to::OtherThing};
            "#,
            r#"
use crate::{
    $0Object, path::to::OtherThing
};
            "#,
        );
        do_check(
            r#"
use {crate::{$0Object, path::to::OtherThing}};
            "#,
            r#"
use {crate::{
    $0Object, path::to::OtherThing
}};
            "#,
        );
        do_check(
            r#"
use {
    crate::{$0Object, path::to::OtherThing}
};
            "#,
            r#"
use {
    crate::{
        $0Object, path::to::OtherThing
    }
};
            "#,
        );
    }

    #[test]
    fn does_not_indent_use_tree_list_when_not_at_curly_brace() {
        do_check_noop(
            r#"
use path::{Thing$0};
            "#,
        );
    }

    #[test]
    fn does_not_indent_use_tree_list_without_curly_braces() {
        do_check_noop(
            r#"
use path::Thing$0;
            "#,
        );
        do_check_noop(
            r#"
use path::$0Thing;
            "#,
        );
        do_check_noop(
            r#"
use path::Thing$0};
            "#,
        );
        do_check_noop(
            r#"
use path::{$0Thing;
            "#,
        );
    }

    #[test]
    fn does_not_indent_multiline_use_tree_list() {
        do_check_noop(
            r#"
use path::{$0
    Thing
};
            "#,
        );
    }
}
<|endoftext|>


<commit_before>use core::f64::MAX;
use rust_decimal::prelude::*;

use super::behaviors::MouseBehavior;

use crate::{api::prelude::*, prelude::*, proc_macros::*, shell::prelude::*, theme::prelude::*};

// --- KEYS --

pub static ID_INPUT: &'static str = "numeric_box_input";
pub static STYLE_INPUT: &'static str = "numeric_box_input";
pub static STYLE_BTN: &'static str = "numeric_box_button";

// --- KEYS --

pub enum InputAction {
    Inc,
    Dec,
    ChangeByKey(KeyEvent),
    ChangeByMouseScroll(Point),
    Focus,
}

#[derive(Default, AsAny)]
pub struct NumericBoxState {
    pub action: Option<InputAction>,
    pub input: Entity,
    pub min: Decimal,
    pub max: Decimal,
    pub step: Decimal,
    pub current_value: Decimal,
}

impl NumericBoxState {
    fn action(&mut self, action: InputAction) {
        self.action = Some(action);
    }

    fn change_val(&mut self, new_value: Decimal, ctx: &mut Context) {
        if self.current_value == self.min && new_value < self.min
            || self.current_value == self.max && new_value > self.max
        {
            return;
        }

        self.current_value = self.max(self.min(new_value));
        ctx.get_widget(self.input)
            .set::<String16>("text", String16::from(self.current_value.to_string()));
    }

    fn min(&self, d: Decimal) -> Decimal {
        if d <= self.min {
            return self.min;
        } else {
            return d;
        }
    }

    fn max(&self, d: Decimal) -> Decimal {
        if d >= self.max {
            return self.max;
        } else {
            return d;
        }
    }

    fn request_focus(&self, ctx: &mut Context) {
        if !ctx.widget().get::<bool>("focused") {
            ctx.widget().set::<bool>("focused", true);
            ctx.push_event_by_window(FocusEvent::RequestFocus(ctx.entity));
        }
    }
}

fn default_or(key: &str, default_value: f64, ctx: &mut Context) -> Decimal {
    let property = ctx.widget().clone_or_default(key);

    match Decimal::from_f64(property) {
        Some(val) => val,
        None => Decimal::from_f64(default_value).unwrap(),
    }
}

impl State for NumericBoxState {
    fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
        self.input = ctx.entity_of_child(ID_INPUT).expect(
            "NumericBoxState
        .init(): the child input could not be found!",
        );
        self.min = default_or("min", 0.0, ctx);
        self.max = default_or("max", MAX, ctx);
        self.step = default_or("step", 1.0, ctx);
        self.current_value = default_or("val", 0.0, ctx);

        let init_value = String16::from(self.current_value.to_string());
        ctx.get_widget(self.input)
            .set::<String16>("text", init_value);
    }

    // TODO: let the user type the value, or select it for cut, copy, paste operations
    fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
        if let Some(action) = &self.action {
            match action {
                InputAction::Inc => {
                    self.change_val(self.current_value + self.step, ctx);
                }
                InputAction::Dec => {
                    self.change_val(self.current_value - self.step, ctx);
                }
                InputAction::ChangeByKey(key_event) => match key_event.key {
                    Key::Up | Key::NumpadAdd => {
                        self.change_val(self.current_value + self.step, ctx);
                    }
                    Key::Down | Key::NumpadSubtract => {
                        self.change_val(self.current_value - self.step, ctx);
                    }
                    Key::Enter => {
                        if *ctx.widget().get::<bool>("lost_focus_on_activation") {
                            ctx.push_event_by_window(FocusEvent::RemoveFocus(ctx.entity));
                        }

                        ctx.push_event_strategy_by_entity(
                            ActivateEvent(ctx.entity),
                            ctx.entity,
                            EventStrategy::Direct,
                        )
                    }
                    _ => {}
                },
                InputAction::ChangeByMouseScroll(delta) => {
                    if delta.y() < 0.0 {
                        self.change_val(self.current_value - self.step, ctx);
                    } else {
                        self.change_val(self.current_value + self.step, ctx);
                    }
                }
                InputAction::Focus => {
                    self.request_focus(ctx);
                }
            }
            self.action = None;
        }
    }
}

widget!(
    /// `NumericBox` is used to let the user increase or decrease
    /// the value of the input by a given, fixed value called `step` until it reaches the upper or
    /// lower bounds.
    /// The widget can be controlled by clicking on the two control buttons, or the keybaord's
    /// Up and Down, Numpad+ and Numpad- keys, or the mouse scroll.
    /// Note: after the widget is initialized, changing the min, max or step properties has no effect.
    ///
    /// # Examples:
    /// Create a NumericBox with default values:
    /// ```rust
    /// NumericBox::new().build(ctx)
    /// ```
    ///
    /// Create a NumericBox with custom values:
    /// ```rust
    /// NumericBox::new().min(10.0).max(100.0).val(50.0).step(5.0).build(ctx)
    /// ```
    NumericBox<NumericBoxState>: ActivateHandler, KeyDownHandler {
        /// Sets or shares the background color property
        background: Brush,

        /// Sets or shares the border color property
        border_brush: Brush,

        /// Sets or shares the border width property
        border_width: Thickness,

        /// Sets or shares the border radius property
        border_radius: f64,

        /// Sets or shares the focused property
        focused: bool,

        /// Sets or shares the foreground color property
        foreground: Brush,

        /// Sets or shares the value that describes if the NumericBox should lost focus on activation (when enter pressed).
        lost_focus_on_activation: bool,

        /// Sets or shares the minimum allowed value property
        min: f64,

        /// Sets or shares the maximum allowed value property
        max: f64,

        /// Sets or shares the stepping value property
        step: f64,

        /// Sets or shares the current value property
        val: f64
    }
);

impl Template for NumericBox {
    fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
        self.name("NumericBox")
            .style("numeric_box")
            .on_changed_filter(vec!["val"])
            .background("transparent")
            .foreground(colors::LINK_WATER_COLOR)
            .border_brush("#647b91")
            .border_width(1.0)
            .border_radius(3.0)
            .focused(false)
            .height(32.0)
            .lost_focus_on_activation(true)
            .min(0.0)
            .max(200.0)
            .step(1.0)
            .val(0.0)
            .min_width(128.0)
            .child(
                MouseBehavior::new()
                    .on_mouse_down(move |states, _| {
                        states
                            .get_mut::<NumericBoxState>(id)
                            .action(InputAction::Focus);
                        true
                    })
                    .on_scroll(move |states, delta| {
                        states
                            .get_mut::<NumericBoxState>(id)
                            .action(InputAction::ChangeByMouseScroll(delta));
                        true
                    })
                    .build(ctx),
            )
            .child(
                Grid::new()
                    .columns(Columns::new().add("*").add(32.))
                    .rows(Rows::new().add(16.0).add(16.0))
                    .child(
                        TextBox::new()
                            .id(ID_INPUT)
                            .style("")
                            .attach(Grid::column(0))
                            .attach(Grid::row_span(2))
                            .attach(Grid::row(0))
                            .foreground(id)
                            .border_brush("transparent")
                            .border_width(0)
                            .background("transparent")
                            .h_align("stretch")
                            .enabled(false)
                            .max_width(96.)
                            .text("0")
                            .lost_focus_on_activation(id)
                            .build(ctx),
                    )
                    .child(
                        Button::new()
                            .style("button_small")
                            .attach(Grid::column(1))
                            .attach(Grid::row(0))
                            .min_width(14)
                            .height(15)
                            .icon(material_icons_font::MD_KEYBOARD_ARROW_UP)
                            .margin(1)
                            .on_click(move |states, _| {
                                states
                                    .get_mut::<NumericBoxState>(id)
                                    .action(InputAction::Inc);
                                true
                            })
                            .build(ctx),
                    )
                    .child(
                        Button::new()
                            .style("button_small")
                            .attach(Grid::column(1))
                            .attach(Grid::row(1))
                            .min_width(14)
                            .height(15)
                            .padding(0.0)
                            .margin(1)
                            .icon(material_icons_font::MD_KEYBOARD_ARROW_DOWN)
                            .on_click(move |states, _| {
                                states
                                    .get_mut::<NumericBoxState>(id)
                                    .action(InputAction::Dec);
                                true
                            })
                            .build(ctx),
                    )
                    .build(ctx),
            )
            .on_key_down(move |states, event| -> bool {
                states
                    .get_mut::<NumericBoxState>(id)
                    .action(InputAction::ChangeByKey(event));
                false
            })
    }

    fn render_object(&self) -> Box<dyn RenderObject> {
        Box::new(RectangleRenderObject)
    }
}
<commit_msg>NumericBox fix.<commit_after>use core::f64::MAX;
use rust_decimal::prelude::*;

use super::behaviors::MouseBehavior;

use crate::{api::prelude::*, prelude::*, proc_macros::*, shell::prelude::*, theme::prelude::*};

// --- KEYS --

pub static ID_INPUT: &'static str = "numeric_box_input";
pub static STYLE_INPUT: &'static str = "numeric_box_input";
pub static STYLE_BTN: &'static str = "numeric_box_button";

// --- KEYS --

pub enum InputAction {
    Inc,
    Dec,
    ChangeByKey(KeyEvent),
    ChangeByMouseScroll(Point),
    Focus,
}

#[derive(Default, AsAny)]
pub struct NumericBoxState {
    pub action: Option<InputAction>,
    pub input: Entity,
    pub min: Decimal,
    pub max: Decimal,
    pub step: Decimal,
    pub current_value: Decimal,
}

impl NumericBoxState {
    fn action(&mut self, action: InputAction) {
        self.action = Some(action);
    }

    fn change_val(&mut self, new_value: Decimal, ctx: &mut Context) {
        if self.current_value == self.min && new_value < self.min
            || self.current_value == self.max && new_value > self.max
        {
            return;
        }

        self.current_value = self.max(self.min(new_value));
        if let Some(val) = self.current_value.to_f64() {
            ctx.widget().set("val", val);
        }

        ctx.get_widget(self.input)
            .set::<String16>("text", String16::from(self.current_value.to_string()));
    }

    fn min(&self, d: Decimal) -> Decimal {
        if d <= self.min {
            return self.min;
        } else {
            return d;
        }
    }

    fn max(&self, d: Decimal) -> Decimal {
        if d >= self.max {
            return self.max;
        } else {
            return d;
        }
    }

    fn request_focus(&self, ctx: &mut Context) {
        if !ctx.widget().get::<bool>("focused") {
            ctx.widget().set::<bool>("focused", true);
            ctx.push_event_by_window(FocusEvent::RequestFocus(ctx.entity));
        }
    }
}

fn default_or(key: &str, default_value: f64, ctx: &mut Context) -> Decimal {
    let property = ctx.widget().clone_or_default(key);

    match Decimal::from_f64(property) {
        Some(val) => val,
        None => Decimal::from_f64(default_value).unwrap(),
    }
}

impl State for NumericBoxState {
    fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
        self.input = ctx.entity_of_child(ID_INPUT).expect(
            "NumericBoxState
        .init(): the child input could not be found!",
        );
        self.min = default_or("min", 0.0, ctx);
        self.max = default_or("max", MAX, ctx);
        self.step = default_or("step", 1.0, ctx);
        self.current_value = default_or("val", 0.0, ctx);

        let init_value = String16::from(self.current_value.to_string());
        ctx.get_widget(self.input)
            .set::<String16>("text", init_value);
    }

    // TODO: let the user type the value, or select it for cut, copy, paste operations
    fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
        if let Some(action) = &self.action {
            match action {
                InputAction::Inc => {
                    self.change_val(self.current_value + self.step, ctx);
                }
                InputAction::Dec => {
                    self.change_val(self.current_value - self.step, ctx);
                }
                InputAction::ChangeByKey(key_event) => match key_event.key {
                    Key::Up | Key::NumpadAdd => {
                        self.change_val(self.current_value + self.step, ctx);
                    }
                    Key::Down | Key::NumpadSubtract => {
                        self.change_val(self.current_value - self.step, ctx);
                    }
                    Key::Enter => {
                        if *ctx.widget().get::<bool>("lost_focus_on_activation") {
                            ctx.push_event_by_window(FocusEvent::RemoveFocus(ctx.entity));
                        }

                        ctx.push_event_strategy_by_entity(
                            ActivateEvent(ctx.entity),
                            ctx.entity,
                            EventStrategy::Direct,
                        )
                    }
                    _ => {}
                },
                InputAction::ChangeByMouseScroll(delta) => {
                    if delta.y() < 0.0 {
                        self.change_val(self.current_value - self.step, ctx);
                    } else {
                        self.change_val(self.current_value + self.step, ctx);
                    }
                }
                InputAction::Focus => {
                    self.request_focus(ctx);
                }
            }
            self.action = None;
        }
    }
}

widget!(
    /// `NumericBox` is used to let the user increase or decrease
    /// the value of the input by a given, fixed value called `step` until it reaches the upper or
    /// lower bounds.
    /// The widget can be controlled by clicking on the two control buttons, or the keybaord's
    /// Up and Down, Numpad+ and Numpad- keys, or the mouse scroll.
    /// Note: after the widget is initialized, changing the min, max or step properties has no effect.
    ///
    /// # Examples:
    /// Create a NumericBox with default values:
    /// ```rust
    /// NumericBox::new().build(ctx)
    /// ```
    ///
    /// Create a NumericBox with custom values:
    /// ```rust
    /// NumericBox::new().min(10.0).max(100.0).val(50.0).step(5.0).build(ctx)
    /// ```
    NumericBox<NumericBoxState>: ActivateHandler, KeyDownHandler {
        /// Sets or shares the background color property
        background: Brush,

        /// Sets or shares the border color property
        border_brush: Brush,

        /// Sets or shares the border width property
        border_width: Thickness,

        /// Sets or shares the border radius property
        border_radius: f64,

        /// Sets or shares the focused property
        focused: bool,

        /// Sets or shares the foreground color property
        foreground: Brush,

        /// Sets or shares the value that describes if the NumericBox should lost focus on activation (when enter pressed).
        lost_focus_on_activation: bool,

        /// Sets or shares the minimum allowed value property
        min: f64,

        /// Sets or shares the maximum allowed value property
        max: f64,

        /// Sets or shares the stepping value property
        step: f64,

        /// Sets or shares the current value property
        val: f64
    }
);

impl Template for NumericBox {
    fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
        self.name("NumericBox")
            .style("numeric_box")
            .on_changed_filter(vec!["val"])
            .background("transparent")
            .foreground(colors::LINK_WATER_COLOR)
            .border_brush("#647b91")
            .border_width(1.0)
            .border_radius(3.0)
            .focused(false)
            .height(32.0)
            .lost_focus_on_activation(true)
            .min(0.0)
            .max(200.0)
            .step(1.0)
            .val(0.0)
            .min_width(128.0)
            .child(
                MouseBehavior::new()
                    .on_mouse_down(move |states, _| {
                        states
                            .get_mut::<NumericBoxState>(id)
                            .action(InputAction::Focus);
                        true
                    })
                    .on_scroll(move |states, delta| {
                        states
                            .get_mut::<NumericBoxState>(id)
                            .action(InputAction::ChangeByMouseScroll(delta));
                        true
                    })
                    .build(ctx),
            )
            .child(
                Grid::new()
                    .columns(Columns::new().add("*").add(32.))
                    .rows(Rows::new().add(16.0).add(16.0))
                    .child(
                        TextBox::new()
                            .id(ID_INPUT)
                            .style("")
                            .attach(Grid::column(0))
                            .attach(Grid::row_span(2))
                            .attach(Grid::row(0))
                            .foreground(id)
                            .border_brush("transparent")
                            .border_width(0)
                            .background("transparent")
                            .h_align("stretch")
                            .enabled(false)
                            .max_width(96.)
                            .text("0")
                            .lost_focus_on_activation(id)
                            .build(ctx),
                    )
                    .child(
                        Button::new()
                            .style("button_small")
                            .attach(Grid::column(1))
                            .attach(Grid::row(0))
                            .min_width(14)
                            .height(15)
                            .icon(material_icons_font::MD_KEYBOARD_ARROW_UP)
                            .margin(1)
                            .on_click(move |states, _| {
                                states
                                    .get_mut::<NumericBoxState>(id)
                                    .action(InputAction::Inc);
                                true
                            })
                            .build(ctx),
                    )
                    .child(
                        Button::new()
                            .style("button_small")
                            .attach(Grid::column(1))
                            .attach(Grid::row(1))
                            .min_width(14)
                            .height(15)
                            .padding(0.0)
                            .margin(1)
                            .icon(material_icons_font::MD_KEYBOARD_ARROW_DOWN)
                            .on_click(move |states, _| {
                                states
                                    .get_mut::<NumericBoxState>(id)
                                    .action(InputAction::Dec);
                                true
                            })
                            .build(ctx),
                    )
                    .build(ctx),
            )
            .on_key_down(move |states, event| -> bool {
                states
                    .get_mut::<NumericBoxState>(id)
                    .action(InputAction::ChangeByKey(event));
                false
            })
    }

    fn render_object(&self) -> Box<dyn RenderObject> {
        Box::new(RectangleRenderObject)
    }
}
<|endoftext|>


<commit_before>use std::path::Path;
use std::fs::File;
use std::f64;

use image::{ DynamicImage, GenericImage, ImageFormat };
use image;

use bitreader::BitReader;

use num_traits::float::Float;

pub struct CoverImage {
    cover_image: DynamicImage
}

impl CoverImage {
    pub fn new(file_path: &str) -> CoverImage {
        CoverImage {
            cover_image: image::open(&Path::new(&file_path)).unwrap()
        }
    }

    pub fn encode_with(&self, message: &str) {
        let bit_vector = get_bit_vec(message);

        encode(&self.cover_image, &bit_vector);

        let ref mut fout = File::create(&Path::new("/home/hugh/Pictures/yurt.png")).unwrap();

        let _ = self.cover_image.save(fout, ImageFormat::PNG).unwrap();
    }
}

// Get a Vector of Bits to Encode the Image with
fn get_bit_vec(message: &str) -> Vec<u8> {
    let mut bit_vector = Vec::new();
    let mut reader = BitReader::new(&message.as_bytes());

    // Multiplied by 8 because it's a Vec of bits not bytes
    for _ in 0..message.len() * 8 {
        bit_vector.push(reader.read_u8(1).unwrap());
    }

    bit_vector
}

// Encode the image with the Vector of Bits
fn encode(c_image: &DynamicImage, bit_vec: &Vec<u8>) {
    let mut tiled_image_vec = tile_image(&c_image);

    let (width, height) = c_image.dimensions();

    let encoded_image = encode_image(&mut tiled_image_vec, bit_vec, width, height);
}

fn tile_image(c_image: &DynamicImage) -> Vec<image::Rgba<u8>> {
    let (width, height) = c_image.dimensions();

    let mut image_blocks = Vec::new();

    for row_index in 0..(height / 8) as u32 {
        for col_index in 0..(width / 8) as u32 {
            for row in 0..8 {
                for column in 0..8 {
                    image_blocks.push(c_image.get_pixel(column + (col_index * 8), row + (row_index * 8)));
                }
            }
        }
    }

    image_blocks
}

fn encode_image(tiled_image: &mut Vec<image::Rgba<u8>>, message: &Vec<u8>, width: u32, height: u32) {
    let mut cu = 0.0;
    let mut cv = 0.0;
    let mut total = 0;

    //just transform single pixel
    for u in 0..(height / 8) as u32 {
        for channel in 0..3 {
            let colour_value = tiled_image[].data[channel];

            for u in 0..8 {
                for v in 0..8 {
                    if u == 0 {
                        cu = 0.0
                    } else {
                        cu = 1.0 / 2.0.sqrt()
                    }

                    if v == 0 {
                        cv = 0.0
                    } else {
                        cv = 1.0 / 2.0.sqrt()
                    }

                    tiled_image[0].data[0]
                }
            }
        }
    }
}

/**************************************************************************************************
 *                                                                                *
 *                                         Tests                                                  *
 *                                                                                *
 **************************************************************************************************/

#[cfg(test)]
#[test]
fn test_get_bit_vec_len() {
    let bits = get_bit_vec("h");

    assert_eq!(8, bits.len());
}

#[cfg(test)]
#[test]
fn test_get_bit_vec() {
    let test_bits = vec![0, 1, 1, 0, 1, 0, 0, 0];
    let bits = get_bit_vec("h");

    assert_eq!(bits, test_bits);
}

#[cfg(test)]
#[test]
fn test_encode_red_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[0] % 2, bit_vec[0]);
}

#[cfg(test)]
#[test]
fn test_encode_green_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[1] % 2, bit_vec[1]);
}

#[cfg(test)]
#[test]
fn test_encode_blue_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[2] % 2 as u8, bit_vec[2]);
}

#[cfg(test)]
#[test]
fn test_full_byte_is_encoded() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let mut encoded_bit_vec = Vec::new();
    let mut count = 0;

    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    'outer: for x_co_ord in 0..3 {
        let pixel = img.get_pixel(x_co_ord, 0);

        for channel in 0..3 {
            if count >= 8 {
                break 'outer;
            }

            encoded_bit_vec.push(pixel.data[channel] % 2);

            count += 1;
        }
    }

    assert_eq!(encoded_bit_vec, bit_vec);
}

#[cfg(test)]
#[test]
fn test_tile_image_length() {
    let img = image::open(&Path::new("/home/hugh/Pictures/colour.jpg")).unwrap();

    let vec = tile_image(&img);

    assert_eq!(vec.len(), 91200);
}

#[cfg(test)]
#[test]
fn test_tile_image_first_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(0, 0);

    let vec = tile_image(&img);

    assert_eq!(vec[0], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel1() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel2() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(40, 16);

    let vec = tile_image(&img);

    assert_eq!(vec[6720], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel3() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_last_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(399, 399);

    let vec = tile_image(&img);

    assert_eq!(vec[159999], pixel);
}
<commit_msg>Nearly finished dct<commit_after>use std::path::Path;
use std::fs::File;
use std::f64;

use image::{ DynamicImage, GenericImage, ImageFormat };
use image;

use bitreader::BitReader;

use num_traits::float::Float;

pub struct CoverImage {
    cover_image: DynamicImage
}

impl CoverImage {
    pub fn new(file_path: &str) -> CoverImage {
        CoverImage {
            cover_image: image::open(&Path::new(&file_path)).unwrap()
        }
    }

    pub fn encode_with(&self, message: &str) {
        let bit_vector = get_bit_vec(message);

        encode(&self.cover_image, &bit_vector);

        let ref mut fout = File::create(&Path::new("/home/hugh/Pictures/yurt.png")).unwrap();

        let _ = self.cover_image.save(fout, ImageFormat::PNG).unwrap();
    }
}

// Get a Vector of Bits to Encode the Image with
fn get_bit_vec(message: &str) -> Vec<u8> {
    let mut bit_vector = Vec::new();
    let mut reader = BitReader::new(&message.as_bytes());

    // Multiplied by 8 because it's a Vec of bits not bytes
    for _ in 0..message.len() * 8 {
        bit_vector.push(reader.read_u8(1).unwrap());
    }

    bit_vector
}

// Encode the image with the Vector of Bits
fn encode(c_image: &DynamicImage, bit_vec: &Vec<u8>) {
    let mut tiled_image_vec = tile_image(&c_image);

    let (width, height) = c_image.dimensions();

    let encoded_image = encode_image(&mut tiled_image_vec, bit_vec, width, height);
}

fn tile_image(c_image: &DynamicImage) -> Vec<image::Rgba<u8>> {
    let (width, height) = c_image.dimensions();

    let mut image_blocks = Vec::new();

    for row_index in 0..(height / 8) as u32 {
        for col_index in 0..(width / 8) as u32 {
            for row in 0..8 {
                for column in 0..8 {
                    image_blocks.push(c_image.get_pixel(column + (col_index * 8), row + (row_index * 8)));
                }
            }
        }
    }

    image_blocks
}

fn encode_image(tiled_image: &mut Vec<image::Rgba<u8>>, message: &Vec<u8>, width: u32, height: u32) {
    // 1
    // - + Cv + Cu
    // 4
    let constants = 1 / 128;

    /*let mut cu = 0.0;
    let mut cv = 0.0;*/
    let mut total = 0.0;
    let mut index: usize = 0;
    let num_of_iterations = if message.len() / 3 == 0 {
                                    (message.len() / 3) as u32
                                } else {
                                    ((message.len() / 3) + 1) as u32
                                };

    for _ in 0..num_of_iterations {
        for channel in 0..3 {
            index = 36 + (num_of_iterations * 64) as usize;

            let colour_value = tiled_image[index].data[channel];

            for y in 0..8 {
                for x in 0..8 {
                    /*if u == 0 {
                        cu = 0.0
                    } else {
                        cu = 1.0 / 2.0.sqrt()
                    }

                    if v == 0 {
                        cv = 0.0
                    } else {
                        cv = 1.0 / 2.0.sqrt()
                    }*/

                    total = total + (4.0 * f64::consts::PI * ((2.0 * y as f64) + 1.0)).cos() *
                                    (4.0 * f64::consts::PI * ((2.0 * x as f64) + 1.0)).cos();
                }
            }

            total = total * constants;
        }
    }
}

/**************************************************************************************************
 *                                                                                *
 *                                         Tests                                                  *
 *                                                                                *
 **************************************************************************************************/

#[cfg(test)]
#[test]
fn test_get_bit_vec_len() {
    let bits = get_bit_vec("h");

    assert_eq!(8, bits.len());
}

#[cfg(test)]
#[test]
fn test_get_bit_vec() {
    let test_bits = vec![0, 1, 1, 0, 1, 0, 0, 0];
    let bits = get_bit_vec("h");

    assert_eq!(bits, test_bits);
}

#[cfg(test)]
#[test]
fn test_encode_red_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[0] % 2, bit_vec[0]);
}

#[cfg(test)]
#[test]
fn test_encode_green_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[1] % 2, bit_vec[1]);
}

#[cfg(test)]
#[test]
fn test_encode_blue_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[2] % 2 as u8, bit_vec[2]);
}

#[cfg(test)]
#[test]
fn test_full_byte_is_encoded() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let mut encoded_bit_vec = Vec::new();
    let mut count = 0;

    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    'outer: for x_co_ord in 0..3 {
        let pixel = img.get_pixel(x_co_ord, 0);

        for channel in 0..3 {
            if count >= 8 {
                break 'outer;
            }

            encoded_bit_vec.push(pixel.data[channel] % 2);

            count += 1;
        }
    }

    assert_eq!(encoded_bit_vec, bit_vec);
}

#[cfg(test)]
#[test]
fn test_tile_image_length() {
    let img = image::open(&Path::new("/home/hugh/Pictures/colour.jpg")).unwrap();

    let vec = tile_image(&img);

    assert_eq!(vec.len(), 91200);
}

#[cfg(test)]
#[test]
fn test_tile_image_first_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(0, 0);

    let vec = tile_image(&img);

    assert_eq!(vec[0], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel1() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel2() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(40, 16);

    let vec = tile_image(&img);

    assert_eq!(vec[6720], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel3() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_last_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(399, 399);

    let vec = tile_image(&img);

    assert_eq!(vec[159999], pixel);
}
<|endoftext|>


<commit_before>use libc::{c_char, c_void, intptr_t, uintptr_t};
use ptr::{mut_null, null, to_unsafe_ptr};
use repr::BoxRepr;
use sys::TypeDesc;
use unsafe::transmute;

export annihilate;

/**
 * Runtime structures
 *
 * NB: These must match the representation in the C++ runtime.
 */

type DropGlue = fn(**TypeDesc, *c_void);
type FreeGlue = fn(**TypeDesc, *c_void);

type TaskID = uintptr_t;

struct StackSegment { priv opaque: () }
struct Scheduler { priv opaque: () }
struct SchedulerLoop { priv opaque: () }
struct Kernel { priv opaque: () }
struct Env { priv opaque: () }
struct AllocHeader { priv opaque: () }
struct MemoryRegion { priv opaque: () }

// XXX: i386
struct Registers {
    data: [u64 * 22]
}

struct Context {
    regs: Registers,
    next: *Context,
    pad: u64
}

struct BoxedRegion {
    env: *Env,
    backing_region: *MemoryRegion,
    live_allocs: *BoxRepr
}

struct Task {
    // Public fields
    refcount: intptr_t,
    id: TaskID,
    ctx: Context,
    stack_segment: *StackSegment,
    runtime_sp: uintptr_t,
    scheduler: *Scheduler,
    scheduler_loop: *SchedulerLoop,

    // Fields known only to the runtime
    kernel: *Kernel,
    name: *c_char,
    list_index: *i32,
    rendezvous_ptr: *uintptr_t,
    boxed_region: BoxedRegion
}

/*
 * Box annihilation
 *
 * This runs at task death to free all boxes.
 */

/// Destroys all managed memory (i.e. @ boxes) held by the current task.
#[cfg(notest)]
#[lang="annihilate"]
pub unsafe fn annihilate() {
    use rt::rt_free;
    use io::WriterUtil;

    let task: *Task = transmute(rustrt::rust_get_task());

    // Pass 1: Make all boxes immortal.
    let box = (*task).boxed_region.live_allocs;
    let mut box: *mut BoxRepr = transmute(copy box);
    while box != mut_null() {
        debug!("making box immortal: %x", box as uint);
        (*box).header.ref_count = 0x77777777;
        box = transmute(copy (*box).header.next);
    }

    // Pass 2: Drop all boxes.
    let box = (*task).boxed_region.live_allocs;
    let mut box: *mut BoxRepr = transmute(copy box);
    while box != mut_null() {
        debug!("calling drop glue for box: %x", box as uint);
        let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc);
        let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0));
        drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data));

        box = transmute(copy (*box).header.next);
    }

    // Pass 3: Free all boxes.
    loop {
        let box = (*task).boxed_region.live_allocs;
        if box == null() { break; }
        let mut box: *mut BoxRepr = transmute(copy box);
        assert (*box).header.prev == null();

        debug!("freeing box: %x", box as uint);
        rt_free(transmute(box));
    }
}

/// Bindings to the runtime
extern mod rustrt {
    #[rust_stack]
    /*priv*/ fn rust_get_task() -> *c_void;
}

<commit_msg>libcore: Fix cleanup for i386<commit_after>use libc::{c_char, c_void, intptr_t, uintptr_t};
use ptr::{mut_null, null, to_unsafe_ptr};
use repr::BoxRepr;
use sys::TypeDesc;
use unsafe::transmute;

export annihilate;

/**
 * Runtime structures
 *
 * NB: These must match the representation in the C++ runtime.
 */

type DropGlue = fn(**TypeDesc, *c_void);
type FreeGlue = fn(**TypeDesc, *c_void);

type TaskID = uintptr_t;

struct StackSegment { priv opaque: () }
struct Scheduler { priv opaque: () }
struct SchedulerLoop { priv opaque: () }
struct Kernel { priv opaque: () }
struct Env { priv opaque: () }
struct AllocHeader { priv opaque: () }
struct MemoryRegion { priv opaque: () }

#[cfg(target_arch="x86")]
struct Registers {
    data: [u32 * 13]
}

#[cfg(target_arch="x86_64")]
struct Registers {
    data: [u64 * 22]
}

struct Context {
    regs: Registers,
    next: *Context,
    pad: u64
}

struct BoxedRegion {
    env: *Env,
    backing_region: *MemoryRegion,
    live_allocs: *BoxRepr
}

struct Task {
    // Public fields
    refcount: intptr_t,
    id: TaskID,
    ctx: Context,
    stack_segment: *StackSegment,
    runtime_sp: uintptr_t,
    scheduler: *Scheduler,
    scheduler_loop: *SchedulerLoop,

    // Fields known only to the runtime
    kernel: *Kernel,
    name: *c_char,
    list_index: *i32,
    rendezvous_ptr: *uintptr_t,
    boxed_region: BoxedRegion
}

/*
 * Box annihilation
 *
 * This runs at task death to free all boxes.
 */

/// Destroys all managed memory (i.e. @ boxes) held by the current task.
#[cfg(notest)]
#[lang="annihilate"]
pub unsafe fn annihilate() {
    use rt::rt_free;
    use io::WriterUtil;

    let task: *Task = transmute(rustrt::rust_get_task());

    // Pass 1: Make all boxes immortal.
    let box = (*task).boxed_region.live_allocs;
    let mut box: *mut BoxRepr = transmute(copy box);
    while box != mut_null() {
        debug!("making box immortal: %x", box as uint);
        (*box).header.ref_count = 0x77777777;
        box = transmute(copy (*box).header.next);
    }

    // Pass 2: Drop all boxes.
    let box = (*task).boxed_region.live_allocs;
    let mut box: *mut BoxRepr = transmute(copy box);
    while box != mut_null() {
        debug!("calling drop glue for box: %x", box as uint);
        let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc);
        let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0));
        drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data));

        box = transmute(copy (*box).header.next);
    }

    // Pass 3: Free all boxes.
    loop {
        let box = (*task).boxed_region.live_allocs;
        if box == null() { break; }
        let mut box: *mut BoxRepr = transmute(copy box);
        assert (*box).header.prev == null();

        debug!("freeing box: %x", box as uint);
        rt_free(transmute(box));
    }
}

/// Bindings to the runtime
extern mod rustrt {
    #[rust_stack]
    /*priv*/ fn rust_get_task() -> *c_void;
}

<|endoftext|>


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

// This file is imported into every module by default.

/* Reexported core operators */

pub use kinds::{Const, Copy, Owned, Durable};
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Drop};
pub use ops::{Shl, Shr, Index};
pub use option::{Option, Some, None};
pub use result::{Result, Ok, Err};

/* Reexported types and traits */

pub use clone::Clone;
pub use cmp::{Eq, Ord};
pub use container::{Container, Mutable, Map, Set};
pub use hash::Hash;
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
pub use num::Num;
pub use path::GenericPath;
pub use path::Path;
pub use path::PosixPath;
pub use path::WindowsPath;
pub use pipes::{GenericChan, GenericPort};
pub use ptr::Ptr;
pub use str::{StrSlice, Trimmable};
pub use to_bytes::IterBytes;
pub use to_str::ToStr;
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
pub use vec::{CopyableVector, ImmutableVector};
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
pub use vec::{OwnedVector, OwnedCopyableVector};

/* Reexported modules */

pub use at_vec;
pub use bool;
pub use cast;
pub use char;
pub use cmp;
pub use dvec;
pub use either;
pub use extfmt;
pub use f32;
pub use f64;
pub use float;
pub use i16;
pub use i32;
pub use i64;
pub use i8;
pub use int;
pub use io;
pub use iter;
pub use libc;
pub use num;
pub use ops;
pub use option;
pub use os;
pub use path;
pub use pipes;
pub use private;
pub use ptr;
pub use rand;
pub use result;
pub use str;
pub use sys;
pub use task;
pub use to_str;
pub use u16;
pub use u32;
pub use u64;
pub use u8;
pub use uint;
pub use vec;

/*
 * Export the log levels as global constants. Higher levels mean
 * more-verbosity. Error is the bottom level, default logging level is
 * warn-and-below.
 */

/// The error log level
pub const error : u32 = 1_u32;
/// The warning log level
pub const warn : u32 = 2_u32;
/// The info log level
pub const info : u32 = 3_u32;
/// The debug log level
pub const debug : u32 = 4_u32;
<commit_msg>core: export either::{Either,Left,Right} from the prelude<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// This file is imported into every module by default.

/* Reexported core operators */

pub use either::{Either, Left, Right};
pub use kinds::{Const, Copy, Owned, Durable};
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Drop};
pub use ops::{Shl, Shr, Index};
pub use option::{Option, Some, None};
pub use result::{Result, Ok, Err};

/* Reexported types and traits */

pub use clone::Clone;
pub use cmp::{Eq, Ord};
pub use container::{Container, Mutable, Map, Set};
pub use hash::Hash;
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
pub use num::Num;
pub use path::GenericPath;
pub use path::Path;
pub use path::PosixPath;
pub use path::WindowsPath;
pub use pipes::{GenericChan, GenericPort};
pub use ptr::Ptr;
pub use str::{StrSlice, Trimmable};
pub use to_bytes::IterBytes;
pub use to_str::ToStr;
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
pub use vec::{CopyableVector, ImmutableVector};
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
pub use vec::{OwnedVector, OwnedCopyableVector};

/* Reexported modules */

pub use at_vec;
pub use bool;
pub use cast;
pub use char;
pub use cmp;
pub use dvec;
pub use either;
pub use extfmt;
pub use f32;
pub use f64;
pub use float;
pub use i16;
pub use i32;
pub use i64;
pub use i8;
pub use int;
pub use io;
pub use iter;
pub use libc;
pub use num;
pub use ops;
pub use option;
pub use os;
pub use path;
pub use pipes;
pub use private;
pub use ptr;
pub use rand;
pub use result;
pub use str;
pub use sys;
pub use task;
pub use to_str;
pub use u16;
pub use u32;
pub use u64;
pub use u8;
pub use uint;
pub use vec;

/*
 * Export the log levels as global constants. Higher levels mean
 * more-verbosity. Error is the bottom level, default logging level is
 * warn-and-below.
 */

/// The error log level
pub const error : u32 = 1_u32;
/// The warning log level
pub const warn : u32 = 2_u32;
/// The info log level
pub const info : u32 = 3_u32;
/// The debug log level
pub const debug : u32 = 4_u32;
<|endoftext|>


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

// This file is imported into every module by default.

/* Reexported core operators */

pub use kinds::{Const, Copy, Owned, Durable};
pub use ops::{Drop};
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Shl, Shr, Index};
pub use option::{Option, Some, None};
pub use result::{Result, Ok, Err};

/* Reexported types and traits */

pub use path::Path;
pub use path::GenericPath;
pub use path::WindowsPath;
pub use path::PosixPath;

pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
pub use str::{StrSlice, Trimmable};
pub use container::{Container, Mutable};
pub use vec::{CopyableVector, ImmutableVector};
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
pub use vec::{OwnedVector, OwnedCopyableVector};
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
pub use container::{Container, Mutable, Map, Set};
pub use pipes::{GenericChan, GenericPort};

pub use num::Num;
pub use ptr::Ptr;
pub use to_str::ToStr;
pub use clone::Clone;

pub use cmp::{Eq, Ord};
pub use hash::Hash;
pub use to_bytes::IterBytes;

/* Reexported modules */

pub use at_vec;
pub use bool;
pub use cast;
pub use char;
pub use cmp;
pub use dvec;
pub use either;
pub use extfmt;
pub use f32;
pub use f64;
pub use float;
pub use i16;
pub use i32;
pub use i64;
pub use i8;
pub use int;
pub use io;
pub use iter;
pub use libc;
pub use num;
pub use ops;
pub use option;
pub use os;
pub use path;
pub use pipes;
pub use private;
pub use ptr;
pub use rand;
pub use result;
pub use str;
pub use sys;
pub use task;
pub use to_str;
pub use u16;
pub use u32;
pub use u64;
pub use u8;
pub use uint;
pub use vec;

/*
 * Export the log levels as global constants. Higher levels mean
 * more-verbosity. Error is the bottom level, default logging level is
 * warn-and-below.
 */

/// The error log level
pub const error : u32 = 1_u32;
/// The warning log level
pub const warn : u32 = 2_u32;
/// The info log level
pub const info : u32 = 3_u32;
/// The debug log level
pub const debug : u32 = 4_u32;
<commit_msg>core: sort each prelude.rs section<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// This file is imported into every module by default.

/* Reexported core operators */

pub use kinds::{Const, Copy, Owned, Durable};
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Drop};
pub use ops::{Shl, Shr, Index};
pub use option::{Option, Some, None};
pub use result::{Result, Ok, Err};

/* Reexported types and traits */

pub use clone::Clone;
pub use cmp::{Eq, Ord};
pub use container::{Container, Mutable, Map, Set};
pub use hash::Hash;
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
pub use num::Num;
pub use path::GenericPath;
pub use path::Path;
pub use path::PosixPath;
pub use path::WindowsPath;
pub use pipes::{GenericChan, GenericPort};
pub use ptr::Ptr;
pub use str::{StrSlice, Trimmable};
pub use to_bytes::IterBytes;
pub use to_str::ToStr;
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
pub use vec::{CopyableVector, ImmutableVector};
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
pub use vec::{OwnedVector, OwnedCopyableVector};

/* Reexported modules */

pub use at_vec;
pub use bool;
pub use cast;
pub use char;
pub use cmp;
pub use dvec;
pub use either;
pub use extfmt;
pub use f32;
pub use f64;
pub use float;
pub use i16;
pub use i32;
pub use i64;
pub use i8;
pub use int;
pub use io;
pub use iter;
pub use libc;
pub use num;
pub use ops;
pub use option;
pub use os;
pub use path;
pub use pipes;
pub use private;
pub use ptr;
pub use rand;
pub use result;
pub use str;
pub use sys;
pub use task;
pub use to_str;
pub use u16;
pub use u32;
pub use u64;
pub use u8;
pub use uint;
pub use vec;

/*
 * Export the log levels as global constants. Higher levels mean
 * more-verbosity. Error is the bottom level, default logging level is
 * warn-and-below.
 */

/// The error log level
pub const error : u32 = 1_u32;
/// The warning log level
pub const warn : u32 = 2_u32;
/// The info log level
pub const info : u32 = 3_u32;
/// The debug log level
pub const debug : u32 = 4_u32;
<|endoftext|>