<commit_before>// Program to verify the vectors.

extern crate noise_protocol as noise;
extern crate noise_sodiumoxide;
extern crate noise_ring;
extern crate noise_rust_crypto;
extern crate serde;
extern crate rustc_serialize;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

use noise::*;
use noise::patterns::*;
use noise_ring as ring;
use noise_rust_crypto as crypto;
use noise_sodiumoxide as sodium;

use rustc_serialize::hex::FromHex;
use serde_json as json;

#[derive(Serialize, Deserialize)]
struct HexString(String);

impl HexString {
    pub fn to_bytes(&self) -> Vec<u8> {
        self.0.from_hex().unwrap()
    }
}

#[derive(Serialize, Deserialize)]
struct Vector {
    name: String,
    pattern: String,
    dh: String,
    cipher: String,
    hash: String,
    init_prologue: HexString,
    init_psk: Option<HexString>,
    init_static: Option<HexString>,
    init_ephemeral: HexString,
    init_remote_static: Option<HexString>,
    resp_prologue: HexString,
    resp_psk: Option<HexString>,
    resp_static: Option<HexString>,
    resp_ephemeral: Option<HexString>,
    resp_remote_static: Option<HexString>,
    handshake_hash: Option<HexString>,
    messages: Vec<Message>,
    fallback: Option<bool>,
}

#[derive(Serialize, Deserialize)]
struct Message {
    payload: HexString,
    ciphertext: HexString,
}

fn get_pattern_by_name(name: &str) -> Option<HandshakePattern> {
    match name {
        "N" => Some(noise_n()),
        "K" => Some(noise_k()),
        "X" => Some(noise_x()),
        "NN" => Some(noise_nn()),
        "NK" => Some(noise_nk()),
        "NX" => Some(noise_nx()),
        "KN" => Some(noise_kn()),
        "KK" => Some(noise_kk()),
        "KX" => Some(noise_kx()),
        "XN" => Some(noise_xn()),
        "XK" => Some(noise_xk()),
        "XX" => Some(noise_xx()),
        "IN" => Some(noise_in()),
        "IK" => Some(noise_ik()),
        "IX" => Some(noise_ix()),
        _ => None,
    }
}

fn to_dh<D>(k: &HexString) -> D::Key
    where D: DH
{
    D::Key::from_slice(k.to_bytes().as_slice())
}

fn to_pubkey<D>(k: &HexString) -> D::Pubkey
    where D: DH
{
    D::Pubkey::from_slice(k.to_bytes().as_slice())
}

fn verify_vector_with<D, C, H>(v: &Vector)
    where D: DH,
          C: Cipher,
          H: Hash
{
    if v.fallback.unwrap_or(false) {
        verify_vector_fallback::<D, C, H>(v);
        return;
    }

    let pattern = get_pattern_by_name(v.pattern.as_str());
    if pattern.is_none() {
        println!("Unknown pattern {}", v.pattern);
        return;
    }
    let pattern = pattern.unwrap();

    let mut h_i = HandshakeState::<D, C, H>::new(pattern.clone(),
                                                 true,
                                                 v.init_prologue.to_bytes(),
                                                 v.init_psk.as_ref().map(HexString::to_bytes),
                                                 v.init_static.as_ref().map(to_dh::<D>),
                                                 Some(to_dh::<D>(&v.init_ephemeral)),
                                                 v.init_remote_static.as_ref().map(to_pubkey::<D>),
                                                 None);
    let mut h_r = HandshakeState::<D, C, H>::new(pattern,
                                                 false,
                                                 v.resp_prologue.to_bytes(),
                                                 v.resp_psk.as_ref().map(HexString::to_bytes),
                                                 v.resp_static.as_ref().map(to_dh::<D>),
                                                 v.resp_ephemeral.as_ref().map(to_dh::<D>),
                                                 v.resp_remote_static.as_ref().map(to_pubkey::<D>),
                                                 None);

    let mut init_send = true;
    let mut handshake_completed = false;

    let mut init_ciphers = None;
    let mut resp_ciphers = None;

    for m in &v.messages {
        let payload = m.payload.to_bytes();
        let payload = payload.as_slice();
        let expected_ciphertext = m.ciphertext.to_bytes();
        let expected_ciphertext = expected_ciphertext.as_slice();

        if !handshake_completed {
            {
                let (h_send, h_recv) = if init_send {
                    (&mut h_i, &mut h_r)
                } else {
                    (&mut h_r, &mut h_i)
                };
                let overhead = h_send.get_next_message_overhead();
                assert_eq!(payload.len() + overhead, expected_ciphertext.len());
                let c = h_send.write_message_vec(payload).unwrap();
                assert_eq!(c, expected_ciphertext);
                let p1 = h_recv.read_message_vec(&c).unwrap();
                assert_eq!(p1, payload);
            }
            if h_i.completed() {
                assert!(h_r.completed());
                init_ciphers = Some(h_i.get_ciphers());
                resp_ciphers = Some(h_r.get_ciphers());
                if v.handshake_hash.is_some() {
                    assert_eq!(v.handshake_hash.as_ref().unwrap().to_bytes(),
                               h_i.get_hash());
                }
                handshake_completed = true;
            }
        } else {
            if init_send {
                let c = init_ciphers.as_mut().unwrap().0.encrypt_vec(payload);
                assert_eq!(c, expected_ciphertext);
                let p1 = resp_ciphers.as_mut().unwrap().0.decrypt_vec(&c).unwrap();
                assert_eq!(p1, payload);
            } else {
                let c = resp_ciphers.as_mut().unwrap().1.encrypt_vec(payload);
                assert_eq!(c, expected_ciphertext);
                let p1 = init_ciphers.as_mut().unwrap().1.decrypt_vec(&c).unwrap();
                assert_eq!(p1, payload);
            }
        }
        // Let the peer send if not a one-way pattern.
        if v.pattern.len() != 1 {
            init_send = !init_send;
        }
    }
}

fn verify_vector_fallback<D, C, H>(v: &Vector)
    where D: DH,
          C: Cipher,
          H: Hash
{
    assert_eq!(v.pattern, "IK");

    let iprologue = v.init_prologue.to_bytes();
    let ie = to_dh::<D>(&v.init_ephemeral);
    let is = to_dh::<D>(v.init_static.as_ref().unwrap());
    let irs = to_pubkey::<D>(v.init_remote_static.as_ref().unwrap());

    let rprologue = v.resp_prologue.to_bytes();
    let re = to_dh::<D>(v.resp_ephemeral.as_ref().unwrap());
    let rs = to_dh::<D>(v.resp_static.as_ref().unwrap());

    let ipsk = v.init_psk.as_ref().map(HexString::to_bytes);
    let ipsk = ipsk.as_ref().map(|x| x.as_slice());
    let rpsk = v.resp_psk.as_ref().map(HexString::to_bytes);
    let rpsk = rpsk.as_ref().map(|x| x.as_slice());

    // Build init handshake state.
    let mut ibuilder = HandshakeStateBuilder::<D>::new();
    ibuilder.set_is_initiator(true);
    ibuilder.set_pattern(noise_ik());
    ibuilder.set_prologue(&iprologue);
    if ipsk.is_some() {
        ibuilder.set_psk(ipsk.unwrap());
    }
    ibuilder.set_e(ie.clone());
    ibuilder.set_s(is.clone());
    ibuilder.set_rs(irs);
    let mut ih0 = ibuilder.build_handshake_state::<C, H>();

    // Build resp handshake state.
    let mut rbuilder = HandshakeStateBuilder::<D>::new();
    rbuilder.set_is_initiator(false);
    rbuilder.set_pattern(noise_ik());
    rbuilder.set_prologue(&rprologue);
    if rpsk.is_some() {
        rbuilder.set_psk(rpsk.unwrap());
    }
    rbuilder.set_s(rs.clone());
    rbuilder.set_e(re.clone());
    let mut rh0 = rbuilder.build_handshake_state::<C, H>();

    // Abbreviated handshake (IK), should fail.
    let m0 = ih0.write_message_vec(v.messages[0].payload.to_bytes().as_slice()).unwrap();
    assert_eq!(m0, v.messages[0].ciphertext.to_bytes().as_slice());

    assert!(rh0.read_message_vec(&m0).is_err());

    // Build init handshake state.
    let mut ibuilder = HandshakeStateBuilder::<D>::new();
    ibuilder.set_is_initiator(true);
    ibuilder.set_pattern(noise_xx_fallback());
    ibuilder.set_prologue(&rprologue);
    if rpsk.is_some() {
        ibuilder.set_psk(rpsk.unwrap());
    }
    ibuilder.set_e(re);
    ibuilder.set_s(rs);
    ibuilder.set_re(rh0.get_re().unwrap());
    let mut ih1 = ibuilder.build_handshake_state::<C, H>();

    // Build resp handshake state.
    let mut rbuilder = HandshakeStateBuilder::<D>::new();
    rbuilder.set_is_initiator(false);
    rbuilder.set_pattern(noise_xx_fallback());
    rbuilder.set_prologue(&iprologue);
    if ipsk.is_some() {
        rbuilder.set_psk(ipsk.unwrap());
    }
    rbuilder.set_s(is);
    rbuilder.set_e(ie);
    let mut rh1 = rbuilder.build_handshake_state::<C, H>();

    // Fallback handshake.
    let m1 = ih1.write_message_vec(v.messages[1].payload.to_bytes().as_slice()).unwrap();
    assert_eq!(m1, v.messages[1].ciphertext.to_bytes());
    rh1.read_message_vec(&m1).unwrap();

    let m2 = rh1.write_message_vec(v.messages[2].payload.to_bytes().as_slice()).unwrap();
    assert_eq!(m2, v.messages[2].ciphertext.to_bytes());
    ih1.read_message_vec(&m2).unwrap();

    assert!(ih1.completed());
    assert!(rh1.completed());

    if v.handshake_hash.is_some() {
        let h = v.handshake_hash.as_ref().unwrap().to_bytes();
        assert_eq!(h, ih1.get_hash());
        assert_eq!(h, rh1.get_hash());
    }

    // Transport messages.
    let mut i_should_send = true;
    let (mut isend, mut irecv) = ih1.get_ciphers();
    let (mut rrecv, mut rsend) = rh1.get_ciphers();

    for m in &v.messages[3..] {
        let (send, recv) = if i_should_send {
            (&mut isend, &mut rrecv)
        } else {
            (&mut rsend, &mut irecv)
        };

        let payload = m.payload.to_bytes();

        let c = send.encrypt_vec(&payload);
        assert_eq!(c, m.ciphertext.to_bytes());

        let m1 = recv.decrypt_vec(&c).unwrap();
        assert_eq!(m1, payload);

        i_should_send = !i_should_send;
    }
}

include!(concat!(env!("OUT_DIR"), "/crypto_impls.rs"));

#[test]
fn noise_c_basic_vectors() {
    let v: json::Value = json::from_str(include_str!("vectors/noise-c-basic.txt")).unwrap();
    let vectors: Vec<Vector> =
        json::from_value(v.as_object().unwrap().get("vectors").unwrap().clone()).unwrap();

    // Assert that we are actually testing something.
    // Avoid deserialization errors.
    assert!(vectors.len() > 0);

    for v in vectors {
        verify_vector(v);
    }
}

#[test]
fn noise_c_fallback_vectors() {
    let v: json::Value = json::from_str(include_str!("vectors/noise-c-fallback.txt")).unwrap();
    let vectors: Vec<Vector> =
        json::from_value(v.as_object().unwrap().get("vectors").unwrap().clone()).unwrap();

    assert!(vectors.len() > 0);

    for v in vectors {
        verify_vector(v);
    }
}

