<commit_before>use std::collections::HashMap;

use yxorp::messages::{Command,HttpFront,TlsFront,Instance};

#[derive(Debug,Clone,PartialEq,Eq,Hash, Serialize, Deserialize)]
pub struct HttpProxyInstance {
  ip_address: String,
  port:       u16,
}

pub type AppId = String;

#[derive(Debug,Clone,PartialEq,Eq,Hash, Serialize, Deserialize)]
pub struct HttpProxyFront {
  app_id:     AppId,
  hostname:   String,
  path_begin: String,
}

#[derive(Debug,Clone,PartialEq,Eq, Serialize, Deserialize)]
pub struct HttpProxy {
  ip_address: String,
  port:       u16,
  fronts:     HashMap<AppId, Vec<HttpProxyFront>>,
  instances:  HashMap<AppId, Vec<HttpProxyInstance>>,
}

#[derive(Debug,Clone,PartialEq,Eq,Hash, Serialize, Deserialize)]
pub struct TlsProxyFront {
  app_id:      AppId,
  hostname:    String,
  path_begin:  String,
  certificate: String,
  key:         String,
  certificate_chain: Vec<String>,
}

#[derive(Debug,Clone,PartialEq,Eq,Serialize, Deserialize)]
pub struct TlsProxy {
  ip_address: String,
  port:       u16,
  fronts:     HashMap<AppId, Vec<TlsProxyFront>>,
  instances:  HashMap<AppId, Vec<HttpProxyInstance>>,
}

#[derive(Debug,Clone,PartialEq,Eq,Serialize,Deserialize)]
pub enum ConfigState {
  Http(HttpProxy),
  Tls(TlsProxy),
  Tcp
}

impl ConfigState {
  pub fn handle_command(&mut self, command: &Command) {
    match *self {
      ConfigState::Http(ref mut state) => state.handle_command(command),
      ConfigState::Tls(ref mut state)  => state.handle_command(command),
      ConfigState::Tcp                 => {},
    }
  }

  pub fn generate_commands(&self) -> Vec<Command> {
    match *self {
      ConfigState::Http(ref state) => state.generate_commands(),
      ConfigState::Tls(ref state)  => state.generate_commands(),
      ConfigState::Tcp             => vec!(),
    }
  }
}

impl HttpProxy {
  pub fn new(ip: String, port: u16) -> HttpProxy {
    HttpProxy {
      ip_address: ip,
      port:       port,
      fronts:     HashMap::new(),
      instances:  HashMap::new(),
    }
  }

  pub fn handle_command(&mut self, command: &Command) {
    match command {
      &Command::AddHttpFront(ref front) => {
        let f = HttpProxyFront {
          app_id:     front.app_id.clone(),
          hostname:   front.hostname.clone(),
          path_begin: front.path_begin.clone(),
        };
        if self.fronts.contains_key(&front.app_id) {
          self.fronts.get_mut(&front.app_id).map(|front| {
            if !front.contains(&f) {
              front.push(f);
            }
          });
        } else {
          self.fronts.insert(front.app_id.clone(), vec!(f));
        }
      },
      &Command::RemoveHttpFront(ref front) => {
        if let Some(front_list) = self.fronts.get_mut(&front.app_id) {
          front_list.retain(|el| el.hostname != front.hostname || el.path_begin != front.path_begin);
        }
      },
      &Command::AddInstance(ref instance)  => {
        let inst = HttpProxyInstance {
          ip_address: instance.ip_address.clone(),
          port:       instance.port,
        };
        if self.instances.contains_key(&instance.app_id) {
          self.instances.get_mut(&instance.app_id).map(|instance| {
            if !instance.contains(&inst) {
              instance.push(inst);
            }
          });
        } else {
          self.instances.insert(instance.app_id.clone(), vec!(inst));
        }
      },
      &Command::RemoveInstance(ref instance) => {
        if let Some(instance_list) = self.instances.get_mut(&instance.app_id) {
          instance_list.retain(|el| el.ip_address != instance.ip_address || el.port != instance.port);
          /*let mut v = Vec::new();
          for el in front.instances.iter() {
            if el.ip_address != instance.ip_address || el.port != instance.port {
              v.push(el.clone());
            }
          }
          front.instances = v;
          */
        }
      }
      _ => {}
    }
  }

  pub fn generate_commands(&self) -> Vec<Command> {
    let mut v = Vec::new();
    for (app_id, front_list) in self.fronts.iter() {
      for front in front_list {
        v.push(Command::AddHttpFront(HttpFront {
          app_id:     app_id.clone(),
          hostname:   front.hostname.clone(),
          path_begin: front.path_begin.clone(),
        }));
      }
      for (app_id,instance_list) in self.instances.iter() {
        for instance in instance_list {
          v.push(Command::AddInstance(Instance {
            app_id:     app_id.clone(),
            ip_address: instance.ip_address.clone(),
            port:       instance.port.clone(),
          }));
        }
      }
    }

    v
  }
}

impl TlsProxy {
  pub fn new(ip: String, port: u16) -> TlsProxy {
    TlsProxy {
      ip_address: ip,
      port:       port,
      fronts:     HashMap::new(),
      instances:  HashMap::new(),
    }
  }

  pub fn handle_command(&mut self, command: &Command) {
    match command {
      &Command::AddTlsFront(ref front) => {
        let f = TlsProxyFront {
          app_id:      front.app_id.clone(),
          hostname:    front.hostname.clone(),
          path_begin:  front.path_begin.clone(),
          certificate: front.certificate.clone(),
          certificate_chain: front.certificate_chain.clone(),
          key:         front.key.clone(),
        };
        if self.fronts.contains_key(&front.app_id) {
          self.fronts.get_mut(&front.app_id).map(|front| {
            if !front.contains(&f) {
              front.push(f);
            }
          });
        } else {
          self.fronts.insert(front.app_id.clone(), vec!(f));
        }
      },
      &Command::RemoveTlsFront(ref front) => {
        self.fronts.remove(&front.app_id);
      },
      &Command::AddInstance(ref instance)  => {
        let inst = HttpProxyInstance {
          ip_address: instance.ip_address.clone(),
          port:       instance.port,
        };
        if self.instances.contains_key(&instance.app_id) {
          self.instances.get_mut(&instance.app_id).map(|instance| {
            if !instance.contains(&inst) {
              instance.push(inst);
            }
          });
        } else {
          self.instances.insert(instance.app_id.clone(), vec!(inst));
        }
      },
      &Command::RemoveInstance(ref instance) => {
        if let Some(instance_list) = self.instances.get_mut(&instance.app_id) {
          instance_list.retain(|el| el.ip_address != instance.ip_address || el.port != instance.port);
          /*let mut v = Vec::new();
          for el in instance_list.iter() {
            if el.ip_address != instance.ip_address || el.port != instance.port {
              v.push(el.clone());
            }
          }
          front.instances = v;*/
        }
      }
      _ => {}
    }
  }

  pub fn generate_commands(&self) -> Vec<Command> {
    let mut v = Vec::new();
    for (app_id, front_list) in &self.fronts {
      for front in front_list {
        v.push(Command::AddTlsFront(TlsFront {
          app_id:      app_id.clone(),
          hostname:    front.hostname.clone(),
          path_begin:  front.path_begin.clone(),
          certificate: front.certificate.clone(),
          certificate_chain: front.certificate_chain.clone(),
          key:         front.key.clone(),
        }));
      }
    }
    for (app_id, instance_list) in &self.instances {
      for instance in instance_list {
        v.push(Command::AddInstance(Instance {
          app_id:     app_id.clone(),
          ip_address: instance.ip_address.clone(),
          port:       instance.port.clone(),
        }));
      }
    }

    v
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use yxorp::messages::{Command,HttpFront,Instance};

  #[test]
  fn serialize() {
    let mut state = HttpProxy::new(String::from("127.0.0.1"), 80);
    state.handle_command(&Command::AddHttpFront(HttpFront { app_id: String::from("app_1"), hostname: String::from("lolcatho.st:8080"), path_begin: String::from("/") }));
    state.handle_command(&Command::AddHttpFront(HttpFront { app_id: String::from("app_2"), hostname: String::from("test.local"), path_begin: String::from("/abc") }));
    state.handle_command(&Command::AddInstance(Instance { app_id: String::from("app_1"), ip_address: String::from("127.0.0.1"), port: 1026 }));
    state.handle_command(&Command::AddInstance(Instance { app_id: String::from("app_1"), ip_address: String::from("127.0.0.2"), port: 1027 }));
    state.handle_command(&Command::AddInstance(Instance { app_id: String::from("app_2"), ip_address: String::from("192.167.1.2"), port: 1026 }));
    state.handle_command(&Command::AddInstance(Instance { app_id: String::from("app_1"), ip_address: String::from("192.168.1.3"), port: 1027 }));
    state.handle_command(&Command::RemoveInstance(Instance { app_id: String::from("app_1"), ip_address: String::from("192.168.1.3"), port: 1027 }));

    /*
    let encoded = state.encode();
    println!("serialized:\n{}", encoded);

    let new_state: Option<HttpProxy> = decode_str(&encoded);
    println!("deserialized:\n{:?}", new_state);
    assert_eq!(new_state, Some(state));
    */
    //assert!(false);
  }
}
<commit_msg>do not generate redundant commands<commit_after>use std::collections::HashMap;

use yxorp::messages::{Command,HttpFront,TlsFront,Instance};

#[derive(Debug,Clone,PartialEq,Eq,Hash, Serialize, Deserialize)]
pub struct HttpProxyInstance {
  ip_address: String,
  port:       u16,
}

pub type AppId = String;

#[derive(Debug,Clone,PartialEq,Eq,Hash, Serialize, Deserialize)]
pub struct HttpProxyFront {
  app_id:     AppId,
  hostname:   String,
  path_begin: String,
}

#[derive(Debug,Clone,PartialEq,Eq, Serialize, Deserialize)]
pub struct HttpProxy {
  ip_address: String,
  port:       u16,
  fronts:     HashMap<AppId, Vec<HttpProxyFront>>,
  instances:  HashMap<AppId, Vec<HttpProxyInstance>>,
}

#[derive(Debug,Clone,PartialEq,Eq,Hash, Serialize, Deserialize)]
pub struct TlsProxyFront {
  app_id:      AppId,
  hostname:    String,
  path_begin:  String,
  certificate: String,
  key:         String,
  certificate_chain: Vec<String>,
}

#[derive(Debug,Clone,PartialEq,Eq,Serialize, Deserialize)]
pub struct TlsProxy {
  ip_address: String,
  port:       u16,
  fronts:     HashMap<AppId, Vec<TlsProxyFront>>,
  instances:  HashMap<AppId, Vec<HttpProxyInstance>>,
}

#[derive(Debug,Clone,PartialEq,Eq,Serialize,Deserialize)]
pub enum ConfigState {
  Http(HttpProxy),
  Tls(TlsProxy),
  Tcp
}

impl ConfigState {
  pub fn handle_command(&mut self, command: &Command) {
    match *self {
      ConfigState::Http(ref mut state) => state.handle_command(command),
      ConfigState::Tls(ref mut state)  => state.handle_command(command),
      ConfigState::Tcp                 => {},
    }
  }

  pub fn generate_commands(&self) -> Vec<Command> {
    match *self {
      ConfigState::Http(ref state) => state.generate_commands(),
      ConfigState::Tls(ref state)  => state.generate_commands(),
      ConfigState::Tcp             => vec!(),
    }
  }
}

impl HttpProxy {
  pub fn new(ip: String, port: u16) -> HttpProxy {
    HttpProxy {
      ip_address: ip,
      port:       port,
      fronts:     HashMap::new(),
      instances:  HashMap::new(),
    }
  }

