<commit_before><commit_msg>Add message assembling.<commit_after>//! Construction of DNS messages for sending
//!

use std::collections::HashMap;
use std::io;
use std::mem;
use std::net;
use std::ptr;
use super::header::Header;
use super::name;
use super::record::{RecordData, RecordDataAssembly};

//------------ Assembly -----------------------------------------------------

/// A type to assemble an outgoing DNS message.
///
/// When assembling messages you sadly need to know what is going on later
/// or come back to parts written earlier. The Assembly type does exactly
/// that.
///
/// Use this type directly if you already know what to put into the message
/// before starting to create it. Otherwise, use `Message` which allows you
/// put things together step by step.
///
#[derive(Debug)]
pub struct Assembly {
    // The message's data.
    inner: Vec<u8>,

    // If we are writing to a stream, the message actually starts with two
    // octets for the length, but references for name pointers and such
    // are relative to after that. To make the math easier, we simply keep
    // the index of the real start of the message in here.
    origin: usize,

    // Maximum size of the resulting package (and thus, `self.inner`).
    //
    // This is limited to 65535 due either to the maximum UDP datagram
    // size or the 16 bit length marker in a stream. We still use usize
    // here because with origin we can overrun the 16 bit boundary.
    maxlen: usize,

    // If we overrun our maxlen while writing, we set this flag. The
    // higher level methods know what to do in this case.
    tc: bool,

    // We need a copy of the header because we may have to modify the
    // tc bit when we are done.
    header: Header,

    // If we do compression, then we will store labels in this here map.
    // If we don't do compression, there is no map.
    compress: Option<HashMap<name::DomainNameBuf, u16>>,
}

// Management
//
impl Assembly {

    /// Creates a new assembly.
    ///
    /// The maximum package size is given in `maxlen`. If more data is
    /// pushed to the assembly, it will be truncated at a record boundary
    /// and the TC bit will be set in the header.
    ///
    /// If the assembly is for a stream, set `for_stream` to true. In this
    /// case the first two octets of the resulting data will be the size
    /// of the message in network order.
    ///
    /// Set `compress` to false, if you want domain names never to be
    /// compressed.
    ///
    pub fn new(maxlen: u16, for_stream: bool, compress: bool) -> Assembly {
        let map = match compress {
            true => Some(HashMap::new()),
            false => None
        };
        if for_stream {
            let mut res = Assembly { inner: Vec::new(),
                                     maxlen: (maxlen as usize) + 2,
                                     origin: 2, tc: false,
                                     header: Header::new(),
                                     compress: map };
            res.push_u16(0);
            res
        }
        else {
            Assembly { inner: Vec::new(), maxlen: maxlen as usize, origin: 0,
                       tc: false, header: Header::new(), compress: map }
        }
    }
}

// Low level writing -- use this in record data implementations.
//
impl Assembly {

    /// Pushes a u8 to the end of the assembly.
    ///
    pub fn push_u8(&mut self, data: u8) {
        if self.keep_pushing(1) {
            self.inner.push(data)
        }
    }

    /// Pushes a u16 to the end of the assembly.
    ///
    pub fn push_u16(&mut self, data: u16) {
        if self.keep_pushing(2) {
            let data = data.to_be();
            let bytes: [u8; 2] = unsafe { mem::transmute(data) };
            self.inner.extend(&bytes);
        }
    }

    /// Pushes a u32 to the end of the assembly.
    ///
    pub fn push_u32(&mut self, data: u32) {
        if self.keep_pushing(4) {
            let data = data.to_be();
            let bytes: [u8; 4] = unsafe { mem::transmute(data) };
            self.inner.extend(&bytes);
        }
    }

    /// Pushes `data` to the end of the assembly.
    ///
    pub fn push_bytes(&mut self, data: &[u8]) {
        if self.keep_pushing(data.len()) {
            self.inner.extend(data);
        }
    }

    /// Pushes a domain name to the end of the assembly.
    ///
    /// The domain name will not be compressed, even if compression is
    /// enabled for the assembly. This is the default because RFC 3597
    /// limits name compression to those record types intially defined in
    /// RFC 1035. So, if you implement a `RecordDataAssembly`, you likely
    /// want to use uncompressed name pushage.
    ///
    pub fn push_name(&mut self, name: &name::DomainName) {
        assert!(!name.is_empty());

        if self.compress.is_none() {
            self._push_name_simple(name);
        }
        else {
            self._push_name_uncompressed(name);
        }
    }

    /// Pushes a domain name to the end of the assembly employing compression.
    ///
    /// This is similar to `push_name()` except that name compression will
    /// be used if it has been enabled for the assembly.
    ///
    pub fn push_name_compressed(&mut self, name: &name::DomainName) {
        assert!(!name.is_empty());

        if self.compress.is_none() {
            self._push_name_simple(name);
        }
        else {
            self._push_name_compressed(name);
        }
    }

    // Simply pushes `name`'s bytes. Luckily, our internal domain name
    // encoding is actually the wire format. Smart, huh?!
    fn _push_name_simple(&mut self, name: &name::DomainName) {
        if self.keep_pushing(name.as_bytes().len()) {
            self.push_bytes(name.as_bytes());
        }
    }

    // Pushes `name` storing the label positions for later referencing
    // if compression is enabled.
    fn _push_name_uncompressed(&mut self, name: &name::DomainName) {
        let mut name = name;
        while !name.is_empty() {
            name = self._push_label(name);
        }
    }

    // Pushes `name`, using a reference for the longest known tail.
    fn _push_name_compressed(&mut self, name: &name::DomainName) {
        let mut name = name;
        while !name.is_empty() {
            let pos;
            {
                pos = match self.compress {
                    None => None,
                    Some(ref map) => {
                        match map.get(name) {
                            None => None,
                            Some(&pos) => Some(pos)
                        }
                    }
                }
            }
            match pos {
                None => name = self._push_label(name),
                Some(pos) => {
                    if self.keep_pushing(2) {
                        self.push_u16(pos | 0xC000);
                    }
                    return
                }
            }
        }
    }

    // Pushes the first label in `name`, store a reference to `name` for
    // later use in compression.
    fn _push_label<'a>(&mut self, name: &'a name::DomainName)
        -> &'a name::DomainName
    {
        let pos = self.pos();
        match self.compress {
            None => { },
            Some(ref mut map) => {
                map.insert(name.to_owned(), (pos - self.origin) as u16);
            }
        }
        let (head, tail) = name.split_first().unwrap();
        assert!(head.len() < 64);
        if self.keep_pushing(head.as_bytes().len() + 1) {
            self.push_u8(head.len() as u8);
            self.push_bytes(head.as_bytes());
        }
        tail
    }

    // Returns whether it is fine to push `len` octets.
    //
    fn keep_pushing(&mut self, len: usize) -> bool {
        if self.inner.len() + len > self.maxlen {
            self.tc = true;
            false
        }
        else { true }
    }

    /// Returns the current position of the assembly.
    ///
    /// You must use the returned position for later use in the replace
    /// methods only. Do not assign any other meaning to it.
    ///
    pub fn pos(&self) -> usize {
        self.inner.len()
    }

    /// Replaces the u8 at position `pos` with `data`.
    ///
    pub fn replace_u8(&mut self, pos: usize, data: u8) {
        assert!(pos < self.inner.len());
        self.inner[pos] = data;
    }

    /// Replaces the u16 beginning at position `pos` with `data`.
    ///
    pub fn replace_u16(&mut self, pos: usize, data: u16) {
        let data = data.to_be();
        assert!(pos + 1 < self.inner.len());
        unsafe {
            let src: [u8; 2] = mem::transmute(data);
            ptr::copy_nonoverlapping(&src.as_ptr(),
                                     &mut self.inner[pos .. pos + 2].as_ptr(),
                                     2);
        }
    }

    /// Replaces the u32 beginning at position `pos` with `data`.
    ///
    pub fn replace_u32(&mut self, pos: usize, data: u32) {
        let data = data.to_be();
        assert!(pos + 1 < self.inner.len());
        unsafe {
            let src: [u8; 4] = mem::transmute(data);
            ptr::copy_nonoverlapping(&src.as_ptr(),
                                     &mut self.inner[pos .. pos + 4].as_ptr(),
                                     4);
        }
    }
}

// High-level writing
//
impl Assembly {
    /// Pushes the message header to the assembly.
    ///
    /// A call to this method must be the first thing on a new assembly.
    /// Later there must not be any more calls to it on threat of a panic.
    ///
    /// The arguments are the actual header, followed by the number of
    /// elements in each seection. You must follow up this call with the
    /// correct number of calls to `push_question()` and `push_rr()` or
    /// `push_raw_rr()`. Finally, you must finish with calling `finish()`.
    ///
    pub fn push_header(&mut self, header: &Header, qdcount: u16, ancount: u16,
                       nscount: u16, arcount: u16)
    {
        assert!(self.pos() == self.origin);
        self.header = header.clone();
        self.header.set_tc(false);
        let header_bytes = self.header.as_u32();
        self.push_u32(header_bytes);
        self.push_u16(qdcount);
        self.push_u16(ancount);
        self.push_u16(nscount);
        self.push_u16(arcount);
    }

    /// Finishes the assembly.
    ///
    /// This must be the last thing you do with the assembly. To make this
    /// clear, the method moves the inner vec back to the caller. This
    /// returned vec can be sent over the wire as is.
    ///
    pub fn finish(mut self) -> Vec<u8> {
        if self.origin == 2 {
            let len = (self.inner.len() - self.origin) as u16;
            self.replace_u16(0, len);
        }
        if self.tc {
            self.header.set_tc(true);
            let pos = self.origin;
            let header_bytes = self.header.as_u32();
            self.replace_u32(pos, header_bytes);
        }
        self.inner
    }

    /// Pushes a question to the assembly.
    ///
    /// If doing so would exceed the maximum length, nothing will be
    /// written, the TC bit will be set in the header later, and false
    /// will be returned now.
    ///
    /// If all goes well, true will be returned.
    ///
    pub fn push_question(&mut self, qname: &name::DomainName, qtype: u16,
                         qclass: u16) -> bool
    {
        if self.tc { return false }
        let pos = self.pos();
        self.push_name_compressed(qname);
        self.push_u16(qtype);
        self.push_u16(qclass);
        if self.tc {
            self.inner.truncate(pos);
        }
        !self.tc
    }

    /// Pushes a raw resource record to the assembly.
    ///
    /// For our purposes, a raw resource record is one for which the type
    /// is explicitely given and record data is already given in its wire
    /// format.
    ///
    /// Returns true if the entire record could be pushed to the assembly.
    /// If this would exceed the maximum length, nothing is pushed at all
    /// and false is returned. Upon finishing the assembly, the TC bit will
    /// be set in the header.
    ///
    pub fn push_raw_rr(&mut self, name: &name::DomainName, rtype: u16,
                       rclass: u16, ttl: u32, rdata: &[u8]) -> bool
    {
        assert!(rdata.len() <= ::std::u16::MAX as usize);
        if self.tc { return false }
        let pos = self.pos();
        self.push_name_compressed(name);
        self.push_u16(rtype);
        self.push_u16(rclass);
        self.push_u32(ttl);
        self.push_u16(rdata.len() as u16);
        self.push_bytes(rdata);
        if self.tc {
            self.inner.truncate(pos);
        }
        !self.tc
    }