#[test]
fn cacophony_vectors() {
    let v: json::Value = json::from_str(include_str!("vectors/cacophony.txt")).unwrap();
    let vectors: Vec<Vector> =
        json::from_value(v.as_object().unwrap().get("vectors").unwrap().clone()).unwrap();

    assert!(vectors.len() > 0);

    for v in vectors {
        verify_vector(v);
    }
}
<commit_msg>Remove PSK in vectors tests<commit_after>// Program to verify the vectors.

extern crate noise_protocol as noise;
extern crate noise_sodiumoxide;
extern crate noise_ring;
extern crate noise_rust_crypto;
extern crate rustc_serialize;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

use noise::*;
use noise::patterns::*;
use noise_ring as ring;
use noise_rust_crypto as crypto;
use noise_sodiumoxide as sodium;

use rustc_serialize::hex::FromHex;
use serde_json as json;

#[derive(Serialize, Deserialize)]
struct HexString(String);

impl HexString {
    pub fn to_bytes(&self) -> Vec<u8> {
        self.0.from_hex().unwrap()
    }
}

#[derive(Serialize, Deserialize)]
struct Vector {
    name: String,
    pattern: String,
    dh: String,
    cipher: String,
    hash: String,
    init_prologue: HexString,
    init_psk: Option<HexString>,
    init_static: Option<HexString>,
    init_ephemeral: HexString,
    init_remote_static: Option<HexString>,
    resp_prologue: HexString,
    resp_psk: Option<HexString>,
    resp_static: Option<HexString>,
    resp_ephemeral: Option<HexString>,
    resp_remote_static: Option<HexString>,
    handshake_hash: Option<HexString>,
    messages: Vec<Message>,
    fallback: Option<bool>,
}

#[derive(Serialize, Deserialize)]
struct Message {
    payload: HexString,
    ciphertext: HexString,
}

fn get_pattern_by_name(name: &str) -> Option<HandshakePattern> {
    match name {
        "N" => Some(noise_n()),
        "K" => Some(noise_k()),
        "X" => Some(noise_x()),
        "NN" => Some(noise_nn()),
        "NK" => Some(noise_nk()),
        "NX" => Some(noise_nx()),
        "KN" => Some(noise_kn()),
        "KK" => Some(noise_kk()),
        "KX" => Some(noise_kx()),
        "XN" => Some(noise_xn()),
        "XK" => Some(noise_xk()),
        "XX" => Some(noise_xx()),
        "IN" => Some(noise_in()),
        "IK" => Some(noise_ik()),
        "IX" => Some(noise_ix()),
        _ => None,
    }
}

fn to_dh<D>(k: &HexString) -> D::Key
    where D: DH
{
    D::Key::from_slice(k.to_bytes().as_slice())
}

fn to_pubkey<D>(k: &HexString) -> D::Pubkey
    where D: DH
{
    D::Pubkey::from_slice(k.to_bytes().as_slice())
}

fn verify_vector_with<D, C, H>(v: &Vector)
    where D: DH,
          C: Cipher,
          H: Hash
{
    if v.init_psk.is_some() {
        return
    }

    if v.fallback.unwrap_or(false) {
        verify_vector_fallback::<D, C, H>(v);
        return;
    }

    let pattern = get_pattern_by_name(v.pattern.as_str());
    if pattern.is_none() {
        println!("Unknown pattern {}", v.pattern);
        return;
    }
    let pattern = pattern.unwrap();

    let mut h_i = HandshakeState::<D, C, H>::new(pattern.clone(),
                                                 true,
                                                 v.init_prologue.to_bytes(),
                                                 v.init_static.as_ref().map(to_dh::<D>),
                                                 Some(to_dh::<D>(&v.init_ephemeral)),
                                                 v.init_remote_static.as_ref().map(to_pubkey::<D>),
                                                 None);
    let mut h_r = HandshakeState::<D, C, H>::new(pattern,
                                                 false,
                                                 v.resp_prologue.to_bytes(),
                                                 v.resp_static.as_ref().map(to_dh::<D>),
                                                 v.resp_ephemeral.as_ref().map(to_dh::<D>),
                                                 v.resp_remote_static.as_ref().map(to_pubkey::<D>),
                                                 None);

    let mut init_send = true;
    let mut handshake_completed = false;

    let mut init_ciphers = None;
    let mut resp_ciphers = None;

    for m in &v.messages {
        let payload = m.payload.to_bytes();
        let payload = payload.as_slice();
        let expected_ciphertext = m.ciphertext.to_bytes();
        let expected_ciphertext = expected_ciphertext.as_slice();

        if !handshake_completed {
            {
                let (h_send, h_recv) = if init_send {
                    (&mut h_i, &mut h_r)
                } else {
                    (&mut h_r, &mut h_i)
                };
                let overhead = h_send.get_next_message_overhead();
                assert_eq!(payload.len() + overhead, expected_ciphertext.len());
                let c = h_send.write_message_vec(payload).unwrap();
                assert_eq!(c, expected_ciphertext);
                let p1 = h_recv.read_message_vec(&c).unwrap();
                assert_eq!(p1, payload);
            }
            if h_i.completed() {
                assert!(h_r.completed());
                init_ciphers = Some(h_i.get_ciphers());
                resp_ciphers = Some(h_r.get_ciphers());
                if v.handshake_hash.is_some() {
                    assert_eq!(v.handshake_hash.as_ref().unwrap().to_bytes(),
                               h_i.get_hash());
                }
                handshake_completed = true;
            }
        } else {
            if init_send {
                let c = init_ciphers.as_mut().unwrap().0.encrypt_vec(payload);
                assert_eq!(c, expected_ciphertext);
                let p1 = resp_ciphers.as_mut().unwrap().0.decrypt_vec(&c).unwrap();
                assert_eq!(p1, payload);
            } else {
                let c = resp_ciphers.as_mut().unwrap().1.encrypt_vec(payload);
                assert_eq!(c, expected_ciphertext);
                let p1 = init_ciphers.as_mut().unwrap().1.decrypt_vec(&c).unwrap();
                assert_eq!(p1, payload);
            }
        }
        // Let the peer send if not a one-way pattern.
        if v.pattern.len() != 1 {
            init_send = !init_send;
        }
    }
}

fn verify_vector_fallback<D, C, H>(v: &Vector)
    where D: DH,
          C: Cipher,
          H: Hash
{
    assert_eq!(v.pattern, "IK");

    let iprologue = v.init_prologue.to_bytes();
    let ie = to_dh::<D>(&v.init_ephemeral);
    let is = to_dh::<D>(v.init_static.as_ref().unwrap());
    let irs = to_pubkey::<D>(v.init_remote_static.as_ref().unwrap());

    let rprologue = v.resp_prologue.to_bytes();
    let re = to_dh::<D>(v.resp_ephemeral.as_ref().unwrap());
    let rs = to_dh::<D>(v.resp_static.as_ref().unwrap());

    // Build init handshake state.
    let mut ibuilder = HandshakeStateBuilder::<D>::new();
    ibuilder.set_is_initiator(true);
    ibuilder.set_pattern(noise_ik());
    ibuilder.set_prologue(&iprologue);
    ibuilder.set_e(ie.clone());
    ibuilder.set_s(is.clone());
    ibuilder.set_rs(irs);
    let mut ih0 = ibuilder.build_handshake_state::<C, H>();

    // Build resp handshake state.
    let mut rbuilder = HandshakeStateBuilder::<D>::new();
    rbuilder.set_is_initiator(false);
    rbuilder.set_pattern(noise_ik());
    rbuilder.set_prologue(&rprologue);
    rbuilder.set_s(rs.clone());
    rbuilder.set_e(re.clone());
    let mut rh0 = rbuilder.build_handshake_state::<C, H>();

    // Abbreviated handshake (IK), should fail.
    let m0 = ih0.write_message_vec(v.messages[0].payload.to_bytes().as_slice()).unwrap();
    assert_eq!(m0, v.messages[0].ciphertext.to_bytes().as_slice());

    assert!(rh0.read_message_vec(&m0).is_err());

    // Build init handshake state.
    let mut ibuilder = HandshakeStateBuilder::<D>::new();
    ibuilder.set_is_initiator(true);
    ibuilder.set_pattern(noise_xx_fallback());
    ibuilder.set_prologue(&rprologue);
    ibuilder.set_e(re);
    ibuilder.set_s(rs);
    ibuilder.set_re(rh0.get_re().unwrap());
    let mut ih1 = ibuilder.build_handshake_state::<C, H>();

    // Build resp handshake state.
    let mut rbuilder = HandshakeStateBuilder::<D>::new();
    rbuilder.set_is_initiator(false);
    rbuilder.set_pattern(noise_xx_fallback());
    rbuilder.set_prologue(&iprologue);
    rbuilder.set_s(is);
    rbuilder.set_e(ie);
    let mut rh1 = rbuilder.build_handshake_state::<C, H>();

    // Fallback handshake.
    let m1 = ih1.write_message_vec(v.messages[1].payload.to_bytes().as_slice()).unwrap();
    assert_eq!(m1, v.messages[1].ciphertext.to_bytes());
    rh1.read_message_vec(&m1).unwrap();

    let m2 = rh1.write_message_vec(v.messages[2].payload.to_bytes().as_slice()).unwrap();
    assert_eq!(m2, v.messages[2].ciphertext.to_bytes());
    ih1.read_message_vec(&m2).unwrap();

    assert!(ih1.completed());
    assert!(rh1.completed());

    if v.handshake_hash.is_some() {
        let h = v.handshake_hash.as_ref().unwrap().to_bytes();
        assert_eq!(h, ih1.get_hash());
        assert_eq!(h, rh1.get_hash());
    }

    // Transport messages.
    let mut i_should_send = true;
    let (mut isend, mut irecv) = ih1.get_ciphers();
    let (mut rrecv, mut rsend) = rh1.get_ciphers();

    for m in &v.messages[3..] {
        let (send, recv) = if i_should_send {
            (&mut isend, &mut rrecv)
        } else {
            (&mut rsend, &mut irecv)
        };

        let payload = m.payload.to_bytes();

        let c = send.encrypt_vec(&payload);
        assert_eq!(c, m.ciphertext.to_bytes());

        let m1 = recv.decrypt_vec(&c).unwrap();
        assert_eq!(m1, payload);

        i_should_send = !i_should_send;
    }
}

include!(concat!(env!("OUT_DIR"), "/crypto_impls.rs"));

#[test]
fn noise_c_basic_vectors() {
    let v: json::Value = json::from_str(include_str!("vectors/noise-c-basic.txt")).unwrap();
    let vectors: Vec<Vector> =
        json::from_value(v.as_object().unwrap().get("vectors").unwrap().clone()).unwrap();

    // Assert that we are actually testing something.
    // Avoid deserialization errors.
    assert!(vectors.len() > 0);

    for v in vectors {
        verify_vector(v);
    }
}

#[test]
fn noise_c_fallback_vectors() {
    let v: json::Value = json::from_str(include_str!("vectors/noise-c-fallback.txt")).unwrap();
    let vectors: Vec<Vector> =
        json::from_value(v.as_object().unwrap().get("vectors").unwrap().clone()).unwrap();

    assert!(vectors.len() > 0);

    for v in vectors {
        verify_vector(v);
    }
}

#[test]
fn cacophony_vectors() {
    let v: json::Value = json::from_str(include_str!("vectors/cacophony.txt")).unwrap();
    let vectors: Vec<Vector> =
        json::from_value(v.as_object().unwrap().get("vectors").unwrap().clone()).unwrap();

    assert!(vectors.len() > 0);

    for v in vectors {
        verify_vector(v);
    }
}
<|endoftext|>


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

// Marauder is grid-less turn-based strategy game.

extern mod glfw;
extern mod gl;
extern mod cgmath;

