<commit_before>// See LICENSE file for copyright and license details.

#[macro_use]
extern crate glium;

extern crate time;

use std::thread;
use std::time::Duration;
use glium::{glutin, DisplayBuild, Surface};
use glium::index::PrimitiveType;
use glium::glutin::ElementState::{Released};

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
    color: [f32; 3],
}

implement_vertex!(Vertex, position, color);

pub enum Action {
    Stop,
    Continue,
}

pub fn start_loop<F>(mut callback: F)
    where F: FnMut() -> Action
{
    let mut accumulator = 0;
    let mut previous_clock = time::precise_time_ns();
    loop {
        match callback() {
            Action::Stop => break,
            Action::Continue => ()
        }
        let now = time::precise_time_ns();
        accumulator += now - previous_clock;
        previous_clock = now;
        const FIXED_TIME_STAMP: u64 = 16666667;
        while accumulator >= FIXED_TIME_STAMP {
            accumulator -= FIXED_TIME_STAMP;
            // if you have a game, update the state here
        }
        thread::sleep(Duration::from_millis(
            ((FIXED_TIME_STAMP - accumulator) / 1000000) as u64));
    }
}

fn make_program(display: &glium::Display) -> glium::Program {
    let api = display.get_window().unwrap().get_api();
    let shader_src_preamble = match api {
        glium::glutin::Api::OpenGl => r"
            #version 120
            #define lowp
            #define mediump
            #define highp
        ",
        glium::glutin::Api::OpenGlEs => r"
            #version 100
        ",
        _ => unimplemented!(),
    }.to_string();
    println!("OZKRIFF: API: {:?}", api);
    let vertex_shader_src = shader_src_preamble.clone() + r"
        uniform lowp mat4 matrix;
        attribute lowp vec2 position;
        attribute lowp vec3 color;
        varying lowp vec3 vColor;
        void main() {
            gl_Position = vec4(position, 0.0, 1.0) * matrix;
            vColor = color;
        }
    ";
    let fragment_shader_src = shader_src_preamble + r"
        varying lowp vec3 vColor;
        void main() {
            gl_FragColor = vec4(vColor, 1.0);
        }
    ";
    let program = glium::Program::from_source(
        display,
        &vertex_shader_src,
        &fragment_shader_src,
        None
    ).unwrap();
    program
}

fn create_display() -> glium::Display {
    let gl_version = glutin::GlRequest::GlThenGles {
        opengles_version: (2, 0),
        opengl_version: (2, 1),
    };
    glutin::WindowBuilder::new()
        .with_gl(gl_version)
        // .with_depth_buffer(24) // TODO
        .with_title("Nergal".to_string())
        .build_glium()
        .unwrap()
}

fn main() {
    std::env::set_var("RUST_BACKTRACE", "1");
    let display = create_display();
    let vertex_buffer = {
        let vertices = [
            Vertex { position: [-0.5, -0.5], color: [0.0, 1.0, 0.0] },
            Vertex { position: [ 0.0,  0.5], color: [0.0, 0.0, 1.0] },
            Vertex { position: [ 0.5, -0.5], color: [1.0, 0.0, 0.0] },
        ];
        glium::VertexBuffer::new(&display, &vertices).unwrap()
    };
    let index_buffer = glium::IndexBuffer::new(
        &display, PrimitiveType::TrianglesList, &[0u16, 1, 2]).unwrap();
    let program = make_program(&display);
    start_loop(|| {
        let uniforms = uniform! {
            matrix: [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0f32],
            ]
        };
        {
            // fn draw() { ...
            let mut target = display.draw();
            target.clear_color(0.0, 0.0, 0.0, 0.0);
            target.draw(
                &vertex_buffer,
                &index_buffer,
                &program,
                &uniforms,
                &Default::default(),
            ).unwrap();
            target.finish().unwrap();
        }
        for event in display.poll_events() {
            match event {
                glutin::Event::Closed => return Action::Stop,
                glutin::Event::KeyboardInput(Released, _, Some(key)) => {
                    match key {
                        glutin::VirtualKeyCode::Q
                            | glutin::VirtualKeyCode::Escape =>
                        {
                            return Action::Stop;
                        }
                        _ => {},
                    }
                },
                _ => ()
            }
        }
        Action::Continue
    });
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>main.rs: create_display: Enabled 24-bit depth buffer<commit_after>// See LICENSE file for copyright and license details.

#[macro_use]
extern crate glium;

extern crate time;

use std::thread;
use std::time::Duration;
use glium::{glutin, DisplayBuild, Surface};
use glium::index::PrimitiveType;
use glium::glutin::ElementState::{Released};

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
    color: [f32; 3],
}

implement_vertex!(Vertex, position, color);

pub enum Action {
    Stop,
    Continue,
}

pub fn start_loop<F>(mut callback: F)
    where F: FnMut() -> Action
{
    let mut accumulator = 0;
    let mut previous_clock = time::precise_time_ns();
    loop {
        match callback() {
            Action::Stop => break,
            Action::Continue => ()
        }
        let now = time::precise_time_ns();
        accumulator += now - previous_clock;
        previous_clock = now;
        const FIXED_TIME_STAMP: u64 = 16666667;
        while accumulator >= FIXED_TIME_STAMP {
            accumulator -= FIXED_TIME_STAMP;
            // if you have a game, update the state here
        }
        thread::sleep(Duration::from_millis(
            ((FIXED_TIME_STAMP - accumulator) / 1000000) as u64));
    }
}

fn make_program(display: &glium::Display) -> glium::Program {
    let api = display.get_window().unwrap().get_api();
    let shader_src_preamble = match api {
        glium::glutin::Api::OpenGl => r"
            #version 120
            #define lowp
            #define mediump
            #define highp
        ",
        glium::glutin::Api::OpenGlEs => r"
            #version 100
        ",
        _ => unimplemented!(),
    }.to_string();
    println!("OZKRIFF: API: {:?}", api);
    let vertex_shader_src = shader_src_preamble.clone() + r"
        uniform lowp mat4 matrix;
        attribute lowp vec2 position;
        attribute lowp vec3 color;
        varying lowp vec3 vColor;
        void main() {
            gl_Position = vec4(position, 0.0, 1.0) * matrix;
            vColor = color;
        }
    ";
    let fragment_shader_src = shader_src_preamble + r"
        varying lowp vec3 vColor;
        void main() {
            gl_FragColor = vec4(vColor, 1.0);
        }
    ";
    let program = glium::Program::from_source(
        display,
        &vertex_shader_src,
        &fragment_shader_src,
        None
    ).unwrap();
    program
}

fn create_display() -> glium::Display {
    let gl_version = glutin::GlRequest::GlThenGles {
        opengles_version: (2, 0),
        opengl_version: (2, 1),
    };
    glutin::WindowBuilder::new()
        .with_gl(gl_version)
        .with_depth_buffer(24)
        .with_title("Nergal".to_string())
        .build_glium()
        .unwrap()
}

fn main() {
    std::env::set_var("RUST_BACKTRACE", "1");
    let display = create_display();
    let vertex_buffer = {
        let vertices = [
            Vertex { position: [-0.5, -0.5], color: [0.0, 1.0, 0.0] },
            Vertex { position: [ 0.0,  0.5], color: [0.0, 0.0, 1.0] },
            Vertex { position: [ 0.5, -0.5], color: [1.0, 0.0, 0.0] },
        ];
        glium::VertexBuffer::new(&display, &vertices).unwrap()
    };
    let index_buffer = glium::IndexBuffer::new(
        &display, PrimitiveType::TrianglesList, &[0u16, 1, 2]).unwrap();
    let program = make_program(&display);
    start_loop(|| {
        let uniforms = uniform! {
            matrix: [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0f32],
            ]
        };
        {
            // fn draw() { ...
            let mut target = display.draw();
            target.clear_color(0.0, 0.0, 0.0, 0.0);
            target.draw(
                &vertex_buffer,
                &index_buffer,
                &program,
                &uniforms,
                &Default::default(),
            ).unwrap();
            target.finish().unwrap();
        }
        for event in display.poll_events() {
            match event {
                glutin::Event::Closed => return Action::Stop,
                glutin::Event::KeyboardInput(Released, _, Some(key)) => {
                    match key {
                        glutin::VirtualKeyCode::Q
                            | glutin::VirtualKeyCode::Escape =>
                        {
                            return Action::Stop;
                        }
                        _ => {},
                    }
                },
                _ => ()
            }
        }
        Action::Continue
    });
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>extern crate discord;

use std::env;
use discord::{Discord, State};
use discord::model::Event;