  pub fn handle_command(&mut self, command: &Command) {
    match command {
      &Command::AddHttpFront(ref front) => {
        let f = HttpProxyFront {
          app_id:     front.app_id.clone(),
          hostname:   front.hostname.clone(),
          path_begin: front.path_begin.clone(),
        };
        if self.fronts.contains_key(&front.app_id) {
          self.fronts.get_mut(&front.app_id).map(|front| {
            if !front.contains(&f) {
              front.push(f);
            }
          });
        } else {
          self.fronts.insert(front.app_id.clone(), vec!(f));
        }
      },
      &Command::RemoveHttpFront(ref front) => {
        if let Some(front_list) = self.fronts.get_mut(&front.app_id) {
          front_list.retain(|el| el.hostname != front.hostname || el.path_begin != front.path_begin);
        }
      },
      &Command::AddInstance(ref instance)  => {
        let inst = HttpProxyInstance {
          ip_address: instance.ip_address.clone(),
          port:       instance.port,
        };
        if self.instances.contains_key(&instance.app_id) {
          self.instances.get_mut(&instance.app_id).map(|instance| {
            if !instance.contains(&inst) {
              instance.push(inst);
            }
          });
        } else {
          self.instances.insert(instance.app_id.clone(), vec!(inst));
        }
      },
      &Command::RemoveInstance(ref instance) => {
        if let Some(instance_list) = self.instances.get_mut(&instance.app_id) {
          instance_list.retain(|el| el.ip_address != instance.ip_address || el.port != instance.port);
          /*let mut v = Vec::new();
          for el in front.instances.iter() {
            if el.ip_address != instance.ip_address || el.port != instance.port {
              v.push(el.clone());
            }
          }
          front.instances = v;
          */
        }
      }
      _ => {}
    }
  }

  pub fn generate_commands(&self) -> Vec<Command> {
    let mut v = Vec::new();
    for (app_id, front_list) in self.fronts.iter() {
      for front in front_list {
        v.push(Command::AddHttpFront(HttpFront {
          app_id:     app_id.clone(),
          hostname:   front.hostname.clone(),
          path_begin: front.path_begin.clone(),
        }));
      }
    }

    for (app_id,instance_list) in self.instances.iter() {
      for instance in instance_list {
        v.push(Command::AddInstance(Instance {
          app_id:     app_id.clone(),
          ip_address: instance.ip_address.clone(),
          port:       instance.port.clone(),
        }));
      }
    }

    v
  }
}

impl TlsProxy {
  pub fn new(ip: String, port: u16) -> TlsProxy {
    TlsProxy {
      ip_address: ip,
      port:       port,
      fronts:     HashMap::new(),
      instances:  HashMap::new(),
    }
  }

  pub fn handle_command(&mut self, command: &Command) {
    match command {
      &Command::AddTlsFront(ref front) => {
        let f = TlsProxyFront {
          app_id:      front.app_id.clone(),
          hostname:    front.hostname.clone(),
          path_begin:  front.path_begin.clone(),
          certificate: front.certificate.clone(),
          certificate_chain: front.certificate_chain.clone(),
          key:         front.key.clone(),
        };
        if self.fronts.contains_key(&front.app_id) {
          self.fronts.get_mut(&front.app_id).map(|front| {
            if !front.contains(&f) {
              front.push(f);
            }
          });
        } else {
          self.fronts.insert(front.app_id.clone(), vec!(f));
        }
      },
      &Command::RemoveTlsFront(ref front) => {
        self.fronts.remove(&front.app_id);
      },
      &Command::AddInstance(ref instance)  => {
        let inst = HttpProxyInstance {
          ip_address: instance.ip_address.clone(),
          port:       instance.port,
        };
        if self.instances.contains_key(&instance.app_id) {
          self.instances.get_mut(&instance.app_id).map(|instance| {
            if !instance.contains(&inst) {
              instance.push(inst);
            }
          });
        } else {
          self.instances.insert(instance.app_id.clone(), vec!(inst));
        }
      },
      &Command::RemoveInstance(ref instance) => {
        if let Some(instance_list) = self.instances.get_mut(&instance.app_id) {
          instance_list.retain(|el| el.ip_address != instance.ip_address || el.port != instance.port);
          /*let mut v = Vec::new();
          for el in instance_list.iter() {
            if el.ip_address != instance.ip_address || el.port != instance.port {
              v.push(el.clone());
            }
          }
          front.instances = v;*/
        }
      }
      _ => {}
    }
  }