use gl::types::{
  GLenum,
  GLuint,
  GLint,
  GLchar,
  GLfloat,
  GLsizeiptr,
  GLboolean
};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::projection;
use cgmath::angle;
use cgmath::vector::{Vec3, Vec2};

#[link(name = "glfw")]
#[link(name = "m")]
extern {}

/// usage: let s = mvp_matrix; println(type_of(&s));
fn type_of<T>(_: &T) -> &'static str {
  unsafe {
    (*std::unstable::intrinsics::get_tydesc::<T>()).name
  }
}

fn print_mat4(name: &str, mat: Mat4<f32>) {
  println!("{}:", name);
  for i in range(0u, 4) {
    for j in range(0u, 4) {
      print!("{} ", *mat.cr(i, j));
    }
    println("");
  }
  println("");
}

static mut MOUSE_POS: Vec2<f32> = Vec2{x: 0.0f32, y: 0.0};
static mut CAMERA_POS: Vec3<f32> = Vec3{x: 0.0f32, y: 0.0, z: 0.0};

static WIN_SIZE: Vec2<uint> = Vec2{x: 640, y: 480};
static VERTICES_COUNT: i32 = 3 * 2;

static VERTEX_DATA: [GLfloat, ..VERTICES_COUNT * 3] = [
   0.0,  1.0, 0.0,
   2.0, -1.0, 0.0,
  -2.0, -1.0, 0.0,

  0.0,  1.0,  0.0,
  0.0, -1.0,  2.0,
  0.0, -1.0, -2.0
];

static VERTEX_SHADER_SRC: &'static str = "
  #version 130
  in vec3 position;
  uniform mat4 model_view_proj_matrix;
  void main() {
    vec4 v = vec4(position, 1);
    gl_Position = model_view_proj_matrix * v;
  }
";

static FRAGMENT_SHADER_SRC: &'static str = "
  #version 130
  out vec4 out_color;
  void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
  }
";

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
  let shader = gl::CreateShader(ty);
  unsafe {
    // Attempt to compile the shader
    gl::ShaderSource(shader, 1, &src.to_c_str().unwrap(), std::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);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetShaderInfoLog(shader, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("compile_shader(): " + std::str::raw::from_utf8(buf));
    }
  }
  shader
}

fn link_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint {
  let program = gl::CreateProgram();
  gl::AttachShader(program, vertex_shader);
  gl::AttachShader(program, fragment_shader);
  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);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetProgramInfoLog(program, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("link_program(): " + std::str::raw::from_utf8(buf));
    }
  }
  program
}

fn tr(m: Mat4<f32>, v: Vec3<f32>) -> Mat4<f32> {
  let mut t = Mat4::<f32>::identity();
  *t.mut_cr(3, 0) = v.x;
  *t.mut_cr(3, 1) = v.y;
  *t.mut_cr(3, 2) = v.z;
  m.mul_m(&t)
}

fn rot_x(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_x(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

fn rot_y(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_y(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

struct Win {
  vertex_shader: GLuint,
  fragment_shader: GLuint,
  program: GLuint,
  vertex_array_obj: GLuint,
  vertex_buffer_obj: GLuint,
  matrix_id: GLint,
  window: glfw::Window
}

impl Win {
  fn new() -> Win {
    // TODO: Move to opengl_init method
    // glfw::window_hint::context_version(3, 2);

    let mut win =  Win{
      vertex_shader: 0,
      fragment_shader: 0,
      program: 0,
      vertex_array_obj: 0,
      vertex_buffer_obj: 0,
      matrix_id: 0,
      window: glfw::Window::create(
        WIN_SIZE.x,
        WIN_SIZE.y,
        "OpenGL",
        glfw::Windowed
      ).unwrap()
    };

    win.window.make_context_current();
    win.window.set_cursor_pos_callback(~CursorPosContext);
    win.window.set_key_callback(~KeyContext);

    // Load the OpenGL function pointers
    gl::load_with(glfw::get_proc_address);

    // Create GLSL shaders
    win.vertex_shader = compile_shader(
      VERTEX_SHADER_SRC, gl::VERTEX_SHADER);
    win.fragment_shader = compile_shader(
      FRAGMENT_SHADER_SRC, gl::FRAGMENT_SHADER);
    win.program = link_program(win.vertex_shader, win.fragment_shader);

    unsafe {
      // Create Vertex Array Object
      gl::GenVertexArrays(1, &mut win.vertex_array_obj);
      gl::BindVertexArray(win.vertex_array_obj);

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

      gl::UseProgram(win.program);
      gl::BindFragDataLocation(win.program, 0, "out_color".to_c_str().unwrap());

      // Specify the layout of the vertex data
      let pos_attr = gl::GetAttribLocation(
        win.program, "position".to_c_str().unwrap()) as GLuint;
      gl::EnableVertexAttribArray(pos_attr);
      let size = 3;
      let normalized = gl::FALSE as GLboolean;
      let stride = 0;
      gl::VertexAttribPointer(
        pos_attr,
        size,
        gl::FLOAT,
        normalized,
        stride,
        std::ptr::null()
      );

      // Get a handle for our "model_view_proj_matrix" uniform.
      // Only at initialisation time.
      win.matrix_id = gl::GetUniformLocation(
        win.program, "model_view_proj_matrix".to_c_str().unwrap()
      );
    }

    win
  }

  fn cleanup(&self) {
    // Cleanup
    gl::DeleteProgram(self.program);
    gl::DeleteShader(self.fragment_shader);
    gl::DeleteShader(self.vertex_shader);
    unsafe {
      gl::DeleteBuffers(1, &self.vertex_buffer_obj);
      gl::DeleteVertexArrays(1, &self.vertex_array_obj);
    }
  }

  fn update_matrices(&self) {
    let fov = angle::deg(45.0f32);
    let ratio = 4.0 / 3.0;
    let display_range_min = 0.1;
    let display_range_max = 100.0;
    let projection_matrix = projection::perspective(
      fov, ratio, display_range_min, display_range_max
    );

    let mut mvp_matrix = projection_matrix;
    unsafe {
      mvp_matrix = tr(mvp_matrix, Vec3{x: 0.0f32, y: 0.0, z: -10.0f32});
      mvp_matrix = rot_x(mvp_matrix, MOUSE_POS.y / 100.0);
      mvp_matrix = rot_y(mvp_matrix, MOUSE_POS.x / 100.0);
      mvp_matrix = tr(mvp_matrix, CAMERA_POS);
    }

    unsafe {
      // Send our transformation to the currently bound shader,
      // in the "model_view_proj_matrix" uniform.
      // For each model you render, since the model_view_proj_matrix
      // will be different (at least the M part).
      gl::UniformMatrix4fv(self.matrix_id, 1, gl::FALSE, mvp_matrix.cr(0, 0));
    }
  }

  fn draw(&self) {
    self.update_matrices();

    // Clear the screen to black
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT);

    // Draw a triangle from the 3 vertices
    gl::DrawArrays(gl::TRIANGLES, 0, VERTICES_COUNT);

    self.window.swap_buffers();
  }

  fn is_running(&self) -> bool {
    return !self.window.should_close()
  }

  fn process_events(&self) {
    glfw::poll_events();
  }
}

struct CursorPosContext;
impl glfw::CursorPosCallback for CursorPosContext {
  fn call(&self, w: &glfw::Window, xpos: f64, ypos: f64) {
    if w.get_mouse_button(glfw::MouseButtonRight) == glfw::Press {
      // println!("Cursor position: ({}, {})", xpos, ypos);
      unsafe {
        MOUSE_POS.x = xpos as f32;
        MOUSE_POS.y = ypos as f32;
      }
    }
  }
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
  fn call(&self, _: glfw::Error, description: ~str) {
    println!("GLFW Error: {:s}", description);
  }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
  fn call(
    &self,
    window: &glfw::Window,
    key:    glfw::Key,
    _:      std::libc::c_int,
    action: glfw::Action,
    _:      glfw::Modifiers
  ) {
    let distance = 1.0;
    match (action, key) {
      (glfw::Press, glfw::KeyEscape) | (glfw::Press, glfw::KeyQ) => {
        window.set_should_close(true)
      }
      (glfw::Press, glfw::KeySpace) => {
        println!("space")
      }
      (glfw::Press, glfw::KeyUp)    => unsafe { CAMERA_POS.y -= distance },
      (glfw::Press, glfw::KeyDown)  => unsafe { CAMERA_POS.y += distance },
      (glfw::Press, glfw::KeyRight) => unsafe { CAMERA_POS.x -= distance },
      (glfw::Press, glfw::KeyLeft)  => unsafe { CAMERA_POS.x += distance },
      _ => {}
    }
  }
}

fn main() {
  glfw::set_error_callback(~ErrorContext);
  do glfw::start {
    let win =  Win::new();
    while win.is_running() {
      win.process_events();
      win.draw();
    }
    win.cleanup();
  }
}

#[start]
fn start(argc: int, argv: **u8) -> int {
  std::rt::start_on_main_thread(argc, argv, main)
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<commit_msg>Simplified keyCallback<commit_after>// See LICENSE file for copyright and license details.

// Marauder is grid-less turn-based strategy game.

extern mod glfw;
extern mod gl;
extern mod cgmath;

use gl::types::{
  GLenum,
  GLuint,
  GLint,
  GLchar,
  GLfloat,
  GLsizeiptr,
  GLboolean
};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::projection;
use cgmath::angle;
use cgmath::vector::{Vec3, Vec2};

#[link(name = "glfw")]
#[link(name = "m")]
extern {}

/// usage: let s = mvp_matrix; println(type_of(&s));
fn type_of<T>(_: &T) -> &'static str {
  unsafe {
    (*std::unstable::intrinsics::get_tydesc::<T>()).name
  }
}

fn print_mat4(name: &str, mat: Mat4<f32>) {
  println!("{}:", name);
  for i in range(0u, 4) {
    for j in range(0u, 4) {
      print!("{} ", *mat.cr(i, j));
    }
    println("");
  }
  println("");
}

static mut MOUSE_POS: Vec2<f32> = Vec2{x: 0.0f32, y: 0.0};
static mut CAMERA_POS: Vec3<f32> = Vec3{x: 0.0f32, y: 0.0, z: 0.0};

static WIN_SIZE: Vec2<uint> = Vec2{x: 640, y: 480};
static VERTICES_COUNT: i32 = 3 * 2;

static VERTEX_DATA: [GLfloat, ..VERTICES_COUNT * 3] = [
   0.0,  1.0, 0.0,
   2.0, -1.0, 0.0,
  -2.0, -1.0, 0.0,

  0.0,  1.0,  0.0,
  0.0, -1.0,  2.0,
  0.0, -1.0, -2.0
];

static VERTEX_SHADER_SRC: &'static str = "
  #version 130
  in vec3 position;
  uniform mat4 model_view_proj_matrix;
  void main() {
    vec4 v = vec4(position, 1);
    gl_Position = model_view_proj_matrix * v;
  }
";

static FRAGMENT_SHADER_SRC: &'static str = "
  #version 130
  out vec4 out_color;
  void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
  }
";

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
  let shader = gl::CreateShader(ty);
  unsafe {
    // Attempt to compile the shader
    gl::ShaderSource(shader, 1, &src.to_c_str().unwrap(), std::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);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetShaderInfoLog(shader, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("compile_shader(): " + std::str::raw::from_utf8(buf));
    }
  }
  shader
}

fn link_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint {
  let program = gl::CreateProgram();
  gl::AttachShader(program, vertex_shader);
  gl::AttachShader(program, fragment_shader);
  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);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetProgramInfoLog(program, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("link_program(): " + std::str::raw::from_utf8(buf));
    }
  }
  program
}