pub fn main() {
	// Log in to Discord using a bot token from the environment
	let discord = Discord::from_bot_token(
		&env::var("DISCORD_TOKEN").expect("Expected token"),
	).expect("login failed");

	// establish websocket and voice connection
	let (mut connection, ready) = discord.connect().expect("connect failed");
	println!("[Ready] {} is serving {} servers", ready.user.username, ready.servers.len());
	let mut state = State::new(ready);
	connection.sync_calls(&state.all_private_channels());

	// receive events forever
	loop {
		let event = match connection.recv_event() {
			Ok(event) => event,
			Err(err) => {
				println!("[Warning] Receive error: {:?}", err);
				if let discord::Error::WebSocket(..) = err {
					// Handle the websocket connection being dropped
					let (new_connection, ready) = discord.connect().expect("connect failed");
					connection = new_connection;
					state = State::new(ready);
					println!("[Ready] Reconnected successfully.");
				}
				if let discord::Error::Closed(..) = err {
					break
				}
				continue
			},
		};
		state.update(&event);

		match event {
			Event::MessageCreate(message) => {
				use std::ascii::AsciiExt;
				// safeguard: stop if the message is from us
				if message.author.id == state.user().id {
					continue
				}

				// reply to a command if there was one
				let mut split = message.content.split(' ');
				let first_word = split.next().unwrap_or("");
				let argument = split.next().unwrap_or("");

				//Section of avaliable commands.
                if first_word.eq_ignore_ascii_case("!help") {
                    if argument.eq_ignore_ascii_case("commands") {
                        warn(discord.send_message(message.channel_id, "help, about, uber, distrowiki, and sourcecode are the avaliable commands. (!dj is buggy)", "", false))
                    }
		    		else if argument.eq_ignore_ascii_case("about") {
			 			warn(discord.send_message(message.channel_id, "Displays info about me. No arguments available.", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("uber") {
						warn(discord.send_message(message.channel_id, "Uber an object (I'm picky).", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("distrowiki") {
						warn(discord.send_message(message.channel_id, "Finds the wiki of the specified distro. Arguments include Arch, Ubuntu, Debian, Antergos, Mint, CentOS, OpenBSD, Opensuse, Sabayon, KaliLinux, Solus, and Gentoo.", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("sourcecode") {
						warn(discord.send_message(message.channel_id, "Displays where I am on GitHub. No arguments available", "", false))
	            	}
		    		else if argument.eq_ignore_ascii_case("help") {
						warn(discord.send_message(message.channel_id, "Are you trying to break me?", "", false))
	            	}
		    		else if argument.eq_ignore_ascii_case("[args]") {
						warn(discord.send_message(message.channel_id, "You're helpless.", "", false))
	            	}
                    else {
                    warn(discord.send_message(message.channel_id, "Umm, you gotta use it like this. !help [args] Try using the `commands` argument.", "", false))
                    }
                }

				//Fun Commands.
                if first_word.eq_ignore_ascii_case("!about") {
                    warn(discord.send_message(message.channel_id, "I have no clue. All I know is that I was written by Arroz in a language called Rust, and my code is still being developed.", "", false))
                }
		        if first_word.eq_ignore_ascii_case("!wheresteal") {
			        warn(discord.send_message(message.channel_id, "He's alive and well.", "", false)) //yay
		        }
                if first_word.eq_ignore_ascii_case("!hello") {
				warn(discord.send_message(message.channel_id, "https://www.tenor.co/xA8B.gif", "", false))
			}
		if first_word.eq_ignore ascii_case("!bye") {
				warn(discord.send_message(message.channel_id, "https://tenor.com/woQk.gif", "", false))
			}
                if first_word.eq_ignore_ascii_case("!uber"){
					if argument.eq_ignore_ascii_case("ddog75") {
                        warn(discord.send_message(message.channel_id, "Alright, 10 minutes.", "", false))
                    	}
					else if argument.eq_ignore_ascii_case("aspire") {
						warn(discord.send_message(message.channel_id, "Not the meatballs.", "", false))
					}
					else if argument.eq_ignore_ascii_case("nic") {
					    warn(discord.send_message(message.channel_id, "NOT THE BEES!!!", "", false))
					}
					else {
                        warn(discord.send_message(message.channel_id, "Fuck off!", "", false))
                    }
                }
                if first_word.eq_ignore_ascii_case("!sourcecode") {
                    warn(discord.send_message(message.channel_id, "Okay, here you go. https://github.com/aarroz/rice_bot2", "", false))
                }
				//Section that prints wikis for linux distributions.
				if first_word.eq_ignore_ascii_case("!distrowiki") {
					if argument.eq_ignore_ascii_case("arch") {
						warn(discord.send_message(message.channel_id, "Here's the Arch Wiki! https://wiki.archlinux.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("ubuntu") {
						warn(discord.send_message(message.channel_id, "Here's the Ubuntu Wiki! https://wiki.ubuntu.com/", "", false))
					}
					else if argument.eq_ignore_ascii_case("debian") {
						warn(discord.send_message(message.channel_id, "Here's the Debian Wiki! https://wiki.debian.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("antergos") {
						warn(discord.send_message(message.channel_id, "Here's the Antergos Wiki! https://antergos.com/wiki/", "", false))
					}
					else if argument.eq_ignore_ascii_case("centos") {
						warn(discord.send_message(message.channel_id, "Here's the CentOS Wiki! https://wiki.centos.org/", "", false))
					}
					//Sorry OpenBSD users.
					else if argument.eq_ignore_ascii_case("openbsd") {
						warn(discord.send_message(message.channel_id, "No, just no.", "", false))
					}
					//Not sorry.
					else if argument.eq_ignore_ascii_case("gentoo") {
						warn(discord.send_message(message.channel_id, "Here's the Gentoo Wiki! https://wiki.gentoo.org/wiki/Main_Page", "", false))
					}
					else if argument.eq_ignore_ascii_case("opensuse") {
						warn(discord.send_message(message.channel_id, "Here's the OpenSuse Wiki! https://en.opensuse.org/Portal:Wiki", "", false))
					}
					else if argument.eq_ignore_ascii_case("sabayon") {
						warn(discord.send_message(message.channel_id, "Here's the Sabayon Wiki! https://wiki.sabayon.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("kalilinux") {
						warn(discord.send_message(message.channel_id, "Heres's the KaliLinux Wiki! https://en.wikipedia.org/wiki/Kali_Linux", "", false))
					}
					else if argument.eq_ignore_ascii_case("mint") {
						warn(discord.send_message(message.channel_id, "Here's the Mint newbie page! https://forums.linuxmint.com/viewforum.php?f=90", "", false))
					}
					else if argument.eq_ignore_ascii_case("solus") {
						warn(discord.send_message(message.channel_id, "There is no wiki for solus, however there is the help page! https://solus-project.com/help-center/home/", "", false))
					}
					else if argument.eq_ignore_ascii_case("windows") {
						warn(discord.send_message(message.channel_id, "Thats not a distro.", "", false))
					}
					else if argument.eq_ignore_ascii_case("macos") {
						warn(discord.send_message(message.channel_id, "Sure its close to linux, but I'm too tired to have that argument.", "", false))
					}
					else {
						warn(discord.send_message(message.channel_id, "Please use a distro from !help distrowiki.", "", false))
					}
				}

                // Command for using dj.
				if first_word.eq_ignore_ascii_case("!dj") {
					let vchan = state.find_voice_user(message.author.id);
					if argument.eq_ignore_ascii_case("stop") {
						vchan.map(|(sid, _)| connection.voice(sid).stop());
					} else if argument.eq_ignore_ascii_case("quit") {
						vchan.map(|(sid, _)| connection.drop_voice(sid));
					} else {
						let output = if let Some((server_id, channel_id)) = vchan {
							match discord::voice::open_ytdl_stream(argument) {
								Ok(stream) => {
									let voice = connection.voice(server_id);
									voice.set_deaf(true);
									voice.connect(channel_id);
									voice.play(stream);
									String::new()
								},
								Err(error) => format!("Error: {}", error),
							}
						} else {
							"You must be in a voice channel to DJ".to_owned()
						};
						if !output.is_empty() {
							warn(discord.send_message(message.channel_id, &output, "", false));
						}
					}
				}
			}
			Event::VoiceStateUpdate(server_id, _) => {
				// If someone moves/hangs up, and we are in a voice channel,
				if let Some(cur_channel) = connection.voice(server_id).current_channel() {
					// and our current voice channel is empty, disconnect from voice
					match server_id {
						Some(server_id) => if let Some(srv) = state.servers().iter().find(|srv| srv.id == server_id) {
							if srv.voice_states.iter().filter(|vs| vs.channel_id == Some(cur_channel)).count() <= 1 {
								connection.voice(Some(server_id)).disconnect();
							}
						},
						None => if let Some(call) = state.calls().get(&cur_channel) {
							if call.voice_states.len() <= 1 {
								connection.voice(server_id).disconnect();
							}
						}
					}
				}
			}
			_ => {}, // discard other events
		}
	}
}

fn warn<T, E: ::std::fmt::Debug>(result: Result<T, E>) {
	match result {
		Ok(_) => {},
		Err(err) => println!("[Warning] {:?}", err)
	}
}
<commit_msg>Update main.rs<commit_after>extern crate discord;

use std::env;
use discord::{Discord, State};
use discord::model::Event;

pub fn main() {
	// Log in to Discord using a bot token from the environment
	let discord = Discord::from_bot_token(
		&env::var("DISCORD_TOKEN").expect("Expected token"),
	).expect("login failed");

	// establish websocket and voice connection
	let (mut connection, ready) = discord.connect().expect("connect failed");
	println!("[Ready] {} is serving {} servers", ready.user.username, ready.servers.len());
	let mut state = State::new(ready);
	connection.sync_calls(&state.all_private_channels());

	// receive events forever
	loop {
		let event = match connection.recv_event() {
			Ok(event) => event,
			Err(err) => {
				println!("[Warning] Receive error: {:?}", err);
				if let discord::Error::WebSocket(..) = err {
					// Handle the websocket connection being dropped
					let (new_connection, ready) = discord.connect().expect("connect failed");
					connection = new_connection;
					state = State::new(ready);
					println!("[Ready] Reconnected successfully.");
				}
				if let discord::Error::Closed(..) = err {
					break
				}
				continue
			},
		};
		state.update(&event);

		match event {
			Event::MessageCreate(message) => {
				use std::ascii::AsciiExt;
				// safeguard: stop if the message is from us
				if message.author.id == state.user().id {
					continue
				}

				// reply to a command if there was one
				let mut split = message.content.split(' ');
				let first_word = split.next().unwrap_or("");
				let argument = split.next().unwrap_or("");

				//Section of avaliable commands.
                if first_word.eq_ignore_ascii_case("!help") {
                    if argument.eq_ignore_ascii_case("commands") {
                        warn(discord.send_message(message.channel_id, "help, about, uber, distrowiki, and sourcecode are the avaliable commands. (!dj is buggy)", "", false))
                    }
		    		else if argument.eq_ignore_ascii_case("about") {
			 			warn(discord.send_message(message.channel_id, "Displays info about me. No arguments available.", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("uber") {
						warn(discord.send_message(message.channel_id, "Uber an object (I'm picky).", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("distrowiki") {
						warn(discord.send_message(message.channel_id, "Finds the wiki of the specified distro. Arguments include Arch, Ubuntu, Debian, Antergos, Mint, CentOS, OpenBSD, Opensuse, Sabayon, KaliLinux, Solus, and Gentoo.", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("sourcecode") {
						warn(discord.send_message(message.channel_id, "Displays where I am on GitHub. No arguments available", "", false))
	            	}
		    		else if argument.eq_ignore_ascii_case("help") {
						warn(discord.send_message(message.channel_id, "Are you trying to break me?", "", false))
	            	}
		    		else if argument.eq_ignore_ascii_case("[args]") {
						warn(discord.send_message(message.channel_id, "You're helpless.", "", false))
	            	}
                    else {
                    warn(discord.send_message(message.channel_id, "Umm, you gotta use it like this. !help [args] Try using the `commands` argument.", "", false))
                    }
                }

				//Fun Commands.
                if first_word.eq_ignore_ascii_case("!about") {
                    warn(discord.send_message(message.channel_id, "I have no clue. All I know is that I was written by Arroz in a language called Rust, and my code is still being developed.", "", false))
                }
		        if first_word.eq_ignore_ascii_case("!wheresteal") {
			        warn(discord.send_message(message.channel_id, "He's alive and well.", "", false)) //yay
		        }
                if first_word.eq_ignore_ascii_case("!hello") {
				warn(discord.send_message(message.channel_id, "https://www.tenor.co/xA8B.gif", "", false))
				}
				if first_word.eq_ignore ascii_case("!bye") {
				warn(discord.send_message(message.channel_id, "https://tenor.com/woQk.gif", "", false))
				}
                if first_word.eq_ignore_ascii_case("!uber"){
					if argument.eq_ignore_ascii_case("ddog75") {
                        warn(discord.send_message(message.channel_id, "Alright, 10 minutes.", "", false))
                    }
					else if argument.eq_ignore_ascii_case("aspire") {
						warn(discord.send_message(message.channel_id, "Not the meatballs.", "", false))
					}
					else if argument.eq_ignore_ascii_case("nic") {
					    warn(discord.send_message(message.channel_id, "NOT THE BEES!!!", "", false))
					}
					else {
                        warn(discord.send_message(message.channel_id, "Fuck off!", "", false))
                    }
                }
                if first_word.eq_ignore_ascii_case("!sourcecode") {
                    warn(discord.send_message(message.channel_id, "Okay, here you go. https://github.com/aarroz/rice_bot2", "", false))
                }
				//Section that prints wikis for linux distributions.
				if first_word.eq_ignore_ascii_case("!distrowiki") {
					if argument.eq_ignore_ascii_case("arch") {
						warn(discord.send_message(message.channel_id, "Here's the Arch Wiki! https://wiki.archlinux.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("ubuntu") {
						warn(discord.send_message(message.channel_id, "Here's the Ubuntu Wiki! https://wiki.ubuntu.com/", "", false))
					}
					else if argument.eq_ignore_ascii_case("debian") {
						warn(discord.send_message(message.channel_id, "Here's the Debian Wiki! https://wiki.debian.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("antergos") {
						warn(discord.send_message(message.channel_id, "Here's the Antergos Wiki! https://antergos.com/wiki/", "", false))
					}
					else if argument.eq_ignore_ascii_case("centos") {
						warn(discord.send_message(message.channel_id, "Here's the CentOS Wiki! https://wiki.centos.org/", "", false))
					}
					//Sorry OpenBSD users.
					else if argument.eq_ignore_ascii_case("openbsd") {
						warn(discord.send_message(message.channel_id, "No, just no.", "", false))
					}
					//Not sorry.
					else if argument.eq_ignore_ascii_case("gentoo") {
						warn(discord.send_message(message.channel_id, "Here's the Gentoo Wiki! https://wiki.gentoo.org/wiki/Main_Page", "", false))
					}
					else if argument.eq_ignore_ascii_case("opensuse") {
						warn(discord.send_message(message.channel_id, "Here's the OpenSuse Wiki! https://en.opensuse.org/Portal:Wiki", "", false))
					}
					else if argument.eq_ignore_ascii_case("sabayon") {
						warn(discord.send_message(message.channel_id, "Here's the Sabayon Wiki! https://wiki.sabayon.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("kalilinux") {
						warn(discord.send_message(message.channel_id, "Heres's the KaliLinux Wiki! https://en.wikipedia.org/wiki/Kali_Linux", "", false))
					}
					else if argument.eq_ignore_ascii_case("mint") {
						warn(discord.send_message(message.channel_id, "Here's the Mint newbie page! https://forums.linuxmint.com/viewforum.php?f=90", "", false))
					}
					else if argument.eq_ignore_ascii_case("solus") {
						warn(discord.send_message(message.channel_id, "There is no wiki for solus, however there is the help page! https://solus-project.com/help-center/home/", "", false))
					}
					else if argument.eq_ignore_ascii_case("windows") {
						warn(discord.send_message(message.channel_id, "Thats not a distro.", "", false))
					}
					else if argument.eq_ignore_ascii_case("macos") {
						warn(discord.send_message(message.channel_id, "Sure its close to linux, but I'm too tired to have that argument.", "", false))
					}
					else {
						warn(discord.send_message(message.channel_id, "Please use a distro from !help distrowiki.", "", false))
					}
				}

                // Command for using dj.
				if first_word.eq_ignore_ascii_case("!dj") {
					let vchan = state.find_voice_user(message.author.id);
					if argument.eq_ignore_ascii_case("stop") {
						vchan.map(|(sid, _)| connection.voice(sid).stop());
					} else if argument.eq_ignore_ascii_case("quit") {
						vchan.map(|(sid, _)| connection.drop_voice(sid));
					} else {
						let output = if let Some((server_id, channel_id)) = vchan {
							match discord::voice::open_ytdl_stream(argument) {
								Ok(stream) => {
									let voice = connection.voice(server_id);
									voice.set_deaf(true);
									voice.connect(channel_id);
									voice.play(stream);
									String::new()
								},
								Err(error) => format!("Error: {}", error),
							}
						} else {
							"You must be in a voice channel to DJ".to_owned()
						};
						if !output.is_empty() {
							warn(discord.send_message(message.channel_id, &output, "", false));
						}
					}
				}
			}
			Event::VoiceStateUpdate(server_id, _) => {
				// If someone moves/hangs up, and we are in a voice channel,
				if let Some(cur_channel) = connection.voice(server_id).current_channel() {
					// and our current voice channel is empty, disconnect from voice
					match server_id {
						Some(server_id) => if let Some(srv) = state.servers().iter().find(|srv| srv.id == server_id) {
							if srv.voice_states.iter().filter(|vs| vs.channel_id == Some(cur_channel)).count() <= 1 {
								connection.voice(Some(server_id)).disconnect();
							}
						},
						None => if let Some(call) = state.calls().get(&cur_channel) {
							if call.voice_states.len() <= 1 {
								connection.voice(server_id).disconnect();
							}
						}
					}
				}
			}
			_ => {}, // discard other events
		}
	}
}

fn warn<T, E: ::std::fmt::Debug>(result: Result<T, E>) {
	match result {
		Ok(_) => {},
		Err(err) => println!("[Warning] {:?}", err)
	}
}
<|endoftext|>


<commit_before>struct Philosopher {
    name: String
}

impl Philosopher {
    fn new(name: &str) -> Philosopher {
        Philosopher {
            name: name.to_string()
        }
    }
}

fn main() {
    let p1 = Philosopher::new("Judith Butler");
    let p2 = Philosopher::new("Gilles Deleuze");
    let p3 = Philosopher::new("Karl Marx");
    let p4 = Philosopher::new("Emma Goldman");
    let p5 = Philosopher::new("Michel Foucault");
}
<commit_msg>Add `eat()` method to `Philosopher`<commit_after>struct Philosopher {
    name: String
}

impl Philosopher {
    fn new(name: &str) -> Philosopher {
        Philosopher {
            name: name.to_string()
        }
    }

    fn eat(&self) {
        println!("{} is done eating.", self.name);
    }
}

fn main() {
    let p1 = Philosopher::new("Judith Butler");
    let p2 = Philosopher::new("Gilles Deleuze");
    let p3 = Philosopher::new("Karl Marx");
    let p4 = Philosopher::new("Emma Goldman");
    let p5 = Philosopher::new("Michel Foucault");
}
<|endoftext|>


<commit_before>extern crate getopts;
extern crate izzet;
extern crate toml;

use getopts::{Matches, Options};
use izzet::error::{Error, Result};
use izzet::{gen, post, server};
use izzet::config::Config;
use std::env;
use std::fs::DirBuilder;
use std::path::PathBuf;
use std::process;
use std::io::Write;

const PROG_NAME: &str = env!("CARGO_PKG_NAME");

fn create_site(m: &Matches) -> Result<()> {
    let dir = m.free.get(1)
        .map(|s| PathBuf::from(s))
        .unwrap_or(env::current_dir()?);

    let opener = izzet::get_opener(m.opt_present("force"));

    // create a default configuration file
    let config: Config = Default::default();
    let config = toml::to_string(&config)?;
    opener.open(dir.join(izzet::CONFIG_FILE))
          .and_then(|mut f| f.write(config.as_bytes()))
          .map_err(|e| format!("fail to create {}: {}", izzet::CONFIG_FILE, e))?;

    // create other files
    // XXX may need to do more things here later
    for filename in izzet::SITE_FILES {
        opener.open(dir.join(filename))
              .map_err(|e| format!("fail to create {}: {}", filename, e))?;
    }

    // create directories
    for dirname in izzet::SITE_DIRS {
        DirBuilder::new()
            .recursive(m.opt_present("force"))
            .create(dir.join(dirname))
            .map_err(|e| format!("fail to create {}: {}", dirname, e))?;
    }

    // create default templates
    for &(filename, html) in izzet::SITE_TEMPLATES {
        let mut file = opener.open(dir.join(izzet::TEMPLATES_DIR)
                                      .join(filename))
                             .map_err(|e| format!("fail to create {}: {}", filename, e))?;
        file.write(html)?;
    }

    Ok(())
}

fn usage(opts: &Options) {
    println!("{}", opts.usage(&format!("usage: {} <options> <args>", PROG_NAME)));
}

fn run(m: Matches, action: &str) -> Result<()> {
    // Note that now we have no configuration file yet
    if action == "new" {
        create_site(&m)?;
        return Ok(());
    }

    // Load config file as a basis which may be overwritten
    // later by the command-line options.
    let mut config = Config::from_file(m.opt_str("config")
                                        .map(|p| PathBuf::from(p))
                                        .unwrap_or(env::current_dir()?)
                                        .join(izzet::CONFIG_FILE))?;

    config.force = Some(m.opt_present("force"));

    match action {
        "article" => {
            let link = m.free.get(1)
                .ok_or(Error::new("need the link of the article".to_string()))?;
            post::create_post(link.to_string(), config, true)?;
        },

        "page" => {
            let link = m.free.get(1)
                .ok_or(Error::new("need the link of the page".to_string()))?;
            post::create_post(link.clone(), config, false)?;
        },

        "gen" => {
            config.in_dir = m.opt_str("input");
            config.out_dir = m.opt_str("output");
            gen::generate(config)?;
        },

        "server" => {
            let dir = m.free.get(1)
                .map(PathBuf::from)
                .unwrap_or(env::current_dir()?);
            server::forever(dir, config)?;
        },

        _ => {
            eprintln!("unknown action {}", action);
            process::exit(1);
        }
    }

    Ok(())
}

fn main() {
    let mut opts = Options::new();

    // One of these flags should be specified
    opts.optflag("n", "new", "Initialize an empty site at the given location.");
    opts.optflag("a", "article", "Create an article with the given permalink.");
    opts.optflag("p", "page", "Create a page with the given permalink.");
    opts.optflag("g", "gen", "Generate site, can be used along with -i and -o \
                              to specify the input and output location.");
    opts.optflag("s", "server", "Start a local server to preview the generated site \
                                 specified by a directory.");
    opts.optflag("f", "force", "Overwrite existing files when creating articles, \
                                generating site output files, etc.");

    opts.optopt("c", "config", "Run with the given configuration file. By default \
                                configuration file will be looked for under the \
                                current directory.", "CONFIG");
    opts.optopt("i", "input", "Input site directory. Read input files from current \
                              directory by default.", "INPUT");
    opts.optopt("o", "output", "Output site directory. Write to current directory \
                               by default.", "OUTPUT");
    opts.optopt("l", "listen", "Port on which the local server will listen.", "PORT");

    opts.optflag("h", "help", "Show this help message.");
    opts.optflag("V", "version", "Display version information.");

    let matches = match opts.parse(env::args()) {
        Ok(m) => m,
        Err(e) => {
            eprintln!("{}\ntry `{1} -h` or `{1} --help` to see the help.", e, PROG_NAME);
            process::exit(1);
        },
    };

    if matches.opt_present("help") {
        usage(&opts);
        return;
    }

    if matches.opt_present("version") {
        println!("{} {}", PROG_NAME, env!("CARGO_PKG_VERSION"));
        return;
    }

    let mutex_opts = ["new", "article", "gen", "page", "server"];
    let action = mutex_opts
        .iter()
        .filter(|o| matches.opt_present(o))
        .collect::<Vec<_>>();

    match action.len() {
        0 => {
            println!("nothing to do");
            return;
        },
        1 => {
            if let Err(e) = run(matches, action.first().unwrap()) {
                eprintln!("{}", e);
                process::exit(1);
            }
        },
        _ => {
            eprintln!("only one of `-n', `-a', `-p', `-s' and `-g' could be specified");
            process::exit(1);
        }
    }
}
<commit_msg>Get port from command line<commit_after>extern crate getopts;
extern crate izzet;
extern crate toml;

use getopts::{Matches, Options};
use izzet::error::{Error, Result};
use izzet::{gen, post, server};
use izzet::config::Config;
use std::env;
use std::fs::DirBuilder;
use std::path::PathBuf;
use std::process;
use std::io::Write;

const PROG_NAME: &str = env!("CARGO_PKG_NAME");

fn create_site(m: &Matches) -> Result<()> {
    let dir = m.free.get(1)
        .map(|s| PathBuf::from(s))
        .unwrap_or(env::current_dir()?);

    let opener = izzet::get_opener(m.opt_present("force"));

    // create a default configuration file
    let config: Config = Default::default();
    let config = toml::to_string(&config)?;
    opener.open(dir.join(izzet::CONFIG_FILE))
          .and_then(|mut f| f.write(config.as_bytes()))
          .map_err(|e| format!("fail to create {}: {}", izzet::CONFIG_FILE, e))?;

    // create other files
    // XXX may need to do more things here later
    for filename in izzet::SITE_FILES {
        opener.open(dir.join(filename))
              .map_err(|e| format!("fail to create {}: {}", filename, e))?;
    }

    // create directories
    for dirname in izzet::SITE_DIRS {
        DirBuilder::new()
            .recursive(m.opt_present("force"))
            .create(dir.join(dirname))
            .map_err(|e| format!("fail to create {}: {}", dirname, e))?;
    }

    // create default templates
    for &(filename, html) in izzet::SITE_TEMPLATES {
        let mut file = opener.open(dir.join(izzet::TEMPLATES_DIR)
                                      .join(filename))
                             .map_err(|e| format!("fail to create {}: {}", filename, e))?;
        file.write(html)?;
    }

    Ok(())
}

fn usage(opts: &Options) {
    println!("{}", opts.usage(&format!("usage: {} <options> <args>", PROG_NAME)));
}

fn run(m: Matches, action: &str) -> Result<()> {
    // Note that now we have no configuration file yet
    if action == "new" {
        create_site(&m)?;
        return Ok(());
    }

    // Load config file as a basis which may be overwritten
    // later by the command-line options.
    let mut config = Config::from_file(m.opt_str("config")
                                        .map(|p| PathBuf::from(p))
                                        .unwrap_or(env::current_dir()?)
                                        .join(izzet::CONFIG_FILE))?;

    config.force = Some(m.opt_present("force"));

    match action {
        "article" => {
            let link = m.free.get(1)
                .ok_or(Error::new("need the link of the article".to_string()))?;
            post::create_post(link.to_string(), config, true)?;
        },

        "page" => {
            let link = m.free.get(1)
                .ok_or(Error::new("need the link of the page".to_string()))?;
            post::create_post(link.clone(), config, false)?;
        },

        "gen" => {
            config.in_dir = m.opt_str("input");
            config.out_dir = m.opt_str("output");
            gen::generate(config)?;
        },

        "server" => {
            let dir = m.free.get(1)
                .map(PathBuf::from)
                .unwrap_or(env::current_dir()?);
            config.port = m.opt_str("listen")
                .and_then(|s| s.parse::<u16>().ok());
            server::forever(dir, config)?;
        },

        _ => {
            eprintln!("unknown action {}", action);
            process::exit(1);
        }
    }

    Ok(())
}

fn main() {
    let mut opts = Options::new();

    // One of these flags should be specified
    opts.optflag("n", "new", "Initialize an empty site at the given location.");
    opts.optflag("a", "article", "Create an article with the given permalink.");
    opts.optflag("p", "page", "Create a page with the given permalink.");
    opts.optflag("g", "gen", "Generate site, can be used along with -i and -o \
                              to specify the input and output location.");
    opts.optflag("s", "server", "Start a local server to preview the generated site \
                                 specified by a directory.");
    opts.optflag("f", "force", "Overwrite existing files when creating articles, \
                                generating site output files, etc.");

    opts.optopt("c", "config", "Run with the given configuration file. By default \
                                configuration file will be looked for under the \
                                current directory.", "CONFIG");
    opts.optopt("i", "input", "Input site directory. Read input files from current \
                              directory by default.", "INPUT");
    opts.optopt("o", "output", "Output site directory. Write to current directory \
                               by default.", "OUTPUT");
    opts.optopt("l", "listen", "Port on which the local server will listen.", "PORT");

    opts.optflag("h", "help", "Show this help message.");
    opts.optflag("V", "version", "Display version information.");

    let matches = match opts.parse(env::args()) {
        Ok(m) => m,
        Err(e) => {
            eprintln!("{}\ntry `{1} -h` or `{1} --help` to see the help.", e, PROG_NAME);
            process::exit(1);
        },
    };

    if matches.opt_present("help") {
        usage(&opts);
        return;
    }

    if matches.opt_present("version") {
        println!("{} {}", PROG_NAME, env!("CARGO_PKG_VERSION"));
        return;
    }

    let mutex_opts = ["new", "article", "gen", "page", "server"];
    let action = mutex_opts
        .iter()
        .filter(|o| matches.opt_present(o))
        .collect::<Vec<_>>();

    match action.len() {
        0 => {
            println!("nothing to do");
            return;
        },
        1 => {
            if let Err(e) = run(matches, action.first().unwrap()) {
                eprintln!("{}", e);
                process::exit(1);
            }
        },
        _ => {
            eprintln!("only one of `-n', `-a', `-p', `-s' and `-g' could be specified");
            process::exit(1);
        }
    }
}
<|endoftext|>


<commit_before>extern crate socket;

use socket::{AF_INET, Socket, SOCK_DGRAM, IP_MULTICAST_TTL, IPPROTO_IP};
use std::collections::HashSet;
use std::net::{IpAddr, SocketAddr};
use std::str::FromStr;
use std::sync::{Arc, mpsc};
use std::thread;
use std::time::Instant;

fn main() {
    println!("{:?}", Discover::new().start(None, Some(4)));
}

pub struct Discover {
    pub devices: Vec<String>,
    multicast: SocketAddr,
    socket: Arc<Socket>
}

impl Discover {
    pub fn new() -> Self {
        Discover {
            devices: Vec::new(),
            multicast: SocketAddr::from_str("239.255.255.250:1900").unwrap(),
            socket: Discover::create_socket()
        }
    }

    fn create_socket() -> Arc<Socket> {
        let socket = Socket::new(AF_INET, SOCK_DGRAM, 0).unwrap();
        let _ = socket.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, 4);

        Arc::new(socket)
    }

    fn send_search(&self) {
        let player_search = r#"M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 1
ST: urn:schemas-upnp-org:device:ZonePlayer:1"#.as_bytes();
        let _ = self.socket.sendto(player_search, 0, &self.multicast);
    }

    pub fn start(&self, timeout: Option<u32>, device_count: Option<usize>) -> HashSet<IpAddr> {
        let timeout = match timeout {
            Some(value) => { value }
            None => 5
        };
        let device_count = match device_count {
            Some(value) => { value }
            None => std::u32::MAX as usize
        };

        let time = Instant::now();

        self.send_search();
        let mut devices = HashSet::new();
        let socket = self.socket.clone();
        while time.elapsed().as_secs() < timeout as u64 && devices.len() < device_count {
            let socket = socket.clone();
            let (sender, receiver) = mpsc::channel();
            let _ = thread::spawn(move ||
                {
                    match socket.recvfrom(1024, 0) {
                        Ok((__addr, _data)) => {
                            let _ = sender.send((__addr, _data));
                        }
                        Err(_) => {}
                    }
                }
            );

            let (_addr, data) = match receiver.recv_timeout(std::time::Duration::new(0, 500000000)) {
                Ok((_addr, data)) => (_addr, data),
                Err(_) => continue
            };
            if devices.contains(&_addr.ip()) || data.is_empty() {
                println!("{:?}", &_addr.ip());
                continue
            }

            let data = String::from_utf8_lossy(&data);
            if data.contains("Sonos") {
                devices.insert(_addr.ip());
            }
        }

        devices
    }
}

impl Drop for Discover {
    fn drop(&mut self) {
        // Socket closes on drop automatically, better safe than sorry
        let _ = self.socket.close();
    }
}

impl Default for Discover {
    fn default() -> Self {
        Discover::new()
    }
}
<commit_msg>Update `fn main`<commit_after>extern crate socket;

use socket::{AF_INET, Socket, SOCK_DGRAM, IP_MULTICAST_TTL, IPPROTO_IP};
use std::collections::HashSet;
use std::net::{IpAddr, SocketAddr};
use std::str::FromStr;
use std::sync::{Arc, mpsc};
use std::thread;
use std::time::Instant;

fn main() {
    let discovery = Discover::new();
    discovery.start(None, Some(4));
    println!("{:?}", discovery);
}

pub struct Discover {
    pub devices: Vec<String>,
    multicast: SocketAddr,
    socket: Arc<Socket>
}

impl Discover {
    pub fn new() -> Self {
        Discover {
            devices: Vec::new(),
            multicast: SocketAddr::from_str("239.255.255.250:1900").unwrap(),
            socket: Discover::create_socket()
        }
    }

    fn create_socket() -> Arc<Socket> {
        let socket = Socket::new(AF_INET, SOCK_DGRAM, 0).unwrap();
        let _ = socket.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, 4);

        Arc::new(socket)
    }

    fn send_search(&self) {
        let player_search = r#"M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 1
ST: urn:schemas-upnp-org:device:ZonePlayer:1"#.as_bytes();
        let _ = self.socket.sendto(player_search, 0, &self.multicast);
    }

    pub fn start(&self, timeout: Option<u32>, device_count: Option<usize>) -> HashSet<IpAddr> {
        let timeout = match timeout {
            Some(value) => { value }
            None => 5
        };
        let device_count = match device_count {
            Some(value) => { value }
            None => std::u32::MAX as usize
        };

        let time = Instant::now();

        self.send_search();
        let mut devices = HashSet::new();
        let socket = self.socket.clone();
        while time.elapsed().as_secs() < timeout as u64 && devices.len() < device_count {
            let socket = socket.clone();
            let (sender, receiver) = mpsc::channel();
            let _ = thread::spawn(move ||
                {
                    match socket.recvfrom(1024, 0) {
                        Ok((__addr, _data)) => {
                            let _ = sender.send((__addr, _data));
                        }
                        Err(_) => {}
                    }
                }
            );

            let (_addr, data) = match receiver.recv_timeout(std::time::Duration::new(0, 500000000)) {
                Ok((_addr, data)) => (_addr, data),
                Err(_) => continue
            };
            if devices.contains(&_addr.ip()) || data.is_empty() {
                println!("{:?}", &_addr.ip());
                continue
            }

            let data = String::from_utf8_lossy(&data);
            if data.contains("Sonos") {
                devices.insert(_addr.ip());
            }
        }

        devices
    }
}

impl Drop for Discover {
    fn drop(&mut self) {
        // Socket closes on drop automatically, better safe than sorry
        let _ = self.socket.close();
    }
}

impl Default for Discover {
    fn default() -> Self {
        Discover::new()
    }
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::env;
use std::fmt;
use std::io;
use std::io::Write;
use std::sync::Mutex;

extern crate syn;
use syn::*;

mod rust_lib;

#[derive(Debug, Clone)]
struct ConvertedType {
    /// The type converted to C (e.g. `uint32_t`)
    prefix: String,
    /// Stuff that might need to go after the identifier (e.g. `[3]` for an array).
    postfix: String,
    /// The types this type depends upon. For example a `prefix` of
    /// Foo<Bar> would have both `Foo` and `Bar` in the `deps`.
    deps: BTreeSet<String>,
}

impl ConvertedType {
    fn append_prefix(&self, str: &str) -> ConvertedType {
        let mut clone = self.clone();
        clone.prefix.push_str(str);
        clone
    }

    fn append_postfix(&self, str: &str) -> ConvertedType {
        let mut clone = self.clone();
        clone.postfix.push_str(str);
        clone
    }

    fn add_dep(&self, dep: String) -> ConvertedType {
        let mut clone = self.clone();
        clone.deps.insert(dep);
        clone
    }

    fn format_with_ident(&self, ident: &Ident) -> String {
        format!("{} {}{}", &self.prefix, &ident.to_string(), &self.postfix)
    }
}

impl From<String> for ConvertedType {
    fn from(str: String) -> ConvertedType {
        let mut initial_set = BTreeSet::new();
        initial_set.insert(str.clone());
        ConvertedType {
            prefix: str,
            postfix: String::new(),
            deps: initial_set,
        }
    }
}

impl fmt::Display for ConvertedType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}", &self.prefix, &self.postfix)
    }
}

fn has_attribute(target: MetaItem, attrs: &Vec<Attribute>) -> bool {
    return attrs
               .iter()
               .any(|ref attr| attr.style == AttrStyle::Outer && attr.value == target);
}

fn has_no_mangle(attrs: &Vec<Attribute>) -> bool {
    has_attribute(MetaItem::Word(Ident::new("no_mangle")), attrs)
}

fn wr_func_body(attrs: &Vec<Attribute>) -> String {
    if has_attribute(MetaItem::Word(Ident::new("destructor_safe")), attrs) {
        String::from("WR_DESTRUCTOR_SAFE_FUNC")
    } else {
        String::from("WR_FUNC")
    }
}

fn is_repr_c(attrs: &Vec<Attribute>) -> bool {
    let repr_args = vec![NestedMetaItem::MetaItem(MetaItem::Word(Ident::new("C")))];
    has_attribute(MetaItem::List(Ident::new("repr"), repr_args), attrs)
}

fn is_repr_u32(attrs: &Vec<Attribute>) -> bool {
    let repr_args = vec![NestedMetaItem::MetaItem(MetaItem::Word(Ident::new("u32")))];
    has_attribute(MetaItem::List(Ident::new("repr"), repr_args), attrs)
}

fn is_c_abi(abi: &Option<Abi>) -> bool {
    abi == &Some(Abi::Named(String::from("C")))
}

fn map_path(p: &Path) -> ConvertedType {
    let l = p.segments[0].ident.to_string();
    let mut c = ConvertedType::from(match l.as_ref() {
        "usize" => "size_t".to_string(),
        "u8" => "uint8_t".to_string(),
        "u32" => "uint32_t".to_string(),
        "u64" => "uint64_t".to_string(),
        "i8" => "int8_t".to_string(),
        "i32" => "int32_t".to_string(),
        "i64" => "int64_t".to_string(),
        "f32" => "float".to_string(),
        "c_void" => "void".to_string(),
        _ => l,
    });
    if let PathParameters::AngleBracketed(ref d) = p.segments[0].parameters {
        let template_args = d.types
            .iter()
            .map(|ty| {
                let conv = map_ty(ty);
                c = c.add_dep(conv.to_string());
                conv.to_string()
            })
            .collect::<Vec<String>>()
            .join(", ");
        if !template_args.is_empty() {
            c = c.append_prefix(&format!("<{}>", &template_args));
        }
    }
    c
}

fn map_mut_ty(mut_ty: &MutTy) -> ConvertedType {
    map_ty(&mut_ty.ty)
}

fn map_ty(ty: &Ty) -> ConvertedType {
    match ty {
        &Ty::Path(_, ref p) => map_path(p),
        &Ty::Ptr(ref p) => map_ty(&p.ty).append_prefix("*"),
        &Ty::Rptr(_, ref mut_ty) => map_mut_ty(mut_ty).append_prefix("*"),
        &Ty::Array(ref p, ConstExpr::Lit(Lit::Int(sz, _))) => map_ty(&p).append_postfix(&format!("[{}]", sz)),
        _ => ConvertedType::from(format!("unknown {:?}", ty)),
    }
}

fn map_return_type(ret: &FunctionRetTy) -> ConvertedType {
    match ret {
        &FunctionRetTy::Default => ConvertedType::from("void".to_string()),
        &FunctionRetTy::Ty(ref ty) => map_ty(ty),
    }
}

fn map_arg(f: &FnArg, dep_set: &mut BTreeSet<String>) -> String {
    match f {
        &FnArg::Captured(Pat::Ident(_, ref ident, _), ref ty) => {
            let mut converted = map_ty(ty);
            dep_set.append(&mut converted.deps);
            converted.format_with_ident(ident)
        }
        _ => "unknown".to_string(),
    }
}

fn map_field(f: &Field, dep_set: &mut BTreeSet<String>) -> String {
    let mut ret = String::from("  ");
    let mut converted = map_ty(&f.ty);
    dep_set.append(&mut converted.deps);
    ret.push_str(&converted.format_with_ident(f.ident.as_ref().expect("Struct fields must have idents")));
    ret.push_str(";\n");
    ret
}

fn map_generic_param(t: &TyParam) -> String {
    let mut ret = String::from("typename ");
    ret.push_str(&t.ident.to_string());
    ret
}

fn fold_enum_variants(accum: (String, i32), v: &Variant) -> (String, i32) {
    // `accum` contains the combined string of converted enum variants so far, to which
    // we will append the converted version of `v`. The other thing in `accum` is the
    // value of the previous variant. If `v` has an explicit value we keep that, otherwise
    // we increment the value of the previous variant to get the new one. This is all
    // so that we properly support enums with explicitly-specified and discontinuous
    // values.
    let mut ret = accum.0;
    ret.push_str("  ");
    ret.push_str(&v.ident.to_string());
    ret.push_str(" = ");
    let new_value = match &v.discriminant {
        &None => accum.1 + 1,
        &Some(ConstExpr::Lit(Lit::Int(ref specified_value, _))) => *specified_value as i32,
        &Some(_) => {
            // we don't handle this yet, so just put in something that will fail C compilation
            writeln!(io::stderr(), "warning, unsupported enum discriminant").unwrap();
            ret.push_str("???");
            accum.1 + 1
        }
    };
    ret.push_str(&new_value.to_string());
    ret.push_str(",\n");
    (ret, new_value)
}

struct ConvertedItem {
    /// This holds the C code that needs to go into the header file.
    c_code: String,
    /// This holds a set of identifiers that the C code depends on.
    /// So for example if a struct A contains another struct B, the
    /// `ConvertedItem` instance for A will have the string "B" in
    /// `deps`.
    deps: BTreeSet<String>,
}

impl ConvertedItem {
    fn new(c_code: String, deps: BTreeSet<String>) -> ConvertedItem {
        ConvertedItem {
            c_code: c_code,
            deps: deps,
        }
    }
}

/// A structure to store all the results of converting Rust stuff to C
/// stuff, so that we can pick and choose what we output.
struct ConversionResults {
    /// This holds the C function signatures of no_mangle rust functions,
    /// in the order that they were encountered in Rust.
    funcs: Vec<ConvertedItem>,
    /// This holds the C conversions of repr(C) structs and repr(u32) enums
    /// from Rust. The 'ds' in the name stands for 'data structures'. The
    /// key of the map is the name of the type.
    ds: BTreeMap<String, ConvertedItem>,
}

fn collect_deps(dst: &mut BTreeSet<String>, results_ref: &ConversionResults, deps: &BTreeSet<String>) {
    for dep in deps {
        dst.insert(dep.to_string());
        results_ref.ds.get(dep).map(|converted| collect_deps(dst, results_ref, &converted.deps));
    }
}

fn main() {
    let p = env::args().nth(1).unwrap();

    let results = Mutex::new(ConversionResults {
        funcs: Vec::new(),
        ds: BTreeMap::new(),
    });

    rust_lib::parse(p, &|mod_name, items| {
        for item in items {
            match item.node {
                ItemKind::Fn(ref decl,
                             ref _unsafe,
                             ref _const,
                             ref abi,
                             ref _generic,
                             ref _block) => {
                    writeln!(io::stderr(), "processing function {}::{}", mod_name, &item.ident).unwrap();
                    if has_no_mangle(&item.attrs) && is_c_abi(&abi) {
                        let mut deps = BTreeSet::new();
                        let mut return_type = map_return_type(&decl.output);
                        deps.append(&mut return_type.deps);
                        let c_code =
                            format!("WR_INLINE {}\n{}({})\n{};\n",
                                    return_type,
                                    item.ident,
                                    decl.inputs
                                        .iter()
                                        .map(|f| map_arg(f, &mut deps))
                                        .collect::<Vec<_>>()
                                        .join(", "),
                                    wr_func_body(&item.attrs));
                        results.lock().unwrap().funcs.push(ConvertedItem::new(c_code, deps));
                    }
                }
                ItemKind::Struct(ref variant,
                                 ref generics) => {
                    writeln!(io::stderr(), "processing struct {}::{}", mod_name, &item.ident).unwrap();
                    if is_repr_c(&item.attrs) {
                        if let &VariantData::Struct(ref fields) = variant {
                            let mut deps = BTreeSet::new();
                            let mut c_code = String::new();
                            if !generics.ty_params.is_empty() {
                                c_code.push_str(&(
                                    format!("template<{}>\n",
                                            generics.ty_params
                                                    .iter()
                                                    .map(map_generic_param)
                                                    .collect::<Vec<_>>()
                                                    .join(", "))));
                            }
                            c_code.push_str(&(
                                format!("struct {} {{\n{}}};\n",
                                        item.ident,
                                        fields.iter()
                                              .map(|f| map_field(f, &mut deps))
                                              .collect::<String>())));
                            results.lock().unwrap().ds.insert(
                                item.ident.to_string(),
                                ConvertedItem::new(c_code, deps));
                        }
                    }
                }
                ItemKind::Enum(ref variants, ref _generics) => {
                    writeln!(io::stderr(), "processing enum {}::{}", mod_name, &item.ident).unwrap();
                    if is_repr_u32(&item.attrs) {
                        let c_code = format!("enum class {}: uint32_t {{\n{}\n  Sentinel /* this must be last for serialization purposes. */\n}};\n",
                                             item.ident,
                                             variants.iter()
                                                     .fold((String::new(), -1), fold_enum_variants)
                                                     .0);
                        results.lock().unwrap().ds.insert(
                            item.ident.to_string(),
                            ConvertedItem::new(c_code, BTreeSet::new()));
                    }
                }
                _ => {}
            }
        }
    });

    let mut all_func_deps = BTreeSet::new();
    let results_ref = &results.lock().unwrap();
    for converted in &results_ref.funcs {
        collect_deps(&mut all_func_deps, results_ref, &converted.deps);
    }
    for dep in all_func_deps {
        results_ref.ds.get(&dep).map(|converted| println!("{}", converted.c_code));
    }
    for converted in &results_ref.funcs {
        println!("{}", converted.c_code);
    }
}
<commit_msg>Add some docs<commit_after>use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::env;
use std::fmt;
use std::io;
use std::io::Write;
use std::sync::Mutex;

extern crate syn;
use syn::*;

mod rust_lib;

#[derive(Debug, Clone)]
struct ConvertedType {
    /// The type converted to C (e.g. `uint32_t`)
    prefix: String,
    /// Stuff that might need to go after the identifier (e.g. `[3]` for an array).
    postfix: String,
    /// The types this type depends upon. For example a `prefix` of
    /// Foo<Bar> would have both `Foo` and `Bar` in the `deps`.
    deps: BTreeSet<String>,
}

impl ConvertedType {
    fn append_prefix(&self, str: &str) -> ConvertedType {
        let mut clone = self.clone();
        clone.prefix.push_str(str);
        clone
    }

    fn append_postfix(&self, str: &str) -> ConvertedType {
        let mut clone = self.clone();
        clone.postfix.push_str(str);
        clone
    }

    fn add_dep(&self, dep: String) -> ConvertedType {
        let mut clone = self.clone();
        clone.deps.insert(dep);
        clone
    }

    fn format_with_ident(&self, ident: &Ident) -> String {
        format!("{} {}{}", &self.prefix, &ident.to_string(), &self.postfix)
    }
}

impl From<String> for ConvertedType {
    fn from(str: String) -> ConvertedType {
        let mut initial_set = BTreeSet::new();
        initial_set.insert(str.clone());
        ConvertedType {
            prefix: str,
            postfix: String::new(),
            deps: initial_set,
        }
    }
}

impl fmt::Display for ConvertedType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}", &self.prefix, &self.postfix)
    }
}

fn has_attribute(target: MetaItem, attrs: &Vec<Attribute>) -> bool {
    return attrs
               .iter()
               .any(|ref attr| attr.style == AttrStyle::Outer && attr.value == target);
}

fn has_no_mangle(attrs: &Vec<Attribute>) -> bool {
    has_attribute(MetaItem::Word(Ident::new("no_mangle")), attrs)
}

fn wr_func_body(attrs: &Vec<Attribute>) -> String {
    if has_attribute(MetaItem::Word(Ident::new("destructor_safe")), attrs) {
        String::from("WR_DESTRUCTOR_SAFE_FUNC")
    } else {
        String::from("WR_FUNC")
    }
}

fn is_repr_c(attrs: &Vec<Attribute>) -> bool {
    let repr_args = vec![NestedMetaItem::MetaItem(MetaItem::Word(Ident::new("C")))];
    has_attribute(MetaItem::List(Ident::new("repr"), repr_args), attrs)
}

fn is_repr_u32(attrs: &Vec<Attribute>) -> bool {
    let repr_args = vec![NestedMetaItem::MetaItem(MetaItem::Word(Ident::new("u32")))];
    has_attribute(MetaItem::List(Ident::new("repr"), repr_args), attrs)
}

fn is_c_abi(abi: &Option<Abi>) -> bool {
    abi == &Some(Abi::Named(String::from("C")))
}

fn map_path(p: &Path) -> ConvertedType {
    let l = p.segments[0].ident.to_string();
    let mut c = ConvertedType::from(match l.as_ref() {
        "usize" => "size_t".to_string(),
        "u8" => "uint8_t".to_string(),
        "u32" => "uint32_t".to_string(),
        "u64" => "uint64_t".to_string(),
        "i8" => "int8_t".to_string(),
        "i32" => "int32_t".to_string(),
        "i64" => "int64_t".to_string(),
        "f32" => "float".to_string(),
        "c_void" => "void".to_string(),
        _ => l,
    });
    if let PathParameters::AngleBracketed(ref d) = p.segments[0].parameters {
        let template_args = d.types
            .iter()
            .map(|ty| {
                let conv = map_ty(ty);
                c = c.add_dep(conv.to_string());
                conv.to_string()
            })
            .collect::<Vec<String>>()
            .join(", ");
        if !template_args.is_empty() {
            c = c.append_prefix(&format!("<{}>", &template_args));
        }
    }
    c
}

fn map_mut_ty(mut_ty: &MutTy) -> ConvertedType {
    map_ty(&mut_ty.ty)
}

fn map_ty(ty: &Ty) -> ConvertedType {
    match ty {
        &Ty::Path(_, ref p) => map_path(p),
        &Ty::Ptr(ref p) => map_ty(&p.ty).append_prefix("*"),
        &Ty::Rptr(_, ref mut_ty) => map_mut_ty(mut_ty).append_prefix("*"),
        &Ty::Array(ref p, ConstExpr::Lit(Lit::Int(sz, _))) => map_ty(&p).append_postfix(&format!("[{}]", sz)),
        _ => ConvertedType::from(format!("unknown {:?}", ty)),
    }
}

fn map_return_type(ret: &FunctionRetTy) -> ConvertedType {
    match ret {
        &FunctionRetTy::Default => ConvertedType::from("void".to_string()),
        &FunctionRetTy::Ty(ref ty) => map_ty(ty),
    }
}

fn map_arg(f: &FnArg, dep_set: &mut BTreeSet<String>) -> String {
    match f {
        &FnArg::Captured(Pat::Ident(_, ref ident, _), ref ty) => {
            let mut converted = map_ty(ty);
            dep_set.append(&mut converted.deps);
            converted.format_with_ident(ident)
        }
        _ => "unknown".to_string(),
    }
}

fn map_field(f: &Field, dep_set: &mut BTreeSet<String>) -> String {
    let mut ret = String::from("  ");
    let mut converted = map_ty(&f.ty);
    dep_set.append(&mut converted.deps);
    ret.push_str(&converted.format_with_ident(f.ident.as_ref().expect("Struct fields must have idents")));
    ret.push_str(";\n");
    ret
}

fn map_generic_param(t: &TyParam) -> String {
    let mut ret = String::from("typename ");
    ret.push_str(&t.ident.to_string());
    ret
}

fn fold_enum_variants(accum: (String, i32), v: &Variant) -> (String, i32) {
    // `accum` contains the combined string of converted enum variants so far, to which
    // we will append the converted version of `v`. The other thing in `accum` is the
    // value of the previous variant. If `v` has an explicit value we keep that, otherwise
    // we increment the value of the previous variant to get the new one. This is all
    // so that we properly support enums with explicitly-specified and discontinuous
    // values.
    let mut ret = accum.0;
    ret.push_str("  ");
    ret.push_str(&v.ident.to_string());
    ret.push_str(" = ");
    let new_value = match &v.discriminant {
        &None => accum.1 + 1,
        &Some(ConstExpr::Lit(Lit::Int(ref specified_value, _))) => *specified_value as i32,
        &Some(_) => {
            // we don't handle this yet, so just put in something that will fail C compilation
            writeln!(io::stderr(), "warning, unsupported enum discriminant").unwrap();
            ret.push_str("???");
            accum.1 + 1
        }
    };
    ret.push_str(&new_value.to_string());
    ret.push_str(",\n");
    (ret, new_value)
}

/// Convenience struct to group stuff associated with a converted
/// item.
struct ConvertedItem {
    /// This holds the C code that needs to go into the header file.
    c_code: String,
    /// This holds a set of identifiers that the C code depends on.
    /// So for example if a struct A contains another struct B, the
    /// `ConvertedItem` instance for A will have the string "B" in
    /// `deps`.
    deps: BTreeSet<String>,
}

impl ConvertedItem {
    fn new(c_code: String, deps: BTreeSet<String>) -> ConvertedItem {
        ConvertedItem {
            c_code: c_code,
            deps: deps,
        }
    }
}

/// A structure to store all the results of converting Rust stuff to C
/// stuff, so that we can pick and choose what we output.
struct ConversionResults {
    /// This holds the C function signatures of no_mangle rust functions,
    /// in the order that they were encountered in Rust.
    funcs: Vec<ConvertedItem>,
    /// This holds the C conversions of repr(C) structs and repr(u32) enums
    /// from Rust. The 'ds' in the name stands for 'data structures'. The
    /// key of the map is the name of the type.
    ds: BTreeMap<String, ConvertedItem>,
}

/// Recursive function to collect the dependencies we need. Deps are collected
/// into `dst`, using the "database" of dependencies in `results_ref`, and
/// using `deps` as the starting set of dependencies we want.
fn collect_deps(dst: &mut BTreeSet<String>, results_ref: &ConversionResults, deps: &BTreeSet<String>) {
    for dep in deps {
        dst.insert(dep.to_string());
        results_ref.ds.get(dep).map(|converted| collect_deps(dst, results_ref, &converted.deps));
    }
}

fn main() {
    let p = env::args().nth(1).unwrap();

    let results = Mutex::new(ConversionResults {
        funcs: Vec::new(),
        ds: BTreeMap::new(),
    });

    rust_lib::parse(p, &|mod_name, items| {
        for item in items {
            match item.node {
                ItemKind::Fn(ref decl,
                             ref _unsafe,
                             ref _const,
                             ref abi,
                             ref _generic,
                             ref _block) => {
                    writeln!(io::stderr(), "processing function {}::{}", mod_name, &item.ident).unwrap();
                    if has_no_mangle(&item.attrs) && is_c_abi(&abi) {
                        let mut deps = BTreeSet::new();
                        let mut return_type = map_return_type(&decl.output);
                        deps.append(&mut return_type.deps);
                        let c_code =
                            format!("WR_INLINE {}\n{}({})\n{};\n",
                                    return_type,
                                    item.ident,
                                    decl.inputs
                                        .iter()
                                        .map(|f| map_arg(f, &mut deps))
                                        .collect::<Vec<_>>()
                                        .join(", "),
                                    wr_func_body(&item.attrs));
                        results.lock().unwrap().funcs.push(ConvertedItem::new(c_code, deps));
                    }
                }
                ItemKind::Struct(ref variant,
                                 ref generics) => {
                    writeln!(io::stderr(), "processing struct {}::{}", mod_name, &item.ident).unwrap();
                    if is_repr_c(&item.attrs) {
                        if let &VariantData::Struct(ref fields) = variant {
                            let mut deps = BTreeSet::new();
                            let mut c_code = String::new();
                            if !generics.ty_params.is_empty() {
                                c_code.push_str(&(
                                    format!("template<{}>\n",
                                            generics.ty_params
                                                    .iter()
                                                    .map(map_generic_param)
                                                    .collect::<Vec<_>>()
                                                    .join(", "))));
                            }
                            c_code.push_str(&(
                                format!("struct {} {{\n{}}};\n",
                                        item.ident,
                                        fields.iter()
                                              .map(|f| map_field(f, &mut deps))
                                              .collect::<String>())));
                            results.lock().unwrap().ds.insert(
                                item.ident.to_string(),
                                ConvertedItem::new(c_code, deps));
                        }
                    }
                }
                ItemKind::Enum(ref variants, ref _generics) => {
                    writeln!(io::stderr(), "processing enum {}::{}", mod_name, &item.ident).unwrap();
                    if is_repr_u32(&item.attrs) {
                        let c_code = format!("enum class {}: uint32_t {{\n{}\n  Sentinel /* this must be last for serialization purposes. */\n}};\n",
                                             item.ident,
                                             variants.iter()
                                                     .fold((String::new(), -1), fold_enum_variants)
                                                     .0);
                        results.lock().unwrap().ds.insert(
                            item.ident.to_string(),
                            ConvertedItem::new(c_code, BTreeSet::new()));
                    }
                }
                _ => {}
            }
        }
    });

    // Collect all the recursive type dependencies using the functions
    // as the roots. (i.e. all the structs/enums referred to by the function
    // return types and arguments, plus all the structs/enums referred to
    // by *those* and so on). We just skip any types that we don't have
    // instead of returning an error. This way we don't have to add special
    // handling for things like void and int32_t and whatnot.
    // Collect into a BTreeSet to strip duplicates and get a deterministic order.
    let mut all_func_deps = BTreeSet::new();
    let results_ref = &results.lock().unwrap();
    for converted in &results_ref.funcs {
        collect_deps(&mut all_func_deps, results_ref, &converted.deps);
    }

    // Showtime!
    for dep in all_func_deps {
        results_ref.ds.get(&dep).map(|converted| println!("{}", converted.c_code));
    }
    for converted in &results_ref.funcs {
        println!("{}", converted.c_code);
    }
}
<|endoftext|>


<commit_before>// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Copyright 2014 Mark McDermott.
//
// Licensed under the the MIT license
// <LICENSE or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed
// except according to those terms.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------

extern crate sdl2;
extern crate gl;
extern crate libc;
extern crate log;
extern crate native;

//use sdl2::video::{Window, PosCentered, OPENGL};
//use sdl2::event::{Quit, None, poll_event};

// --------------------------------------------------------------------------
// Native entry point
// --------------------------------------------------------------------------
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
    native::start(argc, argv, main)
}

// --------------------------------------------------------------------------
// The "Real" entry point
// --------------------------------------------------------------------------
fn main() {
    println!("Welcome to the the Cosmolark editor!")

    sdl2::init(sdl2::INIT_EVERYTHING);

            sdl2::video::gl_set_attribute(sdl2::video::GLContextMajorVersion,3);
        sdl2::video::gl_set_attribute(sdl2::video::GLContextMinorVersion,0);
        sdl2::video::gl_set_attribute(sdl2::video::GLDepthSize,24);
        sdl2::video::gl_set_attribute(sdl2::video::GLDoubleBuffer, 1);
        sdl2::video::gl_set_attribute(sdl2::video::GLContextProfileMask,sdl2::video::ll::SDL_GL_CONTEXT_PROFILE_CORE as int);

    // open a window
    let window = match sdl2::video::Window::new("Cosmolark Asset Editor",sdl2::video::PosCentered, sdl2::video::PosCentered, 300,300,sdl2::video::OPENGL) {
        Ok(window) => window,
        Err(err)   => panic!("failed to create window: {}", err)
    };

    let context = window.gl_create_context().unwrap();
    sdl2::clear_error();
    gl::load_with(|name| {
        match sdl2::video::gl_get_proc_address(name) {
            Some(glproc) => glproc as *const libc::c_void,
            None         => { println!("missing GL function: {}", name); std::ptr::null() }
        }
    });

    window.show();

    unsafe {
        gl::ClearColor(0.3,0.3,0.3,1.0);
        gl::Clear(gl::COLOR_BUFFER_BIT);
    }

    // swap buffer
    window.gl_swap_window();

    'event : loop {
        match sdl2::event::poll_event() {
            sdl2::event::Quit(_) => break 'event,
            sdl2::event::None    => continue,
            event                => println!("event: {}", event),
        }
    }

    sdl2::quit();
} // end function main()

<commit_msg>Added example code from gl-rs to display a triangle<commit_after>// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Copyright 2014 Mark McDermott.
//
// Licensed under the the MIT license
// <LICENSE or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed
// except according to those terms.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------

extern crate sdl2;
extern crate gl;
extern crate libc;
extern crate log;
extern crate native;

use gl::types::{GLfloat,GLuint,GLint,GLchar,GLenum,GLboolean,GLsizeiptr};
use std::ptr;
use std::str;
use std::mem;

// Vertex data
static VERTEX_DATA: [GLfloat, ..6] = [
     0.0,  0.5,
     0.5, -0.5,
    -0.5, -0.5
];

// Shader sources
static VS_SRC: &'static str =
   "#version 150\n\
    in vec2 position;\n\
    void main() {\n\
       gl_Position = vec4(position, 0.0, 1.0);\n\
    }";

static FS_SRC: &'static str =
   "#version 150\n\
    out vec4 out_color;\n\
    void main() {\n\
       out_color = vec4(1.0, 1.0, 1.0, 1.0);\n\
    }";

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
    let shader;
    unsafe {
        shader = gl::CreateShader(ty);
        // Attempt to compile the shader
        src.with_c_str(|ptr| gl::ShaderSource(shader, 1, &ptr, ptr::null()));
        gl::CompileShader(shader);

        // Get the compile status
        let mut status = gl::FALSE as GLint;
        gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

        // Fail on error
        if status != (gl::TRUE as GLint) {
            let mut len = 0;
            gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
            let mut buf = Vec::from_elem(len as uint - 1, 0u8);     // subtract 1 to skip the trailing null character
            gl::GetShaderInfoLog(shader, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
            panic!("{}", str::from_utf8(buf.as_slice()).expect("ShaderInfoLog not valid utf8"));
        }
    }
    shader
}

fn link_program(vs: GLuint, fs: GLuint) -> GLuint { unsafe {
    let program = gl::CreateProgram();
    gl::AttachShader(program, vs);
    gl::AttachShader(program, fs);
    gl::LinkProgram(program);
    unsafe {
        // Get the link status
        let mut status = gl::FALSE as GLint;
        gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

        // Fail on error
        if status != (gl::TRUE as GLint) {
            let mut len: GLint = 0;
            gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
            let mut buf = Vec::from_elem(len as uint - 1, 0u8);     // subtract 1 to skip the trailing null character
            gl::GetProgramInfoLog(program, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
            panic!("{}", str::from_utf8(buf.as_slice()).expect("ProgramInfoLog not valid utf8"));
        }
    }
    program
}}

// --------------------------------------------------------------------------
// Native entry point
// --------------------------------------------------------------------------
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
    native::start(argc, argv, main)
}

// --------------------------------------------------------------------------
// The "Real" entry point
// --------------------------------------------------------------------------
fn main() {
    println!("Welcome to the the Cosmolark editor!")

    sdl2::init(sdl2::INIT_EVERYTHING);

            sdl2::video::gl_set_attribute(sdl2::video::GLContextMajorVersion,3);
        sdl2::video::gl_set_attribute(sdl2::video::GLContextMinorVersion,0);
        sdl2::video::gl_set_attribute(sdl2::video::GLDepthSize,24);
        sdl2::video::gl_set_attribute(sdl2::video::GLDoubleBuffer, 1);
        sdl2::video::gl_set_attribute(sdl2::video::GLContextProfileMask,sdl2::video::ll::SDL_GL_CONTEXT_PROFILE_CORE as int);

    // open a window
    let window = match sdl2::video::Window::new("Cosmolark Asset Editor",sdl2::video::PosCentered, sdl2::video::PosCentered, 300,300,sdl2::video::OPENGL) {
        Ok(window) => window,
        Err(err)   => panic!("failed to create window: {}", err)
    };

    let context = window.gl_create_context().unwrap();
    sdl2::clear_error();
    gl::load_with(|name| {
        match sdl2::video::gl_get_proc_address(name) {
            Some(glproc) => glproc as *const libc::c_void,
            None         => { println!("missing GL function: {}", name); std::ptr::null() }
        }
    });

    let vs = compile_shader(VS_SRC, gl::VERTEX_SHADER);
    let fs = compile_shader(FS_SRC, gl::FRAGMENT_SHADER);
    let program = link_program(vs, fs);

    window.show();

    let mut vao = 0;
    let mut vbo = 0;
    unsafe {
        // Create Vertex Array Object
        gl::GenVertexArrays(1, &mut vao);
        gl::BindVertexArray(vao);

        // Create a Vertex Buffer Object and copy the vertex data to it
        gl::GenBuffers(1, &mut vbo);
        gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
        gl::BufferData(gl::ARRAY_BUFFER,
                      (VERTEX_DATA.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
                      mem::transmute(&VERTEX_DATA[0]),
                      gl::STATIC_DRAW);

        // Use shader program
        gl::UseProgram(program);
        "out_color".with_c_str(|ptr| gl::BindFragDataLocation(program, 0, ptr));

        // Specify the layout of the vertex data
        let pos_attr = "position".with_c_str(|ptr| gl::GetAttribLocation(program, ptr));
        gl::EnableVertexAttribArray(pos_attr as GLuint);
        gl::VertexAttribPointer(pos_attr as GLuint, 2, gl::FLOAT,
                               gl::FALSE as GLboolean, 0, ptr::null());
    }

    unsafe {
        gl::ClearColor(0.3,0.3,0.3,1.0);
        gl::Clear(gl::COLOR_BUFFER_BIT);
        gl::DrawArrays(gl::TRIANGLES, 0,3);
    }

    // swap buffer
    window.gl_swap_window();

    'event : loop {
        match sdl2::event::poll_event() {
            sdl2::event::Quit(_) => break 'event,
            sdl2::event::None    => continue,
            //event                => println!("event: {}", event),
            _                    => continue
        }
    }

    unsafe {
        // Cleanup
        gl::DeleteProgram(program);
        gl::DeleteShader(fs);
        gl::DeleteShader(vs);
        gl::DeleteBuffers(1, &vbo);
        gl::DeleteVertexArrays(1, &vao);
    }
    sdl2::quit();
} // end function main()

<|endoftext|>


<commit_before>extern crate iron;
extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

extern crate router;

use router::Router;
use iron::prelude::*;
use iron::{status, headers};
use iron::method::Method;
use iron::modifiers::Header;

use std::io::Read;
use std::process::Command;

#[derive(Debug, Deserialize, Serialize)]
struct Address {
    address: String
}

#[derive(Debug, Deserialize, Serialize)]
struct TxId {
	txid: String
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniTransaction {
	#[serde(rename = "type")]
	type_type: String,
	txid: String,
	fee: String,
	sendingaddress: String,
	#[serde(default="default_string")]
	referenceaddress: String,
	ismine: bool,
	version: u8,
	type_int: u8,
	propertyid: u8,
	divisible: bool,
	amount: String,
	valid: bool,
	blockhash: String,
	blocktime: u32,
	positioninblock: u32,
	block: u32,
	confirmations: u32,
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniInfo {
	omnicoreversion_int: u32,
	omnicoreversion: String,
	mastercoreversion: String,
	bitcoincoreversion: String,
	block: u32,
	blocktime: u32,
	blocktransactions: u32,
	totaltrades: u32,
	alerts: Vec<String>
}

fn default_string() -> String {
	"reference".to_string()
}
#[derive(Debug, Deserialize, Serialize)]
struct RawTxn {
	rawtx: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct unconfirmedTransactions {
	txid: String,
	fee: String,
	sendingaddress: String,
	referenceaddress: String,
	ismine: bool,
	version: u32,
	type_int: u32,
	#[serde(rename = "type")]
	type_type: String,
	propertyid: u32,
	divisible: bool,
	amount: String,
	confirmations: u32
}

#[derive(Debug, Deserialize, Serialize)]
struct Payload {
	amount: String,
}

fn main() {
	let mut router = Router::new();

	router.post("/balance", move |r: &mut Request| get_balance(r), "get_balance");
	router.post("/transactions", move |r: &mut Request| get_transactions(r), "get_transactions");
	router.post("/broadcast", move |r: &mut Request| broadcast(r), "broadcast");
	router.post("/unconfirmed", move |r: &mut Request| unconfirmed(r), "unconfirmed");
	router.get("/getfee", move |r: &mut Request| getfee(r), "getfee");
	router.post("/getpayload", move |r: &mut Request| getfee(r), "getpayload");
	router.get("/blockheight", get_blockheight, "get_blockheight");

	//route for get balance, accepts a public key, and a property identifier

	fn get_balance(req: &mut Request) -> IronResult<Response> {

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let balance = Command::new("omnicore-cli").arg("omni_getbalance").arg(address.address).arg("56").output().expect("failed");

		let output = balance.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getpayload(req: &mut Request) -> IronResult<Response> {

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let payload: Payload = serde_json::from_str(&payload).unwrap();
		let payload = Command::new("omnicore-cli").arg("omni_createpayload_simplesend").arg("56").arg(payload.amount).output().expect("failed");

		let output = payload.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getfee(req: &mut Request) -> IronResult<Response> {

		let fee = Command::new("omnicore-cli").arg("estimatefee").arg("6").output().expect("failed");

		 let mut s = String::from_utf8(fee.stdout).unwrap();
    		s.pop();
		let mut response = Response::with((status::Ok, s));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn unconfirmed(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("omni_listpendingtransactions").arg(&address.address).output().expect("failed");
		let output = String::from_utf8(output.stdout).unwrap();
		let output: Vec<unconfirmedTransactions> = serde_json::from_str(&output).unwrap();
		let mut pending_balance = 0;
		for txn in output {
			if address.address == txn.sendingaddress {
				pending_balance -= txn.amount.parse::<i32>().unwrap();
			} else {
				pending_balance += txn.amount.parse::<i32>().unwrap();
			}
		}

		let mut response = Response::with((status::Ok, pending_balance.to_string()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn broadcast(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let txn: RawTxn = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("sendrawtransaction").arg(txn.rawtx).output().expect("failed");

		let output = output.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn get_transactions(req: &mut Request) -> IronResult<Response> {
		println!("{:?}", req);
		//todo remove unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		println!("got through read to string");
		let txid: TxId = serde_json::from_str(&payload).unwrap();
		println!("didnt get through txid");

		let transaction = Command::new("omnicore-cli").arg("omni_gettransaction").arg(txid.txid).output().expect("failed");

		println!("got the command in");

		let output = transaction.stdout;

		let string_output = String::from_utf8_lossy(&output);

		let safex_tx: OmniTransaction = serde_json::from_str(&string_output).unwrap();

		if safex_tx.propertyid == 56 {

			let mut response = Response::with((status::Ok, serde_json::to_string(&safex_tx).unwrap()));
			response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
			response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

			Ok(response)
		} else {

			Ok(Response::with((status::Ok)))
		}

	}

	fn get_blockheight(_: &mut Request) -> IronResult<Response> {
		let block_info = Command::new("omnicore-cli").arg("omni_getinfo").output().expect("failed");

		let output = block_info.stdout;

		let string_output = String::from_utf8_lossy(&output);
		let block_info: OmniInfo = serde_json::from_str(&string_output).unwrap();

		let mut response = Response::with((status::Ok, serde_json::to_string(&block_info).unwrap()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

		Ok(response)
	}

	Iron::new(router).http("localhost:3001").unwrap();
}
<commit_msg>replace function<commit_after>extern crate iron;
extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

extern crate router;

use router::Router;
use iron::prelude::*;
use iron::{status, headers};
use iron::method::Method;
use iron::modifiers::Header;

use std::io::Read;
use std::process::Command;

#[derive(Debug, Deserialize, Serialize)]
struct Address {
    address: String
}

#[derive(Debug, Deserialize, Serialize)]
struct TxId {
	txid: String
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniTransaction {
	#[serde(rename = "type")]
	type_type: String,
	txid: String,
	fee: String,
	sendingaddress: String,
	#[serde(default="default_string")]
	referenceaddress: String,
	ismine: bool,
	version: u8,
	type_int: u8,
	propertyid: u8,
	divisible: bool,
	amount: String,
	valid: bool,
	blockhash: String,
	blocktime: u32,
	positioninblock: u32,
	block: u32,
	confirmations: u32,
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniInfo {
	omnicoreversion_int: u32,
	omnicoreversion: String,
	mastercoreversion: String,
	bitcoincoreversion: String,
	block: u32,
	blocktime: u32,
	blocktransactions: u32,
	totaltrades: u32,
	alerts: Vec<String>
}

fn default_string() -> String {
	"reference".to_string()
}
#[derive(Debug, Deserialize, Serialize)]
struct RawTxn {
	rawtx: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct unconfirmedTransactions {
	txid: String,
	fee: String,
	sendingaddress: String,
	referenceaddress: String,
	ismine: bool,
	version: u32,
	type_int: u32,
	#[serde(rename = "type")]
	type_type: String,
	propertyid: u32,
	divisible: bool,
	amount: String,
	confirmations: u32
}

#[derive(Debug, Deserialize, Serialize)]
struct Payload {
	amount: String,
}

fn main() {
	let mut router = Router::new();

	router.post("/balance", move |r: &mut Request| get_balance(r), "get_balance");
	router.post("/transactions", move |r: &mut Request| get_transactions(r), "get_transactions");
	router.post("/broadcast", move |r: &mut Request| broadcast(r), "broadcast");
	router.post("/unconfirmed", move |r: &mut Request| unconfirmed(r), "unconfirmed");
	router.get("/getfee", move |r: &mut Request| getfee(r), "getfee");
	router.post("/getpayload", move |r: &mut Request| getpayload(r), "getpayload");
	router.get("/blockheight", get_blockheight, "get_blockheight");

	//route for get balance, accepts a public key, and a property identifier

	fn get_balance(req: &mut Request) -> IronResult<Response> {

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let balance = Command::new("omnicore-cli").arg("omni_getbalance").arg(address.address).arg("56").output().expect("failed");

		let output = balance.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getpayload(req: &mut Request) -> IronResult<Response> {

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let payload: Payload = serde_json::from_str(&payload).unwrap();
		let payload = Command::new("omnicore-cli").arg("omni_createpayload_simplesend").arg("56").arg(payload.amount).output().expect("failed");

		let output = payload.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getfee(req: &mut Request) -> IronResult<Response> {

		let fee = Command::new("omnicore-cli").arg("estimatefee").arg("6").output().expect("failed");

		 let mut s = String::from_utf8(fee.stdout).unwrap();
    		s.pop();
		let mut response = Response::with((status::Ok, s));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn unconfirmed(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("omni_listpendingtransactions").arg(&address.address).output().expect("failed");
		let output = String::from_utf8(output.stdout).unwrap();
		let output: Vec<unconfirmedTransactions> = serde_json::from_str(&output).unwrap();
		let mut pending_balance = 0;
		for txn in output {
			if address.address == txn.sendingaddress {
				pending_balance -= txn.amount.parse::<i32>().unwrap();
			} else {
				pending_balance += txn.amount.parse::<i32>().unwrap();
			}
		}

		let mut response = Response::with((status::Ok, pending_balance.to_string()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn broadcast(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let txn: RawTxn = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("sendrawtransaction").arg(txn.rawtx).output().expect("failed");

		let output = output.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn get_transactions(req: &mut Request) -> IronResult<Response> {
		println!("{:?}", req);
		//todo remove unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		println!("got through read to string");
		let txid: TxId = serde_json::from_str(&payload).unwrap();
		println!("didnt get through txid");

		let transaction = Command::new("omnicore-cli").arg("omni_gettransaction").arg(txid.txid).output().expect("failed");

		println!("got the command in");

		let output = transaction.stdout;

		let string_output = String::from_utf8_lossy(&output);

		let safex_tx: OmniTransaction = serde_json::from_str(&string_output).unwrap();

		if safex_tx.propertyid == 56 {

			let mut response = Response::with((status::Ok, serde_json::to_string(&safex_tx).unwrap()));
			response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
			response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

			Ok(response)
		} else {

			Ok(Response::with((status::Ok)))
		}

	}

	fn get_blockheight(_: &mut Request) -> IronResult<Response> {
		let block_info = Command::new("omnicore-cli").arg("omni_getinfo").output().expect("failed");

		let output = block_info.stdout;

		let string_output = String::from_utf8_lossy(&output);
		let block_info: OmniInfo = serde_json::from_str(&string_output).unwrap();

		let mut response = Response::with((status::Ok, serde_json::to_string(&block_info).unwrap()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

		Ok(response)
	}

	Iron::new(router).http("localhost:3001").unwrap();
}
<|endoftext|>