<commit_before>use std::fmt;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;

#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
use crate::body::Body;
#[cfg(feature = "server")]
use crate::body::HttpBody;
#[cfg(all(feature = "http2", feature = "server"))]
use crate::proto::h2::server::H2Stream;
use crate::rt::Executor;
#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
use crate::server::server::{Watcher, new_svc::NewSvcTask};
#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
use crate::service::HttpService;

#[cfg(feature = "server")]
pub trait ConnStreamExec<F, B: HttpBody>: Clone {
    fn execute_h2stream(&mut self, fut: H2Stream<F, B>);
}

#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
pub trait NewSvcExec<I, N, S: HttpService<Body>, E, W: Watcher<I, S, E>>: Clone {
    fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>);
}

pub(crate) type BoxSendFuture = Pin<Box<dyn Future<Output = ()> + Send>>;

// Either the user provides an executor for background tasks, or we use
// `tokio::spawn`.
#[derive(Clone)]
pub enum Exec {
    Default,
    Executor(Arc<dyn Executor<BoxSendFuture> + Send + Sync>),
}

// ===== impl Exec =====

impl Exec {
    pub(crate) fn execute<F>(&self, fut: F)
    where
        F: Future<Output = ()> + Send + 'static,
    {
        match *self {
            Exec::Default => {
                #[cfg(feature = "tcp")]
                {
                    tokio::task::spawn(fut);
                }
                #[cfg(not(feature = "tcp"))]
                {
                    // If no runtime, we need an executor!
                    panic!("executor must be set")
                }
            }
            Exec::Executor(ref e) => {
                e.execute(Box::pin(fut));
            }
        }
    }
}

impl fmt::Debug for Exec {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Exec").finish()
    }
}

#[cfg(feature = "server")]
impl<F, B> ConnStreamExec<F, B> for Exec
where
    H2Stream<F, B>: Future<Output = ()> + Send + 'static,
    B: HttpBody,
{
    fn execute_h2stream(&mut self, fut: H2Stream<F, B>) {
        self.execute(fut)
    }
}

#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for Exec
where
    NewSvcTask<I, N, S, E, W>: Future<Output = ()> + Send + 'static,
    S: HttpService<Body>,
    W: Watcher<I, S, E>,
{
    fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) {
        self.execute(fut)
    }
}

// ==== impl Executor =====

#[cfg(feature = "server")]
impl<E, F, B> ConnStreamExec<F, B> for E
where
    E: Executor<H2Stream<F, B>> + Clone,
    H2Stream<F, B>: Future<Output = ()>,
    B: HttpBody,
{
    fn execute_h2stream(&mut self, fut: H2Stream<F, B>) {
        self.execute(fut)
    }
}

#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for E
where
    E: Executor<NewSvcTask<I, N, S, E, W>> + Clone,
    NewSvcTask<I, N, S, E, W>: Future<Output = ()>,
    S: HttpService<Body>,
    W: Watcher<I, S, E>,
{
    fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) {
        self.execute(fut)
    }
}

// If http2 is not enable, we just have a stub here, so that the trait bounds
// that *would* have been needed are still checked. Why?
//
// Because enabling `http2` shouldn't suddenly add new trait bounds that cause
// a compilation error.
#[cfg(not(feature = "http2"))]
#[allow(missing_debug_implementations)]
pub struct H2Stream<F, B>(std::marker::PhantomData<(F, B)>);

#[cfg(not(feature = "http2"))]
impl<F, B, E> Future for H2Stream<F, B>
where
    F: Future<Output = Result<http::Response<B>, E>>,
    B: crate::body::HttpBody,
    B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
    E: Into<Box<dyn std::error::Error + Send + Sync>>,
{
    type Output = ();

    fn poll(
        self: Pin<&mut Self>,
        _cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Self::Output> {
        unreachable!()
    }
}
<commit_msg>style(server): rustfmt<commit_after>use std::fmt;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;

#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
use crate::body::Body;
#[cfg(feature = "server")]
use crate::body::HttpBody;
#[cfg(all(feature = "http2", feature = "server"))]
use crate::proto::h2::server::H2Stream;
use crate::rt::Executor;
#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
use crate::server::server::{new_svc::NewSvcTask, Watcher};
#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
use crate::service::HttpService;

#[cfg(feature = "server")]
pub trait ConnStreamExec<F, B: HttpBody>: Clone {
    fn execute_h2stream(&mut self, fut: H2Stream<F, B>);
}

#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
pub trait NewSvcExec<I, N, S: HttpService<Body>, E, W: Watcher<I, S, E>>: Clone {
    fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>);
}

pub(crate) type BoxSendFuture = Pin<Box<dyn Future<Output = ()> + Send>>;

// Either the user provides an executor for background tasks, or we use
// `tokio::spawn`.
#[derive(Clone)]
pub enum Exec {
    Default,
    Executor(Arc<dyn Executor<BoxSendFuture> + Send + Sync>),
}

// ===== impl Exec =====

impl Exec {
    pub(crate) fn execute<F>(&self, fut: F)
    where
        F: Future<Output = ()> + Send + 'static,
    {
        match *self {
            Exec::Default => {
                #[cfg(feature = "tcp")]
                {
                    tokio::task::spawn(fut);
                }
                #[cfg(not(feature = "tcp"))]
                {
                    // If no runtime, we need an executor!
                    panic!("executor must be set")
                }
            }
            Exec::Executor(ref e) => {
                e.execute(Box::pin(fut));
            }
        }
    }
}

impl fmt::Debug for Exec {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Exec").finish()
    }
}

#[cfg(feature = "server")]
impl<F, B> ConnStreamExec<F, B> for Exec
where
    H2Stream<F, B>: Future<Output = ()> + Send + 'static,
    B: HttpBody,
{
    fn execute_h2stream(&mut self, fut: H2Stream<F, B>) {
        self.execute(fut)
    }
}

#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for Exec
where
    NewSvcTask<I, N, S, E, W>: Future<Output = ()> + Send + 'static,
    S: HttpService<Body>,
    W: Watcher<I, S, E>,
{
    fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) {
        self.execute(fut)
    }
}

// ==== impl Executor =====

#[cfg(feature = "server")]
impl<E, F, B> ConnStreamExec<F, B> for E
where
    E: Executor<H2Stream<F, B>> + Clone,
    H2Stream<F, B>: Future<Output = ()>,
    B: HttpBody,
{
    fn execute_h2stream(&mut self, fut: H2Stream<F, B>) {
        self.execute(fut)
    }
}

#[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))]
impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for E
where
    E: Executor<NewSvcTask<I, N, S, E, W>> + Clone,
    NewSvcTask<I, N, S, E, W>: Future<Output = ()>,
    S: HttpService<Body>,
    W: Watcher<I, S, E>,
{
    fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) {
        self.execute(fut)
    }
}

// If http2 is not enable, we just have a stub here, so that the trait bounds
// that *would* have been needed are still checked. Why?
//
// Because enabling `http2` shouldn't suddenly add new trait bounds that cause
// a compilation error.
#[cfg(not(feature = "http2"))]
#[allow(missing_debug_implementations)]
pub struct H2Stream<F, B>(std::marker::PhantomData<(F, B)>);

