<commit_before>use std::io;
use std::str::FromStr;

pub struct VM {
	stack: Vec<Operator>,
}

impl VM {
	pub fn pop <'a> (&'a mut self) -> Operator {
		return self.stack.pop().expect("gg reinstall");
	}

	pub fn push <'a> (&'a mut self, op: Operator) {
		self.stack.push(op);
	}

	pub fn eval <'a> (&'a mut self, op: Operator) {

	}

	pub fn add <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i+j,
				_ => panic!("can only add ints"),
			},
			_ => panic!("can only add ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn subtract <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i-j,
				_ => panic!("can only add ints"),
			},
			_ => panic!("can only add ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn multiply <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i*j,
				_ => panic!("can only add ints"),
			},
			_ => panic!("can only add ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn divide <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i/j,
				_ => panic!("can only add ints"),
			},
			_ => panic!("can only add ints"),
		};
		self.push(Operator::Value(z));
	}
}

pub enum Operator {
	//stack
	Dup,
	Drop,
	Swap,
	Over,
	Rot,

	//debug
	Print,

	//math
	Add,
	Subtract,
	Multiply,
	Divide,
	Mod,
	And,
	Or,
	Xor,
	Lshift,
	Rshift,
	Abs,
	Max,
	Min,
	Invert,
	Negate,

	//custom
	Define,

	//values and custom calls
	Value(i32),
	Other,
}

fn parse(s: &str) -> Operator {
	match s {
		//stack operations:
		"dup" => Operator::Dup,
		"drop" => Operator::Drop,
		"swap" => Operator::Swap,
		"over" => Operator::Over,
		"rot" => Operator::Rot,

		//debug operations:
		"." => Operator::Print,

		//math operations:
		"+" => Operator::Add,
		"-" => Operator::Subtract,
		"*" => Operator::Multiply,
		"/" => Operator::Divide,
		"mod" => Operator::Mod,
		"and" => Operator::And,
		"or" => Operator::Or,
		"xor" => Operator::Xor,
		"lshift" => Operator::Lshift,
		"<<" => Operator::Lshift,
		"rshift" => Operator::Rshift,
		">>" => Operator::Rshift,
		"abs" => Operator::Abs,
		"max" => Operator::Max,
		"min" => Operator::Min,
		"invert" => Operator::Invert,
		"negate" => Operator::Negate,

		//custom definitions
		":" => Operator::Define,

		//value or custom operator
		x => {
			let y: Option<i32> = FromStr::from_str(x).ok();
			match y{
				Some(i) => Operator::Value(i),
				None => Operator::Other,
			}
		},
	}
}

fn main() {
	let mut x = io::stdin();
	let mut vm = VM {stack: vec![Operator::Print]};

	loop{
		let mut line: String = "".to_string();
		let _ = x.read_line(&mut line);

		for o in line.split(" "){
			println!("evaling: {}", o.trim());
			let b = parse(o.trim());
			vm.eval(b);
		}
	}
}
<commit_msg>all math functions<commit_after>use std::io;
use std::str::FromStr;

pub struct VM {
	stack: Vec<Operator>,
}

impl VM {
	pub fn pop <'a> (&'a mut self) -> Operator {
		return self.stack.pop().expect("gg reinstall");
	}

	pub fn push <'a> (&'a mut self, op: Operator) {
		self.stack.push(op);
	}

	pub fn eval <'a> (&'a mut self, op: Operator) {

	}

	pub fn add <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i+j,
				_ => panic!("can only add ints"),
			},
			_ => panic!("can only add ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn subtract <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i-j,
				_ => panic!("can only subtract ints"),
			},
			_ => panic!("can only subtract ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn multiply <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i*j,
				_ => panic!("can only multiply ints"),
			},
			_ => panic!("can only multiply ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn divide <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i/j,
				_ => panic!("can only divide ints"),
			},
			_ => panic!("can only divide ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn modulus <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i % j,
				_ => panic!("can only mod ints"),
			},
			_ => panic!("can only mod ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn and <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i & j,
				_ => panic!("can only and ints"),
			},
			_ => panic!("can only and ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn or <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i | j,
				_ => panic!("can only or ints"),
			},
			_ => panic!("can only or ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn xor <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i ^ j,
				_ => panic!("can only xor ints"),
			},
			_ => panic!("can only xor ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn lshift <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i << j,
				_ => panic!("can only lshift ints"),
			},
			_ => panic!("can only lshift ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn rshift <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i >> j,
				_ => panic!("can only rshift ints"),
			},
			_ => panic!("can only rshift ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn abs <'a> (&'a mut self) {
		let x = self.pop();
		let z = match x{
			Operator::Value(i) => if i < 0{-i} else {i},
			_ => panic!("can only abs an int"),
		};
		self.push(Operator::Value(z));
	}

	pub fn max <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => if j > i {j} else{i},
				_ => panic!("can only max ints"),
			},
			_ => panic!("can only max ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn min <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => if j < i {j} else {i},
				_ => panic!("can only min ints"),
			},
			_ => panic!("can only min ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn invert <'a> (&'a mut self) {
		let x = self.pop();
		let z = match x{
			Operator::Value(i) => !i,
			_ => panic!("can only invert an int"),
		};
		self.push(Operator::Value(z));
	}

	pub fn negate <'a> (&'a mut self) {
		let x = self.pop();
		let z = match x{
			Operator::Value(i) => -i,
			_ => panic!("can only negate an int"),
		};
		self.push(Operator::Value(z));
	}
}

pub enum Operator {
	//stack
	Dup,
	Drop,
	Swap,
	Over,
	Rot,

	//debug
	Print,

	//math
	Add,
	Subtract,
	Multiply,
	Divide,
	Modulus,
	And,
	Or,
	Xor,
	Lshift,
	Rshift,
	Abs,
	Max,
	Min,
	Invert,
	Negate,

	//custom
	Define,

	//values and custom calls
	Value(i32),
	Other,
}

fn parse(s: &str) -> Operator {
	match s {
		//stack operations:
		"dup" => Operator::Dup,
		"drop" => Operator::Drop,
		"swap" => Operator::Swap,
		"over" => Operator::Over,
		"rot" => Operator::Rot,

		//debug operations:
		"." => Operator::Print,

		//math operations:
		"+" => Operator::Add,
		"-" => Operator::Subtract,
		"*" => Operator::Multiply,
		"/" => Operator::Divide,
		"mod" => Operator::Modulus,
		"and" => Operator::And,
		"or" => Operator::Or,
		"xor" => Operator::Xor,
		"lshift" => Operator::Lshift,
		"<<" => Operator::Lshift,
		"rshift" => Operator::Rshift,
		">>" => Operator::Rshift,
		"abs" => Operator::Abs,
		"max" => Operator::Max,
		"min" => Operator::Min,
		"invert" => Operator::Invert,
		"negate" => Operator::Negate,

		//custom definitions
		":" => Operator::Define,

		//value or custom operator
		x => {
			let y: Option<i32> = FromStr::from_str(x).ok();
			match y{
				Some(i) => Operator::Value(i),
				None => Operator::Other,
			}
		},
	}
}

fn main() {
	let mut x = io::stdin();
	let mut vm = VM {stack: vec![Operator::Print]};

	loop{
		let mut line: String = "".to_string();
		let _ = x.read_line(&mut line);

		for o in line.split(" "){
			println!("evaling: {}", o.trim());
			let b = parse(o.trim());
			vm.eval(b);
		}
	}
}
<|endoftext|>


<commit_before>use crate::*;
use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192};
use serde_derive::{Deserialize, Serialize};
use std::fmt::Debug;

pub trait BeaconStateTypes:
    'static + Default + Sync + Send + Clone + Debug + PartialEq + serde::de::DeserializeOwned
{
    type ShardCount: Unsigned + Clone + Sync + Send + Debug + PartialEq;
    type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send + Debug + PartialEq;
    type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
    type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
    type LatestSlashedExitLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;

    fn spec() -> ChainSpec;
}

/// Ethereum Foundation specifications.
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
pub struct FoundationStateTypes;

impl BeaconStateTypes for FoundationStateTypes {
    type ShardCount = U1024;
    type SlotsPerHistoricalRoot = U8192;
    type LatestRandaoMixesLength = U8192;
    type LatestActiveIndexRootsLength = U8192;
    type LatestSlashedExitLength = U8192;

    fn spec() -> ChainSpec {
        ChainSpec::foundation()
    }
}

pub type FoundationBeaconState = BeaconState<FoundationStateTypes>;

#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
pub struct FewValidatorsStateTypes;

impl BeaconStateTypes for FewValidatorsStateTypes {
    type ShardCount = U8;
    type SlotsPerHistoricalRoot = U8192;
    type LatestRandaoMixesLength = U8192;
    type LatestActiveIndexRootsLength = U8192;
    type LatestSlashedExitLength = U8192;

    fn spec() -> ChainSpec {
        ChainSpec::few_validators()
    }
}

pub type FewValidatorsBeaconState = BeaconState<FewValidatorsStateTypes>;

#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
pub struct LighthouseTestnetStateTypes;

impl BeaconStateTypes for LighthouseTestnetStateTypes {
    type ShardCount = U8;
    type SlotsPerHistoricalRoot = U8192;
    type LatestRandaoMixesLength = U8192;
    type LatestActiveIndexRootsLength = U8192;
    type LatestSlashedExitLength = U8192;

    fn spec() -> ChainSpec {
        ChainSpec::lighthouse_testnet()
    }
}

pub type LighthouseTestnetBeaconState = BeaconState<LighthouseTestnetStateTypes>;
<commit_msg>Add convenience methods to `BeaconStateTypes`<commit_after>use crate::*;
use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192};
use serde_derive::{Deserialize, Serialize};
use std::fmt::Debug;