    /// Pushes a resource record to the assembly.
    ///
    /// The record data is being assembled by calling `assembly()` on the
    /// trait object `rdata`. If pushing
    /// the record would exceed the maximum length, it is removed again and
    /// the TC bit will later be set in the header when the assembly is
    /// being finished. The method returns whether this did not happen.
    ///
    pub fn push_rr(&mut self, name: &name::DomainName, rtype: u16,
                                      rclass: u16, ttl: u32,
                                      rdata: &RecordDataAssembly) -> bool
    {
        if self.tc { return false }
        let pos = self.pos();
        self.push_name_compressed(name);
        self.push_u16(rtype);
        self.push_u16(rclass);
        self.push_u32(ttl);
        let rdlen_pos = self.pos();
        self.push_u16(0);
        rdata.assemble(self);
        if self.tc {
            self.inner.truncate(pos);
        }
        else {
            let rdlen = self.pos() - rdlen_pos;
            self.replace_u16(rdlen_pos, rdlen as u16);
        }
        !self.tc
    }

}

//------------ Message ------------------------------------------------------

/// An outgoing DNS message.
///
/// The message consists of four sections that are vecs over questions or
/// resource records, keeping their own data.
///
/// Once you have all data collected, you can have the actual wire data
/// assembled or even sent out directly.
///
#[derive(Debug)]
pub struct Message {
    header: Header,
    question: QuestionSection,
    answer: RecordSection,
    authority: RecordSection,
    additional: RecordSection
}

impl Message {
    /// Creates a new, empty message.
    ///
    pub fn new() -> Message {
        Message { header: Header::new(), question: QuestionSection::new(),
                  answer: RecordSection::new(),
                  authority: RecordSection::new(),
                  additional: RecordSection::new() }
    }

    /// Gives access to the message header.
    ///
    pub fn header(&mut self) -> &mut Header {
        &mut self.header
    }

    /// Gives access to the question section.
    ///
    /// The question section contains the question being asked in a query.
    ///
    pub fn question(&mut self) -> &mut QuestionSection {
        &mut self.question
    }

    /// Gives access to the zone section of an Update query.
    ///
    /// In an update query, the question section is actually the zone
    /// section specifing the zone to be updated.
    ///
    pub fn zone(&mut self) -> &mut QuestionSection {
        &mut self.question
    }

    /// Gives access to the answer section.
    ///
    /// The answer sections contains those resource records that answer
    /// the question.
    ///
    /// In an Update query, this
    ///
    pub fn answer(&mut self) -> &mut RecordSection {
        &mut self.answer
    }

    /// Gives access to the prerequiste section of an Update query.
    ///
    /// The prerequisite section contains resource records or resource
    /// record sets that must or must not preexist.
    ///
    pub fn prerequisite(&mut self) -> &mut RecordSection {
        &mut self.answer
    }

    /// Gives access to the authority section.
    ///
    /// The authority section contains resource records identifying the
    /// authoritative name servers responsible for answering the question.
    ///
    pub fn authority(&mut self) -> &mut RecordSection {
        &mut self.authority
    }

    /// Gives access to the update section of an Update query.
    ///
    /// The update section contains resource records or resource record
    /// sets to be added or delete.
    ///
    pub fn update(&mut self) -> &mut RecordSection {
        &mut self.authority
    }

    /// Gives access to the additional section.
    ///
    /// The additional section contains resource records that help making
    /// sense of the answer. What exactly ought to be in here depends on
    /// the record type being asked for.
    ///
    pub fn additional(&mut self) -> &mut RecordSection {
        &mut self.additional
    }

    //--- Finish it off ...

    /// Assembles the message.
    ///
    /// Returns a vector containing the wire data of the message and whether
    /// the wire message had to be truncated because it would have been
    /// longer than `maxlen`.
    ///
    /// If you plan on writing the data into a stream, such as a
    /// `TcpStream`, set `for_stream` to true. In this case, the resulting
    /// data will start with the required length indication. If you wish
    /// domain names to be compressed where applicable, set `compress` to
    /// true.
    pub fn assemble(&self, maxlen: u16, for_stream: bool, compress: bool)
        -> (Vec<u8>, bool)
    {
        let mut asm = Assembly::new(maxlen, for_stream, compress);
        asm.push_header(&self.header, self.question.len(),
                        self.answer.len(), self.authority.len(),
                        self.additional.len());
        let complete =  self.question.assemble(&mut asm)
                     && self.answer.assemble(&mut asm)
                     && self.authority.assemble(&mut asm)
                     && self.additional.assemble(&mut asm);
        (asm.finish(), complete)
    }

    pub fn to_udp<A: net::ToSocketAddrs>(&self, sock: &net::UdpSocket,
                                         addr: A, maxlen: u16, compress: bool)
        -> io::Result<(usize, bool)>
    {
        let (vec, complete) = self.assemble(maxlen, false, compress);
        sock.send_to(&vec, addr).map(|x| (x, complete))
    }

    pub fn to_writer<W: io::Write>(&self, w: &mut W, compress: bool)
        -> io::Result<(usize, bool)>
    {
        let (vec, complete) = self.assemble(::std::u16::MAX, true, compress);
        w.write(&vec).map(|x| (x, complete))
    }
}

//------------ QuestionSection ----------------------------------------------

#[derive(Debug)]
struct Question {
    qname: name::DomainNameBuf,
    qtype: u16,
    qclass: u16,
}

/// Collects the questions for a message.
///
#[derive(Debug)]
pub struct QuestionSection {
    inner: Vec<Question>,
}

impl QuestionSection {
    fn new() -> QuestionSection {
        QuestionSection { inner: Vec::new() }
    }

    /// Adds a questions.
    ///
    pub fn push(&mut self, qname: name::DomainNameBuf, qtype: u16,
                qclass: u16)
    {
        assert!(self.inner.len() < ::std::u16::MAX as usize);
        self.inner.push(Question { qname: qname, qtype: qtype,
                                   qclass: qclass })
    }

    /// Returns the length of the question section.
    ///
    pub fn len(&self) -> u16 {
        self.inner.len() as u16
    }

    fn assemble(&self, asm: &mut Assembly) -> bool {
        for q in self.inner.iter() {
            if !asm.push_question(&q.qname, q.qtype, q.qclass) {
                return false
            }
        }
        true
    }
}

//------------ RecordSection ------------------------------------------------

#[derive(Debug)]
struct Record {
    name: name::DomainNameBuf,
    rtype: u16,
    rclass: u16,
    ttl: u32,
    rdata: Box<RecordDataAssembly>
}

/// Collects the resource records of one of the three record sections.
///
#[derive(Debug)]
pub struct RecordSection {
    inner: Vec<Record>,
}

impl RecordSection {
    fn new() -> RecordSection {
        RecordSection { inner: Vec::new() }
    }

    pub fn push<R: RecordData + 'static>(&mut self, name: name::DomainNameBuf,
                                         rclass: u16, ttl: u32,
                                         data: R)
    {
        self.inner.push(Record { name: name, rtype: R::rtype(),
                                 rclass: rclass, ttl: ttl,
                                 rdata: Box::new(data) })
    }

    /// Returns the number of records in the section.
    ///
    pub fn len(&self) -> u16 {
        self.inner.len() as u16
    }

    fn assemble(&self, asm: &mut Assembly) -> bool {
        for rr in self.inner.iter() {
            if !asm.push_rr(&rr.name, rr.rtype, rr.rclass, rr.ttl, &*rr.rdata)
            {
                return false
            }
        }
        true
    }
}

//------------ Tests --------------------------------------------------------

#[cfg(test)]
mod tests {

    #[test]
    fn test_it() {
    }
}
<|endoftext|>


<commit_before>use parse::Executable;
use instruction;
use instruction::{Instruction, Condition, Operand};
use port;
use port::GenericPort;

#[derive(Default)]
pub struct CpuState {
    pub acc: i32,
    pub bak: i32,
    pc: i32,
}

pub struct CpuPorts {
    up:     GenericPort,
    down:   GenericPort,
    left:   GenericPort,
    right:  GenericPort,
}

impl CpuPorts {
    fn new() -> Self {
        CpuPorts {
            up:     GenericPort::create(port::CpuPort::new()),
            down:   GenericPort::create(port::CpuPort::new()),
            left:   GenericPort::create(port::CpuPort::new()),
            right:  GenericPort::create(port::CpuPort::new()),
        }
    }

    fn write_port(&mut self, port: instruction::Port, val: i32) -> bool {
        match port {
            instruction::Port::Up =>    &self.up,
            instruction::Port::Down =>  &self.down,
            instruction::Port::Left =>  &self.left,
            instruction::Port::Right => &self.right,
        }.write(val)
    }

    fn read_port(&mut self, port: instruction::Port) -> Option<i32> {
        panic!("Unimplemented port read");
    }
}

pub struct Cpu {
    state:      CpuState,
    outports:   CpuPorts,
    inports:    CpuPorts,
    executable: Executable,
}

fn get_operand(state: &CpuState, ports: &mut CpuPorts, op: &Operand) -> Option<i32> {
    match op {
        &Operand::Lit(i) => Some(i),
        &Operand::ACC => Some(state.acc),
        &Operand::Port(ref p) => ports.read_port(p.to_owned()),
    }
}

impl Cpu {
    pub fn new(executable: Executable) -> Cpu {
        Self::with_ports(CpuPorts::new(), executable)
    }

    pub fn with_ports(out: CpuPorts, executable: Executable) -> Cpu {
        Cpu { state: Default::default(),
              outports: out,
              inports: CpuPorts::new(),
              executable: executable,
        }
    }

    pub fn execute(&mut self) -> bool {
        if self.executable.len() == 0 {
            return false;
        }

        let advance_pc = match *self.executable.insn_at(self.pc()) {
            Instruction::NOP => true,
            Instruction::MOV { ref src, ref dst } => {
                match get_operand(&self.state, &mut self.inports, src) {
                    Some(i) => match dst {
                            &Operand::Lit(_) => panic!("Cannot store to a literal"),
                            &Operand::ACC => { self.state.acc = i; true },
                            &Operand::Port(ref p) => self.outports.write_port(p.to_owned(), i),
                    },
                    None => false
                }
            },
            Instruction::SWP => {
                let tmp = self.state.acc;
                self.state.acc = self.state.bak;
                self.state.bak = tmp;
                true
            },
            Instruction::SAV => {
                self.state.bak = self.state.acc;
                true
            },
            Instruction::ADD { ref addend } => {
                match get_operand(&self.state, &mut self.inports, addend) {
                    Some(i) => { self.state.acc += i; true },
                    None => false
                }
            },
            Instruction::SUB { ref subtrahend } => {
                match get_operand(&self.state, &mut self.inports, subtrahend) {
                    Some(i) => { self.state.acc -= i; true },
                    None => false
                }
            },
            Instruction::NEG => {
                self.state.acc = -self.state.acc;
                true
            },
            Instruction::J { ref cond, ref dst } => {
                if match *cond {
                    Condition::Unconditional => true,
                    Condition::Ez => self.state.acc == 0,
                    Condition::Nz => self.state.acc != 0,
                    Condition::Gz => self.state.acc > 0,
                    Condition::Lz => self.state.acc < 0,
                } {
                    self.state.pc = self.executable.label_line(dst) as i32;
                    false
                } else {
                    true
                }
            },
            Instruction::JRO { ref dst } => {
                match get_operand(&self.state, &mut self.inports, dst) {
                    Some(i) => { self.state.pc += i; true },
                    None => false
                }
            },
        };
        if advance_pc {
            self.state.pc += 1;
        }
        /* Handle wrapping at the end and via JRO */
        self.state.pc %= self.executable.len() as i32;
        if self.state.pc < 0 {
            self.state.pc = self.executable.len() as i32 + self.state.pc;
        }
        true
    }