#[cfg(not(feature = "http2"))]
impl<F, B, E> Future for H2Stream<F, B>
where
    F: Future<Output = Result<http::Response<B>, E>>,
    B: crate::body::HttpBody,
    B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
    E: Into<Box<dyn std::error::Error + Send + Sync>>,
{
    type Output = ();

    fn poll(
        self: Pin<&mut Self>,
        _cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Self::Output> {
        unreachable!()
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::marker::PhantomData;
use std::collections::HashMap;
use std::any::Any;
use std::sync::{Arc, Mutex};
use std::fs;
use std::io::{BufWriter, Write, BufRead, BufReader};
use log;

use ui;
use render;
use format::{Component, TextComponent, Color};

pub struct CVar<T: Sized + Any + 'static> {
	pub name: &'static str,
	pub ty: PhantomData<T>,
	pub description: &'static str,
	pub mutable: bool,
	pub serializable: bool,
	pub default: &'static Fn() -> T,
}

impl Var for CVar<String> {
	fn serialize(&self, val: &Box<Any>) -> String {
		format!("\"{}\"", val.downcast_ref::<String>().unwrap())
	}

	fn deserialize(&self, input: &String) -> Box<Any> {
		Box::new((&input[1..input.len() - 1]).to_owned())
	}

	fn description(&self) -> &'static str { self.description }
	fn can_serialize(&self) -> bool { self.serializable }
}

pub trait Var {
	fn serialize(&self, val: &Box<Any>) -> String;
	fn deserialize(&self, input: &String) -> Box<Any>;
	fn description(&self) -> &'static str;
	fn can_serialize(&self) -> bool;
}

pub struct Console {
	names: HashMap<String, &'static str>,
	vars: HashMap<&'static str, Box<Var>>,
	var_values: HashMap<&'static str, Box<Any>>,

	history: Vec<Component>,

	collection: ui::Collection,
	active: bool,
	position: f64,
}

impl Console {
	pub fn new() -> Console {
		let mut con = Console {
			names: HashMap::new(),
			vars: HashMap::new(),
			var_values: HashMap::new(),

			history: Vec::with_capacity(200),

			collection: ui::Collection::new(),
			active: false,
			position: -220.0,
		};
		for _ in 0 .. 200 {
			con.history.push(Component::Text(
				TextComponent::new("")
			));
		}
		con
	}

	pub fn register<T: Sized + Any>(&mut self, var: CVar<T>) where CVar<T> : Var {
		if self.vars.contains_key(var.name) {
			panic!("Key registered twice {}", var.name);
		}
		self.names.insert(var.name.to_owned(), var.name);
		self.var_values.insert(var.name, Box::new((var.default)()));
		self.vars.insert(var.name, Box::new(var));
	}

	pub fn get<T: Sized + Any>(&self, var: CVar<T>) -> &T where CVar<T> : Var {
		// Should never fail
		self.var_values.get(var.name).unwrap().downcast_ref::<T>().unwrap()
	}

	pub fn set<T: Sized + Any>(&mut self, var: CVar<T>, val: T) where CVar<T> : Var {
		self.var_values.insert(var.name, Box::new(val));
		self.save_config();
	}

	pub fn is_active(&self) -> bool {
		self.active
	}

	pub fn toggle(&mut self) {
		self.active = !self.active;
	}

	pub fn tick(&mut self, ui_container: &mut ui::Container, renderer: &mut render::Renderer, delta: f64, width: f64) {
		// To make sure the console is always on top it constant removes and readds itself.
		// Its hacky but the console should never appear for normal users so its not really
		// a major issue.
		self.collection.remove_all(ui_container);
		if !self.active && self.position <= -220.0 {
			return;
		}
		if self.active {
			if self.position < 0.0 {
				self.position += delta * 4.0;
			} else {
				self.position = 0.0;
			}
		} else {
			if self.position > -220.0 {
				self.position -= delta * 4.0;
			} else {
				self.position = -220.0;
			}
		}
		let w = match ui_container.mode {
			ui::Mode::Scaled => width,
			ui::Mode::Unscaled(scale) => 854.0 / scale,
		};

		let mut background = ui::Image::new(
			render::Renderer::get_texture(renderer.get_textures_ref(), "steven:solid"),
			0.0, self.position, w, 220.0,
			0.0, 0.0, 1.0, 1.0,
			0, 0, 0
		);
		background.set_a(180);
		let background = self.collection.add(ui_container.add(background));

		let mut lines = Vec::new();
		let mut offset = 0.0;
		for line in self.history.iter().rev() {
			if offset >= 210.0 {
				break;
			}
			let mut fmt = ui::Formatted::with_width_limit(renderer, line.clone(), 5.0, 5.0 + offset, w - 1.0);
			fmt.set_parent(&background);
			fmt.set_v_attach(ui::VAttach::Bottom);
			offset += fmt.get_height();
			lines.push(ui_container.add(fmt));
		}
		for fmt in lines {
			self.collection.add(fmt);
		}
	}

	pub fn load_config(&mut self) {
		if let Ok(file) = fs::File::open("conf.cfg") {
			let reader = BufReader::new(file);
			for line in reader.lines() {
				let line = line.unwrap();
				if line.starts_with("#") || line.is_empty() {
					continue;
				}
				let parts = line.splitn(2, ' ').map(|v| v.to_owned()).collect::<Vec<String>>();
				let (name, arg) = (&parts[0], &parts[1]);
				if let Some(var_name) = self.names.get(name) {
					let var = self.vars.get(var_name).unwrap();
					let val = var.deserialize(&arg);
					if var.can_serialize() {
						self.var_values.insert(var_name, val);
					}
				} else {
					println!("Missing prop");
				}
			}
		}
	}

	pub fn save_config(&self) {
    	let mut file = BufWriter::new(fs::File::create("conf.cfg").unwrap());
    	for (name, var) in &self.vars {
    		if !var.can_serialize() {
    			continue;
    		}
    		for line in var.description().lines() {
    			write!(file, "# {}\n", line).unwrap();
    		}
    		write!(file, "{} {}\n\n", name, var.serialize(self.var_values.get(name).unwrap())).unwrap();
    	}
	}

	fn log(&mut self, record: &log::LogRecord) {
		let mut file = record.location().file();
		if let Some(pos) = file.rfind("src/") {
			file = &file[pos + 4..];
		}
		println!("[{}:{}][{}] {}", file, record.location().line(), record.level(), record.args());
		self.history.remove(0);
		let mut msg = TextComponent::new("");
		msg.modifier.extra = Some(vec![
			Component::Text(TextComponent::new("[")),
			{
				let mut msg = TextComponent::new(file);
				msg.modifier.color = Some(Color::Green);
				Component::Text(msg)
			},
			Component::Text(TextComponent::new(":")),
			{
				let mut msg = TextComponent::new(&format!("{}", record.location().line()));
				msg.modifier.color = Some(Color::Aqua);
				Component::Text(msg)
			},
			Component::Text(TextComponent::new("]")),
			Component::Text(TextComponent::new("[")),
			{
				let mut msg = TextComponent::new(&format!("{}", record.level()));
				msg.modifier.color = Some(match record.level() {
					log::LogLevel::Debug => Color::Green,
					log::LogLevel::Error => Color::Red,
					log::LogLevel::Warn => Color::Yellow,
					log::LogLevel::Info => Color::Aqua,
					log::LogLevel::Trace => Color::Blue,
				});
				Component::Text(msg)
			},
			Component::Text(TextComponent::new("] ")),
			Component::Text(TextComponent::new(&format!("{}", record.args())))
		]);
		self.history.push(Component::Text(
			msg
		));
	}
}

pub struct ConsoleProxy {
	console: Arc<Mutex<Console>>,
}

impl ConsoleProxy {
	pub fn new(con: Arc<Mutex<Console>>) -> ConsoleProxy {
		ConsoleProxy {
			console: con,
		}
	}
}

impl log::Log for ConsoleProxy {
	fn enabled(&self, metadata: &log::LogMetadata) -> bool {
		metadata.level() <= log::LogLevel::Trace
	}

	fn log(&self, record: &log::LogRecord) {
		if self.enabled(record.metadata()) {
			self.console.lock().unwrap().log(record);
		}
	}
}

unsafe impl Send for ConsoleProxy {}
unsafe impl Sync for ConsoleProxy {}
<commit_msg>Fix logging the file name on windows<commit_after>// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::marker::PhantomData;
use std::collections::HashMap;
use std::any::Any;
use std::sync::{Arc, Mutex};
use std::fs;
use std::io::{BufWriter, Write, BufRead, BufReader};
use log;

use ui;
use render;
use format::{Component, TextComponent, Color};

pub struct CVar<T: Sized + Any + 'static> {
	pub name: &'static str,
	pub ty: PhantomData<T>,
	pub description: &'static str,
	pub mutable: bool,
	pub serializable: bool,
	pub default: &'static Fn() -> T,
}

impl Var for CVar<String> {
	fn serialize(&self, val: &Box<Any>) -> String {
		format!("\"{}\"", val.downcast_ref::<String>().unwrap())
	}

	fn deserialize(&self, input: &String) -> Box<Any> {
		Box::new((&input[1..input.len() - 1]).to_owned())
	}

	fn description(&self) -> &'static str { self.description }
	fn can_serialize(&self) -> bool { self.serializable }
}

pub trait Var {
	fn serialize(&self, val: &Box<Any>) -> String;
	fn deserialize(&self, input: &String) -> Box<Any>;
	fn description(&self) -> &'static str;
	fn can_serialize(&self) -> bool;
}

pub struct Console {
	names: HashMap<String, &'static str>,
	vars: HashMap<&'static str, Box<Var>>,
	var_values: HashMap<&'static str, Box<Any>>,

	history: Vec<Component>,

	collection: ui::Collection,
	active: bool,
	position: f64,
}

impl Console {
	pub fn new() -> Console {
		let mut con = Console {
			names: HashMap::new(),
			vars: HashMap::new(),
			var_values: HashMap::new(),

			history: Vec::with_capacity(200),

			collection: ui::Collection::new(),
			active: false,
			position: -220.0,
		};
		for _ in 0 .. 200 {
			con.history.push(Component::Text(
				TextComponent::new("")
			));
		}
		con
	}

	pub fn register<T: Sized + Any>(&mut self, var: CVar<T>) where CVar<T> : Var {
		if self.vars.contains_key(var.name) {
			panic!("Key registered twice {}", var.name);
		}
		self.names.insert(var.name.to_owned(), var.name);
		self.var_values.insert(var.name, Box::new((var.default)()));
		self.vars.insert(var.name, Box::new(var));
	}

	pub fn get<T: Sized + Any>(&self, var: CVar<T>) -> &T where CVar<T> : Var {
		// Should never fail
		self.var_values.get(var.name).unwrap().downcast_ref::<T>().unwrap()
	}

	pub fn set<T: Sized + Any>(&mut self, var: CVar<T>, val: T) where CVar<T> : Var {
		self.var_values.insert(var.name, Box::new(val));
		self.save_config();
	}

	pub fn is_active(&self) -> bool {
		self.active
	}

	pub fn toggle(&mut self) {
		self.active = !self.active;
	}

	pub fn tick(&mut self, ui_container: &mut ui::Container, renderer: &mut render::Renderer, delta: f64, width: f64) {
		// To make sure the console is always on top it constant removes and readds itself.
		// Its hacky but the console should never appear for normal users so its not really
		// a major issue.
		self.collection.remove_all(ui_container);
		if !self.active && self.position <= -220.0 {
			return;
		}
		if self.active {
			if self.position < 0.0 {
				self.position += delta * 4.0;
			} else {
				self.position = 0.0;
			}
		} else {
			if self.position > -220.0 {
				self.position -= delta * 4.0;
			} else {
				self.position = -220.0;
			}
		}
		let w = match ui_container.mode {
			ui::Mode::Scaled => width,
			ui::Mode::Unscaled(scale) => 854.0 / scale,
		};

		let mut background = ui::Image::new(
			render::Renderer::get_texture(renderer.get_textures_ref(), "steven:solid"),
			0.0, self.position, w, 220.0,
			0.0, 0.0, 1.0, 1.0,
			0, 0, 0
		);
		background.set_a(180);
		let background = self.collection.add(ui_container.add(background));

		let mut lines = Vec::new();
		let mut offset = 0.0;
		for line in self.history.iter().rev() {
			if offset >= 210.0 {
				break;
			}
			let mut fmt = ui::Formatted::with_width_limit(renderer, line.clone(), 5.0, 5.0 + offset, w - 1.0);
			fmt.set_parent(&background);
			fmt.set_v_attach(ui::VAttach::Bottom);
			offset += fmt.get_height();
			lines.push(ui_container.add(fmt));
		}
		for fmt in lines {
			self.collection.add(fmt);
		}
	}

	pub fn load_config(&mut self) {
		if let Ok(file) = fs::File::open("conf.cfg") {
			let reader = BufReader::new(file);
			for line in reader.lines() {
				let line = line.unwrap();
				if line.starts_with("#") || line.is_empty() {
					continue;
				}
				let parts = line.splitn(2, ' ').map(|v| v.to_owned()).collect::<Vec<String>>();
				let (name, arg) = (&parts[0], &parts[1]);
				if let Some(var_name) = self.names.get(name) {
					let var = self.vars.get(var_name).unwrap();
					let val = var.deserialize(&arg);
					if var.can_serialize() {
						self.var_values.insert(var_name, val);
					}
				} else {
					println!("Missing prop");
				}
			}
		}
	}

	pub fn save_config(&self) {
    	let mut file = BufWriter::new(fs::File::create("conf.cfg").unwrap());
    	for (name, var) in &self.vars {
    		if !var.can_serialize() {
    			continue;
    		}
    		for line in var.description().lines() {
    			write!(file, "# {}\n", line).unwrap();
    		}
    		write!(file, "{} {}\n\n", name, var.serialize(self.var_values.get(name).unwrap())).unwrap();
    	}
	}

	fn log(&mut self, record: &log::LogRecord) {
		let mut file = &record.location().file().replace("\\", "/")[..];
		if let Some(pos) = file.rfind("src/") {
			file = &file[pos + 4..];
		}
		println!("[{}:{}][{}] {}", file, record.location().line(), record.level(), record.args());
		self.history.remove(0);
		let mut msg = TextComponent::new("");
		msg.modifier.extra = Some(vec![
			Component::Text(TextComponent::new("[")),
			{
				let mut msg = TextComponent::new(file);
				msg.modifier.color = Some(Color::Green);
				Component::Text(msg)
			},
			Component::Text(TextComponent::new(":")),
			{
				let mut msg = TextComponent::new(&format!("{}", record.location().line()));
				msg.modifier.color = Some(Color::Aqua);
				Component::Text(msg)
			},
			Component::Text(TextComponent::new("]")),
			Component::Text(TextComponent::new("[")),
			{
				let mut msg = TextComponent::new(&format!("{}", record.level()));
				msg.modifier.color = Some(match record.level() {
					log::LogLevel::Debug => Color::Green,
					log::LogLevel::Error => Color::Red,
					log::LogLevel::Warn => Color::Yellow,
					log::LogLevel::Info => Color::Aqua,
					log::LogLevel::Trace => Color::Blue,
				});
				Component::Text(msg)
			},
			Component::Text(TextComponent::new("] ")),
			Component::Text(TextComponent::new(&format!("{}", record.args())))
		]);
		self.history.push(Component::Text(
			msg
		));
	}
}

pub struct ConsoleProxy {
	console: Arc<Mutex<Console>>,
}

impl ConsoleProxy {
	pub fn new(con: Arc<Mutex<Console>>) -> ConsoleProxy {
		ConsoleProxy {
			console: con,
		}
	}
}

impl log::Log for ConsoleProxy {
	fn enabled(&self, metadata: &log::LogMetadata) -> bool {
		metadata.level() <= log::LogLevel::Trace
	}

	fn log(&self, record: &log::LogRecord) {
		if self.enabled(record.metadata()) {
			self.console.lock().unwrap().log(record);
		}
	}
}

unsafe impl Send for ConsoleProxy {}
unsafe impl Sync for ConsoleProxy {}
<|endoftext|>


<commit_before>//! Actix web diesel example
//!
//! Diesel does not support tokio, so we have to run it in separate threads.
//! Actix supports sync actors by default, so we going to create sync actor that use diesel.
//! Technically sync actors are worker style actors, multiple of them
//! can run in parallel and process messages from same queue.
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate diesel;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate uuid;
extern crate futures;
extern crate actix;
extern crate actix_web;
extern crate env_logger;

use actix::prelude::*;
use actix_web::{http, middleware,
                App, HttpServer, HttpRequest, HttpResponse, Error, AsyncResponder};

use diesel::prelude::*;
use r2d2_diesel::ConnectionManager;
use futures::future::Future;

mod db;
mod models;
mod schema;

use db::{CreateUser, DbExecutor};

/// State with DbExecutor address
struct App {
    db: Addr<Syn, DbExecutor>,
}

/// Async request handler
fn index(name: Path<(String,)>, state: State<App>) -> FutureResponse<HttpResponse> {
    // send async `CreateUser` message to a `DbExecutor`
    state.db.send(CreateUser{name: name.into_inner()})
        .from_err()
        .and_then(|res| {
            match res {
                Ok(user) => Ok(HttpResponse::Ok().json(user)),
                Err(_) => Ok(HttpResponse::InternalServerError().into())
            }
        })
        .responder()
}

fn main() {
    ::std::env::set_var("RUST_LOG", "actix_web=info");
    env_logger::init();
    let sys = actix::System::new("diesel-example");

    // Start 3 db executor actors
    let manager = ConnectionManager::<SqliteConnection>::new("test.db");
    let pool = r2d2::Pool::builder().build(manager).expect("Failed to create pool.");

    let addr = SyncArbiter::start(3, move || {
        DbExecutor(pool.clone())
    });

    // Start http server
    let _addr = HttpServer::new(move || {
        App::with_state(State{db: addr.clone()})
            // enable logger
            .middleware(middleware::Logger::default())
            .resource("/{name}", |r| r.method(http::Method::GET).with2(index))})
        .bind("127.0.0.1:8080").unwrap()
        .start();

    println!("Started http server: 127.0.0.1:8080");
    let _ = sys.run();
}
<commit_msg>update diesel example<commit_after>//! Actix web diesel example
//!
//! Diesel does not support tokio, so we have to run it in separate threads.
//! Actix supports sync actors by default, so we going to create sync actor that use diesel.
//! Technically sync actors are worker style actors, multiple of them
//! can run in parallel and process messages from same queue.
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate diesel;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate uuid;
extern crate futures;
extern crate actix;
extern crate actix_web;
extern crate env_logger;

use actix::prelude::*;
use actix_web::{http, server, middleware,
                App, Path, State, HttpResponse, AsyncResponder, FutureResponse};

use diesel::prelude::*;
use r2d2_diesel::ConnectionManager;
use futures::future::Future;

mod db;
mod models;
mod schema;

use db::{CreateUser, DbExecutor};

/// State with DbExecutor address
struct AppState {
    db: Addr<Syn, DbExecutor>,
}

/// Async request handler
fn index(name: Path<String>, state: State<AppState>) -> FutureResponse<HttpResponse> {
    // send async `CreateUser` message to a `DbExecutor`
    state.db.send(CreateUser{name: name.into_inner()})
        .from_err()
        .and_then(|res| {
            match res {
                Ok(user) => Ok(HttpResponse::Ok().json(user)),
                Err(_) => Ok(HttpResponse::InternalServerError().into())
            }
        })
        .responder()
}

fn main() {
    ::std::env::set_var("RUST_LOG", "actix_web=info");
    env_logger::init();
    let sys = actix::System::new("diesel-example");

    // Start 3 db executor actors
    let manager = ConnectionManager::<SqliteConnection>::new("test.db");
    let pool = r2d2::Pool::builder().build(manager).expect("Failed to create pool.");

    let addr = SyncArbiter::start(3, move || {
        DbExecutor(pool.clone())
    });

    // Start http server
    server::new(move || {
        App::with_state(AppState{db: addr.clone()})
            // enable logger
            .middleware(middleware::Logger::default())
            .resource("/{name}", |r| r.method(http::Method::GET).with2(index))})
        .bind("127.0.0.1:8080").unwrap()
        .start();

    println!("Started http server: 127.0.0.1:8080");
    let _ = sys.run();
}
<|endoftext|>


<commit_before>
use std::sync::mpsc::{channel, Sender, Receiver};
use std::thread;
use std::collections;
use std::error::Error;
use std::fmt;

use plugwise;

#[derive(Debug)]
pub enum SerialError {
    ConnectError(String)
}

impl Error for SerialError {
    fn description(&self) -> &str {
        match *self {
            SerialError::ConnectError(ref e) => &e[..]
        }
    }

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

impl fmt::Display for SerialError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{}", self.description())
    }
}