  pub fn generate_commands(&self) -> Vec<Command> {
    let mut v = Vec::new();
    for (app_id, front_list) in &self.fronts {
      for front in front_list {
        v.push(Command::AddTlsFront(TlsFront {
          app_id:      app_id.clone(),
          hostname:    front.hostname.clone(),
          path_begin:  front.path_begin.clone(),
          certificate: front.certificate.clone(),
          certificate_chain: front.certificate_chain.clone(),
          key:         front.key.clone(),
        }));
      }
    }
    for (app_id, instance_list) in &self.instances {
      for instance in instance_list {
        v.push(Command::AddInstance(Instance {
          app_id:     app_id.clone(),
          ip_address: instance.ip_address.clone(),
          port:       instance.port.clone(),
        }));
      }
    }

    v
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use yxorp::messages::{Command,HttpFront,Instance};

  #[test]
  fn serialize() {
    let mut state = HttpProxy::new(String::from("127.0.0.1"), 80);
    state.handle_command(&Command::AddHttpFront(HttpFront { app_id: String::from("app_1"), hostname: String::from("lolcatho.st:8080"), path_begin: String::from("/") }));
    state.handle_command(&Command::AddHttpFront(HttpFront { app_id: String::from("app_2"), hostname: String::from("test.local"), path_begin: String::from("/abc") }));
    state.handle_command(&Command::AddInstance(Instance { app_id: String::from("app_1"), ip_address: String::from("127.0.0.1"), port: 1026 }));
    state.handle_command(&Command::AddInstance(Instance { app_id: String::from("app_1"), ip_address: String::from("127.0.0.2"), port: 1027 }));
    state.handle_command(&Command::AddInstance(Instance { app_id: String::from("app_2"), ip_address: String::from("192.167.1.2"), port: 1026 }));
    state.handle_command(&Command::AddInstance(Instance { app_id: String::from("app_1"), ip_address: String::from("192.168.1.3"), port: 1027 }));
    state.handle_command(&Command::RemoveInstance(Instance { app_id: String::from("app_1"), ip_address: String::from("192.168.1.3"), port: 1027 }));

    /*
    let encoded = state.encode();
    println!("serialized:\n{}", encoded);

    let new_state: Option<HttpProxy> = decode_str(&encoded);
    println!("deserialized:\n{:?}", new_state);
    assert_eq!(new_state, Some(state));
    */
    //assert!(false);
  }
}
<|endoftext|>


<commit_before>#![feature(slice_patterns)]
#![feature(path_ext)]
extern crate eve;
extern crate hyper;
extern crate cookie;
extern crate mime;
extern crate url;
extern crate websocket;
extern crate rustc_serialize;
extern crate conduit_mime_types;

use std::io::Read;
use std::io::Write;
use std::fs::File;
use std::error::Error;
use hyper::net::Fresh;
use hyper::server::{Server, Request, Response};
use hyper::uri::RequestUri;
use hyper::Url;
use hyper::header::{Headers,ContentType,Location,SetCookie};
use cookie::Cookie;
use mime::Mime;
use url::SchemeData::Relative;
use rustc_serialize::json;
use websocket::{Message, Sender};
use std::path::Path;
use std::fs::PathExt;
use conduit_mime_types::Types;
use std::str::FromStr;

use eve::client::*;
use eve::server;
use eve::value::Value;

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
struct Session {
	client: String,
	id: String,
	user_id: String,
	object: String,
	created_at: f64,
	expires_at: f64,
	ip: String,
	user: User,
}

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
struct User {
	custom: Custom,
	id: String,
	realm_id: String,
	username: String,
	state: String,
	user_type: String,
	reference: Option<String>,
	name: String,
	email: String,
	object: String,
	last_login_at: f64,
	last_login_on: f64,
	created_at: f64,
	first_name: Option<String>,
	last_name: Option<String>,
	credentials: Vec<Credential>,
	membership_count: f64,
}

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
struct Custom;

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
struct Credential {
	id: String,
	credential_type: String,
	object: String,
}

fn main() {
	Server::http(login).listen("0.0.0.0:8080").unwrap();
}

fn read_file_bytes(filename: &str) -> Vec<u8> {
    let mut file = File::open(&filename).unwrap();
    let mut contents: Vec<u8> = Vec::new();
	file.read_to_end(&mut contents).unwrap();
	contents
}

fn file_exists(path: &str) -> bool {
	let path_obj = Path::new(path);
	path_obj.is_file() && path_obj.exists()
}

fn serve_local_or_file(mut res: Response<Fresh>, path: &Vec<String>, default_file: &str) {
	let mime_types = Types::new().unwrap();
	let local_path = path[1..].iter().fold("../ui".to_owned(), |end, cur| end + "/" + cur);
	let file;
	let file_path: &str;
	if file_exists(&local_path) {
		file = read_file_bytes(&local_path);
		file_path = &local_path;
	} else {
		let content = read_file_bytes(default_file);
		//@HACK, @TODO: absolutize the html file so that it looks in the right place
		//this allows us to use file:/// locally, while still doing the right thing
		//when we're hooked up to the server
		let mut str = String::from_utf8(content).unwrap();
		str = str.replace("href=\"", "href=\"/app/");
		str = str.replace("src=\"", "src=\"/app/");
		file = str.as_bytes().to_owned();
		file_path = default_file;
	}
	let mime: Mime = Mime::from_str(mime_types.mime_for_path(Path::new(&file_path))).unwrap();
	res.headers_mut().set(ContentType(mime));
	let mut res = res.start().unwrap();
	res.write_all(&file).unwrap();
	res.end().unwrap();
}

fn login(req: Request, mut res: Response<Fresh>) {

	match (&req.method.clone(), &req.uri.clone()) {
		(&hyper::Get, &RequestUri::AbsolutePath(ref relative_path)) => {

			// Form a url from the path
			let absolute_path = "http://localhost".to_string() + relative_path;
			let url = Url::parse(&*absolute_path).unwrap();

			// Get the file name
			let scheme_data = &url.scheme_data;

			let requested_file = match scheme_data {
				&Relative(ref rsd) => rsd.path[0].clone(),
				_ => panic!("Expected relative path"),
			};
			let path_info = match scheme_data {
				&Relative(ref rsd) => rsd,
				_ => panic!("Expected relative path"),
			};

			// Parse the query string
			let query_pairs = &url.query_pairs();

			// Handle login
			match &*requested_file {
				"app.html" | "app" => {
					serve_local_or_file(res, &path_info.path, "../ui/app.html");
				},
				"editor.html" | "editor" => {
					serve_local_or_file(res, &path_info.path, "../ui/editor.html");
				},
				"login.html" => {
					println!("Authenticating User");
					let pairs = query_pairs.clone().unwrap();
					match &pairs[..] {
						[(_ , ref page), (ref token_type, ref token), ..] if token_type.clone() == "token".to_string() => {

							// We have a login token, now to authenticate
							let mut client = hyper::client::Client::new();
							let api_call = "https://api-e1.authrocket.com/v1/sessions/".to_string() + token;
							let req = client.request(hyper::method::Method::Get,&*api_call);

							// Set the appropriate headers for authorocket
							let mut headers = Headers::new();
							let json: Mime = "application/json".parse().unwrap();
							let content_type = ContentType(json);
							headers.set_raw("X-Authrocket-Account",vec!["org_0vC7wPw9XphPGQnSqYB6bz".to_string().into_bytes()]);
							headers.set_raw("X-Authrocket-Api-Key",vec!["key_jtnCRWxQvDD0p5HATR9RBIe4WnxnwV6pWNzwmZQLnSZ".to_string().into_bytes()]);
							headers.set_raw("X-Authrocket-Realm",vec!["rl_0vC7wd03CqwhpK7kT8fvAc".to_string().into_bytes()]);
							headers.set_raw("Accept",vec!["application/json".to_string().into_bytes()]);
							headers.set(content_type);

							// Send the request and receive a response with session data
							let mut client_res = req.headers(headers).send().unwrap();

							match client_res.status_raw() {

								&hyper::http::RawStatus(200,_) => {

									let mut body = String::new();
									client_res.read_to_string(&mut body).unwrap();
									let session_data: Session = json::decode(&body).unwrap();
									println!("Welcome to Eve, {:?}!",session_data.user.username);
									println!("Login Successful. Redirecting to user area.");

									// Connect to the Eve runtime and add the user to the eveusers table
									let ws_result = open_websocket("ws://0.0.0.0:2794");
									match ws_result {
										// If things went okay, redirect to the Eve UI
										Ok(mut sender) => {
											// Form the response
											*res.status_mut() = hyper::status::StatusCode::PermanentRedirect;

											// Form the response headers
											let mut headers = Headers::new();
											let location = Location("/".to_string() + page);
											let user_cookie = Cookie::new("userid".to_string(),session_data.user.id.clone());
											let cookies = SetCookie(vec![user_cookie]);
											headers.set(location);
											headers.set(cookies);
											*res.headers_mut() = headers;

											// Create eveusers table and insert the new user
											let table_name = "eveusers";
											let table_fields = vec!["id","username"];

											let row_data = vec![
																Value::String(session_data.user.id.clone()),
																Value::String(session_data.user.username.clone())
														   	   ];
											let insert_user = insert_fact(&table_name,&table_fields,&row_data,None);
											send_event(&insert_user,&mut sender);
											let _ = sender.send_message(Message::Close(None));
										}
										// Otherwise, throw an error... maybe redirect to a special page.
										Err(e) => {
											println!("ERROR: Had trouble connecting to the Eve runtime: {}. Is the server running?",e);
											*res.status_mut() = hyper::status::StatusCode::NotFound;
											panic!("Oh no!");
											//serve_file("404.html",res);
										}
									}

									println!("Login complete.");
								}
								_ => {
									println!("ERROR: Could not authenticate user with token {}",token);
									*res.status_mut() = hyper::status::StatusCode::Forbidden;
									panic!("Oh no!");
									//serve_file("404.html",res);
								}
							};
						},
						_ => panic!("Oh no!"), //serve_file("404.html",res),
					}
				},
				"logout.html" => {
					println!("Logging out...");
					let user_id = server::get_user_id(req.headers.get::<hyper::header::Cookie>());
                	println!("{:?}",user_id);
				},
				"favicon.ico" => (),
				other => panic!("Cannot serve {}",other), //serve_file(&*requested_file,res),
			};
		}
		_ => panic!("Oh no!"),
	}
}<commit_msg>Quick hack to do the right thing for uris incorrectly prepended with "/app/"<commit_after>#![feature(slice_patterns)]
#![feature(path_ext)]
extern crate eve;
extern crate hyper;
extern crate cookie;
extern crate mime;
extern crate url;
extern crate websocket;
extern crate rustc_serialize;
extern crate conduit_mime_types;

use std::io::Read;
use std::io::Write;
use std::fs::File;
use std::error::Error;
use hyper::net::Fresh;
use hyper::server::{Server, Request, Response};
use hyper::uri::RequestUri;
use hyper::Url;
use hyper::header::{Headers,ContentType,Location,SetCookie};
use cookie::Cookie;
use mime::Mime;
use url::SchemeData::Relative;
use rustc_serialize::json;
use websocket::{Message, Sender};
use std::path::Path;
use std::fs::PathExt;
use conduit_mime_types::Types;
use std::str::FromStr;

use eve::client::*;
use eve::server;
use eve::value::Value;

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
struct Session {
	client: String,
	id: String,
	user_id: String,
	object: String,
	created_at: f64,
	expires_at: f64,
	ip: String,
	user: User,
}

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
struct User {
	custom: Custom,
	id: String,
	realm_id: String,
	username: String,
	state: String,
	user_type: String,
	reference: Option<String>,
	name: String,
	email: String,
	object: String,
	last_login_at: f64,
	last_login_on: f64,
	created_at: f64,
	first_name: Option<String>,
	last_name: Option<String>,
	credentials: Vec<Credential>,
	membership_count: f64,
}

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
struct Custom;

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
struct Credential {
	id: String,
	credential_type: String,
	object: String,
}

fn main() {
	Server::http(login).listen("0.0.0.0:8080").unwrap();
}

fn read_file_bytes(filename: &str) -> Vec<u8> {
    let mut file = File::open(&filename).unwrap();
    let mut contents: Vec<u8> = Vec::new();
	file.read_to_end(&mut contents).unwrap();
	contents
}

fn file_exists(path: &str) -> bool {
	let path_obj = Path::new(path);
	path_obj.is_file() && path_obj.exists()
}

fn serve_local_or_file(mut res: Response<Fresh>, path: &Vec<String>, default_file: &str) {
	let mime_types = Types::new().unwrap();
	let local_path = path[1..].iter().fold("../ui".to_owned(), |end, cur| end + "/" + cur);
	let file;
	let file_path: &str;
	if file_exists(&local_path) {
		file = read_file_bytes(&local_path);
		file_path = &local_path;
	} else {
		let content = read_file_bytes(default_file);
		//@HACK, @TODO: absolutize the html file so that it looks in the right place
		//this allows us to use file:/// locally, while still doing the right thing
		//when we're hooked up to the server
		let mut str = String::from_utf8(content).unwrap();
		str = str.replace("href=\"", "href=\"/app/");
		str = str.replace("src=\"", "src=\"/app/");
		str = str.replace("/app/http", "http");
		file = str.as_bytes().to_owned();
		file_path = default_file;
	}
	let mime: Mime = Mime::from_str(mime_types.mime_for_path(Path::new(&file_path))).unwrap();
	res.headers_mut().set(ContentType(mime));
	let mut res = res.start().unwrap();
	res.write_all(&file).unwrap();
	res.end().unwrap();
}

fn login(req: Request, mut res: Response<Fresh>) {

	match (&req.method.clone(), &req.uri.clone()) {
		(&hyper::Get, &RequestUri::AbsolutePath(ref relative_path)) => {

			// Form a url from the path
			let absolute_path = "http://localhost".to_string() + relative_path;
			let url = Url::parse(&*absolute_path).unwrap();

			// Get the file name
			let scheme_data = &url.scheme_data;

			let requested_file = match scheme_data {
				&Relative(ref rsd) => rsd.path[0].clone(),
				_ => panic!("Expected relative path"),
			};
			let path_info = match scheme_data {
				&Relative(ref rsd) => rsd,
				_ => panic!("Expected relative path"),
			};

			// Parse the query string
			let query_pairs = &url.query_pairs();

			// Handle login
			match &*requested_file {
				"app.html" | "app" => {
					serve_local_or_file(res, &path_info.path, "../ui/app.html");
				},
				"editor.html" | "editor" => {
					serve_local_or_file(res, &path_info.path, "../ui/editor.html");
				},
				"login.html" => {
					println!("Authenticating User");
					let pairs = query_pairs.clone().unwrap();
					match &pairs[..] {
						[(_ , ref page), (ref token_type, ref token), ..] if token_type.clone() == "token".to_string() => {

							// We have a login token, now to authenticate
							let mut client = hyper::client::Client::new();
							let api_call = "https://api-e1.authrocket.com/v1/sessions/".to_string() + token;
							let req = client.request(hyper::method::Method::Get,&*api_call);

							// Set the appropriate headers for authorocket
							let mut headers = Headers::new();
							let json: Mime = "application/json".parse().unwrap();
							let content_type = ContentType(json);
							headers.set_raw("X-Authrocket-Account",vec!["org_0vC7wPw9XphPGQnSqYB6bz".to_string().into_bytes()]);
							headers.set_raw("X-Authrocket-Api-Key",vec!["key_jtnCRWxQvDD0p5HATR9RBIe4WnxnwV6pWNzwmZQLnSZ".to_string().into_bytes()]);
							headers.set_raw("X-Authrocket-Realm",vec!["rl_0vC7wd03CqwhpK7kT8fvAc".to_string().into_bytes()]);
							headers.set_raw("Accept",vec!["application/json".to_string().into_bytes()]);
							headers.set(content_type);

							// Send the request and receive a response with session data
							let mut client_res = req.headers(headers).send().unwrap();

							match client_res.status_raw() {

								&hyper::http::RawStatus(200,_) => {

									let mut body = String::new();
									client_res.read_to_string(&mut body).unwrap();
									let session_data: Session = json::decode(&body).unwrap();
									println!("Welcome to Eve, {:?}!",session_data.user.username);
									println!("Login Successful. Redirecting to user area.");

									// Connect to the Eve runtime and add the user to the eveusers table
									let ws_result = open_websocket("ws://0.0.0.0:2794");
									match ws_result {
										// If things went okay, redirect to the Eve UI
										Ok(mut sender) => {
											// Form the response
											*res.status_mut() = hyper::status::StatusCode::PermanentRedirect;

											// Form the response headers
											let mut headers = Headers::new();
											let location = Location("/".to_string() + page);
											let user_cookie = Cookie::new("userid".to_string(),session_data.user.id.clone());
											let cookies = SetCookie(vec![user_cookie]);
											headers.set(location);
											headers.set(cookies);
											*res.headers_mut() = headers;

											// Create eveusers table and insert the new user
											let table_name = "eveusers";
											let table_fields = vec!["id","username"];

											let row_data = vec![
																Value::String(session_data.user.id.clone()),
																Value::String(session_data.user.username.clone())
														   	   ];
											let insert_user = insert_fact(&table_name,&table_fields,&row_data,None);
											send_event(&insert_user,&mut sender);
											let _ = sender.send_message(Message::Close(None));
										}
										// Otherwise, throw an error... maybe redirect to a special page.
										Err(e) => {
											println!("ERROR: Had trouble connecting to the Eve runtime: {}. Is the server running?",e);
											*res.status_mut() = hyper::status::StatusCode::NotFound;
											panic!("Oh no!");
											//serve_file("404.html",res);
										}
									}

									println!("Login complete.");
								}
								_ => {
									println!("ERROR: Could not authenticate user with token {}",token);
									*res.status_mut() = hyper::status::StatusCode::Forbidden;
									panic!("Oh no!");
									//serve_file("404.html",res);
								}
							};
						},
						_ => panic!("Oh no!"), //serve_file("404.html",res),
					}
				},
				"logout.html" => {
					println!("Logging out...");
					let user_id = server::get_user_id(req.headers.get::<hyper::header::Cookie>());
                	println!("{:?}",user_id);
				},
				"favicon.ico" => (),
				other => panic!("Cannot serve {}",other), //serve_file(&*requested_file,res),
			};
		}
		_ => panic!("Oh no!"),
	}
}<|endoftext|>


<commit_before>use libc;

use std::collections::HashMap;
use std::collections::hash_map;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::ptr;

use error::*;
use parsers::Parse;

pub struct PropertyBag<'a>(HashMap<&'a CStr, &'a CStr>);

pub struct OwnedPropertyBag(HashMap<CString, CString>);

pub struct PropertyBagIter<'a> {
    pbag: &'a PropertyBag<'a>,
    iter: hash_map::Iter<'a, &'a CStr, &'a CStr>
}

impl<'a> PropertyBag<'a> {
    pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
        let mut map = HashMap::new();

        if !pairs.is_null() {
            let mut i = 0;
            loop {
                let key = *pairs.offset(i);
                if !key.is_null() {
                    let val = *pairs.offset(i + 1);
                    assert!(!val.is_null());

                    let key_str = CStr::from_ptr(key);
                    let val_str = CStr::from_ptr(val);

                    map.insert(key_str, val_str);
                } else {
                    break;
                }

                i += 2;
            }
        }

        PropertyBag(map)
    }

    pub fn from_owned(owned: &OwnedPropertyBag) -> PropertyBag {
        let mut map = HashMap::new();

        for (k, v) in &owned.0 {
            map.insert(k.deref(), v.deref());
        }

        PropertyBag(map)
    }

    pub fn to_owned(&self) -> OwnedPropertyBag {
        let mut map = HashMap::<CString, CString>::new();

        for (k, v) in &self.0 {
            map.insert((*k).to_owned(), (*v).to_owned());
        }

        OwnedPropertyBag(map)
    }

    pub fn ffi(&self) -> *const PropertyBag {
        self as *const PropertyBag
    }

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

    pub fn lookup_cstr(&self, key: &CStr) -> Option<&CStr> {
        self.0.get(key).map(|v| *v)
    }

    pub fn lookup(&self, key: &str) -> Option<&str> {
        let k = CString::new(key).unwrap();
        self.lookup_cstr(&k).map(|v| v.to_str().unwrap())
    }