fn tr(m: Mat4<f32>, v: Vec3<f32>) -> Mat4<f32> {
  let mut t = Mat4::<f32>::identity();
  *t.mut_cr(3, 0) = v.x;
  *t.mut_cr(3, 1) = v.y;
  *t.mut_cr(3, 2) = v.z;
  m.mul_m(&t)
}

fn rot_x(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_x(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

fn rot_y(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_y(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

struct Win {
  vertex_shader: GLuint,
  fragment_shader: GLuint,
  program: GLuint,
  vertex_array_obj: GLuint,
  vertex_buffer_obj: GLuint,
  matrix_id: GLint,
  window: glfw::Window
}

impl Win {
  fn new() -> Win {
    // TODO: Move to opengl_init method
    // glfw::window_hint::context_version(3, 2);

    let mut win =  Win{
      vertex_shader: 0,
      fragment_shader: 0,
      program: 0,
      vertex_array_obj: 0,
      vertex_buffer_obj: 0,
      matrix_id: 0,
      window: glfw::Window::create(
        WIN_SIZE.x,
        WIN_SIZE.y,
        "OpenGL",
        glfw::Windowed
      ).unwrap()
    };

    win.window.make_context_current();
    win.window.set_cursor_pos_callback(~CursorPosContext);
    win.window.set_key_callback(~KeyContext);

    // Load the OpenGL function pointers
    gl::load_with(glfw::get_proc_address);

    // Create GLSL shaders
    win.vertex_shader = compile_shader(
      VERTEX_SHADER_SRC, gl::VERTEX_SHADER);
    win.fragment_shader = compile_shader(
      FRAGMENT_SHADER_SRC, gl::FRAGMENT_SHADER);
    win.program = link_program(win.vertex_shader, win.fragment_shader);

    unsafe {
      // Create Vertex Array Object
      gl::GenVertexArrays(1, &mut win.vertex_array_obj);
      gl::BindVertexArray(win.vertex_array_obj);

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

      gl::UseProgram(win.program);
      gl::BindFragDataLocation(win.program, 0, "out_color".to_c_str().unwrap());

      // Specify the layout of the vertex data
      let pos_attr = gl::GetAttribLocation(
        win.program, "position".to_c_str().unwrap()) as GLuint;
      gl::EnableVertexAttribArray(pos_attr);
      let size = 3;
      let normalized = gl::FALSE as GLboolean;
      let stride = 0;
      gl::VertexAttribPointer(
        pos_attr,
        size,
        gl::FLOAT,
        normalized,
        stride,
        std::ptr::null()
      );

      // Get a handle for our "model_view_proj_matrix" uniform.
      // Only at initialisation time.
      win.matrix_id = gl::GetUniformLocation(
        win.program, "model_view_proj_matrix".to_c_str().unwrap()
      );
    }

    win
  }

  fn cleanup(&self) {
    // Cleanup
    gl::DeleteProgram(self.program);
    gl::DeleteShader(self.fragment_shader);
    gl::DeleteShader(self.vertex_shader);
    unsafe {
      gl::DeleteBuffers(1, &self.vertex_buffer_obj);
      gl::DeleteVertexArrays(1, &self.vertex_array_obj);
    }
  }

  fn update_matrices(&self) {
    let fov = angle::deg(45.0f32);
    let ratio = 4.0 / 3.0;
    let display_range_min = 0.1;
    let display_range_max = 100.0;
    let projection_matrix = projection::perspective(
      fov, ratio, display_range_min, display_range_max
    );

    let mut mvp_matrix = projection_matrix;
    unsafe {
      mvp_matrix = tr(mvp_matrix, Vec3{x: 0.0f32, y: 0.0, z: -10.0f32});
      mvp_matrix = rot_x(mvp_matrix, MOUSE_POS.y / 100.0);
      mvp_matrix = rot_y(mvp_matrix, MOUSE_POS.x / 100.0);
      mvp_matrix = tr(mvp_matrix, CAMERA_POS);
    }

    unsafe {
      // Send our transformation to the currently bound shader,
      // in the "model_view_proj_matrix" uniform.
      // For each model you render, since the model_view_proj_matrix
      // will be different (at least the M part).
      gl::UniformMatrix4fv(self.matrix_id, 1, gl::FALSE, mvp_matrix.cr(0, 0));
    }
  }

  fn draw(&self) {
    self.update_matrices();

    // Clear the screen to black
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT);

    // Draw a triangle from the 3 vertices
    gl::DrawArrays(gl::TRIANGLES, 0, VERTICES_COUNT);

    self.window.swap_buffers();
  }

  fn is_running(&self) -> bool {
    return !self.window.should_close()
  }

  fn process_events(&self) {
    glfw::poll_events();
  }
}

struct CursorPosContext;
impl glfw::CursorPosCallback for CursorPosContext {
  fn call(&self, w: &glfw::Window, xpos: f64, ypos: f64) {
    if w.get_mouse_button(glfw::MouseButtonRight) == glfw::Press {
      // println!("Cursor position: ({}, {})", xpos, ypos);
      unsafe {
        MOUSE_POS.x = xpos as f32;
        MOUSE_POS.y = ypos as f32;
      }
    }
  }
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
  fn call(&self, _: glfw::Error, description: ~str) {
    println!("GLFW Error: {:s}", description);
  }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
  fn call(
    &self,
    window: &glfw::Window,
    key:    glfw::Key,
    _:      std::libc::c_int,
    action: glfw::Action,
    _:      glfw::Modifiers
  ) {
    let distance = 1.0;
    if action != glfw::Press {
      return;
    }
    match key {
      glfw::KeyEscape | glfw::KeyQ
                     => window.set_should_close(true),
      glfw::KeySpace => println!("space"),
      glfw::KeyUp    => unsafe { CAMERA_POS.y -= distance },
      glfw::KeyDown  => unsafe { CAMERA_POS.y += distance },
      glfw::KeyRight => unsafe { CAMERA_POS.x -= distance },
      glfw::KeyLeft  => unsafe { CAMERA_POS.x += distance },
      _ => {}
    }
  }
}

fn main() {
  glfw::set_error_callback(~ErrorContext);
  do glfw::start {
    let win =  Win::new();
    while win.is_running() {
      win.process_events();
      win.draw();
    }
    win.cleanup();
  }
}

#[start]
fn start(argc: int, argv: **u8) -> int {
  std::rt::start_on_main_thread(argc, argv, main)
}

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


<commit_before>
#[crate_id = "oxidize"];

#[desc = "A micro web framework for Rust"];
#[license = "MIT"];

extern mod extra;
extern mod http;
//extern mod http = "github.com/chris-morgan/rust-http";

//mod routes;

use std::io::net::ip::{SocketAddr, Ipv4Addr};
use std::io::Writer;
use extra::time;

use http::server::{Config, Server, Request, ResponseWriter};
use http::headers;

use http::server::request::{Star, AbsoluteUri, AbsolutePath, Authority};

#[deriving(Clone)]
struct OxidizeServer;

impl Server for OxidizeServer {
    fn get_config(&self) -> Config {
        Config { bind_address: SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 8001 } }
    }

    fn handle_request(&self, _r: &Request, w: &mut ResponseWriter) {
        w.headers.date = Some(time::now_utc());
        w.headers.server = Some(~"Oxidize/0.0.0 (Ubuntu)");

        /*w.headers.last_modified = Some(time::Tm {
            tm_sec: 42, // seconds after the minute ~[0-60]
            tm_min: 46, // minutes after the hour ~[0-59]
            tm_hour: 11, // hours after midnight ~[0-23]
            tm_mday: 5, // days of the month ~[1-31]
            tm_mon: 4, // months since January ~[0-11]
            tm_year: 111, // years since 1900
            tm_wday: 4, // days since Sunday ~[0-6]
            tm_yday: 0, // days since January 1 ~[0-365]
            tm_isdst: 0, // Daylight Savings Time flag
            tm_gmtoff: 0, // offset from UTC in seconds
            tm_zone: ~"GMT", // timezone abbreviation
            tm_nsec: 0, // nanoseconds
        });*/

        let path = match _r.request_uri{
            AbsolutePath(ref i) => i.to_str(),
            AbsoluteUri(ref i) => i.to_str(),
            Authority(ref i) => i.to_str(),
            Star => ~"hello"
        };
        println!("{}",path);

        w.headers.content_type = Some(headers::content_type::MediaType {
            type_: ~"text",
            subtype: ~"html",
            parameters: ~[]
        });

        let response = render("something");
        w.headers.content_length = Some(response.len());

        w.write(response.as_bytes());
    }
}

fn render(path: &str) -> ~str {
    let mut response = ~"\

It works!
\n\

This is the default web page for this server.
\n\

The web server software is running but no content has been added, yet.
\n\
        \n";
    return response;
}

fn main() {
    OxidizeServer.serve_forever();
}<commit_msg>Trying some more stuff.<commit_after>
#[crate_id = "oxidize"];

#[desc = "A micro web framework for Rust"];
#[license = "MIT"];

extern mod extra;
extern mod http;
//extern mod http = "github.com/chris-morgan/rust-http";

//mod routes;

use std::io::net::ip::{SocketAddr, Ipv4Addr};
use std::io::Writer;
use std::io::File;
use extra::time;
use extra::json::{Json, Decoder, ToJson, Object};
use extra::list::List;
use extra::treemap::TreeMap;
use std::str;

use http::server::{Config, Server, Request, ResponseWriter};
use http::headers;

use http::server::request::{Star, AbsoluteUri, AbsolutePath, Authority};

#[deriving(Clone)]
struct OxidizeServer;

impl Server for OxidizeServer {
    fn get_config(&self) -> Config {
        Config { bind_address: SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 8001 } }
    }

    fn handle_request(&self, _r: &Request, w: &mut ResponseWriter) {
        w.headers.date = Some(time::now_utc());
        w.headers.server = Some(~"Oxidize/0.0.0 (Ubuntu)");

        /*w.headers.last_modified = Some(time::Tm {
            tm_sec: 42, // seconds after the minute ~[0-60]
            tm_min: 46, // minutes after the hour ~[0-59]
            tm_hour: 11, // hours after midnight ~[0-23]
            tm_mday: 5, // days of the month ~[1-31]
            tm_mon: 4, // months since January ~[0-11]
            tm_year: 111, // years since 1900
            tm_wday: 4, // days since Sunday ~[0-6]
            tm_yday: 0, // days since January 1 ~[0-365]
            tm_isdst: 0, // Daylight Savings Time flag
            tm_gmtoff: 0, // offset from UTC in seconds
            tm_zone: ~"GMT", // timezone abbreviation
            tm_nsec: 0, // nanoseconds
        });*/

        let path = match _r.request_uri{
            AbsolutePath(ref i) => i.to_str(),
            AbsoluteUri(ref i) => i.to_str(),
            Authority(ref i) => i.to_str(),
            Star => ~"hello"
        };
        println!("{}",path);

        w.headers.content_type = Some(headers::content_type::MediaType {
            type_: ~"text",
            subtype: ~"html",
            parameters: ~[]
        });

        let response = render("something");
        w.headers.content_length = Some(response.len());

        let contents = File::open(&Path::new("routes.json")).read_to_end();
        let mut jsonObj = extra::json::from_str(str::from_utf8(contents)).ok();
        println!("{:?}",jsonObj);

        w.write(response.as_bytes());
    }
}

fn render(path: &str) -> ~str {
    let mut response = ~"\

It works!
\n\

This is the default web page for this server.
\n\

The web server software is running but no content has been added, yet.
\n\
        \n";
    return response;
    //return File::open(&Path::new(path)).read_to_end();
}

fn main() {
    OxidizeServer.serve_forever();
}<|endoftext|>


<commit_before>use std::rc::Rc;
use std::collections::{VecDeque, HashMap};

use parser::Identifier;
use memory::{StaticAllocator, MemoryBlock};

use super::operation::{Operation, OperationsResult};
use super::item_type::ItemType;

pub type TypeId = usize;

/// The arguments that will get passed to a function
/// Arguments are guaranteed by static analysis to match the type defined for the function
pub type FuncArgs = Vec<ScopeItem>;

/// Represents a single item in a scope
pub enum ScopeItem {
    /// A type, not associated with any memory
    /// Used for a struct/type declaration, not the declaration
    /// of a variable with a type (TypedBlock should be used for that)
    Type(TypeId),

    /// A constant set of bytes inlined whenever used
    /// These items have no memory address
    /// The bytes of the constant are stored directly
    Constant {
        type_id: TypeId,
        /// Size of bytes must match the required size of type_id
        bytes: Vec<u8>,
    },

    /// A typed block of memory
    TypedBlock {
        type_id: TypeId,
        memory: MemoryBlock,
    },

    /// A built-in function definition
    BuiltInFunction {
        /// The ID of the type associated with this function
        id: TypeId,
        /// Generates operations that represent calling the
        /// function with the given arguments
        operations: Rc<Fn(&mut ScopeStack, FuncArgs) -> OperationsResult>,
    },
}

/// Represents a single level of scope
pub type Scope = HashMap<Identifier, ScopeItem>;

pub struct ScopeStack {
    stack: VecDeque<Scope>,
    allocator: StaticAllocator,
    /// A vector of all the declared types used to produce unique identities
    /// for all types so that types are static and not dependent on the context
    /// in which they are used.
    /// Basically, if we declare a type Foo and a variable with that type,
    /// we don't want a later declaration of Foo change the type of the variable
    /// Also used in functions/closures to uniquely refer to types in that context
    types: Vec<ItemType>,

    /// The TypeId that corresponds with the bool type
    bool_type_id: Option<TypeId>,
}

impl ScopeStack {
    pub fn new() -> ScopeStack {
        ScopeStack {
            stack: {
                let mut queue = VecDeque::new();
                queue.push_back(Scope::new());
                queue
            },
            allocator: StaticAllocator::new(),
            types: vec![ItemType::Unit],
            bool_type_id: None,
        }
    }

    /// Pushes a new level of scope onto the stack
    /// This scope will become the current scope
    pub fn push_scope(&mut self) {
        self.stack.push_back(Scope::new());
    }

    /// Removes and returns the top level scope (current scope)
    ///
    /// # Panics
    /// Panics if there is no scope in the stack
    pub fn pop_scope(&mut self) -> Scope {
        self.stack.pop_back().unwrap()
    }

    /// Returns the type associated with the given TypeId
    pub fn get_type(&self, type_id: TypeId) -> &ItemType {
        // We just unwrap here because this isn't an error that can be generated by the user's
        // mistake. If this fails, it has to be a bug in the compiler.
        self.types.get(type_id).expect("Invalid TypeId used to lookup type")
    }

    /// Returns the TypeId of the Unit `()` type
    pub fn unit_type_id(&self) -> TypeId {
        0
    }

    /// Returns the TypeId of the bool type
    pub fn bool_type_id(&self) -> TypeId {
        // NOTE: The unit type and the bool type are "special primitives". Both types are
        // fundamentally required for the compiler to function and so we need to provide special
        // access to them in the scope. We want a stronger guarantee than just relying on the name
        // "bool".
        // We don't want to couple the types' implementation with this module, so we simply add a
        // hatch for the implementing modules to define which TypeId should be associated with bool

        self.bool_type_id.expect("Expected a bool TypeId to be defined in the scope")
    }

    /// Set the TypeId for the primitive bool type
    pub fn set_bool_type_id(&mut self, type_id: TypeId) {
        // NOTE: See note in bool_type_id

        // This should only be called once
        debug_assert!(self.bool_type_id.is_none(), "Redefined bool TypeId in scope");

        debug_assert!(type_id != self.unit_type_id(), "Declared bool TypeId with the same TypeId as Unit");

        self.bool_type_id = Some(type_id)
    }

    /// Looks up a name starting at the current scope
    /// Returns ALL matches so that the caller can determine which definition is
    /// the correct one
    /// Definitions are returned in order from latest definition to oldest
    /// Always use the first definition that matches the type you are looking for
    pub fn lookup(&self, name: &Identifier) -> Vec<&ScopeItem> {
        self.stack.iter().rev().map(|sc| sc.get(name)).fold(Vec::new(), |mut acc, r| match r {
            Some(def) => {
                acc.push(def);
                acc
            },
            None => acc,
        })
    }

    /// Declares a type with the given name
    /// Returns the unique identifier of that type
    pub fn declare_type(&mut self, name: Identifier, typ: ItemType) -> TypeId {
        let type_id = self.insert_type(typ);
        self.insert_current(name, ScopeItem::Type(type_id));

        type_id
    }

    /// Declares a constant with the given name
    pub fn declare_constant(&mut self, name: Identifier, type_id: TypeId, value: Vec<u8>) {
        debug_assert!({
            let size = self.get_type(type_id).required_size(self);
            value.len() == size
        });

        self.insert_current(name, ScopeItem::Constant {
            type_id: type_id,
            bytes: value,
        });
    }

    /// Declares a name with the given type and allocates enough space for that type
    /// The name is declared in the "current" scope which is at the top of the stack
    /// Returns the allocated memory block
    pub fn declare(&mut self, name: Identifier, type_id: TypeId) -> MemoryBlock {
        let mem = self.allocate(type_id);
        self.insert_current(name, ScopeItem::TypedBlock {
            type_id: type_id,
            memory: mem,
        });

        mem
    }

    /// Allocate a memory block that is large enough for the given type
    /// Does not associate memory block with a name which means it cannot be looked up later
    /// Returns the allocated memory block
    pub fn allocate(&mut self, type_id: TypeId) -> MemoryBlock {
        let size = self.get_type(type_id).required_size(self);
        self.allocator.allocate(size)
    }

    /// Declares a built in function with the given name and type definition
    /// The name is declared in the "current" scope which is at the top of the stack
    /// The function is guaranteed to be called with arguments that match its given type signature
    pub fn declare_builtin_function<F: 'static>(&mut self, name: Identifier, typ: ItemType, f: F)
        where F: Fn(&mut ScopeStack, FuncArgs) -> OperationsResult {

        // Make sure we are declaring the function as a function type
        debug_assert!(match typ {
            ItemType::Function { .. } => true,
            _ => false,
        });

        let type_id = self.insert_type(typ);
        self.insert_current(name, ScopeItem::BuiltInFunction {
            id: type_id,
            operations: Rc::new(f),
        });
    }

    /// Inserts a ScopeItem into the current scope
    fn insert_current(&mut self, name: Identifier, item: ScopeItem) {
        // Notice that we insert directly without caring about whether the name already exists
        // It's OK to overwrite existing names because we support rebinding
        if let Some(scope) = self.stack.back_mut() {
            scope.insert(name, item);
        }
        else {
            panic!("Attempt to declare name despite having no current scope");
        }
    }

    /// Inserts a type defintion into the types field and returns its new TypeId
    fn insert_type(&mut self, typ: ItemType) -> TypeId {
        self.types.push(typ);

        self.types.len() - 1
    }
}

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

    use parser::Identifier;
    use operations::item_type::ItemType;

    #[test]
    fn unit_type_id() {
        let scope = ScopeStack::new();

        assert!(match *scope.get_type(scope.unit_type_id()) {
            ItemType::Unit => true,
            _ => false,
        });
    }

    #[test]
    fn bool_type_id() {
        const BOOL_TYPE_ID: TypeId = 1;

        let mut scope = ScopeStack::new();
        scope.set_bool_type_id(BOOL_TYPE_ID);

        assert_eq!(scope.bool_type_id(), BOOL_TYPE_ID);
    }

    #[test]
    #[should_panic(expected = "Declared bool TypeId with the same TypeId as Unit")]
    fn bool_type_id_is_unit() {
        let mut scope = ScopeStack::new();

        let unit_id = scope.unit_type_id();
        scope.set_bool_type_id(unit_id);
    }

    #[test]
    #[should_panic(expected = "Expected a bool TypeId to be defined in the scope")]
    fn access_bool_type_id_without_declaration() {
        let scope = ScopeStack::new();

        scope.bool_type_id();
    }

    #[test]
    #[should_panic(expected = "Redefined bool TypeId in scope")]
    fn redefine_bool_type_id() {
        let mut scope = ScopeStack::new();

        scope.set_bool_type_id(1);
        scope.set_bool_type_id(2);
    }

    #[test]
    fn multiple_definitions() {
        let mut scope = ScopeStack::new();
        let type_id = scope.declare_type(Identifier::from("FooType"), ItemType::Primitive(1));
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 0);

        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 1);

        // Declaring the same name in the same scope should overwrite the
        // definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 1);

        scope.push_scope();
        // Declaring foo in another scope should add a definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 2);

        // Declaring the same name in the same scope should overwrite the
        // definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 2);
    }
}
<commit_msg>Fixing use statements in scope<commit_after>use std::rc::Rc;
use std::collections::{VecDeque, HashMap};