enum Command {
    ConnectDevice(Option<Sender<ConnectResponse>>, String),
    ConnectStub,
    Hangup,
    RegisterCircle(String, u64),
}

enum ConnectResponse {
    Ok,
    ConnectionFailed(String),
}

pub struct Serial;

impl Serial {
    fn message_loop(rx: Receiver<Command>) {
        let mut plugwise = None;
        let mut circles = collections::HashMap::new();

        loop {
            let msg = rx.recv()
                        .ok()
                        .expect("BUG: serial receive loop error");

            match msg {
                Command::ConnectDevice(tx, device) => {
                    let new_plugwise = plugwise::plugwise(plugwise::Device::Serial(device.clone()));

                    match new_plugwise {
                        Ok(new_plugwise) => {
                            plugwise = Some(new_plugwise);
                            if let Some(tx) = tx {
                                tx.send(ConnectResponse::Ok)
                                    .ok().expect("unable to send response");
                            }
                        },
                        Err(err) => {
                            if let Some(tx) = tx {
                                tx.send(ConnectResponse::ConnectionFailed(err.description().into()))
                                    .ok().expect("unable to send response");
                            }
                        }
                    }
                },
                Command::ConnectStub => {
                    let new_plugwise = plugwise::plugwise(plugwise::Device::Simulator).ok().expect(
                                    "creating a simulation instance unexpectedly failed!");
                    plugwise = Some(new_plugwise);
                },
                Command::Hangup => break,
                Command::RegisterCircle(alias, mac) => {
                    if let Some(ref plugwise) = plugwise {
                        let circle = plugwise.create_circle(mac);
                        if let Ok(circle) = circle {
                            circles.insert(alias, circle);
                        }
                    }
                },
            }
        }
    }

    pub fn spawn() -> SerialClient {
        let (boot_tx, boot_rx) = channel();

        thread::spawn(move || {
            let (tx, rx) = channel();

            boot_tx.send(tx.clone())
                   .ok()
                   .expect("BUG: bootstrap failed");

            Serial::message_loop(rx);
        });

        let response = boot_rx.recv()
                              .ok()
                              .expect("BUG: bootstrap message expected");

        SerialClient {
            tx: response,
        }
    }
}

#[derive(Clone)]
pub struct SerialClient {
    tx: Sender<Command>,
}

impl SerialClient {
    pub fn connect_stub(&self) {
        self.tx.send(Command::ConnectStub)
               .ok()
               .expect("BUG: serial thread channel error");
    }

    pub fn connect_device(&self, device: &str) -> Result<(), SerialError> {
        let (tx, rx) = channel();

        self.tx.send(Command::ConnectDevice(Some(tx), device.into()))
               .ok()
               .expect("BUG: serial thread channel error");

        let response = rx.recv().ok().expect("BUG: cannot receive answer from serial thread");

        match response {
            ConnectResponse::Ok => Ok(()),
            ConnectResponse::ConnectionFailed(err) => Err(SerialError::ConnectError(err))
        }
    }

    pub fn register_circle(&self, alias: &str, mac: u64) {
        self.tx.send(Command::RegisterCircle(alias.into(), mac))
               .ok()
               .expect("BUG: cannot register circle");
    }

    pub fn hangup(&self) {
        self.tx.send(Command::Hangup)
               .ok()
               .expect("BUG: cannot bring serial thread down");
    }
}

<commit_msg>serial: add asynchronous version of connect device<commit_after>
use std::sync::mpsc::{channel, Sender, Receiver};
use std::thread;
use std::collections;
use std::error::Error;
use std::fmt;

use plugwise;

#[derive(Debug)]
pub enum SerialError {
    ConnectError(String)
}

impl Error for SerialError {
    fn description(&self) -> &str {
        match *self {
            SerialError::ConnectError(ref e) => &e[..]
        }
    }

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

impl fmt::Display for SerialError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{}", self.description())
    }
}

enum Command {
    ConnectDevice(Option<Sender<ConnectResponse>>, String),
    ConnectStub,
    Hangup,
    RegisterCircle(String, u64),
}

enum ConnectResponse {
    Ok,
    ConnectionFailed(String),
}

pub struct Serial;

impl Serial {
    fn message_loop(rx: Receiver<Command>) {
        let mut plugwise = None;
        let mut circles = collections::HashMap::new();

        loop {
            let msg = rx.recv()
                        .ok()
                        .expect("BUG: serial receive loop error");

            match msg {
                Command::ConnectDevice(tx, device) => {
                    let new_plugwise = plugwise::plugwise(plugwise::Device::Serial(device.clone()));

                    match new_plugwise {
                        Ok(new_plugwise) => {
                            plugwise = Some(new_plugwise);
                            if let Some(tx) = tx {
                                tx.send(ConnectResponse::Ok)
                                    .ok().expect("unable to send response");
                            }
                        },
                        Err(err) => {
                            if let Some(tx) = tx {
                                tx.send(ConnectResponse::ConnectionFailed(err.description().into()))
                                    .ok().expect("unable to send response");
                            }
                        }
                    }
                },
                Command::ConnectStub => {
                    let new_plugwise = plugwise::plugwise(plugwise::Device::Simulator).ok().expect(
                                    "creating a simulation instance unexpectedly failed!");
                    plugwise = Some(new_plugwise);
                },
                Command::Hangup => break,
                Command::RegisterCircle(alias, mac) => {
                    if let Some(ref plugwise) = plugwise {
                        let circle = plugwise.create_circle(mac);
                        if let Ok(circle) = circle {
                            circles.insert(alias, circle);
                        }
                    }
                },
            }
        }
    }

    pub fn spawn() -> SerialClient {
        let (boot_tx, boot_rx) = channel();

        thread::spawn(move || {
            let (tx, rx) = channel();

            boot_tx.send(tx.clone())
                   .ok()
                   .expect("BUG: bootstrap failed");

            Serial::message_loop(rx);
        });

        let response = boot_rx.recv()
                              .ok()
                              .expect("BUG: bootstrap message expected");

        SerialClient {
            tx: response,
        }
    }
}

#[derive(Clone)]
pub struct SerialClient {
    tx: Sender<Command>,
}

impl SerialClient {
    pub fn connect_stub(&self) {
        self.tx.send(Command::ConnectStub)
               .ok()
               .expect("BUG: serial thread channel error");
    }

    pub fn connect_device(&self, device: &str) -> Result<(), SerialError> {
        let (tx, rx) = channel();

        self.tx.send(Command::ConnectDevice(Some(tx), device.into()))
               .ok()
               .expect("BUG: serial thread channel error");

        let response = rx.recv().ok().expect("BUG: cannot receive answer from serial thread");

        match response {
            ConnectResponse::Ok => Ok(()),
            ConnectResponse::ConnectionFailed(err) => Err(SerialError::ConnectError(err))
        }
    }

    pub fn async_connect_device(&self, device: &str) {
        self.tx.send(Command::ConnectDevice(None, device.into()))
               .ok()
               .expect("BUG: serial thread channel error");
    }

    pub fn register_circle(&self, alias: &str, mac: u64) {
        self.tx.send(Command::RegisterCircle(alias.into(), mac))
               .ok()
               .expect("BUG: cannot register circle");
    }