    pub fn current_line(&self) -> u32 {
        self.executable.srcline_at(self.pc())
    }

    fn pc(&self) -> usize {
        self.state.pc as usize
    }
}

#[cfg(test)]
mod tests {
    use super::{Cpu, CpuPorts};
    use port::Port;
    use parse;

    #[test]
    fn test_cpu_wrapping() {
        let e = parse::parse("TOP: NOP\nNOP").unwrap();
        let mut cpu = Cpu::new(e);
        assert_eq!(cpu.current_line(), 0);
        cpu.execute();
        assert_eq!(cpu.current_line(), 1);
        cpu.execute();
        assert_eq!(cpu.current_line(), 0);
        cpu.execute();
        assert_eq!(cpu.current_line(), 1);
        cpu.execute();
    }

    #[test]
    fn test_mov() {
        let e = parse::parse("MOV 10 ACC\nNOP").unwrap();
        let mut cpu = Cpu::new(e);
        assert_eq!(cpu.current_line(), 0);
        assert_eq!(cpu.state.acc, 0);
        cpu.execute();
        assert_eq!(cpu.current_line(), 1);
        assert_eq!(cpu.state.acc, 10);
    }

    #[test]
    fn test_add_sub() {
        let e = parse::parse("ADD 10\nADD -20\nSUB 10\nSUB -30").unwrap();
        let mut cpu = Cpu::new(e);
        assert_eq!(cpu.current_line(), 0);
        assert_eq!(cpu.state.acc, 0);
        cpu.execute();
        assert_eq!(cpu.current_line(), 1);
        assert_eq!(cpu.state.acc, 10);
        cpu.execute();
        assert_eq!(cpu.current_line(), 2);
        assert_eq!(cpu.state.acc, -10);
        cpu.execute();
        assert_eq!(cpu.current_line(), 3);
        assert_eq!(cpu.state.acc, -20);
        cpu.execute();
        assert_eq!(cpu.current_line(), 0);
        assert_eq!(cpu.state.acc, 10);
    }

    #[test]
    fn test_ports() {
        let e = parse::parse("MOV 10 DOWN").unwrap();
        let mut cpu = Cpu::new(e);
        cpu.execute();
        assert_eq!(cpu.outports.down.read().unwrap(), 10);
    }

    #[test]
    fn port_borrow() {
        let e = parse::parse("MOV 10 DOWN").unwrap();
        let ports = CpuPorts::new();
        let down = ports.down.clone();
        let mut cpu = Cpu::with_ports(ports, e);
        cpu.execute();
        assert_eq!(down.read().unwrap(), 10);
    }
}
<commit_msg>cpu: implement port read<commit_after>use parse::Executable;
use instruction;
use instruction::{Instruction, Condition, Operand};
use port;
use port::GenericPort;

#[derive(Default)]
pub struct CpuState {
    pub acc: i32,
    pub bak: i32,
    pc: i32,
}

pub struct CpuPorts {
    up:     GenericPort,
    down:   GenericPort,
    left:   GenericPort,
    right:  GenericPort,
}

impl CpuPorts {
    fn new() -> Self {
        CpuPorts {
            up:     GenericPort::create(port::CpuPort::new()),
            down:   GenericPort::create(port::CpuPort::new()),
            left:   GenericPort::create(port::CpuPort::new()),
            right:  GenericPort::create(port::CpuPort::new()),
        }
    }

    /// Index ports structure by instruction port enum
    fn match_port(&mut self, port: instruction::Port) -> &mut GenericPort {
        match port {
            instruction::Port::Up =>    &mut self.up,
            instruction::Port::Down =>  &mut self.down,
            instruction::Port::Left =>  &mut self.left,
            instruction::Port::Right => &mut self.right,
        }
    }

    fn write_port(&mut self, port: instruction::Port, val: i32) -> bool {
        self.match_port(port).write(val)
    }

    fn read_port(&mut self, port: instruction::Port) -> Option<i32> {
        self.match_port(port).read()
    }
}

pub struct Cpu {
    state:      CpuState,
    outports:   CpuPorts,
    inports:    CpuPorts,
    executable: Executable,
}

fn get_operand(state: &CpuState, ports: &mut CpuPorts, op: &Operand) -> Option<i32> {
    match op {
        &Operand::Lit(i) => Some(i),
        &Operand::ACC => Some(state.acc),
        &Operand::Port(ref p) => ports.read_port(p.to_owned()),
    }
}

impl Cpu {
    pub fn new(executable: Executable) -> Cpu {
        Self::with_ports(CpuPorts::new(), executable)
    }

    pub fn with_ports(out: CpuPorts, executable: Executable) -> Cpu {
        Cpu { state: Default::default(),
              outports: out,
              inports: CpuPorts::new(),
              executable: executable,
        }
    }

    pub fn execute(&mut self) -> bool {
        if self.executable.len() == 0 {
            return false;
        }

        let advance_pc = match *self.executable.insn_at(self.pc()) {
            Instruction::NOP => true,
            Instruction::MOV { ref src, ref dst } => {
                match get_operand(&self.state, &mut self.inports, src) {
                    Some(i) => match dst {
                            &Operand::Lit(_) => panic!("Cannot store to a literal"),
                            &Operand::ACC => { self.state.acc = i; true },
                            &Operand::Port(ref p) => self.outports.write_port(p.to_owned(), i),
                    },
                    None => false
                }
            },
            Instruction::SWP => {
                let tmp = self.state.acc;
                self.state.acc = self.state.bak;
                self.state.bak = tmp;
                true
            },
            Instruction::SAV => {
                self.state.bak = self.state.acc;
                true
            },
            Instruction::ADD { ref addend } => {
                match get_operand(&self.state, &mut self.inports, addend) {
                    Some(i) => { self.state.acc += i; true },
                    None => false
                }
            },
            Instruction::SUB { ref subtrahend } => {
                match get_operand(&self.state, &mut self.inports, subtrahend) {
                    Some(i) => { self.state.acc -= i; true },
                    None => false
                }
            },
            Instruction::NEG => {
                self.state.acc = -self.state.acc;
                true
            },
            Instruction::J { ref cond, ref dst } => {
                if match *cond {
                    Condition::Unconditional => true,
                    Condition::Ez => self.state.acc == 0,
                    Condition::Nz => self.state.acc != 0,
                    Condition::Gz => self.state.acc > 0,
                    Condition::Lz => self.state.acc < 0,
                } {
                    self.state.pc = self.executable.label_line(dst) as i32;
                    false
                } else {
                    true
                }
            },
            Instruction::JRO { ref dst } => {
                match get_operand(&self.state, &mut self.inports, dst) {
                    Some(i) => { self.state.pc += i; true },
                    None => false
                }
            },
        };
        if advance_pc {
            self.state.pc += 1;
        }
        /* Handle wrapping at the end and via JRO */
        self.state.pc %= self.executable.len() as i32;
        if self.state.pc < 0 {
            self.state.pc = self.executable.len() as i32 + self.state.pc;
        }
        true
    }

    pub fn current_line(&self) -> u32 {
        self.executable.srcline_at(self.pc())
    }

    fn pc(&self) -> usize {
        self.state.pc as usize
    }
}

#[cfg(test)]
mod tests {
    use super::{Cpu, CpuPorts};
    use port::Port;
    use parse;

    #[test]
    fn test_cpu_wrapping() {
        let e = parse::parse("TOP: NOP\nNOP").unwrap();
        let mut cpu = Cpu::new(e);
        assert_eq!(cpu.current_line(), 0);
        cpu.execute();
        assert_eq!(cpu.current_line(), 1);
        cpu.execute();
        assert_eq!(cpu.current_line(), 0);
        cpu.execute();
        assert_eq!(cpu.current_line(), 1);
        cpu.execute();
    }

    #[test]
    fn test_mov() {
        let e = parse::parse("MOV 10 ACC\nNOP").unwrap();
        let mut cpu = Cpu::new(e);
        assert_eq!(cpu.current_line(), 0);
        assert_eq!(cpu.state.acc, 0);
        cpu.execute();
        assert_eq!(cpu.current_line(), 1);
        assert_eq!(cpu.state.acc, 10);
    }

    #[test]
    fn test_add_sub() {
        let e = parse::parse("ADD 10\nADD -20\nSUB 10\nSUB -30").unwrap();
        let mut cpu = Cpu::new(e);
        assert_eq!(cpu.current_line(), 0);
        assert_eq!(cpu.state.acc, 0);
        cpu.execute();
        assert_eq!(cpu.current_line(), 1);
        assert_eq!(cpu.state.acc, 10);
        cpu.execute();
        assert_eq!(cpu.current_line(), 2);
        assert_eq!(cpu.state.acc, -10);
        cpu.execute();
        assert_eq!(cpu.current_line(), 3);
        assert_eq!(cpu.state.acc, -20);
        cpu.execute();
        assert_eq!(cpu.current_line(), 0);
        assert_eq!(cpu.state.acc, 10);
    }

    #[test]
    fn test_ports() {
        let e = parse::parse("MOV 10 DOWN").unwrap();
        let mut cpu = Cpu::new(e);
        cpu.execute();
        assert_eq!(cpu.outports.down.read().unwrap(), 10);
    }