use parser::Identifier;
use memory::{StaticAllocator, MemoryBlock};

use super::OperationsResult;
use super::item_type::ItemType;

pub type TypeId = usize;

/// The arguments that will get passed to a function
/// Arguments are guaranteed by static analysis to match the type defined for the function
pub type FuncArgs = Vec<ScopeItem>;

/// Represents a single item in a scope
pub enum ScopeItem {
    /// A type, not associated with any memory
    /// Used for a struct/type declaration, not the declaration
    /// of a variable with a type (TypedBlock should be used for that)
    Type(TypeId),

    /// A constant set of bytes inlined whenever used
    /// These items have no memory address
    /// The bytes of the constant are stored directly
    Constant {
        type_id: TypeId,
        /// Size of bytes must match the required size of type_id
        bytes: Vec<u8>,
    },

    /// A typed block of memory
    TypedBlock {
        type_id: TypeId,
        memory: MemoryBlock,
    },

    /// A built-in function definition
    BuiltInFunction {
        /// The ID of the type associated with this function
        id: TypeId,
        /// Generates operations that represent calling the
        /// function with the given arguments
        operations: Rc<Fn(&mut ScopeStack, FuncArgs) -> OperationsResult>,
    },
}

/// Represents a single level of scope
pub type Scope = HashMap<Identifier, ScopeItem>;

pub struct ScopeStack {
    stack: VecDeque<Scope>,
    allocator: StaticAllocator,
    /// A vector of all the declared types used to produce unique identities
    /// for all types so that types are static and not dependent on the context
    /// in which they are used.
    /// Basically, if we declare a type Foo and a variable with that type,
    /// we don't want a later declaration of Foo change the type of the variable
    /// Also used in functions/closures to uniquely refer to types in that context
    types: Vec<ItemType>,

    /// The TypeId that corresponds with the bool type
    bool_type_id: Option<TypeId>,
}

impl ScopeStack {
    pub fn new() -> ScopeStack {
        ScopeStack {
            stack: {
                let mut queue = VecDeque::new();
                queue.push_back(Scope::new());
                queue
            },
            allocator: StaticAllocator::new(),
            types: vec![ItemType::Unit],
            bool_type_id: None,
        }
    }

    /// Pushes a new level of scope onto the stack
    /// This scope will become the current scope
    pub fn push_scope(&mut self) {
        self.stack.push_back(Scope::new());
    }

    /// Removes and returns the top level scope (current scope)
    ///
    /// # Panics
    /// Panics if there is no scope in the stack
    pub fn pop_scope(&mut self) -> Scope {
        self.stack.pop_back().unwrap()
    }