    pub fn enumerate(&self,
                 enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char, data: *const libc::c_void),
                 data: *const libc::c_void) {
        for (k, v) in &self.0 {
            enum_fn(k.as_ptr(), v.as_ptr(), data);
        }
    }

    pub fn iter(&self) -> PropertyBagIter {
        PropertyBagIter {
            pbag: self,
            iter: self.0.iter()
        }
    }
}

impl<'a> Iterator for PropertyBagIter<'a> {
    type Item = (&'a str, &'a str);

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(|(k, v)| (k.to_str().unwrap(), v.to_str().unwrap()))
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_new<'a>(atts: *const *const libc::c_char) -> *const PropertyBag<'a> {
    let pbag = unsafe { PropertyBag::new_from_key_value_pairs(atts) };
    Box::into_raw(Box::new(pbag))
}

#[no_mangle]
pub extern fn rsvg_property_bag_free(pbag: *mut PropertyBag) {
    unsafe {
        let _ = Box::from_raw(pbag);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_size(pbag: *const PropertyBag) -> libc::c_uint {
    unsafe {
        let pbag = &*pbag;

        pbag.len() as libc::c_uint
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_enumerate(pbag: *const PropertyBag,
                                          enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char, data: *const libc::c_void),
                                          data: *const libc::c_void) {
    unsafe {
        let pbag = &*pbag;

        pbag.enumerate(enum_fn, data);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_lookup(pbag: *const PropertyBag,
                                       raw_key: *const libc::c_char) -> *const libc::c_char {
    unsafe {
        let pbag = &*pbag;
        let key = CStr::from_ptr(raw_key);
        match pbag.lookup_cstr(key) {
            Some(v) => v.as_ptr(),
            None => ptr::null()
        }
    }
}

pub fn parse_or_none<T> (pbag: &PropertyBag,
                         key: &str,
                         data: <T as Parse>::Data,
                         validate: Option<fn(T) -> Result<T, AttributeError>>) -> Result <Option<T>, NodeError>
    where T: Parse<Err = AttributeError> + Copy
{
    let value = pbag.lookup(key);

    match value {
        Some (v) => {
            T::parse (&v, data)
                .and_then (|v|
                           if let Some(validate) = validate {
                               validate(v)
                                   .map(Some)
                           } else {
                               Ok(Some(v))
                           })
                .map_err (|e| NodeError::attribute_error (key, e))
        },

        None => Ok(None)
    }
}

pub fn parse_or_default<T> (pbag: &PropertyBag,
                            key: &str,
                            data: <T as Parse>::Data,
                            validate: Option<fn(T) -> Result<T, AttributeError>>) -> Result <T, NodeError>
    where T: Default + Parse<Err = AttributeError> + Copy
{
    parse_or_value (pbag, key, data, T::default (), validate)
}

pub fn parse_or_value<T> (pbag: &PropertyBag,
                          key: &str,
                          data: <T as Parse>::Data,
                          value: T,
                          validate: Option<fn(T) -> Result<T, AttributeError>>) -> Result <T, NodeError>
    where T: Parse<Err = AttributeError> + Copy
{
    Ok (parse_or_none (pbag, key, data, validate)?.unwrap_or (value))
}

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

    #[test]
    fn empty_property_bag() {
        let map = unsafe { PropertyBag::new_from_key_value_pairs(ptr::null()) };
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn property_bag_lookups_and_iters() {
        let pairs = [
            CString::new("alpha").unwrap(),
            CString::new("1").unwrap(),
            CString::new("beta").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        assert_eq!(pbag.lookup("alpha"), Some("1"));
        assert_eq!(pbag.lookup("beta"), Some("2"));
        assert_eq!(pbag.lookup("gamma"), None);

        let mut had_alpha: bool = false;
        let mut had_beta: bool = false;

        for (k, _) in pbag.iter() {
            if k == "alpha" {
                had_alpha = true;
            } else if k == "beta" {
                had_beta = true;
            }
        }

        assert!(had_alpha);
        assert!(had_beta);
    }
}
<commit_msg>PropertyBagIter: remove an unused field<commit_after>use libc;

use std::collections::HashMap;
use std::collections::hash_map;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::ptr;

use error::*;
use parsers::Parse;

pub struct PropertyBag<'a>(HashMap<&'a CStr, &'a CStr>);

pub struct OwnedPropertyBag(HashMap<CString, CString>);

pub struct PropertyBagIter<'a>(hash_map::Iter<'a, &'a CStr, &'a CStr>);

impl<'a> PropertyBag<'a> {
    pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
        let mut map = HashMap::new();

        if !pairs.is_null() {
            let mut i = 0;
            loop {
                let key = *pairs.offset(i);
                if !key.is_null() {
                    let val = *pairs.offset(i + 1);
                    assert!(!val.is_null());

                    let key_str = CStr::from_ptr(key);
                    let val_str = CStr::from_ptr(val);

                    map.insert(key_str, val_str);
                } else {
                    break;
                }

                i += 2;
            }
        }

        PropertyBag(map)
    }

    pub fn from_owned(owned: &OwnedPropertyBag) -> PropertyBag {
        let mut map = HashMap::new();

        for (k, v) in &owned.0 {
            map.insert(k.deref(), v.deref());
        }

        PropertyBag(map)
    }

    pub fn to_owned(&self) -> OwnedPropertyBag {
        let mut map = HashMap::<CString, CString>::new();

        for (k, v) in &self.0 {
            map.insert((*k).to_owned(), (*v).to_owned());
        }

        OwnedPropertyBag(map)
    }

    pub fn ffi(&self) -> *const PropertyBag {
        self as *const PropertyBag
    }

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

    pub fn lookup_cstr(&self, key: &CStr) -> Option<&CStr> {
        self.0.get(key).map(|v| *v)
    }

    pub fn lookup(&self, key: &str) -> Option<&str> {
        let k = CString::new(key).unwrap();
        self.lookup_cstr(&k).map(|v| v.to_str().unwrap())
    }

    pub fn enumerate(&self,
                 enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char, data: *const libc::c_void),
                 data: *const libc::c_void) {
        for (k, v) in &self.0 {
            enum_fn(k.as_ptr(), v.as_ptr(), data);
        }
    }

    pub fn iter(&self) -> PropertyBagIter {
        PropertyBagIter(self.0.iter())
    }
}

impl<'a> Iterator for PropertyBagIter<'a> {
    type Item = (&'a str, &'a str);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(k, v)| (k.to_str().unwrap(), v.to_str().unwrap()))
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_new<'a>(atts: *const *const libc::c_char) -> *const PropertyBag<'a> {
    let pbag = unsafe { PropertyBag::new_from_key_value_pairs(atts) };
    Box::into_raw(Box::new(pbag))
}

#[no_mangle]
pub extern fn rsvg_property_bag_free(pbag: *mut PropertyBag) {
    unsafe {
        let _ = Box::from_raw(pbag);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_size(pbag: *const PropertyBag) -> libc::c_uint {
    unsafe {
        let pbag = &*pbag;

        pbag.len() as libc::c_uint
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_enumerate(pbag: *const PropertyBag,
                                          enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char, data: *const libc::c_void),
                                          data: *const libc::c_void) {
    unsafe {
        let pbag = &*pbag;

        pbag.enumerate(enum_fn, data);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_lookup(pbag: *const PropertyBag,
                                       raw_key: *const libc::c_char) -> *const libc::c_char {
    unsafe {
        let pbag = &*pbag;
        let key = CStr::from_ptr(raw_key);
        match pbag.lookup_cstr(key) {
            Some(v) => v.as_ptr(),
            None => ptr::null()
        }
    }
}

pub fn parse_or_none<T> (pbag: &PropertyBag,
                         key: &str,
                         data: <T as Parse>::Data,
                         validate: Option<fn(T) -> Result<T, AttributeError>>) -> Result <Option<T>, NodeError>
    where T: Parse<Err = AttributeError> + Copy
{
    let value = pbag.lookup(key);

    match value {
        Some (v) => {
            T::parse (&v, data)
                .and_then (|v|
                           if let Some(validate) = validate {
                               validate(v)
                                   .map(Some)
                           } else {
                               Ok(Some(v))
                           })
                .map_err (|e| NodeError::attribute_error (key, e))
        },

        None => Ok(None)
    }
}

pub fn parse_or_default<T> (pbag: &PropertyBag,
                            key: &str,
                            data: <T as Parse>::Data,
                            validate: Option<fn(T) -> Result<T, AttributeError>>) -> Result <T, NodeError>
    where T: Default + Parse<Err = AttributeError> + Copy
{
    parse_or_value (pbag, key, data, T::default (), validate)
}

pub fn parse_or_value<T> (pbag: &PropertyBag,
                          key: &str,
                          data: <T as Parse>::Data,
                          value: T,
                          validate: Option<fn(T) -> Result<T, AttributeError>>) -> Result <T, NodeError>
    where T: Parse<Err = AttributeError> + Copy
{
    Ok (parse_or_none (pbag, key, data, validate)?.unwrap_or (value))
}

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

    #[test]
    fn empty_property_bag() {
        let map = unsafe { PropertyBag::new_from_key_value_pairs(ptr::null()) };
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn property_bag_lookups_and_iters() {
        let pairs = [
            CString::new("alpha").unwrap(),
            CString::new("1").unwrap(),
            CString::new("beta").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        assert_eq!(pbag.lookup("alpha"), Some("1"));
        assert_eq!(pbag.lookup("beta"), Some("2"));
        assert_eq!(pbag.lookup("gamma"), None);

        let mut had_alpha: bool = false;
        let mut had_beta: bool = false;

        for (k, _) in pbag.iter() {
            if k == "alpha" {
                had_alpha = true;
            } else if k == "beta" {
                had_beta = true;
            }
        }

        assert!(had_alpha);
        assert!(had_beta);
    }
}
<|endoftext|>


<commit_before>use super::*;

use std::cmp::Ordering;

pub(crate) fn prefix_encode(prefix: &[u8], buf: &[u8]) -> IVec {
    assert!(
        prefix <= buf,
        "prefix {:?} must be lexicographically <= to the encoded buf {:?}",
        prefix,
        buf
    );

    let max = u8::max_value() as usize;
    let zip = prefix.iter().zip(buf);
    let prefix_len = zip.take(max).take_while(|(a, b)| a == b).count();

    let encoded_len = 1 + buf.len() - prefix_len;

    let mut ret = Vec::with_capacity(encoded_len);
    ret.push(prefix_len as u8);
    ret.extend_from_slice(&buf[prefix_len..]);

    IVec::from(ret)
}

pub(crate) fn prefix_decode(prefix: &[u8], buf: &[u8]) -> Vec<u8> {
    assert!(!buf.is_empty());

    let prefix_len = buf[0] as usize;
    let mut ret = Vec::with_capacity(prefix_len + buf.len() - 1);

    ret.extend_from_slice(&prefix[..prefix_len]);
    ret.extend_from_slice(&buf[1..]);

    ret
}

pub(crate) fn prefix_reencode(
    old_prefix: &[u8],
    new_prefix: &[u8],
    buf: &[u8],
) -> IVec {
    assert!(!buf.is_empty());

    let old_prefix_len = buf[0] as usize;
    let old_prefix = &old_prefix[..old_prefix_len];
    let old_suffix = &buf[1..];

    let decoded_key = old_prefix.iter().chain(old_suffix.iter());
    let max_prefix_len = u8::max_value() as usize;

    let mut output = Vec::with_capacity(buf.len());
    output.push(0_u8);

    for (i, c) in decoded_key.enumerate() {
        if output[0] as usize == i
            && Some(c) == new_prefix.get(i)
            && i != max_prefix_len
        {
            output[0] += 1;
        } else {
            output.push(*c);
        }
    }

    IVec::from(output)
}

// NB: the correctness of this function depends on
// the invariant that the prefix is ALWAYS lexicographically
// Less than or Equal to the keys that have been encoded
// using it. Otherwise this comparison would make no sense.
pub(crate) fn prefix_cmp(a: &[u8], b: &[u8]) -> Ordering {
    if a.is_empty() && b.is_empty() {
        return Ordering::Equal;
    } else if a.is_empty() && !b.is_empty() {
        return Ordering::Less;
    } else if !a.is_empty() && b.is_empty() {
        return Ordering::Greater;
    }

    if a[0] > b[0] {
        Ordering::Less
    } else if a[0] < b[0] {
        Ordering::Greater
    } else {
        a[1..].cmp(&b[1..])
    }
}

/// Compare `a` and `b`, assuming that `a` is prefix encoded and `b` is not.
pub(crate) fn prefix_cmp_encoded(
    a: &[u8],
    mut b: &[u8],
    mut prefix: &[u8],
) -> Ordering {
    assert!(!a.is_empty() && a[0] as usize <= prefix.len());

    let mut a_prefix_len = a[0];
    let a_suffix = &a[1..];

    while a_prefix_len > 0 {
        if b.is_empty() || prefix[0] > b[0] {
            return Ordering::Greater;
        } else if prefix[0] < b[0] {
            return Ordering::Less;
        }

        a_prefix_len -= 1;
        b = &b[1..];
        prefix = &prefix[1..];
    }

    a_suffix.cmp(b)
}

#[test]
fn test_prefix() {
    let prefix = b"cat";
    assert_eq!(prefix_encode(prefix, prefix), vec![prefix.len() as u8]);
    assert_eq!(prefix_encode(prefix, b"catt"), vec![3, b't']);
    assert_eq!(prefix_encode(prefix, b"cb"), vec![1, b'b']);
    assert_eq!(prefix_encode(prefix, b"caz"), vec![2, b'z']);
    assert_eq!(prefix_encode(prefix, b"cvar"), vec![1, b'v', b'a', b'r']);
    assert_eq!(prefix_encode(prefix, b"zig"), vec![0, b'z', b'i', b'g']);

    let prefix = b"";
    assert_eq!(prefix_encode(prefix, prefix), vec![prefix.len() as u8]);
    assert_eq!(prefix_encode(prefix, b"ca"), vec![0, b'c', b'a']);
    assert_eq!(prefix_encode(prefix, b"cat"), vec![0, b'c', b'a', b't']);
    assert_eq!(prefix_encode(prefix, b"cab"), vec![0, b'c', b'a', b'b']);
    assert_eq!(
        prefix_encode(prefix, b"cvar"),
        vec![0, b'c', b'v', b'a', b'r']
    );
    assert_eq!(prefix_encode(prefix, b"zig"), vec![0, b'z', b'i', b'g']);

    let rtt = vec![b"" as &[u8], b"\x00cat", b"\x00", b"oyunwytounw\x00"];
    for item in rtt {
        assert_eq!(
            prefix_decode(prefix, &*prefix_encode(prefix, item)),
            item.to_vec()
        );
    }
}

#[test]
fn test_prefix_cmp() {
    assert_eq!(prefix_cmp(&[], &[]), Ordering::Equal);
    assert_eq!(prefix_cmp(&[0], &[]), Ordering::Greater);
    assert_eq!(prefix_cmp(&[], &[0]), Ordering::Less);

    assert_eq!(prefix_cmp(&[3], &[4]), Ordering::Greater);
    assert_eq!(prefix_cmp(&[4, 3], &[3, 4]), Ordering::Less);

    assert_eq!(prefix_cmp(&[1], &[1]), Ordering::Equal);
    assert_eq!(prefix_cmp(&[1, 1], &[1, 1]), Ordering::Equal);
    assert_eq!(prefix_cmp(&[1, 3], &[1, 1]), Ordering::Greater);
    assert_eq!(prefix_cmp(&[1, 1], &[1, 3]), Ordering::Less);
}

#[test]
fn test_prefix_cmp_encoded() {
    fn assert_pce(a: &[u8], b: &[u8], prefix: &[u8], expected: Ordering) {
        assert_eq!(
            prefix_cmp_encoded(a, &prefix_decode(prefix, b), prefix),
            expected
        );
    }

    let prefix = &vec![3, 3, 3, 3];
    assert_pce(&[0], &[0], prefix, Ordering::Equal);
    assert_pce(&[1], &[0], prefix, Ordering::Greater);
    assert_pce(&[0], &[1], prefix, Ordering::Less);

    assert_pce(&[3], &[2], prefix, Ordering::Greater);
    assert_pce(&[4, 3], &[3, 4], prefix, Ordering::Less);

    assert_pce(&[1], &[1], prefix, Ordering::Equal);
    assert_pce(&[1, 3, 3, 1], &[3, 1], prefix, Ordering::Equal);
    assert_pce(&[1, 3], &[1, 1], prefix, Ordering::Greater);
    assert_pce(&[1, 1], &[3, 3], prefix, Ordering::Less);
}
<commit_msg>Extract constant max prefix encoded size<commit_after>use super::*;

use std::cmp::Ordering;

const MAX_PREFIX_ENCODED_LENGTH: usize = u8::max_value() as usize;

pub(crate) fn prefix_encode(prefix: &[u8], buf: &[u8]) -> IVec {
    assert!(
        prefix <= buf,
        "prefix {:?} must be lexicographically <= to the encoded buf {:?}",
        prefix,
        buf
    );

    let zip = prefix.iter().zip(buf);
    let prefix_len = zip
        .take(MAX_PREFIX_ENCODED_LENGTH)
        .take_while(|(a, b)| a == b)
        .count();

    let encoded_len = 1 + buf.len() - prefix_len;

    let mut ret = Vec::with_capacity(encoded_len);
    ret.push(prefix_len as u8);
    ret.extend_from_slice(&buf[prefix_len..]);

    IVec::from(ret)
}

pub(crate) fn prefix_decode(prefix: &[u8], buf: &[u8]) -> Vec<u8> {
    assert!(!buf.is_empty());

    let prefix_len = buf[0] as usize;
    let mut ret = Vec::with_capacity(prefix_len + buf.len() - 1);

    ret.extend_from_slice(&prefix[..prefix_len]);
    ret.extend_from_slice(&buf[1..]);

    ret
}

pub(crate) fn prefix_reencode(
    old_prefix: &[u8],
    new_prefix: &[u8],
    buf: &[u8],
) -> IVec {
    assert!(!buf.is_empty());

    let old_prefix_len = buf[0] as usize;
    let old_prefix = &old_prefix[..old_prefix_len];
    let old_suffix = &buf[1..];

    let decoded_key = old_prefix.iter().chain(old_suffix.iter());

    let mut output = Vec::with_capacity(buf.len());
    output.push(0_u8);

    for (i, c) in decoded_key.enumerate() {
        if output[0] as usize == i
            && Some(c) == new_prefix.get(i)
            && i != MAX_PREFIX_ENCODED_LENGTH
        {
            output[0] += 1;
        } else {
            output.push(*c);
        }
    }

    IVec::from(output)
}

// NB: the correctness of this function depends on
// the invariant that the prefix is ALWAYS lexicographically
// Less than or Equal to the keys that have been encoded
// using it. Otherwise this comparison would make no sense.
pub(crate) fn prefix_cmp(a: &[u8], b: &[u8]) -> Ordering {
    if a.is_empty() && b.is_empty() {
        return Ordering::Equal;
    } else if a.is_empty() && !b.is_empty() {
        return Ordering::Less;
    } else if !a.is_empty() && b.is_empty() {
        return Ordering::Greater;
    }

    if a[0] > b[0] {
        Ordering::Less
    } else if a[0] < b[0] {
        Ordering::Greater
    } else {
        a[1..].cmp(&b[1..])
    }
}

/// Compare `a` and `b`, assuming that `a` is prefix encoded and `b` is not.
pub(crate) fn prefix_cmp_encoded(
    a: &[u8],
    mut b: &[u8],
    mut prefix: &[u8],
) -> Ordering {
    assert!(!a.is_empty() && a[0] as usize <= prefix.len());

    let mut a_prefix_len = a[0];
    let a_suffix = &a[1..];

    while a_prefix_len > 0 {
        if b.is_empty() || prefix[0] > b[0] {
            return Ordering::Greater;
        } else if prefix[0] < b[0] {
            return Ordering::Less;
        }

        a_prefix_len -= 1;
        b = &b[1..];
        prefix = &prefix[1..];
    }

    a_suffix.cmp(b)
}

#[test]
fn test_prefix() {
    let prefix = b"cat";
    assert_eq!(prefix_encode(prefix, prefix), vec![prefix.len() as u8]);
    assert_eq!(prefix_encode(prefix, b"catt"), vec![3, b't']);
    assert_eq!(prefix_encode(prefix, b"cb"), vec![1, b'b']);
    assert_eq!(prefix_encode(prefix, b"caz"), vec![2, b'z']);
    assert_eq!(prefix_encode(prefix, b"cvar"), vec![1, b'v', b'a', b'r']);
    assert_eq!(prefix_encode(prefix, b"zig"), vec![0, b'z', b'i', b'g']);

    let prefix = b"";
    assert_eq!(prefix_encode(prefix, prefix), vec![prefix.len() as u8]);
    assert_eq!(prefix_encode(prefix, b"ca"), vec![0, b'c', b'a']);
    assert_eq!(prefix_encode(prefix, b"cat"), vec![0, b'c', b'a', b't']);
    assert_eq!(prefix_encode(prefix, b"cab"), vec![0, b'c', b'a', b'b']);
    assert_eq!(
        prefix_encode(prefix, b"cvar"),
        vec![0, b'c', b'v', b'a', b'r']
    );
    assert_eq!(prefix_encode(prefix, b"zig"), vec![0, b'z', b'i', b'g']);

    let rtt = vec![b"" as &[u8], b"\x00cat", b"\x00", b"oyunwytounw\x00"];
    for item in rtt {
        assert_eq!(
            prefix_decode(prefix, &*prefix_encode(prefix, item)),
            item.to_vec()
        );
    }
}

#[test]
fn test_prefix_cmp() {
    assert_eq!(prefix_cmp(&[], &[]), Ordering::Equal);
    assert_eq!(prefix_cmp(&[0], &[]), Ordering::Greater);
    assert_eq!(prefix_cmp(&[], &[0]), Ordering::Less);

    assert_eq!(prefix_cmp(&[3], &[4]), Ordering::Greater);
    assert_eq!(prefix_cmp(&[4, 3], &[3, 4]), Ordering::Less);

    assert_eq!(prefix_cmp(&[1], &[1]), Ordering::Equal);
    assert_eq!(prefix_cmp(&[1, 1], &[1, 1]), Ordering::Equal);
    assert_eq!(prefix_cmp(&[1, 3], &[1, 1]), Ordering::Greater);
    assert_eq!(prefix_cmp(&[1, 1], &[1, 3]), Ordering::Less);
}

#[test]
fn test_prefix_cmp_encoded() {
    fn assert_pce(a: &[u8], b: &[u8], prefix: &[u8], expected: Ordering) {
        assert_eq!(
            prefix_cmp_encoded(a, &prefix_decode(prefix, b), prefix),
            expected
        );
    }

    let prefix = &vec![3, 3, 3, 3];
    assert_pce(&[0], &[0], prefix, Ordering::Equal);
    assert_pce(&[1], &[0], prefix, Ordering::Greater);
    assert_pce(&[0], &[1], prefix, Ordering::Less);

    assert_pce(&[3], &[2], prefix, Ordering::Greater);
    assert_pce(&[4, 3], &[3, 4], prefix, Ordering::Less);

    assert_pce(&[1], &[1], prefix, Ordering::Equal);
    assert_pce(&[1, 3, 3, 1], &[3, 1], prefix, Ordering::Equal);
    assert_pce(&[1, 3], &[1, 1], prefix, Ordering::Greater);
    assert_pce(&[1, 1], &[3, 3], prefix, Ordering::Less);
}
<|endoftext|>


<commit_before>//! Parse a Rust source file into a `syn::File` and print out a debug
//! representation of the syntax tree.
//!
//! Use the following command from this directory to test this program by
//! running it on its own source code:
//!
//!     cargo run -- main.rs
//!
//! The output will begin with:
//!
//!     File {
//!         shebang: None,
//!         attrs: [
//!             Attribute {
//!                 pound_token: Pound,
//!                 style: Inner(
//!         ...
//!     }

use std::env;
use std::fs::File;
use std::io::Read;
use std::process;

fn main() {
    let mut args = env::args();
    let _ = args.next(); // executable name

    let filename = match (args.next(), args.next()) {
        (Some(filename), None) => filename,
        _ => {
            eprintln!("Usage: dump-syntax path/to/filename.rs");
            process::exit(1);
        }
    };

    let mut file = File::open(&filename).expect("Unable to open file");

    let mut src = String::new();
    file.read_to_string(&mut src).expect("Unable to read file");

    let syntax = syn::parse_file(&src).expect("Unable to parse file");
    println!("{:#?}", syntax);
}
<commit_msg>Use std::fs helper function in dump-syntax example<commit_after>//! Parse a Rust source file into a `syn::File` and print out a debug
//! representation of the syntax tree.
//!
//! Use the following command from this directory to test this program by
//! running it on its own source code:
//!
//!     cargo run -- main.rs
//!
//! The output will begin with:
//!
//!     File {
//!         shebang: None,
//!         attrs: [
//!             Attribute {
//!                 pound_token: Pound,
//!                 style: Inner(
//!         ...
//!     }

use std::env;
use std::fs;
use std::process;

fn main() {
    let mut args = env::args();
    let _ = args.next(); // executable name

    let filename = match (args.next(), args.next()) {
        (Some(filename), None) => filename,
        _ => {
            eprintln!("Usage: dump-syntax path/to/filename.rs");
            process::exit(1);
        }
    };

    let src = fs::read_to_string(filename).expect("Unable to read file");

    let syntax = syn::parse_file(&src).expect("Unable to parse file");
    println!("{:#?}", syntax);
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// 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::fs::File;
use std::io::Write;
use std::path::Path;
use std::fs::OpenOptions;
use chrono::prelude::*;

use protocol::jobsrv::Job;
use protocol::scheduler::{Group, Project};

pub struct Logger {
    file: File,
}

impl Logger {
    pub fn init<T: AsRef<Path>>(log_path: T, filename: &str) -> Self {
        let filepath = log_path.as_ref().to_path_buf().join(filename);

        Logger {
            file: OpenOptions::new()
                .append(true)
                .create(true)
                .open(filepath)
                .expect("Failed to initialize log file"),
        }
    }

    pub fn log(&mut self, msg: &str) {
        let dt: DateTime<UTC> = UTC::now();
        let fmt_msg = format!("{},{}\n", dt.format("%Y-%m-%d %H:%M:%S"), msg);

        self.file.write_all(fmt_msg.as_bytes()).expect(&format!(
            "Logger unable to write to {:?}",
            self.file
        ));
    }

    // Log format (fields are comma-separated)
    //   Log entry datetime (UTC)
    //   Entry type - G (group), J (job), P (project), W (worker), I (ident)
    //   Id (group or job id)
    //   State
    //   Project name (for job or project)
    //   Start datetime (UTC) (only for jobs)
    //   End datetime (UTC) (only for jobs)
    //   Start offset (offset from group creation, in seconds, only for jobs)
    //   Duration (job duration, in seconds, only for jobs)
    //   Error (if applicable)

    pub fn log_ident(&mut self, ident: &str) {
        let msg = format!("I,{}", ident);
        self.log(&msg);
    }

    pub fn log_group(&mut self, group: &Group) {
        let msg = format!("G,{},{:?},", group.get_id(), group.get_state());
        self.log(&msg);
    }

    pub fn log_group_project(&mut self, group: &Group, project: &Project) {
        let msg = format!(
            "P,{},{:?},{},",
            group.get_id(),
            project.get_state(),
            project.get_name()
        );
        self.log(&msg);
    }

    pub fn log_group_job(&mut self, group: &Group, job: &Job) {
        let suffix = if job.has_build_started_at() && job.has_build_finished_at() {
            let start = job.get_build_started_at().parse::<DateTime<UTC>>().unwrap();
            let stop = job.get_build_finished_at()
                .parse::<DateTime<UTC>>()
                .unwrap();
            let group_start = group.get_created_at().parse::<DateTime<UTC>>().unwrap();

            let offset = start
                .signed_duration_since(group_start)
                .to_std()
                .unwrap()
                .as_secs();
            let duration = stop.signed_duration_since(start)
                .to_std()
                .unwrap()
                .as_secs();

            format!(
                "{},{},{},{}",
                offset,
                duration,
                start.format("%Y-%m-%d %H:%M:%S").to_string(),
                stop.format("%Y-%m-%d %H:%M:%S").to_string()
            )
        } else {
            "".to_string()
        };

        let error = if job.has_error() {
            format!("{:?}", job.get_error())
        } else {
            "".to_string()
        };

        let msg = format!(
            "J,{},{:?},{},{},{}",
            job.get_owner_id(),
            job.get_state(),
            job.get_project().get_name(),
            suffix,
            error
        );

        self.log(&msg);
    }

    pub fn log_worker_job(&mut self, job: &Job) {
        let start = if job.has_build_started_at() {
            job.get_build_started_at()
                .parse::<DateTime<UTC>>()
                .unwrap()
                .format("%Y-%m-%d %H:%M:%S")
                .to_string()
        } else {
            "".to_string()
        };

        let stop = if job.has_build_finished_at() {
            job.get_build_finished_at()
                .parse::<DateTime<UTC>>()
                .unwrap()
                .format("%Y-%m-%d %H:%M:%S")
                .to_string()
        } else {
            "".to_string()
        };

        let msg = format!(
            "W,{},{:?},{},,,{},{},{:?}",
            job.get_id(),
            job.get_state(),
            job.get_project().get_name(),
            start,
            stop,
            job.get_error()
        );
        self.log(&msg);
    }
}

impl Drop for Logger {
    fn drop(&mut self) {
        self.file.sync_all().expect("Unable to sync log file");
    }
}
<commit_msg>Add job id to scheduler log<commit_after>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// 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::fs::File;
use std::io::Write;
use std::path::Path;
use std::fs::OpenOptions;
use chrono::prelude::*;

use protocol::jobsrv::Job;
use protocol::scheduler::{Group, Project};

pub struct Logger {
    file: File,
}

impl Logger {
    pub fn init<T: AsRef<Path>>(log_path: T, filename: &str) -> Self {
        let filepath = log_path.as_ref().to_path_buf().join(filename);

        Logger {
            file: OpenOptions::new()
                .append(true)
                .create(true)
                .open(filepath)
                .expect("Failed to initialize log file"),
        }
    }

    pub fn log(&mut self, msg: &str) {
        let dt: DateTime<UTC> = UTC::now();
        let fmt_msg = format!("{},{}\n", dt.format("%Y-%m-%d %H:%M:%S"), msg);

        self.file.write_all(fmt_msg.as_bytes()).expect(&format!(
            "Logger unable to write to {:?}",
            self.file
        ));
    }

    // Log format (fields are comma-separated)
    //   Log entry datetime (UTC)
    //   Entry type - G (group), J (job), P (project), W (worker), I (ident)
    //   Id (group or job id)
    //   State
    //   Project name (for job or project)
    //   Start datetime (UTC) (only for jobs)
    //   End datetime (UTC) (only for jobs)
    //   Start offset (offset from group creation, in seconds, only for jobs)
    //   Duration (job duration, in seconds, only for jobs)
    //   Error (if applicable)

    pub fn log_ident(&mut self, ident: &str) {
        let msg = format!("I,{}", ident);
        self.log(&msg);
    }

    pub fn log_group(&mut self, group: &Group) {
        let msg = format!("G,{},{:?},", group.get_id(), group.get_state());
        self.log(&msg);
    }

    pub fn log_group_project(&mut self, group: &Group, project: &Project) {
        let msg = format!(
            "P,{},{:?},{},",
            group.get_id(),
            project.get_state(),
            project.get_name()
        );
        self.log(&msg);
    }

    pub fn log_group_job(&mut self, group: &Group, job: &Job) {
        let suffix = if job.has_build_started_at() && job.has_build_finished_at() {
            let start = job.get_build_started_at().parse::<DateTime<UTC>>().unwrap();
            let stop = job.get_build_finished_at()
                .parse::<DateTime<UTC>>()
                .unwrap();
            let group_start = group.get_created_at().parse::<DateTime<UTC>>().unwrap();

            let offset = start
                .signed_duration_since(group_start)
                .to_std()
                .unwrap()
                .as_secs();
            let duration = stop.signed_duration_since(start)
                .to_std()
                .unwrap()
                .as_secs();

            format!(
                "{},{},{},{}",
                offset,
                duration,
                start.format("%Y-%m-%d %H:%M:%S").to_string(),
                stop.format("%Y-%m-%d %H:%M:%S").to_string()
            )
        } else {
            "".to_string()
        };

        let error = if job.has_error() {
            format!("{:?}", job.get_error())
        } else {
            "".to_string()
        };

        let msg = format!(
            "J,{},{},{:?},{},{},{}",
            job.get_owner_id(),
            job.get_id(),
            job.get_state(),
            job.get_project().get_name(),
            suffix,
            error
        );

        self.log(&msg);
    }

    pub fn log_worker_job(&mut self, job: &Job) {
        let start = if job.has_build_started_at() {
            job.get_build_started_at()
                .parse::<DateTime<UTC>>()
                .unwrap()
                .format("%Y-%m-%d %H:%M:%S")
                .to_string()
        } else {
            "".to_string()
        };

        let stop = if job.has_build_finished_at() {
            job.get_build_finished_at()
                .parse::<DateTime<UTC>>()
                .unwrap()
                .format("%Y-%m-%d %H:%M:%S")
                .to_string()
        } else {
            "".to_string()
        };

        let msg = format!(
            "W,{},{:?},{},,,{},{},{:?}",
            job.get_id(),
            job.get_state(),
            job.get_project().get_name(),
            start,
            stop,
            job.get_error()
        );
        self.log(&msg);
    }
}

impl Drop for Logger {
    fn drop(&mut self) {
        self.file.sync_all().expect("Unable to sync log file");
    }
}
<|endoftext|>


<commit_before>
// Allow dead code since this is an example app.
#![allow(dead_code)]
#![feature(globs)]

extern crate shader_version;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;

use std::cell::RefCell;
use opengl_graphics::{Gl, Texture};
use sdl2_window::Sdl2Window;
use graphics::*;
use event::{ Events, WindowSettings };

fn main() {
    let opengl = shader_version::opengl::OpenGL_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: "Rust-Graphics-Lab: Texture App".to_string(),
            size: [600, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let assets = Path::new("./examples/assets");
    let image = assets.join(&Path::new("dices.png"));
    let image = Texture::from_path(&image).unwrap();

    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);
    for e in Events::new(&window) {
        use event::RenderEvent;
        e.render(|args| {
            gl.viewport(0, 0, args.width as i32, args.height as i32);
            let c = Context::abs(args.width as f64, args.height as f64);
            c.rgb(1.0, 1.0, 1.0).draw(gl);
            c.rect(0.0, 0.0, 50.0, 50.0).rgb(1.0, 0.0, 0.0).draw(gl);
            let offset = 150.0;
            c.trans(0.0, offset).image(&image).draw(gl);
        });
    }
}

<commit_msg>Testing hex colors<commit_after>
// Allow dead code since this is an example app.
#![allow(dead_code)]
#![feature(globs)]

extern crate shader_version;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;

use std::cell::RefCell;
use opengl_graphics::{Gl, Texture};
use sdl2_window::Sdl2Window;
use event::{ Events, WindowSettings };

fn main() {
    let opengl = shader_version::opengl::OpenGL_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: "Rust-Graphics-Lab: Texture App".to_string(),
            size: [600, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let assets = Path::new("./examples/assets");
    let image = assets.join(&Path::new("dices.png"));
    let image = Texture::from_path(&image).unwrap();

    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);
    for e in Events::new(&window) {
        use graphics::*;
        use event::RenderEvent;
        e.render(|args| {
            gl.viewport(0, 0, args.width as i32, args.height as i32);
            let c = Context::abs(args.width as f64, args.height as f64);
            c.hex("ffaa33").draw(gl);
            c.rect(0.0, 0.0, 50.0, 50.0).rgb(1.0, 0.0, 0.0).draw(gl);
            let offset = 150.0;
            c.trans(0.0, offset).image(&image).draw(gl);
        });
    }
}

<|endoftext|>


<commit_before>//! Simple example that echos recevied serial traffic to stdout
extern crate mio;
extern crate mio_serial;

use mio::{Poll, PollOpt, Events, Token, Ready};
use std::time::Duration;
use std::str;
use std::io::Read;
use std::env;

const SERIAL_TOKEN: Token = Token(0);

pub fn main() {

    let mut args = env::args();
    let tty_path = args.nth(1).unwrap_or("/dev/ttyUSB0".into());

    let poll = Poll::new().unwrap();
    let mut events = Events::with_capacity(1024);

    // Create the listener
    let settings = mio_serial::SerialPortSettings::default();

    println!("Opening {} at 9600,8N1", tty_path);
    let mut rx = mio_serial::Serial::from_path(&tty_path, &settings).unwrap();

    // Disable exclusive mode
    rx.set_exclusive(false).expect("Unable to set serial port into non-exclusive mode.");

    poll.register(&rx, SERIAL_TOKEN, Ready::readable(), PollOpt::level()).unwrap();

    let mut rx_buf = [0u8; 1024];

    loop {
        poll.poll(&mut events, Some(Duration::from_secs(1))).unwrap();

        if events.len() == 0 {
            println!("Read timed out!");
            continue;
        }

        for event in events.iter() {
            let bytes_read = match event.token() {
                SERIAL_TOKEN => rx.read(&mut rx_buf),
                _ => unreachable!(),
            };

            match bytes_read {
                Ok(b) => {
                    match b {
                        b if b > 0 => println!("{:?}", String::from_utf8_lossy(&rx_buf[..b])),
                        _ => println!("Read would have blocked."),
                    }
                }
                Err(e) => println!("Error:  {}", e),
            }
        }
    }
}
<commit_msg>Modified example.<commit_after>//! Simple example that echos recevied serial traffic to stdout
extern crate mio;
extern crate mio_serial;

use mio::{Poll, PollOpt, Events, Token, Ready};
use std::time::Duration;
use std::str;
use std::io::Read;
use std::env;

const SERIAL_TOKEN: Token = Token(0);

pub fn main() {

    let mut args = env::args();
    let tty_path = args.nth(1).unwrap_or("/dev/ttyUSB0".into());

    let poll = Poll::new().unwrap();
    let mut events = Events::with_capacity(1024);

    // Create the listener
    let settings = mio_serial::SerialPortSettings::default();

    println!("Opening {} at 9600,8N1", tty_path);
    let mut rx = mio_serial::Serial::from_path(&tty_path, &settings).unwrap();

    // Disable exclusive mode
    rx.set_exclusive(false).expect("Unable to set serial port into non-exclusive mode.");

    poll.register(&rx, SERIAL_TOKEN, Ready::readable() | Ready::hup() | Ready::error(), PollOpt::edge()).unwrap();

    let mut rx_buf = [0u8; 1024];

    'outer: loop {
        poll.poll(&mut events, None).unwrap();

        if events.len() == 0 {
            println!("Read timed out!");
            continue;
        }

        for event in events.iter() {
            match event.token() {
                SERIAL_TOKEN => {
                    let ready = event.kind();
                    if ready.contains(Ready::hup() | Ready::error()) {
                        println!("Quitting due to event: {:?}", ready);
                        break 'outer;
                    }
                    if ready.is_readable() {
                        match rx.read(&mut rx_buf) {
                            Ok(b) => {
                                match b {
                                    b if b > 0 => println!("{:?}", String::from_utf8_lossy(&rx_buf[..b])),
                                    _ => println!("Read would have blocked."),
                                }
                            }
                            Err(e) => println!("Error:  {}", e),
                        }
                    }
                },
                t @ _ => unreachable!("Unexpected token: {:?}", t),
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate rgmk;
extern crate env_logger;

fn main() {
    env_logger::init().unwrap();
    let path = std::env::args().skip(1).next().expect("Expected file name as argument");
    let mut gamedata = rgmk::GameData::from_file(&path).unwrap();
    /// Popping a char messes something up, the audio doesn't play.
    gamedata.strings.strings[0].pop();
    gamedata.save_to_file(&(path + ".rgmk")).unwrap();
}
<commit_msg>Use a normal comment, not a doc comment<commit_after>extern crate rgmk;
extern crate env_logger;

fn main() {
    env_logger::init().unwrap();
    let path = std::env::args().skip(1).next().expect("Expected file name as argument");
    let mut gamedata = rgmk::GameData::from_file(&path).unwrap();
    // Popping a char messes something up, the audio doesn't play.
    gamedata.strings.strings[0].pop();
    gamedata.save_to_file(&(path + ".rgmk")).unwrap();
}
<|endoftext|>


<commit_before>use std::io;
use std::io::Write;
use std::fs::OpenOptions;
use std::path::Path;

use storage::{Storage, Result, ByteEncodable, ByteDecodable};
use chunked_storage::indexing_chunk::HotIndexingChunk;
pub use chunked_storage::indexing_chunk::IndexingChunk;

mod indexing_chunk;

pub const SIZE: usize = 104;
const HOTCHUNKS_FILENAME: &'static str = "hot_chunks.bin";
const ASSOCIATED_FILES: &'static [&'static str; 1] = &[HOTCHUNKS_FILENAME];

pub struct MutChunkRef<'a> {
    chunk: &'a mut HotIndexingChunk,
    archive: &'a mut Box<Storage<IndexingChunk>>,
}

pub struct ChunkRef<'a> {
    read_ptr: usize,
    chunk: &'a HotIndexingChunk,
    archive: &'a Box<Storage<IndexingChunk>>,
}

// The idea here is the abstract the inner workings of chunked storage and indexing chunk from the index
// To do this, we implement Read and Write
impl<'a> io::Write for MutChunkRef<'a> {
    // Fill the HotIndexingChunk
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let bytes_written = try!((&mut self.chunk.data[SIZE - self.chunk.capacity as usize..]).write(buf));
        self.chunk.capacity -= bytes_written as u16;
        if self.chunk.capacity == 0 {
            let id = self.archive.len();
            // TODO: Errorhandling
            self.archive.store(id as u64, self.chunk.archive(id as u32)).unwrap();
        }
        Ok(bytes_written)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl<'a> io::Read for ChunkRef<'a> {
    // BULLSHIT. RETHINK THIS!
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let mut bytes_read = 0;
        loop {
            let chunk_id = self.read_ptr / SIZE;
            if chunk_id < self.chunk.archived_chunks().len() {
                let read = (&self.archive.get(chunk_id as u64).unwrap().get_bytes()[self.read_ptr % SIZE..])
                    .read(&mut buf[bytes_read..])
                    .unwrap();
                if read == 0 {
                    return Ok(bytes_read);
                }
                bytes_read += read;
                self.read_ptr += read;
            } else {
                break;
            }
        }
        let read = (&self.chunk.get_bytes()[self.read_ptr % SIZE..]).read(&mut buf[bytes_read..]).unwrap();
        bytes_read += read;
        self.read_ptr += read;
        Ok(bytes_read)
    }
}

impl<'a> MutChunkRef<'a> {
    #[inline]
    pub fn get_last_doc_id(&self) -> u64 {
        self.chunk.get_last_doc_id()
    }

    pub fn set_last_doc_id(&mut self, new_id: u64) {
        self.chunk.set_last_doc_id(new_id);
    }
}

// TODO: Think about implementing `Persistent` and `Volatile`
pub struct ChunkedStorage {
    hot_chunks: Vec<HotIndexingChunk>, // Size of vocabulary
    archive: Box<Storage<IndexingChunk>>,
}

impl ChunkedStorage {
    pub fn new(capacity: usize, archive: Box<Storage<IndexingChunk>>) -> Self {
        ChunkedStorage {
            hot_chunks: Vec::with_capacity(capacity),
            archive: archive,
        }
    }

    /// Persists hot_chunks to a file.
    /// We currently only need to persist hot_chunks
    /// Archive takes care of the rest
    pub fn persist(&self, target: &Path) -> Result<()> {
        let mut file =
            try!(OpenOptions::new().write(true).create(true).truncate(true).open(target.join(HOTCHUNKS_FILENAME)));
        for chunk in &self.hot_chunks {
            let bytes = chunk.encode();
            try!(file.write(&bytes));
        }
        Ok(())
    }

    pub fn load(source: &Path, archive: Box<Storage<IndexingChunk>>) -> Result<Self> {
        let mut file = try!(OpenOptions::new().read(true).open(source.join(HOTCHUNKS_FILENAME)));
        let mut hot_chunks = Vec::new();
        while let Ok(decoded_chunk) = HotIndexingChunk::decode(&mut file) {
            hot_chunks.push(decoded_chunk);
        }
        Ok(ChunkedStorage {
            hot_chunks: hot_chunks,
            archive: archive,
        })
    }

    pub fn new_chunk(&mut self, term_id: u64) -> MutChunkRef {
        // The following code-uglyness is due to the fact that in indexing one sort thread can
        // overtake the other. That means: ids are not just comming in an incremental order but can jump

        // If the id is larger than the len (e.g. can not be just pushed)
        // Push uninitialized chunks until the desired chunk can be created and pushed
        let diff = term_id as usize - self.hot_chunks.len();
        for _ in 0..diff + 1 {
            self.hot_chunks.push(HotIndexingChunk::new());
        }

        self.hot_chunks[term_id as usize] = HotIndexingChunk::new();
        MutChunkRef {
            chunk: &mut self.hot_chunks[term_id as usize],
            archive: &mut self.archive,
        }
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.hot_chunks.len()
    }

    #[inline]
    pub fn get_current(&self, id: u64) -> ChunkRef {
        ChunkRef {
            read_ptr: 0,
            chunk: &self.hot_chunks[id as usize],
            archive: &self.archive
        }
    }

    #[inline]
    pub fn get_current_mut(&mut self, id: u64) -> MutChunkRef {
        MutChunkRef {
            chunk: &mut self.hot_chunks[id as usize],
            archive: &mut self.archive,
        }
    }

    pub fn associated_files() -> &'static [&'static str] {
        ASSOCIATED_FILES
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io::{Read, Write};
    use utils::persistence::Volatile;
    use storage::RamStorage;

    #[test]
    fn overflowing_chunk_ref() {
        let mut store = ChunkedStorage::new(10, Box::new(RamStorage::new()));
        store.new_chunk(0);
        let data = (0..255u8).collect::<Vec<_>>();
        {
            let mut chunk_ref = store.get_current_mut(0);
            chunk_ref.write_all(&data).unwrap();
        }
        let mut read_data = Vec::new();
        {
            let mut chunk_ref = store.get_current(0);
            chunk_ref.read_to_end(&mut read_data).unwrap();
        }
        assert_eq!(data, read_data);
    }

    #[test]
    fn basic_chunk_ref() {
        let mut store = ChunkedStorage::new(10, Box::new(RamStorage::new()));
        store.new_chunk(0);
        let data = (0..20u8).collect::<Vec<_>>();
        {
            let mut chunk_ref = store.get_current_mut(0);
            chunk_ref.write_all(&data).unwrap();
        }
        let mut read_data = Vec::new();
        {
            let mut chunk_ref = store.get_current(0);
            chunk_ref.read_to_end(&mut read_data).unwrap();
        }
        assert_eq!(data, read_data);
    }

    #[test]
    fn repeated_writes() {
        let mut store = ChunkedStorage::new(10, Box::new(RamStorage::new()));
        store.new_chunk(0);
        let data = (0..20u8).collect::<Vec<_>>();
        {
            let mut chunk_ref = store.get_current_mut(0);
            chunk_ref.write_all(&data[0..10]).unwrap();
            chunk_ref.write_all(&data[10..20]).unwrap();
        }
        let mut read_data = Vec::new();
        {
            let mut chunk_ref = store.get_current(0);
            chunk_ref.read_to_end(&mut read_data).unwrap();
        }
        assert_eq!(data, read_data);
    }

    #[test]
    fn repeated_writes_overflowing() {
        let mut store = ChunkedStorage::new(10, Box::new(RamStorage::new()));
        store.new_chunk(0);
        let data = (0..255u8).collect::<Vec<_>>();
        {
            let mut chunk_ref = store.get_current_mut(0);
            chunk_ref.write_all(&data).unwrap();
            chunk_ref.write_all(&data).unwrap();
            chunk_ref.write_all(&data).unwrap();
        }
        let mut read_data = Vec::new();
        {
            let mut chunk_ref = store.get_current(0);
            chunk_ref.read_to_end(&mut read_data).unwrap();
        }
        assert_eq!(data, &read_data[0..255]);
        assert_eq!(data, &read_data[255..510]);
        assert_eq!(data, &read_data[510..765]);
    }
}
<commit_msg>Errorhandling for MutChunkRef::write<commit_after>use std::io;
use std::io::Write;
use std::fs::OpenOptions;
use std::path::Path;

use storage::{Storage, StorageError, Result, ByteEncodable, ByteDecodable};
use chunked_storage::indexing_chunk::HotIndexingChunk;
pub use chunked_storage::indexing_chunk::IndexingChunk;

mod indexing_chunk;

pub const SIZE: usize = 104;
const HOTCHUNKS_FILENAME: &'static str = "hot_chunks.bin";
const ASSOCIATED_FILES: &'static [&'static str; 1] = &[HOTCHUNKS_FILENAME];

pub struct MutChunkRef<'a> {
    chunk: &'a mut HotIndexingChunk,
    archive: &'a mut Box<Storage<IndexingChunk>>,
}

pub struct ChunkRef<'a> {
    read_ptr: usize,
    chunk: &'a HotIndexingChunk,
    archive: &'a Box<Storage<IndexingChunk>>,
}

// The idea here is the abstract the inner workings of chunked storage and indexing chunk from the index
// To do this, we implement Read and Write
impl<'a> io::Write for MutChunkRef<'a> {
    // Fill the HotIndexingChunk
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let bytes_written = try!((&mut self.chunk.data[SIZE - self.chunk.capacity as usize..]).write(buf));
        self.chunk.capacity -= bytes_written as u16;
        if self.chunk.capacity == 0 {
            let id = self.archive.len();

            match self.archive.store(id as u64, self.chunk.archive(id as u32)) {
                Ok(_) => {},
                Err(StorageError::IO(error)) => return Err(error),
                Err(StorageError::ReadError(Some(error))) => return Err(error),
                Err(StorageError::WriteError(Some(error))) => return Err(error),
                _ => return Err(io::Error::last_os_error())
            }
        }
        Ok(bytes_written)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl<'a> io::Read for ChunkRef<'a> {
    // BULLSHIT. RETHINK THIS!
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let mut bytes_read = 0;
        loop {
            let chunk_id = self.read_ptr / SIZE;
            if chunk_id < self.chunk.archived_chunks().len() {
                let read = (&self.archive.get(chunk_id as u64).unwrap().get_bytes()[self.read_ptr % SIZE..])
                    .read(&mut buf[bytes_read..])
                    .unwrap();
                if read == 0 {
                    return Ok(bytes_read);
                }
                bytes_read += read;
                self.read_ptr += read;
            } else {
                break;
            }
        }
        let read = (&self.chunk.get_bytes()[self.read_ptr % SIZE..]).read(&mut buf[bytes_read..]).unwrap();
        bytes_read += read;
        self.read_ptr += read;
        Ok(bytes_read)
    }
}

impl<'a> MutChunkRef<'a> {
    #[inline]
    pub fn get_last_doc_id(&self) -> u64 {
        self.chunk.get_last_doc_id()
    }

    pub fn set_last_doc_id(&mut self, new_id: u64) {
        self.chunk.set_last_doc_id(new_id);
    }
}

// TODO: Think about implementing `Persistent` and `Volatile`
pub struct ChunkedStorage {
    hot_chunks: Vec<HotIndexingChunk>, // Size of vocabulary
    archive: Box<Storage<IndexingChunk>>,
}

impl ChunkedStorage {
    pub fn new(capacity: usize, archive: Box<Storage<IndexingChunk>>) -> Self {
        ChunkedStorage {
            hot_chunks: Vec::with_capacity(capacity),
            archive: archive,
        }
    }

    /// Persists hot_chunks to a file.
    /// We currently only need to persist hot_chunks
    /// Archive takes care of the rest
    pub fn persist(&self, target: &Path) -> Result<()> {
        let mut file =
            try!(OpenOptions::new().write(true).create(true).truncate(true).open(target.join(HOTCHUNKS_FILENAME)));
        for chunk in &self.hot_chunks {
            let bytes = chunk.encode();
            try!(file.write(&bytes));
        }
        Ok(())
    }

    pub fn load(source: &Path, archive: Box<Storage<IndexingChunk>>) -> Result<Self> {
        let mut file = try!(OpenOptions::new().read(true).open(source.join(HOTCHUNKS_FILENAME)));
        let mut hot_chunks = Vec::new();
        while let Ok(decoded_chunk) = HotIndexingChunk::decode(&mut file) {
            hot_chunks.push(decoded_chunk);
        }
        Ok(ChunkedStorage {
            hot_chunks: hot_chunks,
            archive: archive,
        })
    }

    pub fn new_chunk(&mut self, term_id: u64) -> MutChunkRef {
        // The following code-uglyness is due to the fact that in indexing one sort thread can
        // overtake the other. That means: ids are not just comming in an incremental order but can jump

        // If the id is larger than the len (e.g. can not be just pushed)
        // Push uninitialized chunks until the desired chunk can be created and pushed
        let diff = term_id as usize - self.hot_chunks.len();
        for _ in 0..diff + 1 {
            self.hot_chunks.push(HotIndexingChunk::new());
        }

        self.hot_chunks[term_id as usize] = HotIndexingChunk::new();
        MutChunkRef {
            chunk: &mut self.hot_chunks[term_id as usize],
            archive: &mut self.archive,
        }
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.hot_chunks.len()
    }

    #[inline]
    pub fn get_current(&self, id: u64) -> ChunkRef {
        ChunkRef {
            read_ptr: 0,
            chunk: &self.hot_chunks[id as usize],
            archive: &self.archive
        }
    }

    #[inline]
    pub fn get_current_mut(&mut self, id: u64) -> MutChunkRef {
        MutChunkRef {
            chunk: &mut self.hot_chunks[id as usize],
            archive: &mut self.archive,
        }
    }

    pub fn associated_files() -> &'static [&'static str] {
        ASSOCIATED_FILES
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io::{Read, Write};
    use utils::persistence::Volatile;
    use storage::RamStorage;

    #[test]
    fn overflowing_chunk_ref() {
        let mut store = ChunkedStorage::new(10, Box::new(RamStorage::new()));
        store.new_chunk(0);
        let data = (0..255u8).collect::<Vec<_>>();
        {
            let mut chunk_ref = store.get_current_mut(0);
            chunk_ref.write_all(&data).unwrap();
        }
        let mut read_data = Vec::new();
        {
            let mut chunk_ref = store.get_current(0);
            chunk_ref.read_to_end(&mut read_data).unwrap();
        }
        assert_eq!(data, read_data);
    }

    #[test]
    fn basic_chunk_ref() {
        let mut store = ChunkedStorage::new(10, Box::new(RamStorage::new()));
        store.new_chunk(0);
        let data = (0..20u8).collect::<Vec<_>>();
        {
            let mut chunk_ref = store.get_current_mut(0);
            chunk_ref.write_all(&data).unwrap();
        }
        let mut read_data = Vec::new();
        {
            let mut chunk_ref = store.get_current(0);
            chunk_ref.read_to_end(&mut read_data).unwrap();
        }
        assert_eq!(data, read_data);
    }

    #[test]
    fn repeated_writes() {
        let mut store = ChunkedStorage::new(10, Box::new(RamStorage::new()));
        store.new_chunk(0);
        let data = (0..20u8).collect::<Vec<_>>();
        {
            let mut chunk_ref = store.get_current_mut(0);
            chunk_ref.write_all(&data[0..10]).unwrap();
            chunk_ref.write_all(&data[10..20]).unwrap();
        }
        let mut read_data = Vec::new();
        {
            let mut chunk_ref = store.get_current(0);
            chunk_ref.read_to_end(&mut read_data).unwrap();
        }
        assert_eq!(data, read_data);
    }

    #[test]
    fn repeated_writes_overflowing() {
        let mut store = ChunkedStorage::new(10, Box::new(RamStorage::new()));
        store.new_chunk(0);
        let data = (0..255u8).collect::<Vec<_>>();
        {
            let mut chunk_ref = store.get_current_mut(0);
            chunk_ref.write_all(&data).unwrap();
            chunk_ref.write_all(&data).unwrap();
            chunk_ref.write_all(&data).unwrap();
        }
        let mut read_data = Vec::new();
        {
            let mut chunk_ref = store.get_current(0);
            chunk_ref.read_to_end(&mut read_data).unwrap();
        }
        assert_eq!(data, &read_data[0..255]);
        assert_eq!(data, &read_data[255..510]);
        assert_eq!(data, &read_data[510..765]);
    }
}
<|endoftext|>


<commit_before>use std::io::{Result, Write};

use super::super::general::write_vec;

pub fn begin<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#![allow(non_camel_case_types)]",
"",
"extern crate libc;",
"#[macro_use] extern crate bitflags;",
    ];

    write_vec(w, &v)
}

pub fn after_extern_crates<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#[allow(unused_imports)]",
"use libc::{c_int, c_char, c_float, c_uint, c_double,",
"    c_short, c_ushort, c_long, c_ulong,",
"    c_void, size_t, ssize_t, time_t, FILE};",
    ];

    write_vec(w, &v)
}

pub fn use_glib_ffi<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#[allow(unused_imports)]",
"use glib_ffi::{gboolean, gconstpointer, gpointer, GType, Volatile};",
    ];

    write_vec(w, &v)
}

pub fn only_for_glib<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"pub type gboolean = c_int;",
"pub const GFALSE:  c_int = 0;",
"pub const GTRUE:   c_int = 1;",
"",
"pub type gconstpointer = *const c_void;",
"pub type gpointer = *mut c_void;",
"",
"#[repr(C)]",
"pub struct Volatile<T>(T);",
"",
    ];