    #[test]
    fn port_borrow() {
        let e = parse::parse("MOV 10 DOWN").unwrap();
        let ports = CpuPorts::new();
        let down = ports.down.clone();
        let mut cpu = Cpu::with_ports(ports, e);
        cpu.execute();
        assert_eq!(down.read().unwrap(), 10);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add missing test for unreachable! macro<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:internal error: entered unreachable code
fn main() { unreachable!() }
<|endoftext|>


<commit_before><commit_msg>Add span information to token streams when possible.<commit_after><|endoftext|>


<commit_before><commit_msg>Formatting for chunk_view<commit_after><|endoftext|>


<commit_before><commit_msg>Add some lifetime annotations<commit_after><|endoftext|>


<commit_before>#![crate_id = "piston"]
#![deny(missing_doc)]
#![warn(dead_code)]

//! A user friendly graphics engine.

extern crate time;
extern crate graphics;
extern crate log;
extern crate collections;
extern crate gl;
extern crate glfw;
extern crate sdl2;
extern crate image;
extern crate libc;
extern crate debug;

pub use Game = game::Game;

pub use Render = game_iterator::Render;
pub use Update = game_iterator::Update;
pub use KeyPress = game_iterator::KeyPress;
pub use KeyRelease = game_iterator::KeyRelease;
pub use MousePress = game_iterator::MousePress;
pub use MouseRelease = game_iterator::MouseRelease;
pub use MouseMove = game_iterator::MouseMove;
pub use MouseRelativeMove = game_iterator::MouseRelativeMove;

pub use GameEvent = game_iterator::GameEvent;
pub use GameIterator = game_iterator::GameIterator;
pub use GameIteratorSettings = game_iterator::GameIteratorSettings;
pub use RenderArgs = game_iterator::RenderArgs;
pub use UpdateArgs = game_iterator::UpdateArgs;
pub use KeyPressArgs = game_iterator::KeyPressArgs;
pub use KeyReleaseArgs = game_iterator::KeyReleaseArgs;
pub use MousePressArgs = game_iterator::MousePressArgs;
pub use MouseReleaseArgs = game_iterator::MouseReleaseArgs;
pub use MouseMoveArgs = game_iterator::MouseMoveArgs;
pub use MouseRelativeMoveArgs = game_iterator::MouseRelativeMoveArgs;

pub use GameWindow = game_window::GameWindow;
pub use GameWindowSDL2 = game_window_sdl2::GameWindowSDL2;
pub use GameWindowGLFW = game_window_glfw::GameWindowGLFW;
pub use GameWindowSettings = game_window_settings::GameWindowSettings;
pub use Gl = gl_back_end::Gl;
pub use AssetStore = asset_store::AssetStore;
pub use Texture = texture::Texture;

pub mod shader_utils;
pub mod game_window;
pub mod keyboard;
pub mod event;
pub mod mouse;

mod game;
mod game_iterator;
mod game_window_sdl2;
mod game_window_glfw;
mod game_window_settings;
mod gl_back_end;
mod asset_store;
mod texture;

<commit_msg>Added conditional compilation for GLFW and SDL2<commit_after>#![crate_id = "piston"]
#![deny(missing_doc)]
#![warn(dead_code)]

//! A user friendly graphics engine.
#[cfg(glfw)]
extern crate glfw;
#[cfg(sdl2)]
extern crate sdl2;

extern crate time;
extern crate graphics;
extern crate log;
extern crate collections;
extern crate gl;
extern crate image;
extern crate libc;
extern crate debug;

pub use Game = game::Game;

pub use Render = game_iterator::Render;
pub use Update = game_iterator::Update;
pub use KeyPress = game_iterator::KeyPress;
pub use KeyRelease = game_iterator::KeyRelease;
pub use MousePress = game_iterator::MousePress;
pub use MouseRelease = game_iterator::MouseRelease;
pub use MouseMove = game_iterator::MouseMove;
pub use MouseRelativeMove = game_iterator::MouseRelativeMove;

pub use GameEvent = game_iterator::GameEvent;
pub use GameIterator = game_iterator::GameIterator;
pub use GameIteratorSettings = game_iterator::GameIteratorSettings;
pub use RenderArgs = game_iterator::RenderArgs;
pub use UpdateArgs = game_iterator::UpdateArgs;
pub use KeyPressArgs = game_iterator::KeyPressArgs;
pub use KeyReleaseArgs = game_iterator::KeyReleaseArgs;
pub use MousePressArgs = game_iterator::MousePressArgs;
pub use MouseReleaseArgs = game_iterator::MouseReleaseArgs;
pub use MouseMoveArgs = game_iterator::MouseMoveArgs;
pub use MouseRelativeMoveArgs = game_iterator::MouseRelativeMoveArgs;

pub use GameWindow = game_window::GameWindow;
#[cfg(sdl2)]
pub use GameWindowSDL2 = game_window_sdl2::GameWindowSDL2;
#[cfg(glfw)]
pub use GameWindowGLFW = game_window_glfw::GameWindowGLFW;
pub use GameWindowSettings = game_window_settings::GameWindowSettings;
pub use Gl = gl_back_end::Gl;
pub use AssetStore = asset_store::AssetStore;
pub use Texture = texture::Texture;

pub mod shader_utils;
pub mod game_window;
pub mod keyboard;
pub mod event;
pub mod mouse;

mod game;
mod game_iterator;
mod game_window_settings;
mod gl_back_end;
mod asset_store;
mod texture;

#[cfg(sdl2)]
mod game_window_sdl2;
#[cfg(glfw)]
mod game_window_glfw;

<|endoftext|>


<commit_before><commit_msg>refactor<commit_after><|endoftext|>


<commit_before><commit_msg>fix(doctest): fix fallout of recent changes in operator dispatch<commit_after><|endoftext|>


<commit_before><commit_msg>Restore unsigned.redacted_because<commit_after><|endoftext|>


<commit_before>use std::fmt::{self, Debug, Formatter};

/// A data-structure for storing a sequence of 4-bit values.
///
/// Values are stored in a `Vec<u8>`, with two values per byte.
///
/// Values at even indices are stored in the most-significant half of their byte,
/// while values at odd indices are stored in the least-significant half.
///
/// Imagine a vector of MSB bytes, and you'll be right.
///
/// n = [_ _ | _ _ | _ _]
///
/// # Invariants
/// * If the length is odd, then the second half of the last byte must be 0.
pub struct NibbleVec {
    length: usize,
    data: Vec<u8>
}

impl NibbleVec {
    /// Create an empty nibble vector.
    pub fn new() -> NibbleVec {
        NibbleVec {
            length: 0,
            data: Vec::new()
        }
    }

    /// Create a nibble vector from a vector of bytes.
    ///
    /// Each byte is split into two 4-bit entries (MSB, LSB).
    pub fn from_byte_vec(vec: Vec<u8>) -> NibbleVec {
        let length = 2 * vec.len();
        NibbleVec {
            length: length,
            data: vec
        }
    }

    /// Get the number of elements stored in the vector.
    pub fn len(&self) -> usize {
        self.length
    }

    /// Fetch a single entry from the vector.
    ///
    /// Guaranteed to be a value in the interval [0, 15].
    ///
    /// **Panics** if `idx >= self.len()`.
    pub fn get(&self, idx: usize) -> u8 {
        if idx >= self.length {
            panic!("attempted access beyond vector end. len is {}, index is {}", self.length, idx);
        }
        let vec_idx = idx / 2;
        match idx % 2 {
            // If the index is even, take the first (most significant) half of the stored byte.
            0 => self.data[vec_idx] >> 4,
            // If the index is odd, take the second (least significant) half.
            _ => self.data[vec_idx] & 0x0F
        }
    }

    /// Add a single nibble to the vector.
    ///
    /// Only the 4 least-significant bits of the value are used.
    pub fn push(&mut self, val: u8) {
        if self.length % 2 == 0 {
            self.data.push(val << 4);
        } else {
            let vec_len = self.data.len();

            // Zero the second half of the last byte just to be safe.
            self.data[vec_len - 1] &= 0xF0;

            // Write the new value.
            self.data[vec_len - 1] |= val & 0x0F;
        }
        self.length += 1;
    }

    /// Split the vector into two parts.
    ///
    /// All elements at or following the given index are returned in a new `NibbleVec`,
    /// with exactly `idx` elements remaining in this vector.
    ///
    /// **Panics** if `idx > self.len()`.
    pub fn split(&mut self, idx: usize) -> NibbleVec {
        if idx > self.length {
            panic!("attempted to split past vector end. len is {}, index is {}", self.length, idx);
        } else if idx == self.length {
            NibbleVec::new()
        } else if idx % 2 == 0 {
            self.split_even(idx)
        } else {
            self.split_odd(idx)
        }
    }

    /// Split function for odd *indices*.
    #[inline(always)]
    fn split_odd(&mut self, idx: usize) -> NibbleVec {
        let tail_vec_size = (self.length - idx) / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Perform an overlap copy, copying the last nibble of the original vector only if
        // the length of the new tail is *odd*.
        let tail_length = self.length - idx;
        let take_last = tail_length % 2 == 1;
        self.overlap_copy(idx / 2, self.data.len(), &mut tail.data, &mut tail.length, take_last);

        // Remove the copied bytes, being careful to skip the idx byte.
        for _ in range(idx / 2 + 1, self.data.len()) {
            self.data.pop();
        }

        // Zero the second half of the index byte so as to maintain the last-nibble invariant.
        self.data[idx / 2] &= 0xF0;

        // Update the length of the first NibbleVec.
        self.length = idx;

        tail
    }

    /// Split function for even *indices*.
    #[inline(always)]
    fn split_even(&mut self, idx: usize) -> NibbleVec {
        // Avoid allocating a temporary vector by copying all the bytes in order, then popping them.
        let tail_vec_size = (self.length - idx) / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Copy the bytes.
        for i in range(idx / 2, self.data.len()) {
            tail.data.push(self.data[i]);
        }

        // Pop the same bytes.
        for _ in range(0, tail_vec_size) {
            self.data.pop();
        }

        // Update lengths.
        tail.length = self.length - idx;
        self.length = idx;

        tail
    }

    /// Copy data between the second half of self.data[start] and
    /// self.data[end - 1]. The second half of the last entry is included
    /// if include_last is true.
    #[inline(always)]
    fn overlap_copy(&self, start: usize, end: usize, vec: &mut Vec<u8>, length: &mut usize, include_last: bool) {
        // Copy up to the first half of the last byte.
        for i in range(start, end - 1) {
            // The first half is the second half of the old entry.
            let first_half = self.data[i] & 0x0f;

            // The second half is the first half of the next entry.
            let second_half = self.data[i + 1] >> 4;

            vec.push((first_half << 4) | second_half);
            *length += 2;
        }

        if include_last {
            let last = self.data[end - 1] & 0x0f;
            vec.push(last << 4);
            *length += 1;
        }
    }

    /// Append another nibble vector.
    pub fn join(&mut self, other: &NibbleVec) {
        // If the length is even, we can append directly.
        if self.length % 2 == 0 {
            self.length += other.length;
            self.data.push_all(other.data.as_slice());
            return;
        }

        // If the other vector is empty, bail out.
        if other.len() == 0 {
            return;
        }

        // If the length is odd, we have to perform an overlap copy.
        // Copy the first half of the first element, to make the vector an even length.
        self.push(other.get(0));

        // Copy the rest of the vector using an overlap copy.
        let take_last = other.len() % 2 == 0;
        other.overlap_copy(0, other.data.len(), &mut self.data, &mut self.length, take_last);
    }
}

impl PartialEq<[u8]> for NibbleVec {
    fn eq(&self, other: &[u8]) -> bool {
        if other.len() != self.len() {
            return false;
        }

        for (i, x) in other.iter().enumerate() {
            if self.get(i) != *x {
                return false;
            }
        }
        true
    }
}

impl Clone for NibbleVec {
    fn clone(&self) -> NibbleVec {
        NibbleVec {
            length: self.length,
            data: self.data.clone()
        }
    }
}

impl Debug for NibbleVec {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "NibbleVec ["));

        if self.len() > 0 {
            try!(write!(fmt, "{}", self.get(0)));
        }

        for i in range(1, self.len()) {
            try!(write!(fmt, ", {}", self.get(i)));
        }
        write!(fmt, "]")
    }
}

#[cfg(test)]
mod test {
    use NibbleVec;

    fn v8_7_6_5() -> NibbleVec {
        NibbleVec::from_byte_vec(vec![8 << 4 | 7, 6 << 4 | 5])
    }

    fn v11_10_9() -> NibbleVec {
        let mut result = NibbleVec::from_byte_vec(vec![11 << 4 | 10]);
        result.push(9);
        result
    }

    #[test]
    fn get() {
        let nv = NibbleVec::from_byte_vec(vec![3 << 4 | 7]);
        assert_eq!(nv.get(0), 3u8);
        assert_eq!(nv.get(1), 7u8);
    }