pub trait BeaconStateTypes:
    'static + Default + Sync + Send + Clone + Debug + PartialEq + serde::de::DeserializeOwned
{
    type ShardCount: Unsigned + Clone + Sync + Send + Debug + PartialEq;
    type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send + Debug + PartialEq;
    type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
    type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
    type LatestSlashedExitLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;

    fn spec() -> ChainSpec;

    /// Returns the `SHARD_COUNT` constant for this specification.
    ///
    /// Spec v0.5.1
    fn shard_count() -> usize {
        Self::ShardCount::to_usize()
    }

    /// Returns the `SLOTS_PER_HISTORICAL_ROOT` constant for this specification.
    ///
    /// Spec v0.5.1
    fn slots_per_historical_root() -> usize {
        Self::SlotsPerHistoricalRoot::to_usize()
    }

    /// Returns the `LATEST_RANDAO_MIXES_LENGTH` constant for this specification.
    ///
    /// Spec v0.5.1
    fn latest_randao_mixes_length() -> usize {
        Self::LatestRandaoMixesLength::to_usize()
    }

    /// Returns the `LATEST_ACTIVE_INDEX_ROOTS` constant for this specification.
    ///
    /// Spec v0.5.1
    fn latest_active_index_roots() -> usize {
        Self::LatestActiveIndexRootsLength::to_usize()
    }

    /// Returns the `LATEST_SLASHED_EXIT_LENGTH` constant for this specification.
    ///
    /// Spec v0.5.1
    fn latest_slashed_exit_length() -> usize {
        Self::LatestSlashedExitLength::to_usize()
    }
}

/// Ethereum Foundation specifications.
///
/// Spec v0.5.1
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
pub struct FoundationStateTypes;

impl BeaconStateTypes for FoundationStateTypes {
    type ShardCount = U1024;
    type SlotsPerHistoricalRoot = U8192;
    type LatestRandaoMixesLength = U8192;
    type LatestActiveIndexRootsLength = U8192;
    type LatestSlashedExitLength = U8192;

    fn spec() -> ChainSpec {
        ChainSpec::foundation()
    }
}

pub type FoundationBeaconState = BeaconState<FoundationStateTypes>;

/// Ethereum Foundation specifications, modified to be suitable for < 1000 validators.
///
/// Spec v0.5.1
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
pub struct FewValidatorsStateTypes;

impl BeaconStateTypes for FewValidatorsStateTypes {
    type ShardCount = U8;
    type SlotsPerHistoricalRoot = U8192;
    type LatestRandaoMixesLength = U8192;
    type LatestActiveIndexRootsLength = U8192;
    type LatestSlashedExitLength = U8192;

    fn spec() -> ChainSpec {
        ChainSpec::few_validators()
    }
}

pub type FewValidatorsBeaconState = BeaconState<FewValidatorsStateTypes>;

/// Specifications suitable for a small-scale (< 1000 validators) lighthouse testnet.
///
/// Spec v0.5.1
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
pub struct LighthouseTestnetStateTypes;

impl BeaconStateTypes for LighthouseTestnetStateTypes {
    type ShardCount = U8;
    type SlotsPerHistoricalRoot = U8192;
    type LatestRandaoMixesLength = U8192;
    type LatestActiveIndexRootsLength = U8192;
    type LatestSlashedExitLength = U8192;

    fn spec() -> ChainSpec {
        ChainSpec::lighthouse_testnet()
    }
}

pub type LighthouseTestnetBeaconState = BeaconState<LighthouseTestnetStateTypes>;
<|endoftext|>


<commit_before>//! Utilities for creating `Analysis` instances for tests.
use hir::db::DefDatabase;
use ide_db::base_db::fixture::ChangeFixture;
use test_utils::{extract_annotations, RangeOrOffset};

use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange};

/// Creates analysis for a single file.
pub(crate) fn file(ra_fixture: &str) -> (Analysis, FileId) {
    let mut host = AnalysisHost::default();
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.apply_change(change_fixture.change);
    (host.analysis(), change_fixture.files[0])
}

/// Creates analysis from a multi-file fixture, returns positions marked with $0.
pub(crate) fn position(ra_fixture: &str) -> (Analysis, FilePosition) {
    let mut host = AnalysisHost::default();
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.apply_change(change_fixture.change);
    let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
    let offset = range_or_offset.expect_offset();
    (host.analysis(), FilePosition { file_id, offset })
}

/// Creates analysis for a single file, returns range marked with a pair of $0.
pub(crate) fn range(ra_fixture: &str) -> (Analysis, FileRange) {
    let mut host = AnalysisHost::default();
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.apply_change(change_fixture.change);
    let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
    let range = range_or_offset.expect_range();
    (host.analysis(), FileRange { file_id, range })
}

/// Creates analysis for a single file, returns range marked with a pair of $0 or a position marked with $0.
pub(crate) fn range_or_position(ra_fixture: &str) -> (Analysis, FileId, RangeOrOffset) {
    let mut host = AnalysisHost::default();
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.apply_change(change_fixture.change);
    let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
    (host.analysis(), file_id, range_or_offset)
}

/// Creates analysis from a multi-file fixture, returns positions marked with $0.
pub(crate) fn annotations(ra_fixture: &str) -> (Analysis, FilePosition, Vec<(FileRange, String)>) {
    let mut host = AnalysisHost::default();
    host.db.set_enable_proc_attr_macros(true);
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.apply_change(change_fixture.change);
    let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
    let offset = range_or_offset.expect_offset();

    let annotations = change_fixture
        .files
        .iter()
        .flat_map(|&file_id| {
            let file_text = host.analysis().file_text(file_id).unwrap();
            let annotations = extract_annotations(&file_text);
            annotations.into_iter().map(move |(range, data)| (FileRange { file_id, range }, data))
        })
        .collect();
    (host.analysis(), FilePosition { file_id, offset }, annotations)
}
<commit_msg>Enable attribte macros in ide fixtures<commit_after>//! Utilities for creating `Analysis` instances for tests.
use hir::db::DefDatabase;
use ide_db::base_db::fixture::ChangeFixture;
use test_utils::{extract_annotations, RangeOrOffset};

use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange};

/// Creates analysis for a single file.
pub(crate) fn file(ra_fixture: &str) -> (Analysis, FileId) {
    let mut host = AnalysisHost::default();
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.set_enable_proc_attr_macros(true);
    host.db.apply_change(change_fixture.change);
    (host.analysis(), change_fixture.files[0])
}

/// Creates analysis from a multi-file fixture, returns positions marked with $0.
pub(crate) fn position(ra_fixture: &str) -> (Analysis, FilePosition) {
    let mut host = AnalysisHost::default();
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.set_enable_proc_attr_macros(true);
    host.db.apply_change(change_fixture.change);
    let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
    let offset = range_or_offset.expect_offset();
    (host.analysis(), FilePosition { file_id, offset })
}

/// Creates analysis for a single file, returns range marked with a pair of $0.
pub(crate) fn range(ra_fixture: &str) -> (Analysis, FileRange) {
    let mut host = AnalysisHost::default();
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.set_enable_proc_attr_macros(true);
    host.db.apply_change(change_fixture.change);
    let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
    let range = range_or_offset.expect_range();
    (host.analysis(), FileRange { file_id, range })
}

/// Creates analysis for a single file, returns range marked with a pair of $0 or a position marked with $0.
pub(crate) fn range_or_position(ra_fixture: &str) -> (Analysis, FileId, RangeOrOffset) {
    let mut host = AnalysisHost::default();
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.set_enable_proc_attr_macros(true);
    host.db.apply_change(change_fixture.change);
    let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
    (host.analysis(), file_id, range_or_offset)
}

/// Creates analysis from a multi-file fixture, returns positions marked with $0.
pub(crate) fn annotations(ra_fixture: &str) -> (Analysis, FilePosition, Vec<(FileRange, String)>) {
    let mut host = AnalysisHost::default();
    let change_fixture = ChangeFixture::parse(ra_fixture);
    host.db.set_enable_proc_attr_macros(true);
    host.db.apply_change(change_fixture.change);
    let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
    let offset = range_or_offset.expect_offset();

    let annotations = change_fixture
        .files
        .iter()
        .flat_map(|&file_id| {
            let file_text = host.analysis().file_text(file_id).unwrap();
            let annotations = extract_annotations(&file_text);
            annotations.into_iter().map(move |(range, data)| (FileRange { file_id, range }, data))
        })
        .collect();
    (host.analysis(), FilePosition { file_id, offset }, annotations)
}
<|endoftext|>


<commit_before>//! This module specifies the input to rust-analyzer. In some sense, this is
//! **the** most important module, because all other fancy stuff is strictly
//! derived from this input.
//!
//! Note that neither this module, nor any other part of the analyzer's core do
//! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
//! actual IO is done and lowered to input.

use std::{fmt, str::FromStr};

use ra_cfg::CfgOptions;
use ra_syntax::SmolStr;
use rustc_hash::FxHashMap;
use rustc_hash::FxHashSet;

use crate::{RelativePath, RelativePathBuf};

/// `FileId` is an integer which uniquely identifies a file. File paths are
/// messy and system-dependent, so most of the code should work directly with
/// `FileId`, without inspecting the path. The mapping between `FileId` and path
/// and `SourceRoot` is constant. A file rename is represented as a pair of
/// deletion/creation.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FileId(pub u32);

/// Files are grouped into source roots. A source root is a directory on the
/// file systems which is watched for changes. Typically it corresponds to a
/// Rust crate. Source roots *might* be nested: in this case, a file belongs to
/// the nearest enclosing source root. Paths to files are always relative to a
/// source root, and the analyzer does not know the root path of the source root at
/// all. So, a file from one source root can't refer to a file in another source
/// root by path.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SourceRootId(pub u32);

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SourceRoot {
    /// Sysroot or crates.io library.
    ///
    /// Libraries are considered mostly immutable, this assumption is used to
    /// optimize salsa's query structure
    pub is_library: bool,
    files: FxHashMap<RelativePathBuf, FileId>,
}

impl SourceRoot {
    pub fn new_local() -> SourceRoot {
        SourceRoot { is_library: false, files: Default::default() }
    }
    pub fn new_library() -> SourceRoot {
        SourceRoot { is_library: true, files: Default::default() }
    }
    pub fn insert_file(&mut self, path: RelativePathBuf, file_id: FileId) {
        self.files.insert(path, file_id);
    }
    pub fn remove_file(&mut self, path: &RelativePath) {
        self.files.remove(path);
    }
    pub fn walk(&self) -> impl Iterator<Item = FileId> + '_ {
        self.files.values().copied()
    }
    pub fn file_by_relative_path(&self, path: &RelativePath) -> Option<FileId> {
        self.files.get(path).copied()
    }
}

/// `CrateGraph` is a bit of information which turns a set of text files into a
/// number of Rust crates. Each crate is defined by the `FileId` of its root module,
/// the set of cfg flags (not yet implemented) and the set of dependencies. Note
/// that, due to cfg's, there might be several crates for a single `FileId`! As
/// in the rust-lang proper, a crate does not have a name. Instead, names are
/// specified on dependency edges. That is, a crate might be known under
/// different names in different dependent crates.
///
/// Note that `CrateGraph` is build-system agnostic: it's a concept of the Rust
/// language proper, not a concept of the build system. In practice, we get
/// `CrateGraph` by lowering `cargo metadata` output.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CrateGraph {
    arena: FxHashMap<CrateId, CrateData>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CrateId(pub u32);