    /// Returns the type associated with the given TypeId
    pub fn get_type(&self, type_id: TypeId) -> &ItemType {
        // We just unwrap here because this isn't an error that can be generated by the user's
        // mistake. If this fails, it has to be a bug in the compiler.
        self.types.get(type_id).expect("Invalid TypeId used to lookup type")
    }

    /// Returns the TypeId of the Unit `()` type
    pub fn unit_type_id(&self) -> TypeId {
        0
    }

    /// Returns the TypeId of the bool type
    pub fn bool_type_id(&self) -> TypeId {
        // NOTE: The unit type and the bool type are "special primitives". Both types are
        // fundamentally required for the compiler to function and so we need to provide special
        // access to them in the scope. We want a stronger guarantee than just relying on the name
        // "bool".
        // We don't want to couple the types' implementation with this module, so we simply add a
        // hatch for the implementing modules to define which TypeId should be associated with bool

        self.bool_type_id.expect("Expected a bool TypeId to be defined in the scope")
    }

    /// Set the TypeId for the primitive bool type
    pub fn set_bool_type_id(&mut self, type_id: TypeId) {
        // NOTE: See note in bool_type_id

        // This should only be called once
        debug_assert!(self.bool_type_id.is_none(), "Redefined bool TypeId in scope");

        debug_assert!(type_id != self.unit_type_id(), "Declared bool TypeId with the same TypeId as Unit");

        self.bool_type_id = Some(type_id)
    }

    /// Looks up a name starting at the current scope
    /// Returns ALL matches so that the caller can determine which definition is
    /// the correct one
    /// Definitions are returned in order from latest definition to oldest
    /// Always use the first definition that matches the type you are looking for
    pub fn lookup(&self, name: &Identifier) -> Vec<&ScopeItem> {
        self.stack.iter().rev().map(|sc| sc.get(name)).fold(Vec::new(), |mut acc, r| match r {
            Some(def) => {
                acc.push(def);
                acc
            },
            None => acc,
        })
    }

    /// Declares a type with the given name
    /// Returns the unique identifier of that type
    pub fn declare_type(&mut self, name: Identifier, typ: ItemType) -> TypeId {
        let type_id = self.insert_type(typ);
        self.insert_current(name, ScopeItem::Type(type_id));

        type_id
    }

    /// Declares a constant with the given name
    pub fn declare_constant(&mut self, name: Identifier, type_id: TypeId, value: Vec<u8>) {
        debug_assert!({
            let size = self.get_type(type_id).required_size(self);
            value.len() == size
        });

        self.insert_current(name, ScopeItem::Constant {
            type_id: type_id,
            bytes: value,
        });
    }

    /// Declares a name with the given type and allocates enough space for that type
    /// The name is declared in the "current" scope which is at the top of the stack
    /// Returns the allocated memory block
    pub fn declare(&mut self, name: Identifier, type_id: TypeId) -> MemoryBlock {
        let mem = self.allocate(type_id);
        self.insert_current(name, ScopeItem::TypedBlock {
            type_id: type_id,
            memory: mem,
        });

        mem
    }

    /// Allocate a memory block that is large enough for the given type
    /// Does not associate memory block with a name which means it cannot be looked up later
    /// Returns the allocated memory block
    pub fn allocate(&mut self, type_id: TypeId) -> MemoryBlock {
        let size = self.get_type(type_id).required_size(self);
        self.allocator.allocate(size)
    }

    /// Declares a built in function with the given name and type definition
    /// The name is declared in the "current" scope which is at the top of the stack
    /// The function is guaranteed to be called with arguments that match its given type signature
    pub fn declare_builtin_function<F: 'static>(&mut self, name: Identifier, typ: ItemType, f: F)
        where F: Fn(&mut ScopeStack, FuncArgs) -> OperationsResult {

        // Make sure we are declaring the function as a function type
        debug_assert!(match typ {
            ItemType::Function { .. } => true,
            _ => false,
        });

        let type_id = self.insert_type(typ);
        self.insert_current(name, ScopeItem::BuiltInFunction {
            id: type_id,
            operations: Rc::new(f),
        });
    }

    /// Inserts a ScopeItem into the current scope
    fn insert_current(&mut self, name: Identifier, item: ScopeItem) {
        // Notice that we insert directly without caring about whether the name already exists
        // It's OK to overwrite existing names because we support rebinding
        if let Some(scope) = self.stack.back_mut() {
            scope.insert(name, item);
        }
        else {
            panic!("Attempt to declare name despite having no current scope");
        }
    }

    /// Inserts a type defintion into the types field and returns its new TypeId
    fn insert_type(&mut self, typ: ItemType) -> TypeId {
        self.types.push(typ);

        self.types.len() - 1
    }
}

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

    use parser::Identifier;
    use operations::item_type::ItemType;

    #[test]
    fn unit_type_id() {
        let scope = ScopeStack::new();

        assert!(match *scope.get_type(scope.unit_type_id()) {
            ItemType::Unit => true,
            _ => false,
        });
    }

    #[test]
    fn bool_type_id() {
        const BOOL_TYPE_ID: TypeId = 1;

        let mut scope = ScopeStack::new();
        scope.set_bool_type_id(BOOL_TYPE_ID);

        assert_eq!(scope.bool_type_id(), BOOL_TYPE_ID);
    }

    #[test]
    #[should_panic(expected = "Declared bool TypeId with the same TypeId as Unit")]
    fn bool_type_id_is_unit() {
        let mut scope = ScopeStack::new();

        let unit_id = scope.unit_type_id();
        scope.set_bool_type_id(unit_id);
    }

    #[test]
    #[should_panic(expected = "Expected a bool TypeId to be defined in the scope")]
    fn access_bool_type_id_without_declaration() {
        let scope = ScopeStack::new();

        scope.bool_type_id();
    }

    #[test]
    #[should_panic(expected = "Redefined bool TypeId in scope")]
    fn redefine_bool_type_id() {
        let mut scope = ScopeStack::new();

        scope.set_bool_type_id(1);
        scope.set_bool_type_id(2);
    }

    #[test]
    fn multiple_definitions() {
        let mut scope = ScopeStack::new();
        let type_id = scope.declare_type(Identifier::from("FooType"), ItemType::Primitive(1));
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 0);

        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 1);

        // Declaring the same name in the same scope should overwrite the
        // definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 1);

        scope.push_scope();
        // Declaring foo in another scope should add a definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 2);

        // Declaring the same name in the same scope should overwrite the
        // definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 2);
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::collections::{VecDeque, HashMap};

use parser::Identifier;
use memory::{StaticAllocator, MemoryBlock};

use super::operation::Operation;
use super::item_type::ItemType;

pub type TypeId = usize;

/// The arguments that will get passed to a function
/// Arguments are guaranteed to match the type of the function
pub type FuncArgs = Vec<ScopeItem>;

/// Represents a single item in a scope
pub enum ScopeItem {
    /// A type, not associated with any memory
    /// Used for a struct/type declaration, not the declaration
    /// of a variable with a type (TypedBlock should be used for that)
    Type(TypeId),

    /// A constant set of bytes inlined whenever used
    /// These items have no memory address
    /// The bytes of the constant are stored directly
    Constant {
        type_id: TypeId,
        /// Size of bytes must match the required size of type_id
        bytes: Vec<u8>,
    },

    /// A typed block of memory
    TypedBlock {
        type_id: TypeId,
        memory: MemoryBlock,
    },

    /// A built-in function definition
    BuiltInFunction {
        /// The ID of the type associated with this function
        id: TypeId,
        /// Generates operations that represent calling the
        /// function with the given arguments
        operations: Rc<Fn(FuncArgs, ScopeStack) -> Vec<Operation>>,
    },
}

/// Represents a single level of scope
pub type Scope = HashMap<Identifier, ScopeItem>;

pub struct ScopeStack {
    stack: VecDeque<Scope>,
    allocator: StaticAllocator,
    /// A vector of all the declared types used to produce unique identities
    /// for all types so that types are static and not dependent on the context
    /// in which they are used.
    /// Basically, if we declare a type Foo and a variable with that type,
    /// we don't want a later declaration of Foo change the type of the variable
    /// Also used in functions/closures to uniquely refer to types in that context
    types: Vec<ItemType>,

    /// The TypeId that corresponds with the bool type
    bool_type_id: Option<TypeId>,
}

impl ScopeStack {
    pub fn new() -> ScopeStack {
        ScopeStack {
            stack: {
                let mut queue = VecDeque::new();
                queue.push_back(Scope::new());
                queue
            },
            allocator: StaticAllocator::new(),
            types: vec![ItemType::Unit],
            bool_type_id: None,
        }
    }

    /// Pushes a new level of scope onto the stack
    /// This scope will become the current scope
    pub fn push_scope(&mut self) {
        self.stack.push_back(Scope::new());
    }

    /// Removes and returns the top level scope (current scope)
    ///
    /// # Panics
    /// Panics if there is no scope in the stack
    pub fn pop_scope(&mut self) -> Scope {
        self.stack.pop_back().unwrap()
    }

    /// Returns the type associated with the given TypeId
    pub fn get_type(&self, type_id: TypeId) -> &ItemType {
        // We just unwrap here because this isn't an error that can be generated by the user's
        // mistake. If this fails, it has to be a bug in the compiler.
        self.types.get(type_id).expect("Invalid TypeId used to lookup type")
    }

    /// Returns the TypeId of the Unit `()` type
    pub fn unit_type_id(&self) -> TypeId {
        0
    }

    /// Returns the TypeId of the bool type
    pub fn bool_type_id(&self) -> TypeId {
        // NOTE: The unit type and the bool type are "special primitives". Both types are
        // fundamentally required for the compiler to function and so we need to provide special
        // access to them in the scope. We want a stronger guarantee than just relying on the name
        // "bool".
        // We don't want to couple the types' implementation with this module, so we simply add a
        // hatch for the implementing modules to define which TypeId should be associated with bool

        self.bool_type_id.expect("Expected a bool TypeId to be defined in the scope")
    }

    /// Set the TypeId for the primitive bool type
    pub fn set_bool_type_id(&mut self, type_id: TypeId) {
        // NOTE: See note in bool_type_id

        // This should only be called once
        debug_assert!(self.bool_type_id.is_none(), "Redefined bool TypeId in scope");

        debug_assert!(type_id != self.unit_type_id(), "Declared bool TypeId with the same TypeId as Unit");

        self.bool_type_id = Some(type_id)
    }

    /// Looks up a name starting at the current scope
    /// Returns ALL matches so that the caller can determine which definition is
    /// the correct one
    /// Definitions are returned in order from latest definition to oldest
    /// Always use the first definition that matches the type you are looking for
    pub fn lookup(&self, name: &Identifier) -> Vec<&ScopeItem> {
        self.stack.iter().rev().map(|sc| sc.get(name)).fold(Vec::new(), |mut acc, r| match r {
            Some(def) => {
                acc.push(def);
                acc
            },
            None => acc,
        })
    }

    /// Declares a type with the given name
    /// Returns the unique identifier of that type
    pub fn declare_type(&mut self, name: Identifier, typ: ItemType) -> TypeId {
        let type_id = self.insert_type(typ);
        self.insert_current(name, ScopeItem::Type(type_id));

        type_id
    }

    /// Declares a constant with the given name
    pub fn declare_constant(&mut self, name: Identifier, type_id: TypeId, value: Vec<u8>) {
        debug_assert!({
            let size = self.get_type(type_id).required_size(self);
            value.len() == size
        });

        self.insert_current(name, ScopeItem::Constant {
            type_id: type_id,
            bytes: value,
        });
    }