    #[test]
    fn push() {
        let mut nv = NibbleVec::new();
        let data = vec![0, 1, 3, 5, 7, 9, 11, 15];
        for val in data.iter() {
            nv.push(*val);
        }

        for (i, val) in data.iter().enumerate() {
            assert_eq!(nv.get(i), *val);
        }
    }

    fn split_test(  nibble_vec: &NibbleVec,
                    idx: usize,
                    first: Vec<u8>,
                    second: Vec<u8>) {
        let mut init = nibble_vec.clone();
        let tail = init.split(idx);
        assert!(init == first[..]);
        assert!(tail == second[..]);
    }

    #[test]
    fn split_even_length() {
        let even_length = v8_7_6_5();
        split_test(&even_length, 0, vec![], vec![8, 7, 6, 5]);
        split_test(&even_length, 1, vec![8], vec![7, 6, 5]);
        split_test(&even_length, 2, vec![8, 7], vec![6, 5]);
        split_test(&even_length, 4, vec![8, 7, 6, 5], vec![]);
    }

    #[test]
    fn split_odd_length() {
        let odd_length = v11_10_9();
        split_test(&odd_length, 0, vec![], vec![11, 10, 9]);
        split_test(&odd_length, 1, vec![11], vec![10, 9]);
        split_test(&odd_length, 2, vec![11, 10], vec![9]);
        split_test(&odd_length, 3, vec![11, 10, 9], vec![]);
    }

    /// Join vec2 onto vec1 and ensure that the results matches the one expected.
    fn join_test(vec1: &NibbleVec, vec2: &NibbleVec, result: Vec<u8>) {
        let mut joined = vec1.clone();
        joined.join(vec2);
        assert!(joined == result[..]);
    }

    #[test]
    fn join_even_length() {
        let v1 = v8_7_6_5();
        let v2 = v11_10_9();
        join_test(&v1, &v2, vec![8, 7, 6, 5, 11, 10, 9]);
        join_test(&v1, &v1, vec![8, 7, 6, 5, 8, 7, 6, 5]);
        join_test(&v1, &NibbleVec::new(), vec![8, 7, 6, 5]);
        join_test(&NibbleVec::new(), &v1, vec![8, 7, 6, 5]);
    }

    #[test]
    fn join_odd_length() {
        let v1 = v8_7_6_5();
        let v2 = v11_10_9();
        join_test(&v2, &v1, vec![11, 10, 9, 8, 7, 6, 5]);
        join_test(&v2, &v2, vec![11, 10, 9, 11, 10, 9]);
        join_test(&v2, &NibbleVec::new(), vec![11, 10, 9]);
    }

    /// Ensure that the last nibble is zeroed before reuse.
    #[test]
    fn memory_reuse() {
        let mut vec = NibbleVec::new();
        vec.push(10);
        vec.push(1);

        // Pushing.
        vec.split(1);
        vec.push(2);
        assert_eq!(vec.get(1), 2);

        // Joining.
        vec.split(1);
        vec.join(&NibbleVec::from_byte_vec(vec![1 << 4 | 3, 5 << 4]));
        assert_eq!(vec.get(1), 1);
    }
}
<commit_msg>Make join take self by value to allow chaining.<commit_after>use std::fmt::{self, Debug, Formatter};

/// A data-structure for storing a sequence of 4-bit values.
///
/// Values are stored in a `Vec<u8>`, with two values per byte.
///
/// Values at even indices are stored in the most-significant half of their byte,
/// while values at odd indices are stored in the least-significant half.
///
/// Imagine a vector of MSB bytes, and you'll be right.
///
/// n = [_ _ | _ _ | _ _]
///
/// # Invariants
/// * If the length is odd, then the second half of the last byte must be 0.
pub struct NibbleVec {
    length: usize,
    data: Vec<u8>
}

impl NibbleVec {
    /// Create an empty nibble vector.
    pub fn new() -> NibbleVec {
        NibbleVec {
            length: 0,
            data: Vec::new()
        }
    }

    /// Create a nibble vector from a vector of bytes.
    ///
    /// Each byte is split into two 4-bit entries (MSB, LSB).
    pub fn from_byte_vec(vec: Vec<u8>) -> NibbleVec {
        let length = 2 * vec.len();
        NibbleVec {
            length: length,
            data: vec
        }
    }

    /// Get the number of elements stored in the vector.
    pub fn len(&self) -> usize {
        self.length
    }

    /// Fetch a single entry from the vector.
    ///
    /// Guaranteed to be a value in the interval [0, 15].
    ///
    /// **Panics** if `idx >= self.len()`.
    pub fn get(&self, idx: usize) -> u8 {
        if idx >= self.length {
            panic!("attempted access beyond vector end. len is {}, index is {}", self.length, idx);
        }
        let vec_idx = idx / 2;
        match idx % 2 {
            // If the index is even, take the first (most significant) half of the stored byte.
            0 => self.data[vec_idx] >> 4,
            // If the index is odd, take the second (least significant) half.
            _ => self.data[vec_idx] & 0x0F
        }
    }

    /// Add a single nibble to the vector.
    ///
    /// Only the 4 least-significant bits of the value are used.
    pub fn push(&mut self, val: u8) {
        if self.length % 2 == 0 {
            self.data.push(val << 4);
        } else {
            let vec_len = self.data.len();

            // Zero the second half of the last byte just to be safe.
            self.data[vec_len - 1] &= 0xF0;

            // Write the new value.
            self.data[vec_len - 1] |= val & 0x0F;
        }
        self.length += 1;
    }

    /// Split the vector into two parts.
    ///
    /// All elements at or following the given index are returned in a new `NibbleVec`,
    /// with exactly `idx` elements remaining in this vector.
    ///
    /// **Panics** if `idx > self.len()`.
    pub fn split(&mut self, idx: usize) -> NibbleVec {
        if idx > self.length {
            panic!("attempted to split past vector end. len is {}, index is {}", self.length, idx);
        } else if idx == self.length {
            NibbleVec::new()
        } else if idx % 2 == 0 {
            self.split_even(idx)
        } else {
            self.split_odd(idx)
        }
    }

    /// Split function for odd *indices*.
    #[inline(always)]
    fn split_odd(&mut self, idx: usize) -> NibbleVec {
        let tail_vec_size = (self.length - idx) / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Perform an overlap copy, copying the last nibble of the original vector only if
        // the length of the new tail is *odd*.
        let tail_length = self.length - idx;
        let take_last = tail_length % 2 == 1;
        self.overlap_copy(idx / 2, self.data.len(), &mut tail.data, &mut tail.length, take_last);

        // Remove the copied bytes, being careful to skip the idx byte.
        for _ in range(idx / 2 + 1, self.data.len()) {
            self.data.pop();
        }

        // Zero the second half of the index byte so as to maintain the last-nibble invariant.
        self.data[idx / 2] &= 0xF0;

        // Update the length of the first NibbleVec.
        self.length = idx;

        tail
    }

    /// Split function for even *indices*.
    #[inline(always)]
    fn split_even(&mut self, idx: usize) -> NibbleVec {
        // Avoid allocating a temporary vector by copying all the bytes in order, then popping them.
        let tail_vec_size = (self.length - idx) / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Copy the bytes.
        for i in range(idx / 2, self.data.len()) {
            tail.data.push(self.data[i]);
        }

        // Pop the same bytes.
        for _ in range(0, tail_vec_size) {
            self.data.pop();
        }

        // Update lengths.
        tail.length = self.length - idx;
        self.length = idx;

        tail
    }

    /// Copy data between the second half of self.data[start] and
    /// self.data[end - 1]. The second half of the last entry is included
    /// if include_last is true.
    #[inline(always)]
    fn overlap_copy(&self, start: usize, end: usize, vec: &mut Vec<u8>, length: &mut usize, include_last: bool) {
        // Copy up to the first half of the last byte.
        for i in range(start, end - 1) {
            // The first half is the second half of the old entry.
            let first_half = self.data[i] & 0x0f;

            // The second half is the first half of the next entry.
            let second_half = self.data[i + 1] >> 4;

            vec.push((first_half << 4) | second_half);
            *length += 2;
        }

        if include_last {
            let last = self.data[end - 1] & 0x0f;
            vec.push(last << 4);
            *length += 1;
        }
    }

    /// Append another nibble vector.
    pub fn join(mut self, other: &NibbleVec) -> NibbleVec {
        // If the length is even, we can append directly.
        if self.length % 2 == 0 {
            self.length += other.length;
            self.data.push_all(other.data.as_slice());
            return self;
        }

        // If the other vector is empty, bail out.
        if other.len() == 0 {
            return self;
        }

        // If the length is odd, we have to perform an overlap copy.
        // Copy the first half of the first element, to make the vector an even length.
        self.push(other.get(0));

        // Copy the rest of the vector using an overlap copy.
        let take_last = other.len() % 2 == 0;
        other.overlap_copy(0, other.data.len(), &mut self.data, &mut self.length, take_last);

        self
    }
}

impl PartialEq<[u8]> for NibbleVec {
    fn eq(&self, other: &[u8]) -> bool {
        if other.len() != self.len() {
            return false;
        }

        for (i, x) in other.iter().enumerate() {
            if self.get(i) != *x {
                return false;
            }
        }
        true
    }
}

impl Clone for NibbleVec {
    fn clone(&self) -> NibbleVec {
        NibbleVec {
            length: self.length,
            data: self.data.clone()
        }
    }
}

impl Debug for NibbleVec {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "NibbleVec ["));

        if self.len() > 0 {
            try!(write!(fmt, "{}", self.get(0)));
        }

        for i in range(1, self.len()) {
            try!(write!(fmt, ", {}", self.get(i)));
        }
        write!(fmt, "]")
    }
}

#[cfg(test)]
mod test {
    use NibbleVec;

    fn v8_7_6_5() -> NibbleVec {
        NibbleVec::from_byte_vec(vec![8 << 4 | 7, 6 << 4 | 5])
    }

    fn v11_10_9() -> NibbleVec {
        let mut result = NibbleVec::from_byte_vec(vec![11 << 4 | 10]);
        result.push(9);
        result
    }

    #[test]
    fn get() {
        let nv = NibbleVec::from_byte_vec(vec![3 << 4 | 7]);
        assert_eq!(nv.get(0), 3u8);
        assert_eq!(nv.get(1), 7u8);
    }

    #[test]
    fn push() {
        let mut nv = NibbleVec::new();
        let data = vec![0, 1, 3, 5, 7, 9, 11, 15];
        for val in data.iter() {
            nv.push(*val);
        }

        for (i, val) in data.iter().enumerate() {
            assert_eq!(nv.get(i), *val);
        }
    }

    fn split_test(  nibble_vec: &NibbleVec,
                    idx: usize,
                    first: Vec<u8>,
                    second: Vec<u8>) {
        let mut init = nibble_vec.clone();
        let tail = init.split(idx);
        assert!(init == first[..]);
        assert!(tail == second[..]);
    }

    #[test]
    fn split_even_length() {
        let even_length = v8_7_6_5();
        split_test(&even_length, 0, vec![], vec![8, 7, 6, 5]);
        split_test(&even_length, 1, vec![8], vec![7, 6, 5]);
        split_test(&even_length, 2, vec![8, 7], vec![6, 5]);
        split_test(&even_length, 4, vec![8, 7, 6, 5], vec![]);
    }