    write_vec(w, &v)
}

pub fn only_for_gtk<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"pub const GTK_ENTRY_BUFFER_MAX_SIZE: u16 = ::std::u16::MAX;",
"",
"//pub type GtkTreeModelForeachFunc = fn(model: *mut GtkTreeModel, path: *mut GtkTreePath, iter: *mut GtkTreeIter, data: gpointer) -> gboolean;",
"",
"pub const GTK_STYLE_PROVIDER_PRIORITY_FALLBACK: u32 = 1;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_THEME: u32 = 200;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_SETTINGS: u32 = 400;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_APPLICATION: u32 = 600;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_USER: u32 = 800;",
    ];

    write_vec(w, &v)
}
<commit_msg>Fix build errors<commit_after>use std::io::{Result, Write};

use super::super::general::write_vec;

pub fn begin<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#![allow(non_camel_case_types, non_upper_case_globals)]",
"",
"extern crate libc;",
"#[macro_use] extern crate bitflags;",
    ];

    write_vec(w, &v)
}

pub fn after_extern_crates<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#[allow(unused_imports)]",
"use libc::{c_int, c_char, c_float, c_uint, c_double,",
"    c_short, c_ushort, c_long, c_ulong,",
"    c_void, size_t, ssize_t, time_t, FILE};",
    ];

    write_vec(w, &v)
}

pub fn use_glib_ffi<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#[allow(unused_imports)]",
"use glib_ffi::{gboolean, gconstpointer, gpointer, GType, Volatile};",
    ];

    write_vec(w, &v)
}

pub fn only_for_glib<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"pub type gboolean = c_int;",
"pub const GFALSE:  c_int = 0;",
"pub const GTRUE:   c_int = 1;",
"",
"pub type gconstpointer = *const c_void;",
"pub type gpointer = *mut c_void;",
"",
"#[repr(C)]",
"pub struct Volatile<T>(T);",
"",
    ];

    write_vec(w, &v)
}

pub fn only_for_gtk<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"pub const GTK_ENTRY_BUFFER_MAX_SIZE: u16 = ::std::u16::MAX;",
    ];

    write_vec(w, &v)
}
<|endoftext|>