    /// Declares a name with the given type and allocates enough space for that type
    /// The name is declared in the "current" scope which is at the top of the stack
    /// Returns the allocated memory block
    pub fn declare(&mut self, name: Identifier, type_id: TypeId) -> MemoryBlock {
        let mem = self.allocate(type_id);
        self.insert_current(name, ScopeItem::TypedBlock {
            type_id: type_id,
            memory: mem,
        });

        mem
    }

    /// Allocate a memory block that is large enough for the given type
    /// Does not associate memory block with a name which means it cannot be looked up later
    /// Returns the allocated memory block
    pub fn allocate(&mut self, type_id: TypeId) -> MemoryBlock {
        let size = self.get_type(type_id).required_size(self);
        self.allocator.allocate(size)
    }

    /// Declares a built in function with the given name and type definition
    /// The name is declared in the "current" scope which is at the top of the stack
    /// The function is guaranteed to be called with arguments that match its given type signature
    pub fn declare_builtin_function<F: 'static>(&mut self, name: Identifier, typ: ItemType, f: F)
        where F: Fn(FuncArgs, ScopeStack) -> Vec<Operation> {

        // Make sure we are declaring the function as a function type
        debug_assert!(match typ {
            ItemType::Function { .. } => true,
            _ => false,
        });

        let type_id = self.insert_type(typ);
        self.insert_current(name, ScopeItem::BuiltInFunction {
            id: type_id,
            operations: Rc::new(f),
        });
    }

    /// Inserts a ScopeItem into the current scope
    fn insert_current(&mut self, name: Identifier, item: ScopeItem) {
        // Notice that we insert directly without caring about whether the name already exists
        // It's OK to overwrite existing names because we support rebinding
        if let Some(scope) = self.stack.back_mut() {
            scope.insert(name, item);
        }
        else {
            panic!("Attempt to declare name despite having no current scope");
        }
    }

    /// Inserts a type defintion into the types field and returns its new TypeId
    fn insert_type(&mut self, typ: ItemType) -> TypeId {
        self.types.push(typ);

        self.types.len() - 1
    }
}

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

    use parser::Identifier;
    use operations::item_type::ItemType;

    #[test]
    fn unit_type_id() {
        let scope = ScopeStack::new();

        assert!(match *scope.get_type(scope.unit_type_id()) {
            ItemType::Unit => true,
            _ => false,
        });
    }

    #[test]
    fn bool_type_id() {
        const BOOL_TYPE_ID: TypeId = 1;

        let mut scope = ScopeStack::new();
        scope.set_bool_type_id(BOOL_TYPE_ID);

        assert_eq!(scope.bool_type_id(), BOOL_TYPE_ID);
    }

    #[test]
    #[should_panic(expected = "Declared bool TypeId with the same TypeId as Unit")]
    fn bool_type_id_is_unit() {
        let mut scope = ScopeStack::new();

        let unit_id = scope.unit_type_id();
        scope.set_bool_type_id(unit_id);
    }

    #[test]
    #[should_panic(expected = "Expected a bool TypeId to be defined in the scope")]
    fn access_bool_type_id_without_declaration() {
        let scope = ScopeStack::new();

        scope.bool_type_id();
    }

    #[test]
    #[should_panic(expected = "Redefined bool TypeId in scope")]
    fn redefine_bool_type_id() {
        let mut scope = ScopeStack::new();

        scope.set_bool_type_id(1);
        scope.set_bool_type_id(2);
    }

    #[test]
    fn multiple_definitions() {
        let mut scope = ScopeStack::new();
        let type_id = scope.declare_type(Identifier::from("FooType"), ItemType::Primitive(1));
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 0);

        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 1);

        // Declaring the same name in the same scope should overwrite the
        // definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 1);

        scope.push_scope();
        // Declaring foo in another scope should add a definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 2);

        // Declaring the same name in the same scope should overwrite the
        // definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 2);
    }
}
<commit_msg>Updating definition of built-in function to use the proper types and argument order<commit_after>use std::rc::Rc;
use std::collections::{VecDeque, HashMap};

use parser::Identifier;
use memory::{StaticAllocator, MemoryBlock};

use super::operation::{Operation, OperationsResult};
use super::item_type::ItemType;

pub type TypeId = usize;

/// The arguments that will get passed to a function
/// Arguments are guaranteed by static analysis to match the type defined for the function
pub type FuncArgs = Vec<ScopeItem>;

/// Represents a single item in a scope
pub enum ScopeItem {
    /// A type, not associated with any memory
    /// Used for a struct/type declaration, not the declaration
    /// of a variable with a type (TypedBlock should be used for that)
    Type(TypeId),

    /// A constant set of bytes inlined whenever used
    /// These items have no memory address
    /// The bytes of the constant are stored directly
    Constant {
        type_id: TypeId,
        /// Size of bytes must match the required size of type_id
        bytes: Vec<u8>,
    },

    /// A typed block of memory
    TypedBlock {
        type_id: TypeId,
        memory: MemoryBlock,
    },

    /// A built-in function definition
    BuiltInFunction {
        /// The ID of the type associated with this function
        id: TypeId,
        /// Generates operations that represent calling the
        /// function with the given arguments
        operations: Rc<Fn(&mut ScopeStack, FuncArgs) -> OperationsResult>,
    },
}

/// Represents a single level of scope
pub type Scope = HashMap<Identifier, ScopeItem>;

pub struct ScopeStack {
    stack: VecDeque<Scope>,
    allocator: StaticAllocator,
    /// A vector of all the declared types used to produce unique identities
    /// for all types so that types are static and not dependent on the context
    /// in which they are used.
    /// Basically, if we declare a type Foo and a variable with that type,
    /// we don't want a later declaration of Foo change the type of the variable
    /// Also used in functions/closures to uniquely refer to types in that context
    types: Vec<ItemType>,

    /// The TypeId that corresponds with the bool type
    bool_type_id: Option<TypeId>,
}

impl ScopeStack {
    pub fn new() -> ScopeStack {
        ScopeStack {
            stack: {
                let mut queue = VecDeque::new();
                queue.push_back(Scope::new());
                queue
            },
            allocator: StaticAllocator::new(),
            types: vec![ItemType::Unit],
            bool_type_id: None,
        }
    }

    /// Pushes a new level of scope onto the stack
    /// This scope will become the current scope
    pub fn push_scope(&mut self) {
        self.stack.push_back(Scope::new());
    }

    /// Removes and returns the top level scope (current scope)
    ///
    /// # Panics
    /// Panics if there is no scope in the stack
    pub fn pop_scope(&mut self) -> Scope {
        self.stack.pop_back().unwrap()
    }

    /// Returns the type associated with the given TypeId
    pub fn get_type(&self, type_id: TypeId) -> &ItemType {
        // We just unwrap here because this isn't an error that can be generated by the user's
        // mistake. If this fails, it has to be a bug in the compiler.
        self.types.get(type_id).expect("Invalid TypeId used to lookup type")
    }

    /// Returns the TypeId of the Unit `()` type
    pub fn unit_type_id(&self) -> TypeId {
        0
    }

    /// Returns the TypeId of the bool type
    pub fn bool_type_id(&self) -> TypeId {
        // NOTE: The unit type and the bool type are "special primitives". Both types are
        // fundamentally required for the compiler to function and so we need to provide special
        // access to them in the scope. We want a stronger guarantee than just relying on the name
        // "bool".
        // We don't want to couple the types' implementation with this module, so we simply add a
        // hatch for the implementing modules to define which TypeId should be associated with bool

        self.bool_type_id.expect("Expected a bool TypeId to be defined in the scope")
    }

    /// Set the TypeId for the primitive bool type
    pub fn set_bool_type_id(&mut self, type_id: TypeId) {
        // NOTE: See note in bool_type_id

        // This should only be called once
        debug_assert!(self.bool_type_id.is_none(), "Redefined bool TypeId in scope");

        debug_assert!(type_id != self.unit_type_id(), "Declared bool TypeId with the same TypeId as Unit");

        self.bool_type_id = Some(type_id)
    }

    /// Looks up a name starting at the current scope
    /// Returns ALL matches so that the caller can determine which definition is
    /// the correct one
    /// Definitions are returned in order from latest definition to oldest
    /// Always use the first definition that matches the type you are looking for
    pub fn lookup(&self, name: &Identifier) -> Vec<&ScopeItem> {
        self.stack.iter().rev().map(|sc| sc.get(name)).fold(Vec::new(), |mut acc, r| match r {
            Some(def) => {
                acc.push(def);
                acc
            },
            None => acc,
        })
    }

    /// Declares a type with the given name
    /// Returns the unique identifier of that type
    pub fn declare_type(&mut self, name: Identifier, typ: ItemType) -> TypeId {
        let type_id = self.insert_type(typ);
        self.insert_current(name, ScopeItem::Type(type_id));

        type_id
    }

    /// Declares a constant with the given name
    pub fn declare_constant(&mut self, name: Identifier, type_id: TypeId, value: Vec<u8>) {
        debug_assert!({
            let size = self.get_type(type_id).required_size(self);
            value.len() == size
        });

        self.insert_current(name, ScopeItem::Constant {
            type_id: type_id,
            bytes: value,
        });
    }

    /// Declares a name with the given type and allocates enough space for that type
    /// The name is declared in the "current" scope which is at the top of the stack
    /// Returns the allocated memory block
    pub fn declare(&mut self, name: Identifier, type_id: TypeId) -> MemoryBlock {
        let mem = self.allocate(type_id);
        self.insert_current(name, ScopeItem::TypedBlock {
            type_id: type_id,
            memory: mem,
        });

        mem
    }

    /// Allocate a memory block that is large enough for the given type
    /// Does not associate memory block with a name which means it cannot be looked up later
    /// Returns the allocated memory block
    pub fn allocate(&mut self, type_id: TypeId) -> MemoryBlock {
        let size = self.get_type(type_id).required_size(self);
        self.allocator.allocate(size)
    }

    /// Declares a built in function with the given name and type definition
    /// The name is declared in the "current" scope which is at the top of the stack
    /// The function is guaranteed to be called with arguments that match its given type signature
    pub fn declare_builtin_function<F: 'static>(&mut self, name: Identifier, typ: ItemType, f: F)
        where F: Fn(&mut ScopeStack, FuncArgs) -> OperationsResult {

        // Make sure we are declaring the function as a function type
        debug_assert!(match typ {
            ItemType::Function { .. } => true,
            _ => false,
        });

        let type_id = self.insert_type(typ);
        self.insert_current(name, ScopeItem::BuiltInFunction {
            id: type_id,
            operations: Rc::new(f),
        });
    }

    /// Inserts a ScopeItem into the current scope
    fn insert_current(&mut self, name: Identifier, item: ScopeItem) {
        // Notice that we insert directly without caring about whether the name already exists
        // It's OK to overwrite existing names because we support rebinding
        if let Some(scope) = self.stack.back_mut() {
            scope.insert(name, item);
        }
        else {
            panic!("Attempt to declare name despite having no current scope");
        }
    }