    #[test]
    fn split_odd_length() {
        let odd_length = v11_10_9();
        split_test(&odd_length, 0, vec![], vec![11, 10, 9]);
        split_test(&odd_length, 1, vec![11], vec![10, 9]);
        split_test(&odd_length, 2, vec![11, 10], vec![9]);
        split_test(&odd_length, 3, vec![11, 10, 9], vec![]);
    }

    /// Join vec2 onto vec1 and ensure that the results matches the one expected.
    fn join_test(vec1: &NibbleVec, vec2: &NibbleVec, result: Vec<u8>) {
        let joined = vec1.clone().join(vec2);
        assert!(joined == result[..]);
    }

    #[test]
    fn join_even_length() {
        let v1 = v8_7_6_5();
        let v2 = v11_10_9();
        join_test(&v1, &v2, vec![8, 7, 6, 5, 11, 10, 9]);
        join_test(&v1, &v1, vec![8, 7, 6, 5, 8, 7, 6, 5]);
        join_test(&v1, &NibbleVec::new(), vec![8, 7, 6, 5]);
        join_test(&NibbleVec::new(), &v1, vec![8, 7, 6, 5]);
    }

    #[test]
    fn join_odd_length() {
        let v1 = v8_7_6_5();
        let v2 = v11_10_9();
        join_test(&v2, &v1, vec![11, 10, 9, 8, 7, 6, 5]);
        join_test(&v2, &v2, vec![11, 10, 9, 11, 10, 9]);
        join_test(&v2, &NibbleVec::new(), vec![11, 10, 9]);
    }

    /// Ensure that the last nibble is zeroed before reuse.
    #[test]
    fn memory_reuse() {
        let mut vec = NibbleVec::new();
        vec.push(10);
        vec.push(1);

        // Pushing.
        vec.split(1);
        vec.push(2);
        assert_eq!(vec.get(1), 2);

        // Joining.
        vec.split(1);
        vec = vec.join(&NibbleVec::from_byte_vec(vec![1 << 4 | 3, 5 << 4]));
        assert_eq!(vec.get(1), 1);
    }
}
<|endoftext|>


<commit_before><commit_msg>test_sort_zero_sized_type should test pdqsort, not rust's<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor, clean up, optimize, tweak<commit_after><|endoftext|>


<commit_before><commit_msg>Return IO errors that aren't NotFound when reading parent env files.<commit_after><|endoftext|>


<commit_before><commit_msg>Simplify `ArgParser` API<commit_after><|endoftext|>


<commit_before><commit_msg>make structs cloneable<commit_after><|endoftext|>


<commit_before>/*!
This is an OAuth 2.0 library for the Rust language.  It defines types and traits useful
for implementing an OAuth 2.0 compliant system as specified by RFC 6749.

WARNING: We've just started.  It is practically useless at this point.

Applicability

OAuth 2.0 is a protocol framework that allows an application (the Client, usually a web
site) to obtain limited access to an HTTP service (the Resource Server) on behalf of
a Resource Owner which interacts with the Client via a User-Agent (browser).
This is mediated via an Authorization Server (which could be th Resource Server
itself, or separated from it).

The term "client" can be confusing here.  The client of the OAuth service is typically a
web site.   The client of that web site is the user-agent (browser).  To minimize
confusion, the user-agent will not be referred to as a client.

OAuth is a Framework Only

OAuth 2.0 is an Authorization Framework.  In order to get something usable, you must supply
the missing pieces.  And there are quite a few missing pieces which you will need to implement
in order to get a working system.  These include:

Issuing and receiving HTTP requests (e.g. you'll need to plug in some HTTP
    library, we won't pick one for you).

Storing state.  Often database tables are used.  Manytimes the Authorization
    Server and Resource Server use the same database, or perhaps are the same
    server.  This is out of scope, and left up to you.

Initial client registration (between the Client and the Authorization
    Server).  Often people just use config files, but this is for you to decide.

Client authentication (by the Authorization Server)

User-Agent session management (by the Client).  Usually via a session cookie,
    but we leave this up to you.

User-Agent authentication and authorization (by the Authorization Server)

Perhaps more

Sample Implementation

FIXME: A sample implementation is intended to be supplied to demonstrate how to use this
library.

Coverage and Standard Support

We do not (and likely will not) support every standard compliant way to use OAuth 2.0.
But we do try to be as flexible as possible.  That being said, the following limitations
apply:

All HTTP traffic is required to be TLS protected.  All endpoints must use the
    https scheme.  The standard only requires this of most traffic.

All IDs and tokens are taken to be respresented in UTF-8 encodings.  We will not
    work with other encodings.  The standard is silent on most encoding issues.

FIXME: More limitations will be added to this list as the development progresses.

*/

extern crate url;

use std::fmt;
use std::fmt::Display;

pub mod syntax;
pub mod resource_server;
pub mod authorization_server;
pub mod client;

/// Client Identifier, issued to Clients by Authorization Servers when registering
///
/// See RFC 6749 Section 2.2.   In particular:
///

///
The authorization server issues this to the client at registration, and uses it
///     to look up details about the client during the main protocol.

///
It is not a secret.

///

//
/// Charset validator ```syntax::valid_client_id_str```
pub type ClientId = String;

/// Client Type, either 'confidential' or 'public'.
///
/// See RFC 6749 Section 2.2.   In particular:
///

///
If the client cannot be trusted with secrets, it is 'public'.  This usually includes
///     all clients in end-user hands like javascript ones, but strictly speaking it depends
///     on your security model.

///

pub enum ClientType {
    ConfidentialClient,
    PublicClient,
}
impl Display for ClientType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match *self {
            ClientType::ConfidentialClient => write!(f, "confidential"),
            ClientType::PublicClient => write!(f, "public"),
        }
    }
}
<commit_msg>minor<commit_after>/*!
This is an OAuth 2.0 library for the Rust language.  It defines types and traits useful
for implementing an OAuth 2.0 compliant system as specified by RFC 6749.

WARNING: We've just started.  It is practically useless at this point.

Applicability

OAuth 2.0 is a protocol framework that allows an application (the Client, usually a web
site) to obtain limited access to an HTTP service (the Resource Server) on behalf of
a Resource Owner which interacts with the Client via a User-Agent (browser).
This is mediated via an Authorization Server (which could be the Resource Server
itself, or separated from it).

The term "client" can be confusing here.  The client of the OAuth service is typically a
web site.   The client of that web site is the user-agent (browser).  To minimize
confusion, the user-agent will not be referred to as a client.

OAuth is a Framework Only

OAuth 2.0 is an Authorization Framework.  In order to get something usable, you must supply
the missing pieces.  And there are quite a few missing pieces which you will need to implement
in order to get a working system.  These include:

Issuing and receiving HTTP requests (e.g. you'll need to work with HTTP somehow,
    perhaps with hyper or other HTTP related library, or directly).

Storing state.  Often database tables are used.  Manytimes the Authorization
    Server and Resource Server use the same database, or perhaps are the same
    server.  This is out of scope, and left up to you.

Initial client registration (between the Client and the Authorization
    Server).  Often people just use config files, but this is for you to decide.

Client authentication (by the Authorization Server)

User-Agent session management (by the Client).  Usually via a session cookie,
    but we leave this up to you.

User-Agent authentication and authorization (by the Authorization Server)

Perhaps more

Sample Implementation

FIXME: A sample implementation is intended to be supplied to demonstrate how to use this
library.

Coverage and Standard Support

We do not (and likely will not) support every standard compliant way to use OAuth 2.0.
But we do try to be as flexible as possible.  That being said, the following limitations
apply:

All HTTP traffic is required to be TLS protected.  All endpoints must use the
    https scheme.  The standard only requires this of most traffic.

All IDs and tokens are taken to be respresented in UTF-8 encodings.  We will not
    work with other encodings.  The standard is silent on most encoding issues.

FIXME: More limitations will be added to this list as the development progresses.

*/

extern crate url;

use std::fmt;
use std::fmt::Display;

pub mod syntax;
pub mod resource_server;
pub mod authorization_server;
pub mod client;

/// Client Identifier, issued to Clients by Authorization Servers when registering
///
/// See RFC 6749 Section 2.2.   In particular:
///

///
The authorization server issues this to the client at registration, and uses it
///     to look up details about the client during the main protocol.

///
It is not a secret.

///

//
/// Charset validator ```syntax::valid_client_id_str```
pub type ClientId = String;

/// Client Type, either 'confidential' or 'public'.
///
/// See RFC 6749 Section 2.2.   In particular:
///

///
If the client cannot be trusted with secrets, it is 'public'.  This usually includes
///     all clients in end-user hands like javascript ones, but strictly speaking it depends
///     on your security model.

///

pub enum ClientType {
    ConfidentialClient,
    PublicClient,
}
impl Display for ClientType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match *self {
            ClientType::ConfidentialClient => write!(f, "confidential"),
            ClientType::PublicClient => write!(f, "public"),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement number_of_keys for DbPage<commit_after><|endoftext|>


<commit_before>extern crate libc;

use std::ffi::CString;
use std::memory::transmute;

#[link(name = "rust")]
extern {
  fn klee_make_symbolic(data: *const libc::c_void, length: usize, name: *const libc::c_char);
}

pub fn any(data: *const libc::c_void, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(data, length, name_cstr.as_ptr());
  }
}

pub fn i32(data: *const i32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}

pub fn u32(data: *const u32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}
<commit_msg>Update lib.rs<commit_after>extern crate libc;

use std::ffi::CString;
use std::mem::transmute;

#[link(name = "rust")]
extern {
  fn klee_make_symbolic(data: *const libc::c_void, length: usize, name: *const libc::c_char);
}

pub fn any(data: *const libc::c_void, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(data, length, name_cstr.as_ptr());
  }
}

pub fn i32(data: *const i32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}

pub fn u32(data: *const u32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}
<|endoftext|>


<commit_before>use quote::{ToTokens, Tokens};

use metadata::Metadata;
use parse::Entry;
use request::Request;
use response::Response;

#[derive(Debug)]
pub struct Api {
    metadata: Metadata,
    request: Request,
    response: Response,
}