    pub fn hangup(&self) {
        self.tx.send(Command::Hangup)
               .ok()
               .expect("BUG: cannot bring serial thread down");
    }
}

<|endoftext|>


<commit_before>struct Point {
    x: f64,
    y: f64,
}

// Implementation block, all `Point` methods go in here
impl Point {
    // This is a static method
    // Static methods don't need to be called by an instance
    // These methods are generally used as constructors
    fn origin() -> Point {
        Point { x: 0.0, y: 0.0 }
    }

    // Another static method, that takes two arguments
    fn new(x: f64, y: f64) -> Point {
        Point { x: x, y: y }
    }
}

struct Rectangle {
    p1: Point,
    p2: Point,
}

impl Rectangle {
    // This is an instance method
    // `&self` is sugar for `self: &Self`, where `Self` is the type of the
    // caller object. In this case `Self` = `Rectangle`
    fn area(&self) -> f64 {
        // `self` gives access to the struct fields via the dot operator
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        // `abs` is a `f64` method that returns the absolute value of the
        // caller
        ((x1 - x2) * (y1 - y2)).abs()
    }

    fn perimeter(&self) -> f64 {
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        2.0 * (x1 - x2).abs() + 2.0 * (y1 - y2).abs()
    }

    // This method requires the caller object to be mutable
    // `&mut self` desugars to `self: &mut Self`
    fn move(&mut self, x: f64, y: f64) {
        self.p1.x += x;
        self.p2.x += x;

        self.p1.y += y;
        self.p2.y += y;
    }
}

// `Pair` owns resources: two heap allocated integers
struct Pair(Box<int>, Box<int>);

impl Pair {
    // This method "consumes" the resources of the caller object
    // `self` desugars to `self: Self`
    fn destroy(self) {
        // Destructure `self`
        let Pair(first, second) = self;

        println!("Destroying Pair({}, {})", first, second);

        // `first` and `second` go out of scope and get freed
    }
}

fn main() {
    let rectangle = Rectangle {
        // Static methods are called using double colons
        p1: Point::origin(),
        p2: Point::new(3.0, 4.0),
    };

    // Instance method are called using the dot operator
    // Note that the first argument `&self` is implicitly passed, i.e.
    // `rectangle.perimeter()` === `perimeter(&rectangle)`
    println!("Rectangle perimeter: {}", rectangle.perimeter());
    println!("Rectangle area: {}", rectangle.area());

    let mut square = Rectangle {
        p1: Point::origin(),
        p2: Point::new(1.0, 1.0),
    };

    // Error! `rectangle` is immutable, but this method requires a mutable
    // object
    //rectangle.move(1.0, 0.0);
    // TODO ^ Try uncommenting this line

    // Ok, mutable object can call mutable methods
    square.move(1.0, 1.0);

    let pair = Pair(box 1, box 2);

    pair.destroy();

    // Error! Previous `destroy` call "consumed" `pair`
    //pair.destroyed();
    // TODO ^ Try uncommenting this line
}
<commit_msg>'destroyed' is not a method of Pair<commit_after>struct Point {
    x: f64,
    y: f64,
}

// Implementation block, all `Point` methods go in here
impl Point {
    // This is a static method
    // Static methods don't need to be called by an instance
    // These methods are generally used as constructors
    fn origin() -> Point {
        Point { x: 0.0, y: 0.0 }
    }

    // Another static method, that takes two arguments
    fn new(x: f64, y: f64) -> Point {
        Point { x: x, y: y }
    }
}

struct Rectangle {
    p1: Point,
    p2: Point,
}

impl Rectangle {
    // This is an instance method
    // `&self` is sugar for `self: &Self`, where `Self` is the type of the
    // caller object. In this case `Self` = `Rectangle`
    fn area(&self) -> f64 {
        // `self` gives access to the struct fields via the dot operator
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        // `abs` is a `f64` method that returns the absolute value of the
        // caller
        ((x1 - x2) * (y1 - y2)).abs()
    }

    fn perimeter(&self) -> f64 {
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        2.0 * (x1 - x2).abs() + 2.0 * (y1 - y2).abs()
    }

    // This method requires the caller object to be mutable
    // `&mut self` desugars to `self: &mut Self`
    fn move(&mut self, x: f64, y: f64) {
        self.p1.x += x;
        self.p2.x += x;

        self.p1.y += y;
        self.p2.y += y;
    }
}

// `Pair` owns resources: two heap allocated integers
struct Pair(Box<int>, Box<int>);

impl Pair {
    // This method "consumes" the resources of the caller object
    // `self` desugars to `self: Self`
    fn destroy(self) {
        // Destructure `self`
        let Pair(first, second) = self;

        println!("Destroying Pair({}, {})", first, second);

        // `first` and `second` go out of scope and get freed
    }
}

fn main() {
    let rectangle = Rectangle {
        // Static methods are called using double colons
        p1: Point::origin(),
        p2: Point::new(3.0, 4.0),
    };

    // Instance method are called using the dot operator
    // Note that the first argument `&self` is implicitly passed, i.e.
    // `rectangle.perimeter()` === `perimeter(&rectangle)`
    println!("Rectangle perimeter: {}", rectangle.perimeter());
    println!("Rectangle area: {}", rectangle.area());

    let mut square = Rectangle {
        p1: Point::origin(),
        p2: Point::new(1.0, 1.0),
    };

    // Error! `rectangle` is immutable, but this method requires a mutable
    // object
    //rectangle.move(1.0, 0.0);
    // TODO ^ Try uncommenting this line

    // Ok, mutable object can call mutable methods
    square.move(1.0, 1.0);

    let pair = Pair(box 1, box 2);

    pair.destroy();

    // Error! Previous `destroy` call "consumed" `pair`
    //pair.destroy();
    // TODO ^ Try uncommenting this line
}
<|endoftext|>


<commit_before>// Copyright 2015 Jauhien Piatlicki.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Core LLVM: Module
// LLVM-C header Core.h

use std;
use std::ffi::CString;

use libc::c_char;

use llvm_sys::prelude::*;
use llvm_sys::core::*;

use ::{LLVMRef, LLVMRefCtor};
use core::context;
use core::value::FunctionRef;

pub struct Module {
    module: LLVMModuleRef,
    owned: bool
}

//TODO: add print to file and metadata methods
impl Module {
    pub fn new(module_id: &str) -> Module {
        let module_id = CString::new(module_id).unwrap();
        unsafe {
            Module {
                module: LLVMModuleCreateWithName(module_id.as_ptr() as *const c_char),
                owned: true
            }
        }
    }

    pub fn new_in_context(module_id: &str, ctx: &context::Context) -> Module {
        let module_id = CString::new(module_id).unwrap();
        unsafe {
            Module {
                module: LLVMModuleCreateWithNameInContext(module_id.as_ptr() as *const c_char, ctx.to_ref()),
                owned: true
            }
        }
    }

    pub fn get_data_layout(&self) -> String {
        unsafe {
            let buf = std::ffi::CStr::from_ptr(LLVMGetDataLayout(self.to_ref()));
            String::from_utf8_lossy(buf.to_bytes()).into_owned()
        }
    }

    pub fn set_data_layout(&mut self, triple: &str) {
        let triple = CString::new(triple).unwrap();
        unsafe {
            LLVMSetDataLayout(self.to_ref(), triple.as_ptr() as *const c_char);
        }
    }

    pub fn get_target(&self) -> String {
        unsafe {
            let buf = std::ffi::CStr::from_ptr(LLVMGetTarget(self.to_ref()));
            String::from_utf8_lossy(buf.to_bytes()).into_owned()
        }
    }

    pub fn set_target(&mut self, triple: &str) {
        let triple = CString::new(triple).unwrap();
        unsafe {
            LLVMSetTarget(self.to_ref(), triple.as_ptr() as *const c_char);
        }
    }

    pub fn dump(&self) {
        unsafe {
            LLVMDumpModule(self.to_ref());
        }
    }

    pub fn print_to_string(&self) -> String {
        unsafe {
            let buf = LLVMPrintModuleToString(self.to_ref());
            let cstr_buf = std::ffi::CStr::from_ptr(buf);
            let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
            LLVMDisposeMessage(buf);
            result
        }
    }

    pub fn set_inline_asm(&mut self, asm: &str) {
        let asm = CString::new(asm).unwrap();
        unsafe {
            LLVMSetModuleInlineAsm(self.to_ref(), asm.as_ptr() as *const c_char);
        }
    }

    pub fn get_context(&self) -> context::Context {
        unsafe {
            let ctx = LLVMGetModuleContext(self.to_ref());
            context::Context::from_ref(ctx)
        }
    }

    pub fn get_type_by_name(&self, name: &str) -> Option<LLVMTypeRef> {
        let name = CString::new(name).unwrap();
        let ty = unsafe {
            LLVMGetTypeByName(self.to_ref(), name.as_ptr() as *const c_char)
        };
        if !ty.is_null() {
            Some(ty)
        } else {
            None
        }
    }

    pub fn get_function_by_name(&self, name: &str) -> Option<FunctionRef> {
        let name = CString::new(name).unwrap();
        let function = unsafe {
            LLVMGetNamedFunction(self.to_ref(), name.as_ptr() as *const c_char)
        };
        if !function.is_null() {
            unsafe {
                Some(FunctionRef::from_ref(function))
            }
        } else {
            None
        }
    }

    pub fn function_iter(&self) -> FunctionIter {
        let first = unsafe {
            LLVMGetFirstFunction(self.to_ref())
        };

        let current = if first.is_null() {
            None
        } else {
            unsafe {
                Some(FunctionRef::from_ref(first))
            }
        };

        FunctionIter{current: current}
    }

    pub unsafe fn unown(&mut self) {
        self.owned = false;
    }
}

pub struct FunctionIter {
    current: Option<FunctionRef>
}

impl Iterator for FunctionIter {
    type Item = FunctionRef;

    fn next(&mut self) -> Option<FunctionRef> {
        match self.current {
            Some(cur) => {
                let next = unsafe {
                    LLVMGetNextFunction(cur.to_ref())
                };
                self.current = if next.is_null() {
                    None
                } else {
                    unsafe {
                        Some(FunctionRef::from_ref(next))
                    }
                };

                self.current
            },
            None => None
        }
    }
}

impl LLVMRef<LLVMModuleRef> for Module {
    fn to_ref(&self) -> LLVMModuleRef {
        self.module
    }
}

impl LLVMRefCtor<LLVMModuleRef> for Module {
    unsafe fn from_ref(module_ref : LLVMModuleRef) -> Module {
        Module{
            module: module_ref,
            owned: false
        }
    }
}

impl Clone for Module {
    fn clone(&self) -> Self {
        unsafe {
            Module {
                module: LLVMCloneModule(self.to_ref()),
                owned: true
            }
        }
    }
}

impl Drop for Module {
    fn drop(&mut self) {
        if self.owned {
            unsafe {
                LLVMDisposeModule(self.to_ref());
            }
        }
    }
}
<commit_msg>[core] add module verification<commit_after>// Copyright 2015 Jauhien Piatlicki.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Core LLVM: Module
// LLVM-C header Core.h

use std;
use std::ffi::CString;

use libc::c_char;

use llvm_sys::prelude::*;
use llvm_sys::core::*;
use llvm_sys::analysis::*;

use ::{LLVMRef, LLVMRefCtor};
use core::context;
use core::value::FunctionRef;

pub struct Module {
    module: LLVMModuleRef,
    owned: bool
}

//TODO: add print to file and metadata methods
impl Module {
    pub fn new(module_id: &str) -> Module {
        let module_id = CString::new(module_id).unwrap();
        unsafe {
            Module {
                module: LLVMModuleCreateWithName(module_id.as_ptr() as *const c_char),
                owned: true
            }
        }
    }