    /// Inserts a type defintion into the types field and returns its new TypeId
    fn insert_type(&mut self, typ: ItemType) -> TypeId {
        self.types.push(typ);

        self.types.len() - 1
    }
}

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

    use parser::Identifier;
    use operations::item_type::ItemType;

    #[test]
    fn unit_type_id() {
        let scope = ScopeStack::new();

        assert!(match *scope.get_type(scope.unit_type_id()) {
            ItemType::Unit => true,
            _ => false,
        });
    }

    #[test]
    fn bool_type_id() {
        const BOOL_TYPE_ID: TypeId = 1;

        let mut scope = ScopeStack::new();
        scope.set_bool_type_id(BOOL_TYPE_ID);

        assert_eq!(scope.bool_type_id(), BOOL_TYPE_ID);
    }

    #[test]
    #[should_panic(expected = "Declared bool TypeId with the same TypeId as Unit")]
    fn bool_type_id_is_unit() {
        let mut scope = ScopeStack::new();

        let unit_id = scope.unit_type_id();
        scope.set_bool_type_id(unit_id);
    }

    #[test]
    #[should_panic(expected = "Expected a bool TypeId to be defined in the scope")]
    fn access_bool_type_id_without_declaration() {
        let scope = ScopeStack::new();

        scope.bool_type_id();
    }

    #[test]
    #[should_panic(expected = "Redefined bool TypeId in scope")]
    fn redefine_bool_type_id() {
        let mut scope = ScopeStack::new();

        scope.set_bool_type_id(1);
        scope.set_bool_type_id(2);
    }

    #[test]
    fn multiple_definitions() {
        let mut scope = ScopeStack::new();
        let type_id = scope.declare_type(Identifier::from("FooType"), ItemType::Primitive(1));
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 0);

        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 1);

        // Declaring the same name in the same scope should overwrite the
        // definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 1);

        scope.push_scope();
        // Declaring foo in another scope should add a definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 2);

        // Declaring the same name in the same scope should overwrite the
        // definition
        scope.declare(Identifier::from("foo"), type_id);
        assert_eq!(scope.lookup(&Identifier::from("foo")).len(), 2);
    }
}
<|endoftext|>


<commit_before>use super::*;
use redox::*;

use orbital::*;

impl Editor {
    /// Redraw the window
    pub fn redraw(&mut self) {
        // TODO: Only draw when relevant for the window
        let (mut pos_x, pos_y) = self.pos();
        // Redraw window
        self.window.set(Color::rgb(25, 25, 25));

        let w = self.window.width();

        pos_x += self.delta();

        if self.options.line_marker {
            self.window.rect(0, (pos_y - self.scroll_y) as isize * 16, w, 16, Color::rgb(45, 45, 45));
        }

        self.window.rect(8 * (pos_x - self.scroll_x) as isize,
                         16 * (pos_y - self.scroll_y) as isize,
                         8,
                         16,
                         Color::WHITE);

        let mut string = false;

        for (y, row) in self.text.iter().enumerate() {
            for (x, &c) in row.iter().enumerate() {
                // TODO: Move outta here
                let color = if self.options.highlight {
                    match c {
                        '\'' | '"' => {
                            string = !string;
                            (226, 225, 167) //(167, 222, 156)
                        },
                        _ if string => (226, 225, 167), //(167, 222, 156)
                        '!' | '@' | '#' | '$' | '%' | '^' | '&' | '|' | '*' | '+' | '-' | '/' | ':' | '=' | '<' | '>' => (198, 83, 83), //(228, 190, 175), //(194, 106, 71),
                        '.' | ',' => (241, 213, 226),
                        '(' | ')' | '[' | ']' | '{' | '}' => (164, 212, 125), //(195, 139, 75),
                        '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => (209, 209, 177),
                        _ => (255, 255, 255),
                    }
                } else {
                    (255, 255, 255)
                };

                let c = if c == '\t' { ' ' } else { c };

                if pos_x == x && pos_y == y {
                    self.window.char(8 * (x - self.scroll_x) as isize,
                                     16 * (y - self.scroll_y) as isize,
                                     c,
                                     Color::rgb(color.0 / 3, color.1 / 3, color.2 / 3));
                } else {
                    self.window.char(8 * (x - self.scroll_x) as isize,
                                     16 * (y - self.scroll_y) as isize,
                                     c,
                                     Color::rgb(color.0, color.1, color.2));
                }
            }
        }

        self.redraw_task = RedrawTask::Null;

        self.redraw_status_bar();
        self.window.sync();
    }

    /// Redraw the status bar
    pub fn redraw_status_bar(&mut self) {
        let h = self.window.height();
        let w = self.window.width();
        let mode = self.cursor().mode;
        self.window.rect(0, h as isize - 18 - {
            if mode == Mode::Primitive(PrimitiveMode::Prompt) {
                18
            } else {
                0
            }
        }, w, 18, Color::rgba(74, 74, 74, 255));

        let sb_mode = self.status_bar.mode.clone();
        status_bar(self, sb_mode, 0, 4);
        let sb_file = self.status_bar.file.clone();
        status_bar(self, sb_file, 1, 4);
        let sb_cmd = self.status_bar.cmd.clone();
        status_bar(self, sb_cmd, 2, 4);
        let sb_msg = self.status_bar.msg.clone();
        status_bar(self, sb_msg, 3, 4);

        for (n, c) in self.prompt.chars().enumerate() {
            self.window.char(n as isize * 8, h as isize - 16 - 1, c, Color::WHITE);
        }

        self.window.sync();
    }
}

fn status_bar(editor: &mut Editor, text: String, a: usize, b: usize) {

    let h = editor.window.height();
    let w = editor.window.width();
    let y = editor.y();
    let mode = editor.cursor().mode;

    for (n, c) in (if text.len() > w / (8 * b) {
        text.chars().take(w / (8 * b) - 5).chain(vec!['.', '.', '.']).collect::<Vec<_>>()
    } else {
        text.chars().collect()
    }).into_iter().enumerate() {

        editor.window.char(((w * a) / b) as isize + (n as isize * 8), h as isize - 16 - 1 - {
            if mode == Mode::Primitive(PrimitiveMode::Prompt) {
                16 + 1 + 1
            } else {
                0
            }
        }, c, Color::WHITE);
    }
}

/// The statubar (showing various info about the current state of the editor)
pub struct StatusBar {
    /// The current mode
    pub mode: String,
    /// The cureent char
    pub file: String,
    /// The current command
    pub cmd: String,
    /// A message (such as an error or other info to the user)
    pub msg: String,
}

impl StatusBar {
    /// Create new status bar
    pub fn new() -> Self {
        StatusBar {
            mode: "Normal".to_string(),
            file: String::new(),
            cmd: String::new(),
            msg: "Welcome to Sodium!".to_string(),
        }
    }
}
<commit_msg>Fix warning for unused field - add the line code as comment...<commit_after>use super::*;
use redox::*;

use orbital::*;

impl Editor {
    /// Redraw the window
    pub fn redraw(&mut self) {
        // TODO: Only draw when relevant for the window
        let (mut pos_x, pos_y) = self.pos();
        // Redraw window
        self.window.set(Color::rgb(25, 25, 25));

        let w = self.window.width();

        pos_x += self.delta();

        if self.options.line_marker {
            self.window.rect(0, (pos_y - self.scroll_y) as isize * 16, w, 16, Color::rgb(45, 45, 45));
        }

        self.window.rect(8 * (pos_x - self.scroll_x) as isize,
                         16 * (pos_y - self.scroll_y) as isize,
                         8,
                         16,
                         Color::WHITE);

        let mut string = false;

        for (y, row) in self.text.iter().enumerate() {
            for (x, &c) in row.iter().enumerate() {
                // TODO: Move outta here
                let color = if self.options.highlight {
                    match c {
                        '\'' | '"' => {
                            string = !string;
                            (226, 225, 167) //(167, 222, 156)
                        },
                        _ if string => (226, 225, 167), //(167, 222, 156)
                        '!' | '@' | '#' | '$' | '%' | '^' | '&' | '|' | '*' | '+' | '-' | '/' | ':' | '=' | '<' | '>' => (198, 83, 83), //(228, 190, 175), //(194, 106, 71),
                        '.' | ',' => (241, 213, 226),
                        '(' | ')' | '[' | ']' | '{' | '}' => (164, 212, 125), //(195, 139, 75),
                        '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => (209, 209, 177),
                        _ => (255, 255, 255),
                    }
                } else {
                    (255, 255, 255)
                };

                let c = if c == '\t' { ' ' } else { c };

                if pos_x == x && pos_y == y {
                    self.window.char(8 * (x - self.scroll_x) as isize,
                                     16 * (y - self.scroll_y) as isize,
                                     c,
                                     Color::rgb(color.0 / 3, color.1 / 3, color.2 / 3));
                } else {
                    self.window.char(8 * (x - self.scroll_x) as isize,
                                     16 * (y - self.scroll_y) as isize,
                                     c,
                                     Color::rgb(color.0, color.1, color.2));
                }
            }
        }

        self.redraw_task = RedrawTask::Null;

        self.redraw_status_bar();
        self.window.sync();
    }

    /// Redraw the status bar
    pub fn redraw_status_bar(&mut self) {
        let h = self.window.height();
        let w = self.window.width();
        let mode = self.cursor().mode;
        self.window.rect(0, h as isize - 18 - {
            if mode == Mode::Primitive(PrimitiveMode::Prompt) {
                18
            } else {
                0
            }
        }, w, 18, Color::rgba(74, 74, 74, 255));

        let sb_mode = self.status_bar.mode.clone();
        status_bar(self, sb_mode, 0, 4);
        let sb_file = self.status_bar.file.clone();
        status_bar(self, sb_file, 1, 4);
        let sb_cmd = self.status_bar.cmd.clone();
        status_bar(self, sb_cmd, 2, 4);
        let sb_msg = self.status_bar.msg.clone();
        status_bar(self, sb_msg, 3, 4);

        for (n, c) in self.prompt.chars().enumerate() {
            self.window.char(n as isize * 8, h as isize - 16 - 1, c, Color::WHITE);
        }

        self.window.sync();
    }
}

fn status_bar(editor: &mut Editor, text: String, a: usize, b: usize) {

    let h = editor.window.height();
    let w = editor.window.width();
    //let y = editor.y();
    let mode = editor.cursor().mode;

    for (n, c) in (if text.len() > w / (8 * b) {
        text.chars().take(w / (8 * b) - 5).chain(vec!['.', '.', '.']).collect::<Vec<_>>()
    } else {
        text.chars().collect()
    }).into_iter().enumerate() {

        editor.window.char(((w * a) / b) as isize + (n as isize * 8), h as isize - 16 - 1 - {
            if mode == Mode::Primitive(PrimitiveMode::Prompt) {
                16 + 1 + 1
            } else {
                0
            }
        }, c, Color::WHITE);
    }
}

/// The statubar (showing various info about the current state of the editor)
pub struct StatusBar {
    /// The current mode
    pub mode: String,
    /// The cureent char
    pub file: String,
    /// The current command
    pub cmd: String,
    /// A message (such as an error or other info to the user)
    pub msg: String,
}

impl StatusBar {
    /// Create new status bar
    pub fn new() -> Self {
        StatusBar {
            mode: "Normal".to_string(),
            file: String::new(),
            cmd: String::new(),
            msg: "Welcome to Sodium!".to_string(),
        }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin, custom_derive)]
#![plugin(nbt_macros)]

// This throws many, many errors.

#[derive(NbtFmt)]
      //~^ ERROR failed to resolve. Maybe a missing `extern crate nbt`?
      //~^^ ERROR use of undeclared trait name `nbt::serialize::NbtFmt`
      //~^^^ ERROR failed to resolve. Maybe a missing `extern crate nbt`?
      //~^^^^ ERROR use of undeclared type name `nbt::Error`
      //~^^^^^ ERROR failed to resolve. Maybe a missing `extern crate nbt`?
      //~^^^^^^ ERROR unresolved name `nbt::serialize::close_nbt`
struct One {
	byte: i8
	//~^ ERROR failed to resolve. Maybe a missing `extern crate nbt`?
    //~^^ ERROR unresolved name `nbt::serialize::NbtFmt::to_nbt`
}
<commit_msg>Removes the `missing extern` test -- it had no relation to the plugin.<commit_after><|endoftext|>