impl ToTokens for Api {
    fn to_tokens(&self, tokens: &mut Tokens) {
        let description = &self.metadata.description;
        let method = &self.metadata.method;
        let name = &self.metadata.name;
        let path = &self.metadata.path;
        let rate_limited = &self.metadata.rate_limited;
        let requires_authentication = &self.metadata.requires_authentication;

        let request_types = {
            let mut tokens = Tokens::new();
            self.request.to_tokens(&mut tokens);
            tokens
        };
        let response_types = {
            let mut tokens = Tokens::new();
            self.response.to_tokens(&mut tokens);
            tokens
        };

        let add_body_to_request = if self.request.has_body_fields() {
            let request_body_init_fields = self.request.request_body_init_fields();

            quote! {
                let request_body = RequestBody {
                    #request_body_init_fields
                };

                hyper_request.set_body(
                    ::serde_json::to_vec(&request_body)
                        .expect("failed to serialize request body to JSON")
                );
            }
        } else {
            Tokens::new()
        };

        let deserialize_response_body = if self.response.has_body_fields() {
            quote! {
                let bytes = hyper_response.body().fold::<_, _, Result<_, ::hyper::Error>>(
                    Vec::new(),
                    |mut bytes, chunk| {
                        bytes.write_all(&chunk).expect("failed to append body chunk");

                        Ok(bytes)
                    }).wait().expect("failed to read response body chunks into byte vector");

                let response_body: ResponseBody = ::serde_json::from_slice(bytes.as_slice())
                    .expect("failed to deserialize body");
            }
        } else {
            Tokens::new()
        };

        let response_init_fields = if self.response.has_fields() {
            self.response.init_fields()
        } else {
            Tokens::new()
        };

        tokens.append(quote! {
            use std::io::Write as _Write;

            use ::futures::{Future as _Future, Stream as _Stream};
            use ::ruma_api::Endpoint as _RumaApiEndpoint;

            /// The API endpoint.
            #[derive(Debug)]
            pub struct Endpoint;

            #request_types

            impl ::std::convert::TryFrom<Request> for ::hyper::Request {
                type Error = ();

                #[allow(unused_mut, unused_variables)]
                fn try_from(request: Request) -> Result<Self, Self::Error> {
                    let metadata = Endpoint::METADATA;

                    let mut hyper_request = ::hyper::Request::new(
                        metadata.method,
                        metadata.path.parse().expect("failed to parse request URI"),
                    );

                    #add_body_to_request

                    Ok(hyper_request)
                }
            }

            #response_types

            impl ::std::convert::TryFrom<::hyper::Response> for Response {
                type Error = ();

                fn try_from(hyper_response: ::hyper::Response) -> Result<Self, Self::Error> {
                    #deserialize_response_body

                    let response = Response {
                        #response_init_fields
                    };

                    Ok(response)
                }
            }

            impl ::ruma_api::Endpoint for Endpoint {
                type Request = Request;
                type Response = Response;

                const METADATA: ::ruma_api::Metadata = ::ruma_api::Metadata {
                    description: #description,
                    method: ::hyper::#method,
                    name: #name,
                    path: #path,
                    rate_limited: #rate_limited,
                    requires_authentication: #requires_authentication,
                };
            }
        });
    }
}

impl From<Vec<Entry>> for Api {
    fn from(entries: Vec<Entry>) -> Api {
        if entries.len() != 3 {
            panic!("ruma_api! expects 3 blocks: metadata, request, and response");
        }

        let mut metadata = None;
        let mut request = None;
        let mut response = None;

        for entry in entries {
            match entry {
                Entry::Metadata(fields) => metadata = Some(Metadata::from(fields)),
                Entry::Request(fields) => request = Some(Request::from(fields)),
                Entry::Response(fields) => response = Some(Response::from(fields)),
            }
        }

        Api {
            metadata: metadata.expect("ruma_api! is missing metadata"),
            request: request.expect("ruma_api! is missing request"),
            response: response.expect("ruma_api! is missing response"),
        }
    }
}
<commit_msg>Propagate errors instead of panicking.<commit_after>use quote::{ToTokens, Tokens};

use metadata::Metadata;
use parse::Entry;
use request::Request;
use response::Response;

#[derive(Debug)]
pub struct Api {
    metadata: Metadata,
    request: Request,
    response: Response,
}

impl ToTokens for Api {
    fn to_tokens(&self, tokens: &mut Tokens) {
        let description = &self.metadata.description;
        let method = &self.metadata.method;
        let name = &self.metadata.name;
        let path = &self.metadata.path;
        let rate_limited = &self.metadata.rate_limited;
        let requires_authentication = &self.metadata.requires_authentication;

        let request_types = {
            let mut tokens = Tokens::new();
            self.request.to_tokens(&mut tokens);
            tokens
        };
        let response_types = {
            let mut tokens = Tokens::new();
            self.response.to_tokens(&mut tokens);
            tokens
        };

        let add_body_to_request = if self.request.has_body_fields() {
            let request_body_init_fields = self.request.request_body_init_fields();

            quote! {
                let request_body = RequestBody {
                    #request_body_init_fields
                };

                hyper_request.set_body(::serde_json::to_vec(&request_body)?);
            }
        } else {
            Tokens::new()
        };

        let deserialize_response_body = if self.response.has_body_fields() {
            let mut tokens = Tokens::new();

            tokens.append(quote! {
                hyper_response.body()
                    .fold::<_, _, Result<_, ::std::io::Error>>(Vec::new(), |mut bytes, chunk| {
                        bytes.write_all(&chunk)?;

                        Ok(bytes)
                    })
                    .map_err(::ruma_api::Error::from)
                    .and_then(|bytes| {
                        ::serde_json::from_slice::<ResponseBody>(bytes.as_slice())
                            .map_err(::ruma_api::Error::from)
                    })
            });

            tokens.append(".and_then(|response_body| {");

            tokens
        } else {
            let mut tokens = Tokens::new();

            tokens.append(quote! {
                ::futures::future::ok(())
            });

            tokens.append(".and_then(|_| {");

            tokens
        };

        let mut closure_end = Tokens::new();
        closure_end.append("})");

        let response_init_fields = if self.response.has_fields() {
            self.response.init_fields()
        } else {
            Tokens::new()
        };

        tokens.append(quote! {
            use std::io::Write as _Write;

            use ::futures::{Future as _Future, Stream as _Stream};
            use ::ruma_api::Endpoint as _RumaApiEndpoint;

            /// The API endpoint.
            #[derive(Debug)]
            pub struct Endpoint;

            #request_types

            impl ::std::convert::TryFrom<Request> for ::hyper::Request {
                type Error = ::ruma_api::Error;

                #[allow(unused_mut, unused_variables)]
                fn try_from(request: Request) -> Result<Self, Self::Error> {
                    let metadata = Endpoint::METADATA;

                    let mut hyper_request = ::hyper::Request::new(
                        metadata.method,
                        metadata.path.parse()?,
                    );

                    #add_body_to_request

                    Ok(hyper_request)
                }
            }

            #response_types

            impl ::std::convert::TryFrom<::hyper::Response> for Response {
                type Error = ::ruma_api::Error;

                fn try_from(hyper_response: ::hyper::Response) -> Result<Self, Self::Error> {
                    #deserialize_response_body

                    let response = Response {
                        #response_init_fields
                    };

                    Ok(response)
                    #closure_end
                    .wait()
                }
            }

            impl ::ruma_api::Endpoint for Endpoint {
                type Request = Request;
                type Response = Response;

                const METADATA: ::ruma_api::Metadata = ::ruma_api::Metadata {
                    description: #description,
                    method: ::hyper::#method,
                    name: #name,
                    path: #path,
                    rate_limited: #rate_limited,
                    requires_authentication: #requires_authentication,
                };
            }
        });
    }
}

impl From<Vec<Entry>> for Api {
    fn from(entries: Vec<Entry>) -> Api {
        if entries.len() != 3 {
            panic!("ruma_api! expects 3 blocks: metadata, request, and response");
        }

        let mut metadata = None;
        let mut request = None;
        let mut response = None;

        for entry in entries {
            match entry {
                Entry::Metadata(fields) => metadata = Some(Metadata::from(fields)),
                Entry::Request(fields) => request = Some(Request::from(fields)),
                Entry::Response(fields) => response = Some(Response::from(fields)),
            }
        }

        Api {
            metadata: metadata.expect("ruma_api! is missing metadata"),
            request: request.expect("ruma_api! is missing request"),
            response: response.expect("ruma_api! is missing response"),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add test example.<commit_after>#![allow(unused_variables)]
#[macro_use]
extern crate cargonauts;

use cargonauts::api;

routes! {
    resource User => ["get"] {
        related Photo: "has-many";
    }
    resource Photo => ["get", "index"] {
        related User: "has-one";
    }
}

struct User;

impl cargonauts::Serialize for User {
    fn serialize<S: cargonauts::Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
        unimplemented!()
    }
}

impl api::Resource for User {
    type Id = u32;

    fn id(&self) -> u32 {
        unimplemented!()
    }

    fn resource() -> &'static str {
        "user"
    }
}

impl api::Get for User {
    fn get(id: Self::Id) -> Option<User> {
        unimplemented!()
    }
}

impl api::HasMany<Photo> for User {
    fn has_many(id: &Self::Id) -> Vec<Photo> {
        unimplemented!()
    }
}

struct Photo;

impl cargonauts::Serialize for Photo {
    fn serialize<S: cargonauts::Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
        unimplemented!()
    }
}

impl api::Resource for Photo {
    type Id = u32;

    fn id(&self) -> u32 {
        unimplemented!()
    }

    fn resource() -> &'static str {
        "photo"
    }
}

impl api::Get for Photo {
    fn get(id: Self::Id) -> Option<Photo> {
        unimplemented!()
    }
}

impl api::Index for Photo {
    fn index() -> Vec<Photo> {
        unimplemented!()
    }
}

impl api::HasOne<User> for Photo {
    fn has_one(id: &Self::Id) -> Option<User> {
        unimplemented!()
    }
}

#[test]
fn it_compiles() { }
<|endoftext|>


<commit_before><commit_msg>Implement search_dbpage_from_root method<commit_after><|endoftext|>


<commit_before><commit_msg>broken build: fiddling with action space for flash cursor input<commit_after><|endoftext|>


<commit_before>#![feature(macro_rules, phase, default_type_params)]
#![deny(missing_doc)]
#![deny(warnings)]
#![experimental]

//! # Hyper
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
//! layer over "stringly-typed" HTTP.
//!
//! Hyper offers both an HTTP/S client an HTTP server which can be used to drive
//! complex web applications written entirely in Rust.
//!
//! ## Internal Design
//!
//! Hyper is designed as a relatively low-level wrapped over raw HTTP. It should
//! allow the implementation of higher-level abstractions with as little pain as
//! possible, and should not irrevocably hide any information from its users.
//!
//! ### Common Functionality
//!
//! Functionality and code shared between the Server and Client implementations can
//! be found in `src` directly - this includes `NetworkStream`s, `Method`s,
//! `StatusCode`, and so on.
//!
//! #### Methods
//!
//! Methods are represented as a single `enum` to remain as simple as possible.
//! Extension Methods are represented as raw `String`s. A method's safety and
//! idempotence can be accessed using the `safe` and `idempotent` methods.
//!
//! #### StatusCode
//!
//! Status codes are also represented as a single, exhaustive, `enum`. This
//! representation is efficient, typesafe, and ergonomic as it allows the use of
//! `match` to disambiguate known status codes.
//!
//! #### Headers
//!
//! Hyper's header representation is likely the most complex API exposed by Hyper.
//!
//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
//! typesafe API for interacting with headers that does not rely on the use of
//! "string-typing."
//!
//! Each HTTP header in Hyper has an associated type and implementation of the
//! `Header` trait, which defines an HTTP headers name as a string, how to parse
//! that header, and how to format that header.
//!
//! Headers are then parsed from the string representation lazily when the typed
//! representation of a header is requested and formatted back into their string
//! representation when headers are written back to the client.
//!
//! #### NetworkStream and NetworkAcceptor
//!
//! These are found in `src/net.rs` and define the interface that acceptors and
//! streams must fulfill for them to be used within Hyper. They are by and large
//! internal tools and you should only need to mess around with them if you want to
//! mock or replace `TcpStream` and `TcpAcceptor`.
//!
//! ### Server
//!
//! Server-specific functionality, such as `Request` and `Response`
//! representations, are found in in `src/serer`.
//!
//! #### Handler + Server
//!
//! A Handler in Hyper just accepts an Iterator of `(Request, Response)` pairs and
//! does whatever it wants with it. This gives Handlers maximum flexibility to decide
//! on concurrency strategy and exactly how they want to distribute the work of
//! dealing with `Request` and `Response.`
//!
//! #### Request
//!
//! An incoming HTTP Request is represented as a struct containing
//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
//! address, an HTTP version, and a `Method` - relatively standard stuff.
//!
//! `Request` implements `Reader` itself, meaning that you can ergonomically get
//! the body out of a `Request` using standard `Reader` methods and helpers.
//!
//! #### Response
//!
//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
//! over a `NetworkStream` which represents the Response body in addition to
//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
//! implementation provides a streaming interface for sending data over to the
//! client.
//!
//! One of the traditional problems with representing outgoing HTTP Responses is
//! tracking the write-status of the Response - have we written the status-line,
//! the headers, the body, etc.? Hyper tracks this information statically using the
//! type system and prevents you, using the type system, from writing headers after
//! you have started writing to the body or vice versa.
//!
//! Hyper does this through a phantom type parameter in the definition of Response,
//! which tracks whether you are allowed to write to the headers or the body. This
//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
//! indicating that you can write the headers and `Streaming` indicating that you
//! may write to the body, but not the headers.
//!
//! ### Client
//!
//! Client-specific functionality, such as `Request` and `Response`
//! representations, are found in `src/client`.
//!
//! #### Request
//!
//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
//! a `NetworkStream` which represents the Request body in addition to the standard
//! information such as headers and the request method.
//!
//! Outgoing Requests track their write-status in almost exactly the same way as
//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
//! in the documentation for sever Response.
//!
//! Requests expose an efficient streaming interface instead of a builder pattern,
//! but they also provide the needed interface for creating a builder pattern over
//! the API exposed by core Hyper.
//!
//! #### Response
//!
//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
//! a `NetworkStream` and contain headers, a status, and an http version. They
//! implement `Reader` and can be read to get the data out of a `Response`.
//!