    pub fn new_in_context(module_id: &str, ctx: &context::Context) -> Module {
        let module_id = CString::new(module_id).unwrap();
        unsafe {
            Module {
                module: LLVMModuleCreateWithNameInContext(module_id.as_ptr() as *const c_char, ctx.to_ref()),
                owned: true
            }
        }
    }

    pub fn get_data_layout(&self) -> String {
        unsafe {
            let buf = std::ffi::CStr::from_ptr(LLVMGetDataLayout(self.to_ref()));
            String::from_utf8_lossy(buf.to_bytes()).into_owned()
        }
    }

    pub fn set_data_layout(&mut self, triple: &str) {
        let triple = CString::new(triple).unwrap();
        unsafe {
            LLVMSetDataLayout(self.to_ref(), triple.as_ptr() as *const c_char);
        }
    }

    pub fn get_target(&self) -> String {
        unsafe {
            let buf = std::ffi::CStr::from_ptr(LLVMGetTarget(self.to_ref()));
            String::from_utf8_lossy(buf.to_bytes()).into_owned()
        }
    }

    pub fn set_target(&mut self, triple: &str) {
        let triple = CString::new(triple).unwrap();
        unsafe {
            LLVMSetTarget(self.to_ref(), triple.as_ptr() as *const c_char);
        }
    }

    pub fn dump(&self) {
        unsafe {
            LLVMDumpModule(self.to_ref());
        }
    }

    pub fn print_to_string(&self) -> String {
        unsafe {
            let buf = LLVMPrintModuleToString(self.to_ref());
            let cstr_buf = std::ffi::CStr::from_ptr(buf);
            let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
            LLVMDisposeMessage(buf);
            result
        }
    }

    pub fn set_inline_asm(&mut self, asm: &str) {
        let asm = CString::new(asm).unwrap();
        unsafe {
            LLVMSetModuleInlineAsm(self.to_ref(), asm.as_ptr() as *const c_char);
        }
    }

    pub fn get_context(&self) -> context::Context {
        unsafe {
            let ctx = LLVMGetModuleContext(self.to_ref());
            context::Context::from_ref(ctx)
        }
    }

    pub fn get_type_by_name(&self, name: &str) -> Option<LLVMTypeRef> {
        let name = CString::new(name).unwrap();
        let ty = unsafe {
            LLVMGetTypeByName(self.to_ref(), name.as_ptr() as *const c_char)
        };
        if !ty.is_null() {
            Some(ty)
        } else {
            None
        }
    }

    pub fn get_function_by_name(&self, name: &str) -> Option<FunctionRef> {
        let name = CString::new(name).unwrap();
        let function = unsafe {
            LLVMGetNamedFunction(self.to_ref(), name.as_ptr() as *const c_char)
        };
        if !function.is_null() {
            unsafe {
                Some(FunctionRef::from_ref(function))
            }
        } else {
            None
        }
    }

    pub fn verify(&self, action: LLVMVerifierFailureAction) -> Result<(), String> {
        let mut error = 0 as *mut c_char;
        unsafe {
            if LLVMVerifyModule(self.to_ref(), action, &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            } else {
                Ok(())
            }
        }
    }

    pub fn function_iter(&self) -> FunctionIter {
        let first = unsafe {
            LLVMGetFirstFunction(self.to_ref())
        };

        let current = if first.is_null() {
            None
        } else {
            unsafe {
                Some(FunctionRef::from_ref(first))
            }
        };

        FunctionIter{current: current}
    }

    pub unsafe fn unown(&mut self) {
        self.owned = false;
    }
}

pub struct FunctionIter {
    current: Option<FunctionRef>
}

impl Iterator for FunctionIter {
    type Item = FunctionRef;

    fn next(&mut self) -> Option<FunctionRef> {
        match self.current {
            Some(cur) => {
                let next = unsafe {
                    LLVMGetNextFunction(cur.to_ref())
                };
                self.current = if next.is_null() {
                    None
                } else {
                    unsafe {
                        Some(FunctionRef::from_ref(next))
                    }
                };

                self.current
            },
            None => None
        }
    }
}

impl LLVMRef<LLVMModuleRef> for Module {
    fn to_ref(&self) -> LLVMModuleRef {
        self.module
    }
}

impl LLVMRefCtor<LLVMModuleRef> for Module {
    unsafe fn from_ref(module_ref : LLVMModuleRef) -> Module {
        Module{
            module: module_ref,
            owned: false
        }
    }
}

impl Clone for Module {
    fn clone(&self) -> Self {
        unsafe {
            Module {
                module: LLVMCloneModule(self.to_ref()),
                owned: true
            }
        }
    }
}