pub struct CrateName(SmolStr);

impl CrateName {
    /// Crates a crate name, checking for dashes in the string provided.
    /// Dashes are not allowed in the crate names,
    /// hence the input string is returned as `Err` for those cases.
    pub fn new(name: &str) -> Result<CrateName, &str> {
        if name.contains('-') {
            Err(name)
        } else {
            Ok(Self(SmolStr::new(name)))
        }
    }

    /// Crates a crate name, unconditionally replacing the dashes with underscores.
    pub fn normalize_dashes(name: &str) -> CrateName {
        Self(SmolStr::new(name.replace('-', "_")))
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct CrateData {
    file_id: FileId,
    edition: Edition,
    cfg_options: CfgOptions,
    env: Env,
    dependencies: Vec<Dependency>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Edition {
    Edition2018,
    Edition2015,
}

#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Env {
    entries: FxHashMap<String, String>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Dependency {
    pub crate_id: CrateId,
    pub name: SmolStr,
}

impl CrateGraph {
    pub fn add_crate_root(
        &mut self,
        file_id: FileId,
        edition: Edition,
        cfg_options: CfgOptions,
        env: Env,
    ) -> CrateId {
        let data = CrateData::new(file_id, edition, cfg_options, env);
        let crate_id = CrateId(self.arena.len() as u32);
        let prev = self.arena.insert(crate_id, data);
        assert!(prev.is_none());
        crate_id
    }

    pub fn cfg_options(&self, crate_id: CrateId) -> &CfgOptions {
        &self.arena[&crate_id].cfg_options
    }

    pub fn add_dep(
        &mut self,
        from: CrateId,
        name: CrateName,
        to: CrateId,
    ) -> Result<(), CyclicDependenciesError> {
        if self.dfs_find(from, to, &mut FxHashSet::default()) {
            return Err(CyclicDependenciesError);
        }
        self.arena.get_mut(&from).unwrap().add_dep(name.0, to);
        Ok(())
    }

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

    pub fn iter<'a>(&'a self) -> impl Iterator<Item = CrateId> + 'a {
        self.arena.keys().copied()
    }

    pub fn crate_root(&self, crate_id: CrateId) -> FileId {
        self.arena[&crate_id].file_id
    }

    pub fn edition(&self, crate_id: CrateId) -> Edition {
        self.arena[&crate_id].edition
    }

    // FIXME: this only finds one crate with the given root; we could have multiple
    pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
        let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?;
        Some(crate_id)
    }

    pub fn dependencies<'a>(
        &'a self,
        crate_id: CrateId,
    ) -> impl Iterator<Item = &'a Dependency> + 'a {
        self.arena[&crate_id].dependencies.iter()
    }

    /// Extends this crate graph by adding a complete disjoint second crate
    /// graph.
    ///
    /// The ids of the crates in the `other` graph are shifted by the return
    /// amount.
    pub fn extend(&mut self, other: CrateGraph) -> u32 {
        let start = self.arena.len() as u32;
        self.arena.extend(other.arena.into_iter().map(|(id, mut data)| {
            let new_id = id.shift(start);
            for dep in &mut data.dependencies {
                dep.crate_id = dep.crate_id.shift(start);
            }
            (new_id, data)
        }));
        start
    }

    fn dfs_find(&self, target: CrateId, from: CrateId, visited: &mut FxHashSet<CrateId>) -> bool {
        if !visited.insert(from) {
            return false;
        }

        for dep in self.dependencies(from) {
            let crate_id = dep.crate_id();
            if crate_id == target {
                return true;
            }

            if self.dfs_find(target, crate_id, visited) {
                return true;
            }
        }
        false
    }
}

impl CrateId {
    pub fn shift(self, amount: u32) -> CrateId {
        CrateId(self.0 + amount)
    }
}

impl CrateData {
    fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions, env: Env) -> CrateData {
        CrateData { file_id, edition, dependencies: Vec::new(), cfg_options, env }
    }

    fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) {
        self.dependencies.push(Dependency { name, crate_id })
    }
}

impl FromStr for Edition {
    type Err = ParseEditionError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let res = match s {
            "2015" => Edition::Edition2015,
            "2018" => Edition::Edition2018,
            _ => return Err(ParseEditionError { invalid_input: s.to_string() }),
        };
        Ok(res)
    }
}

impl fmt::Display for Edition {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match self {
            Edition::Edition2015 => "2015",
            Edition::Edition2018 => "2018",
        })
    }
}

impl Dependency {
    pub fn crate_id(&self) -> CrateId {
        self.crate_id
    }
}

#[derive(Debug)]
pub struct ParseEditionError {
    invalid_input: String,
}

impl fmt::Display for ParseEditionError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "invalid edition: {:?}", self.invalid_input)
    }
}

impl std::error::Error for ParseEditionError {}

#[derive(Debug)]
pub struct CyclicDependenciesError;

#[cfg(test)]
mod tests {
    use super::{CfgOptions, CrateGraph, CrateName, Dependency, Edition::Edition2018, Env, FileId};

    #[test]
    fn it_should_panic_because_of_cycle_dependencies() {
        let mut graph = CrateGraph::default();
        let crate1 =
            graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default());
        let crate2 =
            graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default());
        let crate3 =
            graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default());
        assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
        assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
        assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err());
    }

    #[test]
    fn it_works() {
        let mut graph = CrateGraph::default();
        let crate1 =
            graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default());
        let crate2 =
            graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default());
        let crate3 =
            graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default());
        assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
        assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
    }

    #[test]
    fn dashes_are_normalized() {
        let mut graph = CrateGraph::default();
        let crate1 =
            graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default());
        let crate2 =
            graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default());
        assert!(graph
            .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2)
            .is_ok());
        assert_eq!(
            graph.dependencies(crate1).collect::<Vec<_>>(),
            vec![&Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }]
        );
    }
}
<commit_msg>ra_db: removed a couple of explicit lifetimes<commit_after>//! This module specifies the input to rust-analyzer. In some sense, this is
//! **the** most important module, because all other fancy stuff is strictly
//! derived from this input.
//!
//! Note that neither this module, nor any other part of the analyzer's core do
//! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
//! actual IO is done and lowered to input.

use std::{fmt, str::FromStr};

use ra_cfg::CfgOptions;
use ra_syntax::SmolStr;
use rustc_hash::FxHashMap;
use rustc_hash::FxHashSet;

use crate::{RelativePath, RelativePathBuf};

/// `FileId` is an integer which uniquely identifies a file. File paths are
/// messy and system-dependent, so most of the code should work directly with
/// `FileId`, without inspecting the path. The mapping between `FileId` and path
/// and `SourceRoot` is constant. A file rename is represented as a pair of
/// deletion/creation.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FileId(pub u32);

/// Files are grouped into source roots. A source root is a directory on the
/// file systems which is watched for changes. Typically it corresponds to a
/// Rust crate. Source roots *might* be nested: in this case, a file belongs to
/// the nearest enclosing source root. Paths to files are always relative to a
/// source root, and the analyzer does not know the root path of the source root at
/// all. So, a file from one source root can't refer to a file in another source
/// root by path.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SourceRootId(pub u32);

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SourceRoot {
    /// Sysroot or crates.io library.
    ///
    /// Libraries are considered mostly immutable, this assumption is used to
    /// optimize salsa's query structure
    pub is_library: bool,
    files: FxHashMap<RelativePathBuf, FileId>,
}

impl SourceRoot {
    pub fn new_local() -> SourceRoot {
        SourceRoot { is_library: false, files: Default::default() }
    }
    pub fn new_library() -> SourceRoot {
        SourceRoot { is_library: true, files: Default::default() }
    }
    pub fn insert_file(&mut self, path: RelativePathBuf, file_id: FileId) {
        self.files.insert(path, file_id);
    }
    pub fn remove_file(&mut self, path: &RelativePath) {
        self.files.remove(path);
    }
    pub fn walk(&self) -> impl Iterator<Item = FileId> + '_ {
        self.files.values().copied()
    }
    pub fn file_by_relative_path(&self, path: &RelativePath) -> Option<FileId> {
        self.files.get(path).copied()
    }
}

/// `CrateGraph` is a bit of information which turns a set of text files into a
/// number of Rust crates. Each crate is defined by the `FileId` of its root module,
/// the set of cfg flags (not yet implemented) and the set of dependencies. Note
/// that, due to cfg's, there might be several crates for a single `FileId`! As
/// in the rust-lang proper, a crate does not have a name. Instead, names are
/// specified on dependency edges. That is, a crate might be known under
/// different names in different dependent crates.
///
/// Note that `CrateGraph` is build-system agnostic: it's a concept of the Rust
/// language proper, not a concept of the build system. In practice, we get
/// `CrateGraph` by lowering `cargo metadata` output.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CrateGraph {
    arena: FxHashMap<CrateId, CrateData>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CrateId(pub u32);

pub struct CrateName(SmolStr);

impl CrateName {
    /// Crates a crate name, checking for dashes in the string provided.
    /// Dashes are not allowed in the crate names,
    /// hence the input string is returned as `Err` for those cases.
    pub fn new(name: &str) -> Result<CrateName, &str> {
        if name.contains('-') {
            Err(name)
        } else {
            Ok(Self(SmolStr::new(name)))
        }
    }