extern crate time;
extern crate url;
extern crate openssl;
#[phase(plugin,link)] extern crate log;
#[cfg(test)] extern crate test;
extern crate "unsafe-any" as uany;
extern crate "move-acceptor" as macceptor;
extern crate intertwine;
extern crate typeable;

pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port};
pub use mimewrapper::mime;
pub use url::Url;
pub use method::{Get, Head, Post, Delete};
pub use status::{Ok, BadRequest, NotFound};
pub use server::Server;

use std::fmt;
use std::io::IoError;

use std::rt::backtrace;

macro_rules! try_io(
    ($e:expr) => (match $e { Ok(v) => v, Err(e) => return Err(::HttpIoError(e)) })
)

macro_rules! todo(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        format_args!(|args| log!(5, "TODO: {}", args), $($arg)*)
    })
)

#[allow(dead_code)]
struct Trace;

impl fmt::Show for Trace {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let _ = backtrace::write(fmt);
        ::std::result::Ok(())
    }
}

macro_rules! trace(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        format_args!(|args| log!(5, "{}\n{}", args, ::Trace), $($arg)*)
    })
)

pub mod client;
pub mod method;
pub mod header;
pub mod http;
pub mod net;
pub mod server;
pub mod status;
pub mod uri;
pub mod version;

mod mimewrapper {
    /// Re-exporting the mime crate, for convenience.
    extern crate mime;
}

/// Result type often returned from methods that can have `HttpError`s.
pub type HttpResult<T> = Result<T, HttpError>;

/// A set of errors that can occur parsing HTTP streams.
#[deriving(Show, PartialEq, Clone)]
pub enum HttpError {
    /// An invalid `Method`, such as `GE,T`.
    HttpMethodError,
    /// An invalid `RequestUri`, such as `exam ple.domain`.
    HttpUriError,
    /// An invalid `HttpVersion`, such as `HTP/1.1`
    HttpVersionError,
    /// An invalid `Header`.
    HttpHeaderError,
    /// An invalid `Status`, such as `1337 ELITE`.
    HttpStatusError,
    /// An `IoError` that occured while trying to read or write to a network stream.
    HttpIoError(IoError),
}

//FIXME: when Opt-in Built-in Types becomes a thing, we can force these structs
//to be Send. For now, this has the compiler do a static check.
fn _assert_send<T: Send>() {
    _assert_send::<client::Request<net::Fresh>>();
    _assert_send::<client::Response>();

    _assert_send::<server::Request>();
    _assert_send::<server::Response<net::Fresh>>();
}
<commit_msg>Fix typo in documentation<commit_after>#![feature(macro_rules, phase, default_type_params)]
#![deny(missing_doc)]
#![deny(warnings)]
#![experimental]

//! # Hyper
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
//! layer over "stringly-typed" HTTP.
//!
//! Hyper offers both an HTTP/S client an HTTP server which can be used to drive
//! complex web applications written entirely in Rust.
//!
//! ## Internal Design
//!
//! Hyper is designed as a relatively low-level wrapped over raw HTTP. It should
//! allow the implementation of higher-level abstractions with as little pain as
//! possible, and should not irrevocably hide any information from its users.
//!
//! ### Common Functionality
//!
//! Functionality and code shared between the Server and Client implementations can
//! be found in `src` directly - this includes `NetworkStream`s, `Method`s,
//! `StatusCode`, and so on.
//!
//! #### Methods
//!
//! Methods are represented as a single `enum` to remain as simple as possible.
//! Extension Methods are represented as raw `String`s. A method's safety and
//! idempotence can be accessed using the `safe` and `idempotent` methods.
//!
//! #### StatusCode
//!
//! Status codes are also represented as a single, exhaustive, `enum`. This
//! representation is efficient, typesafe, and ergonomic as it allows the use of
//! `match` to disambiguate known status codes.
//!
//! #### Headers
//!
//! Hyper's header representation is likely the most complex API exposed by Hyper.
//!
//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
//! typesafe API for interacting with headers that does not rely on the use of
//! "string-typing."
//!
//! Each HTTP header in Hyper has an associated type and implementation of the
//! `Header` trait, which defines an HTTP headers name as a string, how to parse
//! that header, and how to format that header.
//!
//! Headers are then parsed from the string representation lazily when the typed
//! representation of a header is requested and formatted back into their string
//! representation when headers are written back to the client.
//!
//! #### NetworkStream and NetworkAcceptor
//!
//! These are found in `src/net.rs` and define the interface that acceptors and
//! streams must fulfill for them to be used within Hyper. They are by and large
//! internal tools and you should only need to mess around with them if you want to
//! mock or replace `TcpStream` and `TcpAcceptor`.
//!
//! ### Server
//!
//! Server-specific functionality, such as `Request` and `Response`
//! representations, are found in in `src/server`.
//!
//! #### Handler + Server
//!
//! A Handler in Hyper just accepts an Iterator of `(Request, Response)` pairs and
//! does whatever it wants with it. This gives Handlers maximum flexibility to decide
//! on concurrency strategy and exactly how they want to distribute the work of
//! dealing with `Request` and `Response.`
//!
//! #### Request
//!
//! An incoming HTTP Request is represented as a struct containing
//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
//! address, an HTTP version, and a `Method` - relatively standard stuff.
//!
//! `Request` implements `Reader` itself, meaning that you can ergonomically get
//! the body out of a `Request` using standard `Reader` methods and helpers.
//!
//! #### Response
//!
//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
//! over a `NetworkStream` which represents the Response body in addition to
//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
//! implementation provides a streaming interface for sending data over to the
//! client.
//!
//! One of the traditional problems with representing outgoing HTTP Responses is
//! tracking the write-status of the Response - have we written the status-line,
//! the headers, the body, etc.? Hyper tracks this information statically using the
//! type system and prevents you, using the type system, from writing headers after
//! you have started writing to the body or vice versa.
//!
//! Hyper does this through a phantom type parameter in the definition of Response,
//! which tracks whether you are allowed to write to the headers or the body. This
//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
//! indicating that you can write the headers and `Streaming` indicating that you
//! may write to the body, but not the headers.
//!
//! ### Client
//!
//! Client-specific functionality, such as `Request` and `Response`
//! representations, are found in `src/client`.
//!
//! #### Request
//!
//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
//! a `NetworkStream` which represents the Request body in addition to the standard
//! information such as headers and the request method.
//!
//! Outgoing Requests track their write-status in almost exactly the same way as
//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
//! in the documentation for sever Response.
//!
//! Requests expose an efficient streaming interface instead of a builder pattern,
//! but they also provide the needed interface for creating a builder pattern over
//! the API exposed by core Hyper.
//!
//! #### Response
//!
//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
//! a `NetworkStream` and contain headers, a status, and an http version. They
//! implement `Reader` and can be read to get the data out of a `Response`.
//!

extern crate time;
extern crate url;
extern crate openssl;
#[phase(plugin,link)] extern crate log;
#[cfg(test)] extern crate test;
extern crate "unsafe-any" as uany;
extern crate "move-acceptor" as macceptor;
extern crate intertwine;
extern crate typeable;

pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port};
pub use mimewrapper::mime;
pub use url::Url;
pub use method::{Get, Head, Post, Delete};
pub use status::{Ok, BadRequest, NotFound};
pub use server::Server;

use std::fmt;
use std::io::IoError;

use std::rt::backtrace;

macro_rules! try_io(
    ($e:expr) => (match $e { Ok(v) => v, Err(e) => return Err(::HttpIoError(e)) })
)

macro_rules! todo(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        format_args!(|args| log!(5, "TODO: {}", args), $($arg)*)
    })
)

#[allow(dead_code)]
struct Trace;

impl fmt::Show for Trace {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let _ = backtrace::write(fmt);
        ::std::result::Ok(())
    }
}

macro_rules! trace(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        format_args!(|args| log!(5, "{}\n{}", args, ::Trace), $($arg)*)
    })
)

pub mod client;
pub mod method;
pub mod header;
pub mod http;
pub mod net;
pub mod server;
pub mod status;
pub mod uri;
pub mod version;

mod mimewrapper {
    /// Re-exporting the mime crate, for convenience.
    extern crate mime;
}

/// Result type often returned from methods that can have `HttpError`s.
pub type HttpResult<T> = Result<T, HttpError>;

/// A set of errors that can occur parsing HTTP streams.
#[deriving(Show, PartialEq, Clone)]
pub enum HttpError {
    /// An invalid `Method`, such as `GE,T`.
    HttpMethodError,
    /// An invalid `RequestUri`, such as `exam ple.domain`.
    HttpUriError,
    /// An invalid `HttpVersion`, such as `HTP/1.1`
    HttpVersionError,
    /// An invalid `Header`.
    HttpHeaderError,
    /// An invalid `Status`, such as `1337 ELITE`.
    HttpStatusError,
    /// An `IoError` that occured while trying to read or write to a network stream.
    HttpIoError(IoError),
}

//FIXME: when Opt-in Built-in Types becomes a thing, we can force these structs
//to be Send. For now, this has the compiler do a static check.
fn _assert_send<T: Send>() {
    _assert_send::<client::Request<net::Fresh>>();
    _assert_send::<client::Response>();

    _assert_send::<server::Request>();
    _assert_send::<server::Response<net::Fresh>>();
}
<|endoftext|>


<commit_before><commit_msg>Use triple slash for documentation on Url::origin method<commit_after><|endoftext|>


<commit_before><commit_msg>A few more changes to work on x86, confirmed functioning.<commit_after><|endoftext|>


<commit_before><commit_msg>better error reporting<commit_after><|endoftext|>