impl Drop for Module {
    fn drop(&mut self) {
        if self.owned {
            unsafe {
                LLVMDisposeModule(self.to_ref());
            }
        }
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::io::{Read, Result};

// use data::SideData;

bitflags! {
    flags PacketFlags: u32 {
        const KEY     = 0b0001,
        const CORRUPT = 0b0010,
        const NONE    = 0,
    }
}

#[derive(Debug)]
pub struct Packet {
    data : Vec<u8>,
    pts : Option<i64>,
    dts : Option<i64>,
    pos : Option<i64>,
    stream_index : isize,

    // side_data : SideData;

    flags : PacketFlags,
}

impl Packet {
    pub fn with_capacity(capacity: usize) -> Self {
        Packet {
            data : Vec::with_capacity(capacity),
            pts : None,
            dts : None,
            pos : None,
            stream_index : -1,
            flags : NONE
        }
    }

    pub fn new() -> Self {
        Self::with_capacity(0)
    }
}

pub trait ReadPacket: Read {
    fn get_packet(&mut self, len: usize) -> Result<Packet> {
        let mut pkt = Packet::with_capacity(len);
        unsafe {
            pkt.data.set_len(len);
            try!(self.read(pkt.data.as_mut_slice()));
        }
        Ok(pkt)
    }
}

impl<R: Read + ?Sized> ReadPacket for R {}

#[cfg(test)]
mod test {
    use std::io::Cursor;
    use super::*;

    #[test]
    fn read_packet() {
        let mut buf = Cursor::new(vec![0; 1024]);

        match buf.get_packet(1024) {
            Ok(pkt) => assert!(pkt.data[0] == 0),
            _ => assert!(false)
        }
    }
}
<commit_msg>draft: Packet API<commit_after>#![allow(dead_code)]

use std::io::{Read, Write, Result};

// use data::SideData;

bitflags! {
    flags PacketFlags: u32 {
        const KEY     = 0b0001,
        const CORRUPT = 0b0010,
        const NONE    = 0,
    }
}

#[derive(Debug)]
pub struct Packet {
    data : Vec<u8>,
    pts : Option<i64>,
    dts : Option<i64>,
    pos : Option<i64>,
    stream_index : isize,

    // side_data : SideData;

    flags : PacketFlags,
}

impl Packet {
    pub fn with_capacity(capacity: usize) -> Self {
        Packet {
            data : Vec::with_capacity(capacity),
            pts : None,
            dts : None,
            pos : None,
            stream_index : -1,
            flags : NONE
        }
    }

    pub fn new() -> Self {
        Self::with_capacity(0)
    }
}

pub trait ReadPacket: Read {
    fn get_packet(&mut self, len: usize) -> Result<Packet> {
        let mut pkt = Packet::with_capacity(len);
        unsafe {
            pkt.data.set_len(len);
            try!(self.read(pkt.data.as_mut_slice()));
        }
        Ok(pkt)
    }
}

pub trait WritePacket: Write {
    fn put_packet(&mut self, pkt: Packet) -> Result<()> {
        self.write_all(pkt.data.as_slice())
    }
}

impl<R: Read + ?Sized> ReadPacket for R {}
impl<W: Write + ?Sized> WritePacket for W {}

#[cfg(test)]
mod test {
    use std::io::Cursor;
    use super::*;

    #[test]
    fn read_packet() {
        let mut buf = Cursor::new(vec![0; 1024]);

        match buf.get_packet(1024) {
            Ok(pkt) => assert!(pkt.data[0] == 0),
            _ => assert!(false)
        }
    }

    #[test]
    fn write_packet() {
        let size = 1024;
        let mut buf = Cursor::new(Vec::with_capacity(size));

        let mut pkt = Packet::with_capacity(size);

        for i in 0..size {
            pkt.data.push(i as u8);
        }

        buf.put_packet(pkt).unwrap();

        let vec = buf.into_inner();

        for i in 0..size {
            println!("{}", vec[i]);
            assert!(vec[i] == i as u8);
        }
    }
}
<|endoftext|>


<commit_before>use super::{Map, MapExt, List};
use super::{Database, StorageValue, Error};
use super::{MemoryDB, LevelDB};
// use super::{Iterable, Seekable};

use tempdir::TempDir;
use leveldb::options::Options;

fn leveldb_database() -> LevelDB {
    let mut options = Options::new();
    options.create_if_missing = true;
    LevelDB::new(TempDir::new("da").unwrap().path(), options).unwrap()
}

fn test_map_simple<T: Map<[u8], Vec<u8>>>(mut db: T) -> Result<(), Error> {
    db.put(b"aba", vec![1, 2, 3])?;
    assert_eq!(db.get(b"aba")?, Some(vec![1, 2, 3]));
    assert_eq!(db.get(b"caba")?, None);

    db.put(b"caba", vec![50, 14])?;
    db.delete(b"aba")?;
    assert_eq!(db.get(b"aba")?, None);
    db.put(b"caba", vec![1, 2, 3, 117, 3])?;
    assert_eq!(db.get(b"caba")?, Some(vec![1, 2, 3, 117, 3]));
    Ok(())
}

fn test_database_merge<T: Database>(mut db: T) -> Result<(), Error> {
    db.put(b"ab", vec![1, 2, 3])?;
    db.put(b"aba", vec![14, 22, 3])?;
    db.put(b"caba", vec![34, 2, 3])?;
    db.put(b"abacaba", vec![1, 65])?;

    let patch;
    {
        let mut fork = db.fork();
        fork.delete(b"ab")?;
        fork.put(b"abacaba", vec![18, 34])?;
        fork.put(b"caba", vec![10])?;
        fork.put(b"abac", vec![117, 32, 64])?;
        fork.put(b"abac", vec![14, 12])?;
        fork.delete(b"abacaba")?;

        assert_eq!(fork.get(b"ab")?, None);
        assert_eq!(fork.get(b"caba")?, Some(vec![10]));
        assert_eq!(fork.get(b"abac")?, Some(vec![14, 12]));
        assert_eq!(fork.get(b"aba")?, Some(vec![14, 22, 3]));
        assert_eq!(fork.get(b"abacaba")?, None);

        patch = fork.patch();
    }
    assert_eq!(db.get(b"ab")?, Some(vec![1, 2, 3]));
    assert_eq!(db.get(b"aba")?, Some(vec![14, 22, 3]));
    assert_eq!(db.get(b"caba")?, Some(vec![34, 2, 3]));
    assert_eq!(db.get(b"abacaba")?, Some(vec![1, 65]));

    db.merge(patch)?;
    assert_eq!(db.get(b"ab")?, None);
    assert_eq!(db.get(b"caba")?, Some(vec![10]));
    assert_eq!(db.get(b"abac")?, Some(vec![14, 12]));
    assert_eq!(db.get(b"aba")?, Some(vec![14, 22, 3]));
    assert_eq!(db.get(b"abacaba")?, None);
    Ok(())
}

fn test_table_list<T: Database>(prefix: Vec<u8>, db: &mut T) -> Result<(), Error> {
    let mut list = db.list(prefix);
    assert_eq!(list.len()?, 0 as u64);
    list.append(vec![10])?;
    assert_eq!(list.get(0)?, Some(vec![10]));

    list.append(vec![15])?;
    assert_eq!(list.len()?, 2);
    assert_eq!(list.last()?, Some(vec![15]));

    let bound: u64 = 500;
    for i in 0..bound {
        list.append(StorageValue::serialize(i as u64))?;
    }
    assert_eq!(list.last()?, Some(StorageValue::serialize(bound - 1)));
    assert_eq!(list.len()?, 2 + bound);
    Ok(())
}

fn test_table_map<T: Database>(prefix: Vec<u8>, db: &mut T) -> Result<(), Error> {
    let map = db.map(prefix);
    test_map_simple(map)
}

fn test_map_find_keys<T: Map<[u8], Vec<u8>>>(db: &mut T) {
    db.put(b"a", b"12345".to_vec()).unwrap();
    db.put(b"ab", b"123456".to_vec()).unwrap();
    db.put(b"ac", b"123457".to_vec()).unwrap();
    db.put(b"baca", b"1".to_vec()).unwrap();
    db.put(b"bza", b"2".to_vec()).unwrap();
    db.put(b"bzac", b"3".to_vec()).unwrap();

    assert_eq!(db.find_key(b"a").unwrap(), Some(b"a".to_vec()));
    assert_eq!(db.find_key(&[]).unwrap(), Some(b"a".to_vec()));
    assert_eq!(db.find_key(b"b").unwrap(), Some(b"baca".to_vec()));
    assert_eq!(db.find_key(b"c").unwrap(), None);
}

fn test_map_table_different_prefixes<T: MapExt>(db: &mut T) {
    {
        let mut map2 = db.map(b"abc".to_vec());
        map2.put(&b"abac".to_vec(), b"12345".to_vec()).unwrap();
    }
    let mut map1 = db.map(b"bcd".to_vec());
    map1.put(&b"baca".to_vec(), b"1".to_vec()).unwrap();

    assert_eq!(map1.find_key(&b"abd".to_vec()).unwrap(), None);
}

#[test]
fn serializer() {
    let a: u32 = 10;
    let b: u64 = 15;
    let c: Vec<u8> = vec![10, 15, 24, 2, 1];

    let a_s = a.serialize();
    let b_s = b.serialize();
    let c_s = c.clone().serialize();
    let c_d: Vec<u8> = StorageValue::deserialize(c_s);
    assert_eq!(a, StorageValue::deserialize(a_s));
    assert_eq!(b, StorageValue::deserialize(b_s));
    assert_eq!(c, c_d);
}

#[test]
fn memory_database_simple() {
    let db = MemoryDB::new();
    test_map_simple(db).unwrap();
}

#[test]
fn leveldb_database_simple() {
    let db = leveldb_database();
    test_map_simple(db).unwrap();
}

#[test]
fn memory_database_merge() {
    let db = MemoryDB::new();
    test_database_merge(db).unwrap();
}

#[test]
fn leveldb_database_merge() {
    let db = leveldb_database();
    test_database_merge(db).unwrap();
}

#[test]
fn memorydb_table_list() {
    let mut db = MemoryDB::new();
    test_table_list(vec![01], &mut db).unwrap();
    test_table_list(vec![02], &mut db).unwrap();
}

#[test]
fn leveldb_table_list() {
    let mut db = leveldb_database();
    test_table_list(vec![01], &mut db).unwrap();
    test_table_list(vec![02], &mut db).unwrap();
}

#[test]
fn memorydb_table_map() {
    let mut db = MemoryDB::new();
    test_table_map(vec![01], &mut db).unwrap();
    test_table_map(vec![02], &mut db).unwrap();
}

#[test]
fn leveldb_table_map() {
    let mut db = leveldb_database();
    test_table_map(vec![01], &mut db).unwrap();
    test_table_map(vec![02], &mut db).unwrap();
}

#[test]
fn leveldb_find_key() {
    let mut db = leveldb_database();
    test_map_find_keys(&mut db);
}

#[test]
fn memorydb_find_key() {
    let mut db = MemoryDB::new();
    test_map_find_keys(&mut db);
}

#[test]
fn leveldb_map_find_key() {
    let mut db = leveldb_database();
    let mut map = db.map(vec![02]);
    test_map_find_keys(&mut map);
}

#[test]
fn memorydb_map_find_key() {
    let mut db = MemoryDB::new();
    let mut map = db.map(vec![02]);
    test_map_find_keys(&mut map);
}

#[test]
fn leveldb_map_table_different_prefixes() {
    let mut db = leveldb_database();
    test_map_table_different_prefixes(&mut db);
}

#[test]
fn memorydb_map_table_different_prefixes() {
    let mut db = MemoryDB::new();
    test_map_table_different_prefixes(&mut db);
}

// #[test]
// fn memorydb_iter() {
//     let mut db = MemoryDB::new();
//     db.put(b"a", b"12345".to_vec()).unwrap();
//     db.put(b"ab", b"123456".to_vec()).unwrap();
//     db.put(b"ac", b"123457".to_vec()).unwrap();
//     db.put(b"baca", b"1".to_vec()).unwrap();
//     db.put(b"bza", b"2".to_vec()).unwrap();
//     db.put(b"bzac", b"3".to_vec()).unwrap();

//     let mut it = db.iter();
//     assert_eq!(it.next(), Some((b"a".to_vec(), b"12345".to_vec())));
//     assert_eq!(it.next(), Some((b"ab".to_vec(), b"123456".to_vec())));
//     assert_eq!(it.next(), Some((b"ac".to_vec(), b"123457".to_vec())));

//     assert_eq!(it.seek(&b"bza".to_vec()), Some((b"bza".to_vec(), b"2".to_vec())));
//     assert_eq!(it.next(), Some((b"bzac".to_vec(), b"3".to_vec())));
// }

// #[test]
// fn leveldb_iter() {
//     let mut db = leveldb_database();

//     db.put(b"a", b"12345".to_vec()).unwrap();
//     db.put(b"ab", b"123456".to_vec()).unwrap();
//     db.put(b"ac", b"123457".to_vec()).unwrap();
//     db.put(b"baca", b"1".to_vec()).unwrap();
//     db.put(b"bza", b"2".to_vec()).unwrap();
//     db.put(b"bzac", b"3".to_vec()).unwrap();

//     let mut it = db.iter();
//     assert_eq!(it.next(), Some((b"a".to_vec(), b"12345".to_vec())));
//     assert_eq!(it.next(), Some((b"ab".to_vec(), b"123456".to_vec())));
//     assert_eq!(it.next(), Some((b"ac".to_vec(), b"123457".to_vec())));

//     assert_eq!(it.seek(&b"bza".to_vec()), Some((b"bza".to_vec(), b"2".to_vec())));
//     assert_eq!(it.next(), Some((b"bzac".to_vec(), b"3".to_vec())));
// }

// #[test]
// fn leveldb_map_table_iter() {
//     let mut db = leveldb_database();
//     let mut map = db.map(vec![02]);

//     map.put(&vec![1, 2], vec![1, 3, 4]).unwrap();
//     map.put(&vec![1, 3], vec![1, 4, 5]).unwrap();
//     map.put(&vec![2, 3], vec![2, 4, 5]).unwrap();
//     map.put(&vec![2, 4], vec![4, 4, 5]).unwrap();

//     let mut it = map.into_iter();
//     assert_eq!(it.next(), Some((vec![1, 2], vec![1, 3, 4])));
//     assert_eq!(it.next(), Some((vec![1, 3], vec![1, 4, 5])));
//     assert_eq!(it.seek(&vec![2, 4]), Some((vec![2, 4], vec![4, 4, 5])));
// }

// TODO add tests for changes
<commit_msg>Fix test<commit_after>use super::{Map, MapExt, List};
use super::{Database, StorageValue, Error};
use super::{MemoryDB, LevelDB, Patch};
// use super::{Iterable, Seekable};

use tempdir::TempDir;
use leveldb::options::Options;

fn leveldb_database() -> LevelDB {
    let mut options = Options::new();
    options.create_if_missing = true;
    LevelDB::new(TempDir::new("da").unwrap().path(), options).unwrap()
}

fn test_map_simple<T: Map<[u8], Vec<u8>>>(mut db: T) -> Result<(), Error> {
    db.put(b"aba", vec![1, 2, 3])?;
    assert_eq!(db.get(b"aba")?, Some(vec![1, 2, 3]));
    assert_eq!(db.get(b"caba")?, None);

    db.put(b"caba", vec![50, 14])?;
    db.delete(b"aba")?;
    assert_eq!(db.get(b"aba")?, None);
    db.put(b"caba", vec![1, 2, 3, 117, 3])?;
    assert_eq!(db.get(b"caba")?, Some(vec![1, 2, 3, 117, 3]));
    Ok(())
}

fn test_database_merge<T: Database>(mut db: T) -> Result<(), Error> {
    db.put(b"ab", vec![1, 2, 3])?;
    db.put(b"aba", vec![14, 22, 3])?;
    db.put(b"caba", vec![34, 2, 3])?;
    db.put(b"abacaba", vec![1, 65])?;

    let patch;
    {
        let mut fork = db.fork();
        fork.delete(b"ab")?;
        fork.put(b"abacaba", vec![18, 34])?;
        fork.put(b"caba", vec![10])?;
        fork.put(b"abac", vec![117, 32, 64])?;
        fork.put(b"abac", vec![14, 12])?;
        fork.delete(b"abacaba")?;

        assert_eq!(fork.get(b"ab")?, None);
        assert_eq!(fork.get(b"caba")?, Some(vec![10]));
        assert_eq!(fork.get(b"abac")?, Some(vec![14, 12]));
        assert_eq!(fork.get(b"aba")?, Some(vec![14, 22, 3]));
        assert_eq!(fork.get(b"abacaba")?, None);

        patch = Patch::from(fork);
    }
    assert_eq!(db.get(b"ab")?, Some(vec![1, 2, 3]));
    assert_eq!(db.get(b"aba")?, Some(vec![14, 22, 3]));
    assert_eq!(db.get(b"caba")?, Some(vec![34, 2, 3]));
    assert_eq!(db.get(b"abacaba")?, Some(vec![1, 65]));

    db.merge(patch)?;
    assert_eq!(db.get(b"ab")?, None);
    assert_eq!(db.get(b"caba")?, Some(vec![10]));
    assert_eq!(db.get(b"abac")?, Some(vec![14, 12]));
    assert_eq!(db.get(b"aba")?, Some(vec![14, 22, 3]));
    assert_eq!(db.get(b"abacaba")?, None);
    Ok(())
}

fn test_table_list<T: Database>(prefix: Vec<u8>, db: &mut T) -> Result<(), Error> {
    let mut list = db.list(prefix);
    assert_eq!(list.len()?, 0 as u64);
    list.append(vec![10])?;
    assert_eq!(list.get(0)?, Some(vec![10]));

    list.append(vec![15])?;
    assert_eq!(list.len()?, 2);
    assert_eq!(list.last()?, Some(vec![15]));

    let bound: u64 = 500;
    for i in 0..bound {
        list.append(StorageValue::serialize(i as u64))?;
    }
    assert_eq!(list.last()?, Some(StorageValue::serialize(bound - 1)));
    assert_eq!(list.len()?, 2 + bound);
    Ok(())
}

fn test_table_map<T: Database>(prefix: Vec<u8>, db: &mut T) -> Result<(), Error> {
    let map = db.map(prefix);
    test_map_simple(map)
}

fn test_map_find_keys<T: Map<[u8], Vec<u8>>>(db: &mut T) {
    db.put(b"a", b"12345".to_vec()).unwrap();
    db.put(b"ab", b"123456".to_vec()).unwrap();
    db.put(b"ac", b"123457".to_vec()).unwrap();
    db.put(b"baca", b"1".to_vec()).unwrap();
    db.put(b"bza", b"2".to_vec()).unwrap();
    db.put(b"bzac", b"3".to_vec()).unwrap();

    assert_eq!(db.find_key(b"a").unwrap(), Some(b"a".to_vec()));
    assert_eq!(db.find_key(&[]).unwrap(), Some(b"a".to_vec()));
    assert_eq!(db.find_key(b"b").unwrap(), Some(b"baca".to_vec()));
    assert_eq!(db.find_key(b"c").unwrap(), None);
}

fn test_map_table_different_prefixes<T: MapExt>(db: &mut T) {
    {
        let mut map2 = db.map(b"abc".to_vec());
        map2.put(&b"abac".to_vec(), b"12345".to_vec()).unwrap();
    }
    let mut map1 = db.map(b"bcd".to_vec());
    map1.put(&b"baca".to_vec(), b"1".to_vec()).unwrap();

    assert_eq!(map1.find_key(&b"abd".to_vec()).unwrap(), None);
}

#[test]
fn serializer() {
    let a: u32 = 10;
    let b: u64 = 15;
    let c: Vec<u8> = vec![10, 15, 24, 2, 1];

    let a_s = a.serialize();
    let b_s = b.serialize();
    let c_s = c.clone().serialize();
    let c_d: Vec<u8> = StorageValue::deserialize(c_s);
    assert_eq!(a, StorageValue::deserialize(a_s));
    assert_eq!(b, StorageValue::deserialize(b_s));
    assert_eq!(c, c_d);
}

#[test]
fn memory_database_simple() {
    let db = MemoryDB::new();
    test_map_simple(db).unwrap();
}

#[test]
fn leveldb_database_simple() {
    let db = leveldb_database();
    test_map_simple(db).unwrap();
}

#[test]
fn memory_database_merge() {
    let db = MemoryDB::new();
    test_database_merge(db).unwrap();
}

#[test]
fn leveldb_database_merge() {
    let db = leveldb_database();
    test_database_merge(db).unwrap();
}

#[test]
fn memorydb_table_list() {
    let mut db = MemoryDB::new();
    test_table_list(vec![01], &mut db).unwrap();
    test_table_list(vec![02], &mut db).unwrap();
}

#[test]
fn leveldb_table_list() {
    let mut db = leveldb_database();
    test_table_list(vec![01], &mut db).unwrap();
    test_table_list(vec![02], &mut db).unwrap();
}

#[test]
fn memorydb_table_map() {
    let mut db = MemoryDB::new();
    test_table_map(vec![01], &mut db).unwrap();
    test_table_map(vec![02], &mut db).unwrap();
}

#[test]
fn leveldb_table_map() {
    let mut db = leveldb_database();
    test_table_map(vec![01], &mut db).unwrap();
    test_table_map(vec![02], &mut db).unwrap();
}

#[test]
fn leveldb_find_key() {
    let mut db = leveldb_database();
    test_map_find_keys(&mut db);
}

#[test]
fn memorydb_find_key() {
    let mut db = MemoryDB::new();
    test_map_find_keys(&mut db);
}

#[test]
fn leveldb_map_find_key() {
    let mut db = leveldb_database();
    let mut map = db.map(vec![02]);
    test_map_find_keys(&mut map);
}

#[test]
fn memorydb_map_find_key() {
    let mut db = MemoryDB::new();
    let mut map = db.map(vec![02]);
    test_map_find_keys(&mut map);
}

#[test]
fn leveldb_map_table_different_prefixes() {
    let mut db = leveldb_database();
    test_map_table_different_prefixes(&mut db);
}

#[test]
fn memorydb_map_table_different_prefixes() {
    let mut db = MemoryDB::new();
    test_map_table_different_prefixes(&mut db);
}

// #[test]
// fn memorydb_iter() {
//     let mut db = MemoryDB::new();
//     db.put(b"a", b"12345".to_vec()).unwrap();
//     db.put(b"ab", b"123456".to_vec()).unwrap();
//     db.put(b"ac", b"123457".to_vec()).unwrap();
//     db.put(b"baca", b"1".to_vec()).unwrap();
//     db.put(b"bza", b"2".to_vec()).unwrap();
//     db.put(b"bzac", b"3".to_vec()).unwrap();

//     let mut it = db.iter();
//     assert_eq!(it.next(), Some((b"a".to_vec(), b"12345".to_vec())));
//     assert_eq!(it.next(), Some((b"ab".to_vec(), b"123456".to_vec())));
//     assert_eq!(it.next(), Some((b"ac".to_vec(), b"123457".to_vec())));

//     assert_eq!(it.seek(&b"bza".to_vec()), Some((b"bza".to_vec(), b"2".to_vec())));
//     assert_eq!(it.next(), Some((b"bzac".to_vec(), b"3".to_vec())));
// }

// #[test]
// fn leveldb_iter() {
//     let mut db = leveldb_database();

//     db.put(b"a", b"12345".to_vec()).unwrap();
//     db.put(b"ab", b"123456".to_vec()).unwrap();
//     db.put(b"ac", b"123457".to_vec()).unwrap();
//     db.put(b"baca", b"1".to_vec()).unwrap();
//     db.put(b"bza", b"2".to_vec()).unwrap();
//     db.put(b"bzac", b"3".to_vec()).unwrap();

//     let mut it = db.iter();
//     assert_eq!(it.next(), Some((b"a".to_vec(), b"12345".to_vec())));
//     assert_eq!(it.next(), Some((b"ab".to_vec(), b"123456".to_vec())));
//     assert_eq!(it.next(), Some((b"ac".to_vec(), b"123457".to_vec())));

//     assert_eq!(it.seek(&b"bza".to_vec()), Some((b"bza".to_vec(), b"2".to_vec())));
//     assert_eq!(it.next(), Some((b"bzac".to_vec(), b"3".to_vec())));
// }

// #[test]
// fn leveldb_map_table_iter() {
//     let mut db = leveldb_database();
//     let mut map = db.map(vec![02]);

//     map.put(&vec![1, 2], vec![1, 3, 4]).unwrap();
//     map.put(&vec![1, 3], vec![1, 4, 5]).unwrap();
//     map.put(&vec![2, 3], vec![2, 4, 5]).unwrap();
//     map.put(&vec![2, 4], vec![4, 4, 5]).unwrap();

//     let mut it = map.into_iter();
//     assert_eq!(it.next(), Some((vec![1, 2], vec![1, 3, 4])));
//     assert_eq!(it.next(), Some((vec![1, 3], vec![1, 4, 5])));
//     assert_eq!(it.seek(&vec![2, 4]), Some((vec![2, 4], vec![4, 4, 5])));
// }

// TODO add tests for changes
<|endoftext|>


<commit_before>use crate::graphic::moving_window_texture::GlMovingWindowTexture;
use crate::graphic::tiled_texture_loader::TiledTextureLoader;
use crate::graphic::uniform::GlUniform;
use crate::graphic::GlProgram;
use crate::terrain_drawer::read_write::Metadata;
use cgmath::{Decomposed, Matrix4, Point3, Vector2, Vector3};
use image::{ImageBuffer, LumaA, Rgba};
use point_viewer::math::Isometry3;
use std::convert::TryInto;
use std::io;
use std::rc::Rc;

// The last integer that can be exactly represented in a f64
const F64_MAX_SAFE_INT: i64 = 9_007_199_254_740_992;
const F64_MIN_SAFE_INT: i64 = -F64_MAX_SAFE_INT;

struct HeightAndColor {
    height: ImageBuffer<LumaA<f32>, Vec<f32>>,
    color: ImageBuffer<Rgba<u8>, Vec<u8>>,
}

pub struct TerrainLayer {
    grid_coordinates: GridCoordinateFrame,
    // The terrain pos is the coordinate of the lower corner of the terrain.
    // It converted to f64 at the latest possible moment, so that all
    // calculations have 64-bit integer precision.
    terrain_pos: Vector2<i64>,
    u_terrain_pos: GlUniform<Vector2<f64>>,
    height_tiles: TiledTextureLoader<LumaA<f32>>,
    color_tiles: TiledTextureLoader<Rgba<u8>>,
    heightmap: GlMovingWindowTexture<LumaA<f32>>,
    colormap: GlMovingWindowTexture<Rgba<u8>>,
    // The texture size shouldn't be negative or larger than u32::MAX, but it's
    // more convenient for our calculations to store it as an i64.
    texture_size: i64,
}

#[allow(dead_code)]
impl TerrainLayer {
    pub fn new<P: AsRef<std::path::Path>>(
        program: &GlProgram,
        path: P,
        texture_size: u32,
    ) -> io::Result<Self> {
        assert!(texture_size % 2 == 0 && texture_size > 0);
        let metadata = Metadata::from_dir(&path)?;
        let (height_tiles, color_tiles) = metadata.read_tiles(&path)?;

        let grid_coordinates = GridCoordinateFrame::new(program, metadata, texture_size);

        // Initial terrain pos
        let terrain_pos: Vector2<i64> =
            grid_coordinates.terrain_pos_for_camera_pos(Point3::new(0.0, 0.0, 0.0));
        let u_terrain_pos = GlUniform::new(&program, "terrain_pos", terrain_pos.cast().unwrap());

        let height_initial = height_tiles.load(
            terrain_pos.x,
            terrain_pos.y,
            texture_size.try_into().unwrap(),
            texture_size.try_into().unwrap(),
        );
        let heightmap = GlMovingWindowTexture::new(
            &program,
            Rc::clone(&program.gl),
            "height",
            texture_size,
            0, // texture_unit
            height_initial,
        );

        let color_initial = color_tiles.load(
            terrain_pos.x,
            terrain_pos.y,
            texture_size.try_into().unwrap(),
            texture_size.try_into().unwrap(),
        );
        let colormap = GlMovingWindowTexture::new(
            &program,
            Rc::clone(&program.gl),
            "color",
            texture_size,
            1, // texture_unit
            color_initial,
        );
        let texture_size = i64::from(texture_size);

        Ok(TerrainLayer {
            grid_coordinates,
            terrain_pos,
            u_terrain_pos,
            height_tiles,
            color_tiles,
            heightmap,
            colormap,
            texture_size,
        })
    }

    // We already have the data between self.terrain_pos and self.terrain_pos + texture_size
    // Only fetch the "L" shape that is needed, as separate horizontal and vertical strips.
    // Don't get confused, the horizontal strip is determined by the movement in y direction and
    // the vertical strip is determined by the movement in x direction.
    pub fn update(&mut self, cur_world_pos: Point3<f64>) {
        let cur_pos = self
            .grid_coordinates
            .terrain_pos_for_camera_pos(cur_world_pos);
        let moved = cur_pos - self.terrain_pos;
        self.terrain_pos = cur_pos;
        // Convert to f64, because GLSL doesn't understand i64
        assert!(
            cur_pos.x < F64_MAX_SAFE_INT && cur_pos.x > F64_MIN_SAFE_INT,
            "Terrain location not representable."
        );
        assert!(
            cur_pos.y < F64_MAX_SAFE_INT && cur_pos.y > F64_MIN_SAFE_INT,
            "Terrain location not representable."
        );
        self.u_terrain_pos.value = cur_pos.cast().unwrap();

        let hori_strip = if moved.y > 0 {
            self.load(
                cur_pos.x,
                self.terrain_pos.y + self.texture_size,
                self.texture_size.try_into().unwrap(),
                moved.y.try_into().unwrap(),
            )
        } else {
            self.load(
                cur_pos.x,
                cur_pos.y,
                self.texture_size.try_into().unwrap(),
                moved.y.abs().try_into().unwrap(),
            )
        };
        let vert_strip = if moved.x > 0 {
            self.load(
                self.terrain_pos.x + self.texture_size,
                cur_pos.y,
                moved.x.try_into().unwrap(),
                self.texture_size.try_into().unwrap(),
            )
        } else {
            self.load(
                cur_pos.x,
                cur_pos.y,
                moved.x.abs().try_into().unwrap(),
                self.texture_size.try_into().unwrap(),
            )
        };

        self.heightmap.incremental_update(
            moved.x as i32,
            moved.y as i32,
            vert_strip.height,
            hori_strip.height,
        );
        self.colormap.incremental_update(
            moved.x as i32,
            moved.y as i32,
            vert_strip.color,
            hori_strip.color,
        );
    }

    pub fn terrain_from_world(&self) -> Isometry3<f64> {
        self.grid_coordinates.terrain_from_world.clone()
    }

    pub fn submit(&self) {
        self.grid_coordinates.submit();
        self.u_terrain_pos.submit();
        self.heightmap.submit();
        self.colormap.submit();
    }

    fn load(&self, min_x: i64, min_y: i64, width: usize, height: usize) -> HeightAndColor {
        HeightAndColor {
            height: self.height_tiles.load(min_x, min_y, width, height),
            color: self.color_tiles.load(min_x, min_y, width, height),
        }
    }
}

/// This struct's job is to convert from continuous world positions to discrete
/// terrain positions and to provide the necessary variables to do the inverse
/// calculation to the vertex shader.
struct GridCoordinateFrame {
    u_origin: GlUniform<Vector3<f64>>,
    u_world_from_terrain: GlUniform<Matrix4<f64>>,
    u_resolution_m: GlUniform<f64>,
    texture_half_extent: Vector2<i64>,
    terrain_from_world: Isometry3<f64>,
}

impl GridCoordinateFrame {
    fn new(program: &GlProgram, metadata: Metadata, texture_size: u32) -> Self {
        let u_origin = GlUniform::new(&program, "terrain_origin_m", metadata.origin);
        let terrain_from_world = metadata.world_from_terrain.inverse();
        let u_world_from_terrain = GlUniform::new(
            &program,
            "terrain_to_world",
            Matrix4::from({
                let decomp: Decomposed<_, _> = metadata.world_from_terrain.into();
                decomp
            }),
        );
        let u_resolution_m = GlUniform::new(&program, "terrain_res_m", metadata.resolution_m);
        let texture_half_extent =
            Vector2::new(i64::from(texture_size) / 2, i64::from(texture_size) / 2);
        GridCoordinateFrame {
            u_origin,
            u_world_from_terrain,
            u_resolution_m,
            texture_half_extent,
            terrain_from_world,
        }
    }

    /// Returns the terrain pos (i.e. the coordinate of the lower corner of the terrain) for
    /// a given camera position (in the world coordinate system).
    fn terrain_pos_for_camera_pos(&self, world_pos: Point3<f64>) -> Vector2<i64> {
        let local_pos = &self.terrain_from_world * &world_pos;
        let x = ((local_pos.x - self.u_origin.value.x) / self.u_resolution_m.value).floor();
        let y = ((local_pos.y - self.u_origin.value.y) / self.u_resolution_m.value).floor();
        (Vector2::new(x, y)).cast().unwrap() - self.texture_half_extent
    }

    fn submit(&self) {
        self.u_origin.submit();
        self.u_world_from_terrain.submit();
        self.u_resolution_m.submit();
    }
}
<commit_msg>sdl_viewer: Fix bug causing empty stripes in terrain (#375)<commit_after>use crate::graphic::moving_window_texture::GlMovingWindowTexture;
use crate::graphic::tiled_texture_loader::TiledTextureLoader;
use crate::graphic::uniform::GlUniform;
use crate::graphic::GlProgram;
use crate::terrain_drawer::read_write::Metadata;
use cgmath::{Decomposed, Matrix4, Point3, Vector2, Vector3};
use image::{ImageBuffer, LumaA, Rgba};
use point_viewer::math::Isometry3;
use std::convert::TryInto;
use std::io;
use std::rc::Rc;

// The last integer that can be exactly represented in a f64
const F64_MAX_SAFE_INT: i64 = 9_007_199_254_740_992;
const F64_MIN_SAFE_INT: i64 = -F64_MAX_SAFE_INT;

struct HeightAndColor {
    height: ImageBuffer<LumaA<f32>, Vec<f32>>,
    color: ImageBuffer<Rgba<u8>, Vec<u8>>,
}

pub struct TerrainLayer {
    grid_coordinates: GridCoordinateFrame,
    // The terrain pos is the coordinate of the lower corner of the terrain.
    // It converted to f64 at the latest possible moment, so that all
    // calculations have 64-bit integer precision.
    terrain_pos: Vector2<i64>,
    u_terrain_pos: GlUniform<Vector2<f64>>,
    height_tiles: TiledTextureLoader<LumaA<f32>>,
    color_tiles: TiledTextureLoader<Rgba<u8>>,
    heightmap: GlMovingWindowTexture<LumaA<f32>>,
    colormap: GlMovingWindowTexture<Rgba<u8>>,
    // The texture size shouldn't be negative or larger than u32::MAX, but it's
    // more convenient for our calculations to store it as an i64.
    texture_size: i64,
}

#[allow(dead_code)]
impl TerrainLayer {
    pub fn new<P: AsRef<std::path::Path>>(
        program: &GlProgram,
        path: P,
        texture_size: u32,
    ) -> io::Result<Self> {
        assert!(texture_size % 2 == 0 && texture_size > 0);
        let metadata = Metadata::from_dir(&path)?;
        let (height_tiles, color_tiles) = metadata.read_tiles(&path)?;

        let grid_coordinates = GridCoordinateFrame::new(program, metadata, texture_size);

        // Initial terrain pos
        let terrain_pos: Vector2<i64> =
            grid_coordinates.terrain_pos_for_camera_pos(Point3::new(0.0, 0.0, 0.0));
        let u_terrain_pos = GlUniform::new(&program, "terrain_pos", terrain_pos.cast().unwrap());

        let height_initial = height_tiles.load(
            terrain_pos.x,
            terrain_pos.y,
            texture_size.try_into().unwrap(),
            texture_size.try_into().unwrap(),
        );
        let heightmap = GlMovingWindowTexture::new(
            &program,
            Rc::clone(&program.gl),
            "height",
            texture_size,
            0, // texture_unit
            height_initial,
        );

        let color_initial = color_tiles.load(
            terrain_pos.x,
            terrain_pos.y,
            texture_size.try_into().unwrap(),
            texture_size.try_into().unwrap(),
        );
        let colormap = GlMovingWindowTexture::new(
            &program,
            Rc::clone(&program.gl),
            "color",
            texture_size,
            1, // texture_unit
            color_initial,
        );
        let texture_size = i64::from(texture_size);

        Ok(TerrainLayer {
            grid_coordinates,
            terrain_pos,
            u_terrain_pos,
            height_tiles,
            color_tiles,
            heightmap,
            colormap,
            texture_size,
        })
    }

    // We already have the data between self.terrain_pos and self.terrain_pos + texture_size
    // Only fetch the "L" shape that is needed, as separate horizontal and vertical strips.
    // Don't get confused, the horizontal strip is determined by the movement in y direction and
    // the vertical strip is determined by the movement in x direction.
    pub fn update(&mut self, cur_world_pos: Point3<f64>) {
        let cur_pos = self
            .grid_coordinates
            .terrain_pos_for_camera_pos(cur_world_pos);
        let moved = cur_pos - self.terrain_pos;

        let hori_strip = if moved.y > 0 {
            self.load(
                cur_pos.x,
                self.terrain_pos.y + self.texture_size,
                self.texture_size.try_into().unwrap(),
                moved.y.try_into().unwrap(),
            )
        } else {
            self.load(
                cur_pos.x,
                cur_pos.y,
                self.texture_size.try_into().unwrap(),
                moved.y.abs().try_into().unwrap(),
            )
        };
        let vert_strip = if moved.x > 0 {
            self.load(
                self.terrain_pos.x + self.texture_size,
                cur_pos.y,
                moved.x.try_into().unwrap(),
                self.texture_size.try_into().unwrap(),
            )
        } else {
            self.load(
                cur_pos.x,
                cur_pos.y,
                moved.x.abs().try_into().unwrap(),
                self.texture_size.try_into().unwrap(),
            )
        };

        self.heightmap.incremental_update(
            moved.x as i32,
            moved.y as i32,
            vert_strip.height,
            hori_strip.height,
        );
        self.colormap.incremental_update(
            moved.x as i32,
            moved.y as i32,
            vert_strip.color,
            hori_strip.color,
        );

        self.terrain_pos = cur_pos;
        // Convert to f64, because GLSL doesn't understand i64
        assert!(
            cur_pos.x < F64_MAX_SAFE_INT && cur_pos.x > F64_MIN_SAFE_INT,
            "Terrain location not representable."
        );
        assert!(
            cur_pos.y < F64_MAX_SAFE_INT && cur_pos.y > F64_MIN_SAFE_INT,
            "Terrain location not representable."
        );
        self.u_terrain_pos.value = cur_pos.cast().unwrap();
    }

    pub fn terrain_from_world(&self) -> Isometry3<f64> {
        self.grid_coordinates.terrain_from_world.clone()
    }

    pub fn submit(&self) {
        self.grid_coordinates.submit();
        self.u_terrain_pos.submit();
        self.heightmap.submit();
        self.colormap.submit();
    }

    fn load(&self, min_x: i64, min_y: i64, width: usize, height: usize) -> HeightAndColor {
        HeightAndColor {
            height: self.height_tiles.load(min_x, min_y, width, height),
            color: self.color_tiles.load(min_x, min_y, width, height),
        }
    }
}

/// This struct's job is to convert from continuous world positions to discrete
/// terrain positions and to provide the necessary variables to do the inverse
/// calculation to the vertex shader.
struct GridCoordinateFrame {
    u_origin: GlUniform<Vector3<f64>>,
    u_world_from_terrain: GlUniform<Matrix4<f64>>,
    u_resolution_m: GlUniform<f64>,
    texture_half_extent: Vector2<i64>,
    terrain_from_world: Isometry3<f64>,
}

impl GridCoordinateFrame {
    fn new(program: &GlProgram, metadata: Metadata, texture_size: u32) -> Self {
        let u_origin = GlUniform::new(&program, "terrain_origin_m", metadata.origin);
        let terrain_from_world = metadata.world_from_terrain.inverse();
        let u_world_from_terrain = GlUniform::new(
            &program,
            "terrain_to_world",
            Matrix4::from({
                let decomp: Decomposed<_, _> = metadata.world_from_terrain.into();
                decomp
            }),
        );
        let u_resolution_m = GlUniform::new(&program, "terrain_res_m", metadata.resolution_m);
        let texture_half_extent =
            Vector2::new(i64::from(texture_size) / 2, i64::from(texture_size) / 2);
        GridCoordinateFrame {
            u_origin,
            u_world_from_terrain,
            u_resolution_m,
            texture_half_extent,
            terrain_from_world,
        }
    }

    /// Returns the terrain pos (i.e. the coordinate of the lower corner of the terrain) for
    /// a given camera position (in the world coordinate system).
    fn terrain_pos_for_camera_pos(&self, world_pos: Point3<f64>) -> Vector2<i64> {
        let local_pos = &self.terrain_from_world * &world_pos;
        let x = ((local_pos.x - self.u_origin.value.x) / self.u_resolution_m.value).floor();
        let y = ((local_pos.y - self.u_origin.value.y) / self.u_resolution_m.value).floor();
        (Vector2::new(x, y)).cast().unwrap() - self.texture_half_extent
    }

    fn submit(&self) {
        self.u_origin.submit();
        self.u_world_from_terrain.submit();
        self.u_resolution_m.submit();
    }
}
<|endoftext|>