    /// Crates a crate name, unconditionally replacing the dashes with underscores.
    pub fn normalize_dashes(name: &str) -> CrateName {
        Self(SmolStr::new(name.replace('-', "_")))
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct CrateData {
    file_id: FileId,
    edition: Edition,
    cfg_options: CfgOptions,
    env: Env,
    dependencies: Vec<Dependency>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Edition {
    Edition2018,
    Edition2015,
}

#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Env {
    entries: FxHashMap<String, String>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Dependency {
    pub crate_id: CrateId,
    pub name: SmolStr,
}

impl CrateGraph {
    pub fn add_crate_root(
        &mut self,
        file_id: FileId,
        edition: Edition,
        cfg_options: CfgOptions,
        env: Env,
    ) -> CrateId {
        let data = CrateData::new(file_id, edition, cfg_options, env);
        let crate_id = CrateId(self.arena.len() as u32);
        let prev = self.arena.insert(crate_id, data);
        assert!(prev.is_none());
        crate_id
    }

    pub fn cfg_options(&self, crate_id: CrateId) -> &CfgOptions {
        &self.arena[&crate_id].cfg_options
    }

    pub fn add_dep(
        &mut self,
        from: CrateId,
        name: CrateName,
        to: CrateId,
    ) -> Result<(), CyclicDependenciesError> {
        if self.dfs_find(from, to, &mut FxHashSet::default()) {
            return Err(CyclicDependenciesError);
        }
        self.arena.get_mut(&from).unwrap().add_dep(name.0, to);
        Ok(())
    }

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

    pub fn iter(&self) -> impl Iterator<Item = CrateId> + '_ {
        self.arena.keys().copied()
    }

    pub fn crate_root(&self, crate_id: CrateId) -> FileId {
        self.arena[&crate_id].file_id
    }

    pub fn edition(&self, crate_id: CrateId) -> Edition {
        self.arena[&crate_id].edition
    }

    // FIXME: this only finds one crate with the given root; we could have multiple
    pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
        let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?;
        Some(crate_id)
    }

    pub fn dependencies(&self, crate_id: CrateId) -> impl Iterator<Item = &Dependency> {
        self.arena[&crate_id].dependencies.iter()
    }

    /// Extends this crate graph by adding a complete disjoint second crate
    /// graph.
    ///
    /// The ids of the crates in the `other` graph are shifted by the return
    /// amount.
    pub fn extend(&mut self, other: CrateGraph) -> u32 {
        let start = self.arena.len() as u32;
        self.arena.extend(other.arena.into_iter().map(|(id, mut data)| {
            let new_id = id.shift(start);
            for dep in &mut data.dependencies {
                dep.crate_id = dep.crate_id.shift(start);
            }
            (new_id, data)
        }));
        start
    }

    fn dfs_find(&self, target: CrateId, from: CrateId, visited: &mut FxHashSet<CrateId>) -> bool {
        if !visited.insert(from) {
            return false;
        }

        for dep in self.dependencies(from) {
            let crate_id = dep.crate_id();
            if crate_id == target {
                return true;
            }

            if self.dfs_find(target, crate_id, visited) {
                return true;
            }
        }
        false
    }
}

impl CrateId {
    pub fn shift(self, amount: u32) -> CrateId {
        CrateId(self.0 + amount)
    }
}

impl CrateData {
    fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions, env: Env) -> CrateData {
        CrateData { file_id, edition, dependencies: Vec::new(), cfg_options, env }
    }

    fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) {
        self.dependencies.push(Dependency { name, crate_id })
    }
}

impl FromStr for Edition {
    type Err = ParseEditionError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let res = match s {
            "2015" => Edition::Edition2015,
            "2018" => Edition::Edition2018,
            _ => return Err(ParseEditionError { invalid_input: s.to_string() }),
        };
        Ok(res)
    }
}

impl fmt::Display for Edition {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match self {
            Edition::Edition2015 => "2015",
            Edition::Edition2018 => "2018",
        })
    }
}

impl Dependency {
    pub fn crate_id(&self) -> CrateId {
        self.crate_id
    }
}

#[derive(Debug)]
pub struct ParseEditionError {
    invalid_input: String,
}

impl fmt::Display for ParseEditionError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "invalid edition: {:?}", self.invalid_input)
    }
}

impl std::error::Error for ParseEditionError {}

#[derive(Debug)]
pub struct CyclicDependenciesError;

#[cfg(test)]
mod tests {
    use super::{CfgOptions, CrateGraph, CrateName, Dependency, Edition::Edition2018, Env, FileId};

    #[test]
    fn it_should_panic_because_of_cycle_dependencies() {
        let mut graph = CrateGraph::default();
        let crate1 =
            graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default());
        let crate2 =
            graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default());
        let crate3 =
            graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default());
        assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
        assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
        assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err());
    }

    #[test]
    fn it_works() {
        let mut graph = CrateGraph::default();
        let crate1 =
            graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default());
        let crate2 =
            graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default());
        let crate3 =
            graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default());
        assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
        assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
    }

    #[test]
    fn dashes_are_normalized() {
        let mut graph = CrateGraph::default();
        let crate1 =
            graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default());
        let crate2 =
            graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default());
        assert!(graph
            .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2)
            .is_ok());
        assert_eq!(
            graph.dependencies(crate1).collect::<Vec<_>>(),
            vec![&Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }]
        );
    }
}
<|endoftext|>


<commit_before>//! This module contains elements to work with window events.

/// Represents a keyboard key.
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum Key {
    Unknown,
    Backspace,
    Up,
    Down,
    Delete,
    Left,
    Right,
    Space,
    Enter,
    Control,
    ShiftL,
    ShiftR,
    Alt,
    Escape,
    Home,
    CapsLock,
    A(bool),
    B(bool),
    C(bool),
    D(bool),
    E(bool),
    F(bool),
    G(bool),
    H(bool),
    I(bool),
    J(bool),
    K(bool),
    L(bool),
    M(bool),
    N(bool),
    O(bool),
    P(bool),
    Q(bool),
    S(bool),
    R(bool),
    T(bool),
    U(bool),
    V(bool),
    W(bool),
    X(bool),
    Y(bool),
    Z(bool),
    Hash,
    At,
    Zero,
    One,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Dot,
    QuestionMark,
    ExclamationMark,
}

impl From<Key> for &'static str {
    fn from(key: Key) -> &'static str {
        match key {
            Key::A(false) => "a",
            Key::B(false) => "b",
            Key::C(false) => "c",
            Key::D(false) => "d",
            Key::E(false) => "e",
            Key::F(false) => "f",
            Key::G(false) => "g",
            Key::H(false) => "h",
            Key::I(false) => "i",
            Key::J(false) => "j",
            Key::K(false) => "k",
            Key::L(false) => "l",
            Key::M(false) => "m",
            Key::N(false) => "n",
            Key::O(false) => "o",
            Key::P(false) => "p",
            Key::Q(false) => "q",
            Key::R(false) => "r",
            Key::S(false) => "s",
            Key::T(false) => "t",
            Key::U(false) => "u",
            Key::V(false) => "v",
            Key::W(false) => "w",
            Key::X(false) => "x",
            Key::Y(false) => "y",
            Key::Z(false) => "z",
            Key::A(true) => "A",
            Key::B(true) => "B",
            Key::C(true) => "C",
            Key::D(true) => "D",
            Key::E(true) => "E",
            Key::F(true) => "F",
            Key::G(true) => "G",
            Key::H(true) => "H",
            Key::I(true) => "I",
            Key::J(true) => "J",
            Key::K(true) => "K",
            Key::L(true) => "L",
            Key::M(true) => "M",
            Key::N(true) => "N",
            Key::O(true) => "O",
            Key::P(true) => "P",
            Key::Q(true) => "Q",
            Key::R(true) => "R",
            Key::S(true) => "S",
            Key::T(true) => "T",
            Key::U(true) => "U",
            Key::V(true) => "V",
            Key::W(true) => "W",
            Key::X(true) => "X",
            Key::Y(true) => "Y",
            Key::Z(true) => "Z",
            Key::Hash => "#",
            Key::At => "@",
            Key::Zero => "0",
            Key::One => "1",
            Key::Two => "2",
            Key::Three => "3",
            Key::Four => "4",
            Key::Five => "5",
            Key::Six => "6",
            Key::Seven => "7",
            Key::Eight => "8",
            Key::Nine => "9",
            Key::Space => " ",
            Key::Dot => ".",
            Key::QuestionMark => "?",
            Key::ExclamationMark => "!",
            _ => "",
        }
    }
}

impl From<Key> for Option<u8> {
    fn from(key: Key) -> Option<u8> {
        match key {
            Key::A(false) => Some(b'a'),
            Key::B(false) => Some(b'b'),
            Key::C(false) => Some(b'c'),
            Key::D(false) => Some(b'd'),
            Key::E(false) => Some(b'e'),
            Key::F(false) => Some(b'f'),
            Key::G(false) => Some(b'g'),
            Key::H(false) => Some(b'h'),
            Key::I(false) => Some(b'i'),
            Key::J(false) => Some(b'j'),
            Key::K(false) => Some(b'k'),
            Key::L(false) => Some(b'l'),
            Key::M(false) => Some(b'm'),
            Key::N(false) => Some(b'n'),
            Key::O(false) => Some(b'o'),
            Key::P(false) => Some(b'p'),
            Key::Q(false) => Some(b'q'),
            Key::R(false) => Some(b'r'),
            Key::S(false) => Some(b's'),
            Key::T(false) => Some(b't'),
            Key::U(false) => Some(b'u'),
            Key::V(false) => Some(b'v'),
            Key::W(false) => Some(b'w'),
            Key::X(false) => Some(b'x'),
            Key::Y(false) => Some(b'y'),
            Key::Z(false) => Some(b'z'),
            Key::A(true) => Some(b'A'),
            Key::B(true) => Some(b'B'),
            Key::C(true) => Some(b'C'),
            Key::D(true) => Some(b'D'),
            Key::E(true) => Some(b'E'),
            Key::F(true) => Some(b'F'),
            Key::G(true) => Some(b'G'),
            Key::H(true) => Some(b'H'),
            Key::I(true) => Some(b'I'),
            Key::J(true) => Some(b'J'),
            Key::K(true) => Some(b'K'),
            Key::L(true) => Some(b'L'),
            Key::M(true) => Some(b'M'),
            Key::N(true) => Some(b'N'),
            Key::O(true) => Some(b'O'),
            Key::P(true) => Some(b'P'),
            Key::Q(true) => Some(b'Q'),
            Key::R(true) => Some(b'R'),
            Key::S(true) => Some(b'S'),
            Key::T(true) => Some(b'T'),
            Key::U(true) => Some(b'U'),
            Key::V(true) => Some(b'V'),
            Key::W(true) => Some(b'W'),
            Key::X(true) => Some(b'X'),
            Key::Y(true) => Some(b'Y'),
            Key::Z(true) => Some(b'Z'),
            Key::Hash => Some(b'#'),
            Key::At => Some(b'@'),
            Key::Zero => Some(b'0'),
            Key::One => Some(b'1'),
            Key::Two => Some(b'2'),
            Key::Three => Some(b'3'),
            Key::Four => Some(b'4'),
            Key::Five => Some(b'5'),
            Key::Six => Some(b'6'),
            Key::Seven => Some(b'7'),
            Key::Eight => Some(b'8'),
            Key::Nine => Some(b'9'),
            Key::Space => Some(b' '),
            Key::Dot => Some(b'.'),
            Key::QuestionMark => Some(b'?'),
            Key::ExclamationMark => Some(b'!'),
            _ => None,
        }
    }
}

impl ToString for Key {
    fn to_string(&self) -> String {
        <&'static str>::from(*self).to_owned()
    }
}

impl From<char> for Key {
    fn from(sight: char) -> Self {
        match sight {
            'a' => Key::A(false),
            'å' => Key::A(false),
            'b' => Key::B(false),
            'c' => Key::C(false),
            'd' => Key::D(false),
            'e' => Key::E(false),
            'f' => Key::F(false),
            'g' => Key::G(false),
            'h' => Key::H(false),
            'i' => Key::I(false),
            'j' => Key::J(false),
            'k' => Key::K(false),
            'l' => Key::L(false),
            'm' => Key::M(false),
            'n' => Key::N(false),
            'o' => Key::O(false),
            'p' => Key::P(false),
            'q' => Key::Q(false),
            'r' => Key::R(false),
            's' => Key::S(false),
            't' => Key::T(false),
            'u' => Key::U(false),
            'v' => Key::V(false),
            '√' => Key::V(false),
            'w' => Key::W(false),
            'x' => Key::X(false),
            'y' => Key::Y(false),
            'z' => Key::Z(false),
            'A' => Key::A(true),
            'B' => Key::B(true),
            'C' => Key::C(true),
            'D' => Key::D(true),
            'E' => Key::E(true),
            'F' => Key::F(true),
            'G' => Key::G(true),
            'H' => Key::H(true),
            'I' => Key::I(true),
            'J' => Key::J(true),
            'K' => Key::K(true),
            'L' => Key::L(true),
            'M' => Key::M(true),
            'N' => Key::N(true),
            'O' => Key::O(true),
            'P' => Key::P(true),
            'Q' => Key::Q(true),
            'R' => Key::R(true),
            'S' => Key::S(true),
            'T' => Key::T(true),
            'U' => Key::U(true),
            'V' => Key::V(true),
            'W' => Key::W(true),
            'X' => Key::X(true),
            'Y' => Key::Y(true),
            'Z' => Key::Z(true),
            '#' => Key::Hash,
            '@' => Key::At,
            '0' => Key::Zero,
            '1' => Key::One,
            '2' => Key::Two,
            '3' => Key::Three,
            '4' => Key::Four,
            '5' => Key::Five,
            '6' => Key::Six,
            '7' => Key::Seven,
            '8' => Key::Eight,
            '9' => Key::Nine,
            ' ' => Key::Space,
            '.' => Key::Dot,
            '?' => Key::QuestionMark,
            '!' => Key::ExclamationMark,
            '\u{f700}' => Key::Up,
            '\u{f701}' => Key::Down,
            '\u{f702}' => Key::Left,
            '\u{f703}' => Key::Right,
            '\u{8}' => Key::Backspace,
            _ => Key::Unknown,
        }
    }
}

/// Describes a specific mouse button.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum MouseButton {
    Left,
    Middle,
    Right,
}

/// Describes the position / state of a button.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum ButtonState {
    Down,

    Up,
}

/// Represents a mouse event.
#[derive(PartialEq, Clone, Copy, Debug)]
pub struct MouseEvent {
    pub x: f64,

    pub y: f64,

    pub button: MouseButton,

    pub state: ButtonState,
}

/// Represents a keyboard key event.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct KeyEvent {
    pub key: Key,

    pub state: ButtonState,

    pub text: String,
}
<commit_msg>Added numpad /*-+ and enter buttons<commit_after>//! This module contains elements to work with window events.

/// Represents a keyboard key.
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum Key {
    Unknown,
    Backspace,
    Up,
    Down,
    Delete,
    Left,
    Right,
    Space,
    Enter,
    Control,
    ShiftL,
    ShiftR,
    Alt,
    Escape,
    Home,
    CapsLock,
    A(bool),
    B(bool),
    C(bool),
    D(bool),
    E(bool),
    F(bool),
    G(bool),
    H(bool),
    I(bool),
    J(bool),
    K(bool),
    L(bool),
    M(bool),
    N(bool),
    O(bool),
    P(bool),
    Q(bool),
    S(bool),
    R(bool),
    T(bool),
    U(bool),
    V(bool),
    W(bool),
    X(bool),
    Y(bool),
    Z(bool),
    Hash,
    At,
    Zero,
    One,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Dot,
    QuestionMark,
    ExclamationMark,
    NumpadDivide,
    NumpadMultiply,
    NumpadSubtract,
    NumpadAdd,
    NumpadEnter,
}

impl From<Key> for &'static str {
    fn from(key: Key) -> &'static str {
        match key {
            Key::A(false) => "a",
            Key::B(false) => "b",
            Key::C(false) => "c",
            Key::D(false) => "d",
            Key::E(false) => "e",
            Key::F(false) => "f",
            Key::G(false) => "g",
            Key::H(false) => "h",
            Key::I(false) => "i",
            Key::J(false) => "j",
            Key::K(false) => "k",
            Key::L(false) => "l",
            Key::M(false) => "m",
            Key::N(false) => "n",
            Key::O(false) => "o",
            Key::P(false) => "p",
            Key::Q(false) => "q",
            Key::R(false) => "r",
            Key::S(false) => "s",
            Key::T(false) => "t",
            Key::U(false) => "u",
            Key::V(false) => "v",
            Key::W(false) => "w",
            Key::X(false) => "x",
            Key::Y(false) => "y",
            Key::Z(false) => "z",
            Key::A(true) => "A",
            Key::B(true) => "B",
            Key::C(true) => "C",
            Key::D(true) => "D",
            Key::E(true) => "E",
            Key::F(true) => "F",
            Key::G(true) => "G",
            Key::H(true) => "H",
            Key::I(true) => "I",
            Key::J(true) => "J",
            Key::K(true) => "K",
            Key::L(true) => "L",
            Key::M(true) => "M",
            Key::N(true) => "N",
            Key::O(true) => "O",
            Key::P(true) => "P",
            Key::Q(true) => "Q",
            Key::R(true) => "R",
            Key::S(true) => "S",
            Key::T(true) => "T",
            Key::U(true) => "U",
            Key::V(true) => "V",
            Key::W(true) => "W",
            Key::X(true) => "X",
            Key::Y(true) => "Y",
            Key::Z(true) => "Z",
            Key::Hash => "#",
            Key::At => "@",
            Key::Zero => "0",
            Key::One => "1",
            Key::Two => "2",
            Key::Three => "3",
            Key::Four => "4",
            Key::Five => "5",
            Key::Six => "6",
            Key::Seven => "7",
            Key::Eight => "8",
            Key::Nine => "9",
            Key::Space => " ",
            Key::Dot => ".",
            Key::QuestionMark => "?",
            Key::ExclamationMark => "!",
            Key::NumpadDivide => "/",
            Key::NumpadMultiply => "*",
            Key::NumpadSubtract => "-",
            Key::NumpadAdd => "+",
            _ => "",
        }
    }
}

impl From<Key> for Option<u8> {
    fn from(key: Key) -> Option<u8> {
        match key {
            Key::A(false) => Some(b'a'),
            Key::B(false) => Some(b'b'),
            Key::C(false) => Some(b'c'),
            Key::D(false) => Some(b'd'),
            Key::E(false) => Some(b'e'),
            Key::F(false) => Some(b'f'),
            Key::G(false) => Some(b'g'),
            Key::H(false) => Some(b'h'),
            Key::I(false) => Some(b'i'),
            Key::J(false) => Some(b'j'),
            Key::K(false) => Some(b'k'),
            Key::L(false) => Some(b'l'),
            Key::M(false) => Some(b'm'),
            Key::N(false) => Some(b'n'),
            Key::O(false) => Some(b'o'),
            Key::P(false) => Some(b'p'),
            Key::Q(false) => Some(b'q'),
            Key::R(false) => Some(b'r'),
            Key::S(false) => Some(b's'),
            Key::T(false) => Some(b't'),
            Key::U(false) => Some(b'u'),
            Key::V(false) => Some(b'v'),
            Key::W(false) => Some(b'w'),
            Key::X(false) => Some(b'x'),
            Key::Y(false) => Some(b'y'),
            Key::Z(false) => Some(b'z'),
            Key::A(true) => Some(b'A'),
            Key::B(true) => Some(b'B'),
            Key::C(true) => Some(b'C'),
            Key::D(true) => Some(b'D'),
            Key::E(true) => Some(b'E'),
            Key::F(true) => Some(b'F'),
            Key::G(true) => Some(b'G'),
            Key::H(true) => Some(b'H'),
            Key::I(true) => Some(b'I'),
            Key::J(true) => Some(b'J'),
            Key::K(true) => Some(b'K'),
            Key::L(true) => Some(b'L'),
            Key::M(true) => Some(b'M'),
            Key::N(true) => Some(b'N'),
            Key::O(true) => Some(b'O'),
            Key::P(true) => Some(b'P'),
            Key::Q(true) => Some(b'Q'),
            Key::R(true) => Some(b'R'),
            Key::S(true) => Some(b'S'),
            Key::T(true) => Some(b'T'),
            Key::U(true) => Some(b'U'),
            Key::V(true) => Some(b'V'),
            Key::W(true) => Some(b'W'),
            Key::X(true) => Some(b'X'),
            Key::Y(true) => Some(b'Y'),
            Key::Z(true) => Some(b'Z'),
            Key::Hash => Some(b'#'),
            Key::At => Some(b'@'),
            Key::Zero => Some(b'0'),
            Key::One => Some(b'1'),
            Key::Two => Some(b'2'),
            Key::Three => Some(b'3'),
            Key::Four => Some(b'4'),
            Key::Five => Some(b'5'),
            Key::Six => Some(b'6'),
            Key::Seven => Some(b'7'),
            Key::Eight => Some(b'8'),
            Key::Nine => Some(b'9'),
            Key::Space => Some(b' '),
            Key::Dot => Some(b'.'),
            Key::QuestionMark => Some(b'?'),
            Key::ExclamationMark => Some(b'!'),
            Key::NumpadDivide => Some(b'/'),
            Key::NumpadMultiply => Some(b'*'),
            Key::NumpadSubtract => Some(b'-'),
            Key::NumpadAdd => Some(b'+'),
            _ => None,
        }
    }
}

impl ToString for Key {
    fn to_string(&self) -> String {
        <&'static str>::from(*self).to_owned()
    }
}

impl From<char> for Key {
    fn from(sight: char) -> Self {
        match sight {
            'a' => Key::A(false),
            'å' => Key::A(false),
            'b' => Key::B(false),
            'c' => Key::C(false),
            'd' => Key::D(false),
            'e' => Key::E(false),
            'f' => Key::F(false),
            'g' => Key::G(false),
            'h' => Key::H(false),
            'i' => Key::I(false),
            'j' => Key::J(false),
            'k' => Key::K(false),
            'l' => Key::L(false),
            'm' => Key::M(false),
            'n' => Key::N(false),
            'o' => Key::O(false),
            'p' => Key::P(false),
            'q' => Key::Q(false),
            'r' => Key::R(false),
            's' => Key::S(false),
            't' => Key::T(false),
            'u' => Key::U(false),
            'v' => Key::V(false),
            '√' => Key::V(false),
            'w' => Key::W(false),
            'x' => Key::X(false),
            'y' => Key::Y(false),
            'z' => Key::Z(false),
            'A' => Key::A(true),
            'B' => Key::B(true),
            'C' => Key::C(true),
            'D' => Key::D(true),
            'E' => Key::E(true),
            'F' => Key::F(true),
            'G' => Key::G(true),
            'H' => Key::H(true),
            'I' => Key::I(true),
            'J' => Key::J(true),
            'K' => Key::K(true),
            'L' => Key::L(true),
            'M' => Key::M(true),
            'N' => Key::N(true),
            'O' => Key::O(true),
            'P' => Key::P(true),
            'Q' => Key::Q(true),
            'R' => Key::R(true),
            'S' => Key::S(true),
            'T' => Key::T(true),
            'U' => Key::U(true),
            'V' => Key::V(true),
            'W' => Key::W(true),
            'X' => Key::X(true),
            'Y' => Key::Y(true),
            'Z' => Key::Z(true),
            '#' => Key::Hash,
            '@' => Key::At,
            '0' => Key::Zero,
            '1' => Key::One,
            '2' => Key::Two,
            '3' => Key::Three,
            '4' => Key::Four,
            '5' => Key::Five,
            '6' => Key::Six,
            '7' => Key::Seven,
            '8' => Key::Eight,
            '9' => Key::Nine,
            ' ' => Key::Space,
            '.' => Key::Dot,
            '?' => Key::QuestionMark,
            '!' => Key::ExclamationMark,
            '\u{f700}' => Key::Up,
            '\u{f701}' => Key::Down,
            '\u{f702}' => Key::Left,
            '\u{f703}' => Key::Right,
            '\u{8}' => Key::Backspace,
            '/' => Key::NumpadDivide,
            '*' => Key::NumpadMultiply,
            '-' => Key::NumpadSubtract,
            '+' => Key::NumpadAdd,
            _ => Key::Unknown,
        }
    }
}

/// Describes a specific mouse button.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum MouseButton {
    Left,
    Middle,
    Right,
}

/// Describes the position / state of a button.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum ButtonState {
    Down,

    Up,
}

/// Represents a mouse event.
#[derive(PartialEq, Clone, Copy, Debug)]
pub struct MouseEvent {
    pub x: f64,

    pub y: f64,

    pub button: MouseButton,

    pub state: ButtonState,
}

/// Represents a keyboard key event.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct KeyEvent {
    pub key: Key,

    pub state: ButtonState,

    pub text: String,
}
<|endoftext|>


<commit_before>//! Provides various functions and structs for MessagePack encoding.

mod sint;
mod uint;
mod dec;
mod str;
mod bin;
mod vec;
mod map;
mod ext;

pub use self::sint::{write_nfix, write_i8, write_i16, write_i32, write_i64, write_sint};
pub use self::uint::{write_pfix, write_u8, write_u16, write_u32, write_u64, write_uint};
pub use self::dec::{write_f32, write_f64};
pub use self::str::{write_str_len, write_str};
pub use self::bin::{write_bin_len, write_bin};

use std::error;
use std::fmt::{self, Display, Formatter};
use std::io::Write;

use byteorder::{self, WriteBytesExt};

use Marker;

/// The error type for I/O operations of the `Write` and associated traits.
pub type Error = ::std::io::Error;

// An error returned from the `write_marker` and `write_fixval` functions.
struct MarkerWriteError(Error);

impl From<Error> for MarkerWriteError {
    fn from(err: Error) -> MarkerWriteError {
        MarkerWriteError(err)
    }
}

impl From<MarkerWriteError> for Error {
    fn from(err: MarkerWriteError) -> Error {
        err.0
    }
}

/// Attempts to write the given marker into the writer.
fn write_marker<W: Write>(wr: &mut W, marker: Marker) -> Result<(), MarkerWriteError> {
    wr.write_u8(marker.to_u8()).map_err(MarkerWriteError)
}

/// An error returned from primitive values write functions.
struct DataWriteError(Error);

impl From<Error> for DataWriteError {
    fn from(err: Error) -> DataWriteError {
        DataWriteError(err)
    }
}

impl From<DataWriteError> for Error {
    fn from(err: DataWriteError) -> Error {
        err.0
    }
}

/// Encodes and attempts to write a nil value into the given write.
///
/// According to the MessagePack specification, a nil value is represented as a single `0xc0` byte.
///
/// # Errors
///
/// This function will return `Error` on any I/O error occurred while writing the nil marker.
///
/// # Examples
///
/// ```
/// let mut buf = Vec::new();
///
/// rmp::encode::write_nil(&mut buf).unwrap();
///
/// assert_eq!(vec![0xc0], buf);
/// ```
pub fn write_nil<W: Write>(wr: &mut W) -> Result<(), Error> {
    write_marker(wr, Marker::Null).map_err(|err| err.0)
}

/// Encodes and attempts to write a bool value into the given write.
///
/// According to the MessagePack specification, an encoded boolean value is represented as a single
/// byte.
///
/// # Errors
///
/// Each call to this function may generate an I/O error indicating that the operation could not be
/// completed.
pub fn write_bool<W: Write>(wr: &mut W, val: bool) -> Result<(), Error> {
    let marker = if val {
        Marker::True
    } else {
        Marker::False
    };

    write_marker(wr, marker).map_err(From::from)
}

fn write_data_u8<W: Write>(wr: &mut W, val: u8) -> Result<(), DataWriteError> {
    wr.write_u8(val).map_err(DataWriteError)
}

fn write_data_u16<W: Write>(wr: &mut W, val: u16) -> Result<(), DataWriteError> {
    wr.write_u16::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_u32<W: Write>(wr: &mut W, val: u32) -> Result<(), DataWriteError> {
    wr.write_u32::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_u64<W: Write>(wr: &mut W, val: u64) -> Result<(), DataWriteError> {
    wr.write_u64::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_i8<W: Write>(wr: &mut W, val: i8) -> Result<(), DataWriteError> {
    wr.write_i8(val).map_err(DataWriteError)
}

fn write_data_i16<W: Write>(wr: &mut W, val: i16) -> Result<(), DataWriteError> {
    wr.write_i16::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_i32<W: Write>(wr: &mut W, val: i32) -> Result<(), DataWriteError> {
    wr.write_i32::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_i64<W: Write>(wr: &mut W, val: i64) -> Result<(), DataWriteError> {
    wr.write_i64::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_f32<W: Write>(wr: &mut W, val: f32) -> Result<(), DataWriteError> {
    wr.write_f32::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_f64<W: Write>(wr: &mut W, val: f64) -> Result<(), DataWriteError> {
    wr.write_f64::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

/// An error that can occur when attempring to write multibyte MessagePack value.
#[derive(Debug)]
pub enum ValueWriteError {
    /// I/O error while writing marker.
    InvalidMarkerWrite(Error),
    /// I/O error while writing data.
    InvalidDataWrite(Error),
}

impl From<MarkerWriteError> for ValueWriteError {
    fn from(err: MarkerWriteError) -> ValueWriteError {
        match err {
            MarkerWriteError(err) => ValueWriteError::InvalidMarkerWrite(err),
        }
    }
}

impl From<DataWriteError> for ValueWriteError {
    fn from(err: DataWriteError) -> ValueWriteError {
        match err {
            DataWriteError(err) => ValueWriteError::InvalidDataWrite(err),
        }
    }
}

impl From<ValueWriteError> for Error {
    fn from(err: ValueWriteError) -> Error {
        match err {
            ValueWriteError::InvalidMarkerWrite(err) |
            ValueWriteError::InvalidDataWrite(err) => err,
        }
    }
}

impl error::Error for ValueWriteError {
    fn description(&self) -> &str {
        "error while writing multibyte MessagePack value"
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            ValueWriteError::InvalidMarkerWrite(ref err) |
            ValueWriteError::InvalidDataWrite(ref err) => Some(err),
        }
    }
}

impl Display for ValueWriteError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        error::Error::description(self).fmt(f)
    }
}

/// Encodes and attempts to write the most efficient array length implementation to the given write,
/// returning the marker used.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data, except the EINTR, which is handled internally.
pub fn write_array_len<W: Write>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError> {
    let marker = if len < 16 {
        try!(write_marker(wr, Marker::FixArray(len as u8)));
        Marker::FixArray(len as u8)
    } else if len < 65536 {
        try!(write_marker(wr, Marker::Array16));
        try!(write_data_u16(wr, len as u16));
        Marker::Array16
    } else {
        try!(write_marker(wr, Marker::Array32));
        try!(write_data_u32(wr, len));
        Marker::Array32
    };

    Ok(marker)
}

/// Encodes and attempts to write the most efficient map length implementation to the given write,
/// returning the marker used.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data, except the EINTR, which is handled internally.
pub fn write_map_len<W: Write>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError> {
    let marker = if len < 16 {
        try!(write_marker(wr, Marker::FixMap(len as u8)));
        Marker::FixMap(len as u8)
    } else if len < 65536 {
        try!(write_marker(wr, Marker::Map16));
        try!(write_data_u16(wr, len as u16));
        Marker::Map16
    } else {
        try!(write_marker(wr, Marker::Map32));
        try!(write_data_u32(wr, len));
        Marker::Map32
    };

    Ok(marker)
}

/// Encodes and attempts to write the most efficient ext metadata implementation to the given
/// write, returning the marker used.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data, except the EINTR, which is handled internally.
///
/// # Panics
///
/// Panics if `ty` is negative, because it is reserved for future MessagePack extension including
/// 2-byte type information.
pub fn write_ext_meta<W: Write>(wr: &mut W, len: u32, ty: i8) -> Result<Marker, ValueWriteError> {
    assert!(ty >= 0);

    let marker = match len {
        1 => {
            try!(write_marker(wr, Marker::FixExt1));
            Marker::FixExt1
        }
        2 => {
            try!(write_marker(wr, Marker::FixExt2));
            Marker::FixExt2
        }
        4 => {
            try!(write_marker(wr, Marker::FixExt4));
            Marker::FixExt4
        }
        8 => {
            try!(write_marker(wr, Marker::FixExt8));
            Marker::FixExt8
        }
        16 => {
            try!(write_marker(wr, Marker::FixExt16));
            Marker::FixExt16
        }
        len if len < 256 => {
            try!(write_marker(wr, Marker::Ext8));
            try!(write_data_u8(wr, len as u8));
            Marker::Ext8
        }
        len if len < 65536 => {
            try!(write_marker(wr, Marker::Ext16));
            try!(write_data_u16(wr, len as u16));
            Marker::Ext16
        }
        len => {
            try!(write_marker(wr, Marker::Ext32));
            try!(write_data_u32(wr, len));
            Marker::Ext32
        }
    };

    try!(write_data_i8(wr, ty));

    Ok(marker)
}
<commit_msg>refactor: styling<commit_after>//! Provides various functions and structs for MessagePack encoding.

mod sint;
mod uint;
mod dec;
mod str;
mod bin;
mod vec;
mod map;
mod ext;

pub use self::sint::{write_nfix, write_i8, write_i16, write_i32, write_i64, write_sint};
pub use self::uint::{write_pfix, write_u8, write_u16, write_u32, write_u64, write_uint};
pub use self::dec::{write_f32, write_f64};
pub use self::str::{write_str_len, write_str};
pub use self::bin::{write_bin_len, write_bin};

use std::error;
use std::fmt::{self, Display, Formatter};
use std::io::Write;

use byteorder::{self, WriteBytesExt};

use Marker;

/// The error type for I/O operations of the `Write` and associated traits.
pub type Error = ::std::io::Error;

// An error returned from the `write_marker` and `write_fixval` functions.
struct MarkerWriteError(Error);

impl From<Error> for MarkerWriteError {
    fn from(err: Error) -> MarkerWriteError {
        MarkerWriteError(err)
    }
}

impl From<MarkerWriteError> for Error {
    fn from(err: MarkerWriteError) -> Error {
        match err {
            MarkerWriteError(err) => err
        }
    }
}

/// Attempts to write the given marker into the writer.
fn write_marker<W: Write>(wr: &mut W, marker: Marker) -> Result<(), MarkerWriteError> {
    wr.write_u8(marker.to_u8()).map_err(MarkerWriteError)
}

/// An error returned from primitive values write functions.
struct DataWriteError(Error);

impl From<Error> for DataWriteError {
    fn from(err: Error) -> DataWriteError {
        DataWriteError(err)
    }
}

impl From<DataWriteError> for Error {
    fn from(err: DataWriteError) -> Error {
        err.0
    }
}

/// Encodes and attempts to write a nil value into the given write.
///
/// According to the MessagePack specification, a nil value is represented as a single `0xc0` byte.
///
/// # Errors
///
/// This function will return `Error` on any I/O error occurred while writing the nil marker.
///
/// # Examples
///
/// ```
/// let mut buf = Vec::new();
///
/// rmp::encode::write_nil(&mut buf).unwrap();
///
/// assert_eq!(vec![0xc0], buf);
/// ```
pub fn write_nil<W: Write>(wr: &mut W) -> Result<(), Error> {
    write_marker(wr, Marker::Null).map_err(From::from)
}

/// Encodes and attempts to write a bool value into the given write.
///
/// According to the MessagePack specification, an encoded boolean value is represented as a single
/// byte.
///
/// # Errors
///
/// Each call to this function may generate an I/O error indicating that the operation could not be
/// completed.
pub fn write_bool<W: Write>(wr: &mut W, val: bool) -> Result<(), Error> {
    let marker = if val {
        Marker::True
    } else {
        Marker::False
    };

    write_marker(wr, marker).map_err(From::from)
}

fn write_data_u8<W: Write>(wr: &mut W, val: u8) -> Result<(), DataWriteError> {
    wr.write_u8(val).map_err(DataWriteError)
}

fn write_data_u16<W: Write>(wr: &mut W, val: u16) -> Result<(), DataWriteError> {
    wr.write_u16::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_u32<W: Write>(wr: &mut W, val: u32) -> Result<(), DataWriteError> {
    wr.write_u32::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_u64<W: Write>(wr: &mut W, val: u64) -> Result<(), DataWriteError> {
    wr.write_u64::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_i8<W: Write>(wr: &mut W, val: i8) -> Result<(), DataWriteError> {
    wr.write_i8(val).map_err(DataWriteError)
}

fn write_data_i16<W: Write>(wr: &mut W, val: i16) -> Result<(), DataWriteError> {
    wr.write_i16::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_i32<W: Write>(wr: &mut W, val: i32) -> Result<(), DataWriteError> {
    wr.write_i32::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_i64<W: Write>(wr: &mut W, val: i64) -> Result<(), DataWriteError> {
    wr.write_i64::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_f32<W: Write>(wr: &mut W, val: f32) -> Result<(), DataWriteError> {
    wr.write_f32::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

fn write_data_f64<W: Write>(wr: &mut W, val: f64) -> Result<(), DataWriteError> {
    wr.write_f64::<byteorder::BigEndian>(val).map_err(DataWriteError)
}

/// An error that can occur when attempring to write multibyte MessagePack value.
#[derive(Debug)]
pub enum ValueWriteError {
    /// I/O error while writing marker.
    InvalidMarkerWrite(Error),
    /// I/O error while writing data.
    InvalidDataWrite(Error),
}

impl From<MarkerWriteError> for ValueWriteError {
    fn from(err: MarkerWriteError) -> ValueWriteError {
        match err {
            MarkerWriteError(err) => ValueWriteError::InvalidMarkerWrite(err),
        }
    }
}

impl From<DataWriteError> for ValueWriteError {
    fn from(err: DataWriteError) -> ValueWriteError {
        match err {
            DataWriteError(err) => ValueWriteError::InvalidDataWrite(err),
        }
    }
}

impl From<ValueWriteError> for Error {
    fn from(err: ValueWriteError) -> Error {
        match err {
            ValueWriteError::InvalidMarkerWrite(err) |
            ValueWriteError::InvalidDataWrite(err) => err,
        }
    }
}

impl error::Error for ValueWriteError {
    fn description(&self) -> &str {
        "error while writing multibyte MessagePack value"
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            ValueWriteError::InvalidMarkerWrite(ref err) |
            ValueWriteError::InvalidDataWrite(ref err) => Some(err),
        }
    }
}

impl Display for ValueWriteError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        error::Error::description(self).fmt(f)
    }
}

/// Encodes and attempts to write the most efficient array length implementation to the given write,
/// returning the marker used.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data, except the EINTR, which is handled internally.
pub fn write_array_len<W: Write>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError> {
    let marker = if len < 16 {
        try!(write_marker(wr, Marker::FixArray(len as u8)));
        Marker::FixArray(len as u8)
    } else if len < 65536 {
        try!(write_marker(wr, Marker::Array16));
        try!(write_data_u16(wr, len as u16));
        Marker::Array16
    } else {
        try!(write_marker(wr, Marker::Array32));
        try!(write_data_u32(wr, len));
        Marker::Array32
    };

    Ok(marker)
}

/// Encodes and attempts to write the most efficient map length implementation to the given write,
/// returning the marker used.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data, except the EINTR, which is handled internally.
pub fn write_map_len<W: Write>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError> {
    let marker = if len < 16 {
        try!(write_marker(wr, Marker::FixMap(len as u8)));
        Marker::FixMap(len as u8)
    } else if len < 65536 {
        try!(write_marker(wr, Marker::Map16));
        try!(write_data_u16(wr, len as u16));
        Marker::Map16
    } else {
        try!(write_marker(wr, Marker::Map32));
        try!(write_data_u32(wr, len));
        Marker::Map32
    };

    Ok(marker)
}

/// Encodes and attempts to write the most efficient ext metadata implementation to the given
/// write, returning the marker used.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data, except the EINTR, which is handled internally.
///
/// # Panics
///
/// Panics if `ty` is negative, because it is reserved for future MessagePack extension including
/// 2-byte type information.
pub fn write_ext_meta<W: Write>(wr: &mut W, len: u32, ty: i8) -> Result<Marker, ValueWriteError> {
    assert!(ty >= 0);

    let marker = match len {
        1 => {
            try!(write_marker(wr, Marker::FixExt1));
            Marker::FixExt1
        }
        2 => {
            try!(write_marker(wr, Marker::FixExt2));
            Marker::FixExt2
        }
        4 => {
            try!(write_marker(wr, Marker::FixExt4));
            Marker::FixExt4
        }
        8 => {
            try!(write_marker(wr, Marker::FixExt8));
            Marker::FixExt8
        }
        16 => {
            try!(write_marker(wr, Marker::FixExt16));
            Marker::FixExt16
        }
        len if len < 256 => {
            try!(write_marker(wr, Marker::Ext8));
            try!(write_data_u8(wr, len as u8));
            Marker::Ext8
        }
        len if len < 65536 => {
            try!(write_marker(wr, Marker::Ext16));
            try!(write_data_u16(wr, len as u16));
            Marker::Ext16
        }
        len => {
            try!(write_marker(wr, Marker::Ext32));
            try!(write_data_u32(wr, len));
            Marker::Ext32
        }
    };

    try!(write_data_i8(wr, ty));

    Ok(marker)
}
<|endoftext|>


<commit_before>extern crate proc_macro;
use self::proc_macro::TokenStream;

use quote::{quote, ToTokens};
use std::collections::HashSet as Set;
use syn::fold::{self, Fold};
use syn::parse::{Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
use syn::{parse_macro_input, parse_quote, Expr, Ident, ItemFn, Local, Pat, Stmt, Token};

/// Parses a list of variable names separated by commas.
///
///     a, b, c
///
/// This is how the compiler passes in arguments to our attribute -- it is
/// everything inside the delimiters after the attribute name.
///
///     #[trace_var(a, b, c)]
///                 ^^^^^^^
struct Args {
    vars: Set<Ident>,
}

impl Parse for Args {
    fn parse(input: ParseStream) -> Result<Self> {
        let vars = Punctuated::<Ident, Token![,]>::parse_terminated(input)?;
        Ok(Args {
            vars: vars.into_iter().collect(),
        })
    }
}

impl Args {
    /// Determines whether the given `Expr` is a path referring to one of the
    /// variables we intend to print. Expressions are used as the left-hand side
    /// of the assignment operator.
    fn should_print_expr(&self, e: &Expr) -> bool {
        match *e {
            Expr::Path(ref e) => {
                if e.path.leading_colon.is_some() {
                    false
                } else if e.path.segments.len() != 1 {
                    false
                } else {
                    let first = e.path.segments.first().unwrap();
                    let segment = first.value();
                    self.vars.contains(&segment.ident) && segment.arguments.is_empty()
                }
            }
            _ => false,
        }
    }

    /// Determines whether the given `Pat` is an identifier equal to one of the
    /// variables we intend to print. Patterns are used as the left-hand side of
    /// a `let` binding.
    fn should_print_pat(&self, p: &Punctuated<Pat, Token![|]>) -> bool {
        if p.len() != 1 {
            return false;
        }
        match p[0] {
            Pat::Ident(ref p) => self.vars.contains(&p.ident),
            _ => false,
        }
    }

    /// Produces an expression that assigns the right-hand side to the left-hand
    /// side and then prints the value.
    ///
    ///     // Before
    ///     VAR = INIT
    ///
    ///     // After
    ///     { VAR = INIT; println!("VAR = {:?}", VAR); }
    fn assign_and_print(&mut self, left: Expr, op: &ToTokens, right: Expr) -> Expr {
        let right = fold::fold_expr(self, right);
        parse_quote!({
            #left #op #right;
            println!(concat!(stringify!(#left), " = {:?}"), #left);
        })
    }

    /// Produces a let-binding that assigns the right-hand side to the left-hand
    /// side and then prints the value.
    ///
    ///     // Before
    ///     let VAR = INIT;
    ///
    ///     // After
    ///     let VAR = { let VAR = INIT; println!("VAR = {:?}", VAR); VAR };
    fn let_and_print(&mut self, local: Local) -> Stmt {
        let Local { pats, ty, init, .. } = local;
        let pat = &pats[0];
        let ty = ty.map(|(colon_token, ty)| quote!(#colon_token #ty));
        let init = self.fold_expr(*init.unwrap().1);
        let ident = match *pat {
            Pat::Ident(ref p) => &p.ident,
            _ => unreachable!(),
        };
        parse_quote! {
            let #pat #ty = {
                let #pat = #init;
                println!(concat!(stringify!(#ident), " = {:?}"), #ident);
                #ident
            };
        }
    }
}

/// The `Fold` trait is a way to traverse an owned syntax tree and replace some
/// of its nodes.
///
/// Syn provides two other syntax tree traversal traits: `Visit` which walks a
/// shared borrow of a syntax tree, and `VisitMut` which walks an exclusive
/// borrow of a syntax tree and can mutate it in place.
///
/// All three traits have a method corresponding to each type of node in Syn's
/// syntax tree. All of these methods have default no-op implementations that
/// simply recurse on any child nodes. We can override only those methods for
/// which we want non-default behavior. In this case the traversal needs to
/// transform `Expr` and `Stmt` nodes.
impl Fold for Args {
    fn fold_expr(&mut self, e: Expr) -> Expr {
        match e {
            Expr::Assign(e) => {
                if self.should_print_expr(&e.left) {
                    self.assign_and_print(*e.left, &e.eq_token, *e.right)
                } else {
                    Expr::Assign(fold::fold_expr_assign(self, e))
                }
            }
            Expr::AssignOp(e) => {
                if self.should_print_expr(&e.left) {
                    self.assign_and_print(*e.left, &e.op, *e.right)
                } else {
                    Expr::AssignOp(fold::fold_expr_assign_op(self, e))
                }
            }
            _ => fold::fold_expr(self, e),
        }
    }

    fn fold_stmt(&mut self, s: Stmt) -> Stmt {
        match s {
            Stmt::Local(s) => {
                if s.init.is_some() && self.should_print_pat(&s.pats) {
                    self.let_and_print(s)
                } else {
                    Stmt::Local(fold::fold_local(self, s))
                }
            }
            _ => fold::fold_stmt(self, s),
        }
    }
}

/// Attribute to print the value of the given variables each time they are
/// reassigned.
///
/// # Example
///
/// ```
/// #[trace_var(p, n)]
/// fn factorial(mut n: u64) -> u64 {
///     let mut p = 1;
///     while n > 1 {
///         p *= n;
///         n -= 1;
///     }
///     p
/// }
/// ```
#[proc_macro_attribute]
pub fn trace_var(args: TokenStream, input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as ItemFn);

    // Parse the list of variables the user wanted to print.
    let mut args = parse_macro_input!(args as Args);

    // Use a syntax tree traversal to transform the function body.
    let output = args.fold_item_fn(input);

    // Hand the resulting function body back to the compiler.
    TokenStream::from(quote!(#output))
}
<commit_msg>Work around mut warning in trace-var<commit_after>extern crate proc_macro;
use self::proc_macro::TokenStream;

use quote::{quote, ToTokens};
use std::collections::HashSet as Set;
use syn::fold::{self, Fold};
use syn::parse::{Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
use syn::{parse_macro_input, parse_quote, Expr, Ident, ItemFn, Local, Pat, Stmt, Token};

/// Parses a list of variable names separated by commas.
///
///     a, b, c
///
/// This is how the compiler passes in arguments to our attribute -- it is
/// everything inside the delimiters after the attribute name.
///
///     #[trace_var(a, b, c)]
///                 ^^^^^^^
struct Args {
    vars: Set<Ident>,
}

impl Parse for Args {
    fn parse(input: ParseStream) -> Result<Self> {
        let vars = Punctuated::<Ident, Token![,]>::parse_terminated(input)?;
        Ok(Args {
            vars: vars.into_iter().collect(),
        })
    }
}

impl Args {
    /// Determines whether the given `Expr` is a path referring to one of the
    /// variables we intend to print. Expressions are used as the left-hand side
    /// of the assignment operator.
    fn should_print_expr(&self, e: &Expr) -> bool {
        match *e {
            Expr::Path(ref e) => {
                if e.path.leading_colon.is_some() {
                    false
                } else if e.path.segments.len() != 1 {
                    false
                } else {
                    let first = e.path.segments.first().unwrap();
                    let segment = first.value();
                    self.vars.contains(&segment.ident) && segment.arguments.is_empty()
                }
            }
            _ => false,
        }
    }

    /// Determines whether the given `Pat` is an identifier equal to one of the
    /// variables we intend to print. Patterns are used as the left-hand side of
    /// a `let` binding.
    fn should_print_pat(&self, p: &Punctuated<Pat, Token![|]>) -> bool {
        if p.len() != 1 {
            return false;
        }
        match p[0] {
            Pat::Ident(ref p) => self.vars.contains(&p.ident),
            _ => false,
        }
    }

    /// Produces an expression that assigns the right-hand side to the left-hand
    /// side and then prints the value.
    ///
    ///     // Before
    ///     VAR = INIT
    ///
    ///     // After
    ///     { VAR = INIT; println!("VAR = {:?}", VAR); }
    fn assign_and_print(&mut self, left: Expr, op: &ToTokens, right: Expr) -> Expr {
        let right = fold::fold_expr(self, right);
        parse_quote!({
            #left #op #right;
            println!(concat!(stringify!(#left), " = {:?}"), #left);
        })
    }

    /// Produces a let-binding that assigns the right-hand side to the left-hand
    /// side and then prints the value.
    ///
    ///     // Before
    ///     let VAR = INIT;
    ///
    ///     // After
    ///     let VAR = { let VAR = INIT; println!("VAR = {:?}", VAR); VAR };
    fn let_and_print(&mut self, local: Local) -> Stmt {
        let Local { pats, ty, init, .. } = local;
        let pat = &pats[0];
        let ty = ty.map(|(colon_token, ty)| quote!(#colon_token #ty));
        let init = self.fold_expr(*init.unwrap().1);
        let ident = match *pat {
            Pat::Ident(ref p) => &p.ident,
            _ => unreachable!(),
        };
        parse_quote! {
            let #pat #ty = {
                #[allow(unused_mut)]
                let #pat = #init;
                println!(concat!(stringify!(#ident), " = {:?}"), #ident);
                #ident
            };
        }
    }
}

/// The `Fold` trait is a way to traverse an owned syntax tree and replace some
/// of its nodes.
///
/// Syn provides two other syntax tree traversal traits: `Visit` which walks a
/// shared borrow of a syntax tree, and `VisitMut` which walks an exclusive
/// borrow of a syntax tree and can mutate it in place.
///
/// All three traits have a method corresponding to each type of node in Syn's
/// syntax tree. All of these methods have default no-op implementations that
/// simply recurse on any child nodes. We can override only those methods for
/// which we want non-default behavior. In this case the traversal needs to
/// transform `Expr` and `Stmt` nodes.
impl Fold for Args {
    fn fold_expr(&mut self, e: Expr) -> Expr {
        match e {
            Expr::Assign(e) => {
                if self.should_print_expr(&e.left) {
                    self.assign_and_print(*e.left, &e.eq_token, *e.right)
                } else {
                    Expr::Assign(fold::fold_expr_assign(self, e))
                }
            }
            Expr::AssignOp(e) => {
                if self.should_print_expr(&e.left) {
                    self.assign_and_print(*e.left, &e.op, *e.right)
                } else {
                    Expr::AssignOp(fold::fold_expr_assign_op(self, e))
                }
            }
            _ => fold::fold_expr(self, e),
        }
    }

    fn fold_stmt(&mut self, s: Stmt) -> Stmt {
        match s {
            Stmt::Local(s) => {
                if s.init.is_some() && self.should_print_pat(&s.pats) {
                    self.let_and_print(s)
                } else {
                    Stmt::Local(fold::fold_local(self, s))
                }
            }
            _ => fold::fold_stmt(self, s),
        }
    }
}

/// Attribute to print the value of the given variables each time they are
/// reassigned.
///
/// # Example
///
/// ```
/// #[trace_var(p, n)]
/// fn factorial(mut n: u64) -> u64 {
///     let mut p = 1;
///     while n > 1 {
///         p *= n;
///         n -= 1;
///     }
///     p
/// }
/// ```
#[proc_macro_attribute]
pub fn trace_var(args: TokenStream, input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as ItemFn);

    // Parse the list of variables the user wanted to print.
    let mut args = parse_macro_input!(args as Args);

    // Use a syntax tree traversal to transform the function body.
    let output = args.fold_item_fn(input);

    // Hand the resulting function body back to the compiler.
    TokenStream::from(quote!(#output))
}
<|endoftext|>