<commit_before>use std::io::{Read, Write};
use std::default::Default;

use num::traits::ToPrimitive;
use byteorder::{ByteOrder, BigEndian, ReadBytesExt, WriteBytesExt};

use error::{Result, Error};

pub trait ToByte {
    fn encode<T: Write>(&self, buffer: &mut T) -> Result<()>;
}

impl<'a, T: ToByte + 'a + ?Sized> ToByte for &'a T {
    fn encode<W: Write>(&self, buffer: &mut W) -> Result<()> {
        (*self).encode(buffer)
    }
}

impl ToByte for i8 {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        buffer.write_i8(*self).or_else(|e| Err(From::from(e)))
    }
}

impl ToByte for i16 {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        buffer.write_i16::<BigEndian>(*self).or_else(|e| Err(From::from(e)))
    }
}

impl ToByte for i32 {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        buffer.write_i32::<BigEndian>(*self).or_else(|e| Err(From::from(e)))
    }
}

impl ToByte for i64 {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        buffer.write_i64::<BigEndian>(*self).or_else(|e| Err(From::from(e)))
    }
}

impl ToByte for str {
    fn encode<T: Write>(&self, buffer: &mut T) -> Result<()> {
        let l = try!(self.len().to_i16().ok_or(Error::CodecError));
        try!(buffer.write_i16::<BigEndian>(l));
        buffer.write_all(self.as_bytes()).or_else(|e| Err(From::from(e)))
    }
}

impl <V: ToByte> ToByte for [V] {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        let l = try!(self.len().to_i32().ok_or(Error::CodecError));
        try!(buffer.write_i32::<BigEndian>(l));
        for e in self {
            try!(e.encode(buffer));
        }
        Ok(())
    }
}

impl ToByte for [u8] {
    fn encode<T: Write>(&self, buffer: &mut T) -> Result<()> {
        let l = try!(self.len().to_i32().ok_or(Error::CodecError));
        try!(buffer.write_i32::<BigEndian>(l));
        buffer.write_all(self).or_else(|e| Err(From::from(e)))
    }
}

// ~ this allows to render a slice of various types (typically &str
// and String) as strings
pub struct AsStrings<'a, T: 'a>(pub &'a [T]);

impl<'a, T: AsRef<str> + 'a> ToByte for AsStrings<'a, T> {
    fn encode<W: Write>(&self, buffer: &mut W) -> Result<()> {
        let &AsStrings(xs) = self;
        let l = try!(xs.len().to_i32().ok_or(Error::CodecError));
        try!(buffer.write_i32::<BigEndian>(l));
        for x in xs {
            try!(x.as_ref().encode(buffer));
        }
        Ok(())
    }
}

// --------------------------------------------------------------------

pub trait FromByte {
    type R: Default + FromByte;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()>;
    fn decode_new<T: Read>(buffer: &mut T) -> Result<Self::R> {
        let mut temp: Self::R = Default::default();
        match temp.decode(buffer) {
            Ok(_) => Ok(temp),
            Err(e) => Err(e)
        }
    }
}

macro_rules! dec_helper {
    ($val: expr, $dest:expr) => ({
        match $val {
            Ok(val) => {
                *$dest = val;
                Ok(())
                },
            Err(e) => Err(From::from(e))
        }
    })
}
macro_rules! decode {
    ($src:expr, $dest:expr) => ({
        dec_helper!($src.read_i8(), $dest)

    });
    ($src:expr, $method:ident, $dest:expr) => ({
        dec_helper!($src.$method::<BigEndian>(), $dest)

    });
}

impl FromByte for i8 {
    type R = i8;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        decode!(buffer, self)
    }
}

impl FromByte for i16 {
    type R = i16;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        decode!(buffer, read_i16, self)
    }
}

impl FromByte for i32 {
    type R = i32;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        decode!(buffer, read_i32, self)
    }
}

impl FromByte for i64 {
    type R = i64;
    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        decode!(buffer, read_i64, self)
    }
}

impl FromByte for String {
    type R = String;
    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        let mut length: i16 = 0;
        if let Err(e) = decode!(buffer, read_i16, &mut length) {
            return Err(e);
        }
        if length <= 0 { return Ok(()); }
        self.reserve(length as usize);
        let _ = buffer.take(length as u64).read_to_string(self);
        if self.len() != length as usize {
            return Err(Error::UnexpectedEOF);
        }
        Ok(())
    }
}

impl <V: FromByte + Default> FromByte for Vec<V>{
    type R = Vec<V>;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        let mut length: i32 = 0;
        if let Err(e) = decode!(buffer, read_i32, &mut length) {
            return Err(e);
        }
        if length <= 0 { return Ok(()); }
        self.reserve(length as usize);
        for _ in 0..length {
            let mut e: V = Default::default();
            try!(e.decode(buffer));
            self.push(e);
        }
        Ok(())
    }
}

impl FromByte for Vec<u8>{
    type R = Vec<u8>;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        let mut length: i32 = 0;
        match decode!(buffer, read_i32, &mut length) {
            Ok(_) => {},
            Err(e) => return Err(e)
        }
        if length <= 0 {return Ok(());}
        self.reserve(length as usize);
        match buffer.take(length as u64).read_to_end(self) {
            Ok(size) => {
                if size < length as usize {
                    return Err(Error::UnexpectedEOF)
                } else {
                    Ok(())
                }
            },
            Err(e) => Err(From::from(e))
        }
    }
}

#[test]
fn codec_i8() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: i8 = 5;

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [5]);

    // Read from buffer into existing variable
    let mut dec1: i8 = 0;
    dec1.decode(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = i8::decode_new(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_i16() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: i16 = 5;

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 5]);

    // Read from buffer into existing variable
    let mut dec1: i16 = 0;
    dec1.decode(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = i16::decode_new(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_32() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: i32 = 5;

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 0, 0, 5]);

    // Read from buffer into existing variable
    let mut dec1: i32 = 0;
    dec1.decode(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = i32::decode_new(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_i64() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: i64 = 5;

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 0, 0, 0, 0, 0, 0, 5]);

    // Read from buffer into existing variable
    let mut dec1: i64 = 0;
    dec1.decode(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = i64::decode_new(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_string() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig = "test".to_owned();

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 4, 116, 101, 115, 116]);

    // Read from buffer into existing variable
    let mut dec1 = String::new();
    dec1.decode(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = String::decode_new(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_vec_u8() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: Vec<u8> = vec!(1, 2, 3);

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 0, 0, 3, 1, 2, 3]);

    // Read from buffer into existing variable
    let mut dec1: Vec<u8> = vec!();
    dec1.decode(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = Vec::<u8>::decode_new(&mut Cursor::new(&buf)).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_as_strings() {

    macro_rules! enc_dec_cmp {
        ($orig:expr) => {{
            use std::io::Cursor;

            let orig = $orig;

            // Encode into buffer
            let mut buf = Vec::new();
            AsStrings(&orig).encode(&mut buf).unwrap();
            assert_eq!(buf, [0, 0, 0, 2,
                             0, 3, b'a', b'b', b'c',
                             0, 4, b'd', b'e', b'f', b'g']);

            // Decode from buffer into existing value
            {
                let mut dec: Vec<String> = Vec::new();
                dec.decode(&mut Cursor::new(&buf)).unwrap();
                assert_eq!(dec, orig);
            }

            // Read from buffer into new variable
            {
                let dec = Vec::<String>::decode_new(&mut Cursor::new(&buf)).unwrap();
                assert_eq!(dec, orig);
            }
        }}
    }

    { // slice of &str
        let orig: &[&str] = &["abc", "defg"];
        enc_dec_cmp!(orig);
    }

    { // vec of &str
        let orig: Vec<&str> = vec!["abc", "defg"];
        enc_dec_cmp!(orig);
    }

    { // vec of String
        let orig: Vec<String> = vec!["abc".to_owned(), "defg".to_owned()];
        enc_dec_cmp!(orig);
    }
}
<commit_msg>#! Fix test compilation for rust stable<commit_after>use std::io::{Read, Write};
use std::default::Default;

use num::traits::ToPrimitive;
use byteorder::{ByteOrder, BigEndian, ReadBytesExt, WriteBytesExt};

use error::{Result, Error};

pub trait ToByte {
    fn encode<T: Write>(&self, buffer: &mut T) -> Result<()>;
}

impl<'a, T: ToByte + 'a + ?Sized> ToByte for &'a T {
    fn encode<W: Write>(&self, buffer: &mut W) -> Result<()> {
        (*self).encode(buffer)
    }
}

impl ToByte for i8 {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        buffer.write_i8(*self).or_else(|e| Err(From::from(e)))
    }
}

impl ToByte for i16 {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        buffer.write_i16::<BigEndian>(*self).or_else(|e| Err(From::from(e)))
    }
}

impl ToByte for i32 {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        buffer.write_i32::<BigEndian>(*self).or_else(|e| Err(From::from(e)))
    }
}

impl ToByte for i64 {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        buffer.write_i64::<BigEndian>(*self).or_else(|e| Err(From::from(e)))
    }
}

impl ToByte for str {
    fn encode<T: Write>(&self, buffer: &mut T) -> Result<()> {
        let l = try!(self.len().to_i16().ok_or(Error::CodecError));
        try!(buffer.write_i16::<BigEndian>(l));
        buffer.write_all(self.as_bytes()).or_else(|e| Err(From::from(e)))
    }
}

impl <V: ToByte> ToByte for [V] {
    fn encode<T:Write>(&self, buffer: &mut T) -> Result<()> {
        let l = try!(self.len().to_i32().ok_or(Error::CodecError));
        try!(buffer.write_i32::<BigEndian>(l));
        for e in self {
            try!(e.encode(buffer));
        }
        Ok(())
    }
}

impl ToByte for [u8] {
    fn encode<T: Write>(&self, buffer: &mut T) -> Result<()> {
        let l = try!(self.len().to_i32().ok_or(Error::CodecError));
        try!(buffer.write_i32::<BigEndian>(l));
        buffer.write_all(self).or_else(|e| Err(From::from(e)))
    }
}

// ~ this allows to render a slice of various types (typically &str
// and String) as strings
pub struct AsStrings<'a, T: 'a>(pub &'a [T]);

impl<'a, T: AsRef<str> + 'a> ToByte for AsStrings<'a, T> {
    fn encode<W: Write>(&self, buffer: &mut W) -> Result<()> {
        let &AsStrings(xs) = self;
        let l = try!(xs.len().to_i32().ok_or(Error::CodecError));
        try!(buffer.write_i32::<BigEndian>(l));
        for x in xs {
            try!(x.as_ref().encode(buffer));
        }
        Ok(())
    }
}

// --------------------------------------------------------------------

pub trait FromByte {
    type R: Default + FromByte;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()>;
    fn decode_new<T: Read>(buffer: &mut T) -> Result<Self::R> {
        let mut temp: Self::R = Default::default();
        match temp.decode(buffer) {
            Ok(_) => Ok(temp),
            Err(e) => Err(e)
        }
    }
}

macro_rules! dec_helper {
    ($val: expr, $dest:expr) => ({
        match $val {
            Ok(val) => {
                *$dest = val;
                Ok(())
                },
            Err(e) => Err(From::from(e))
        }
    })
}
macro_rules! decode {
    ($src:expr, $dest:expr) => ({
        dec_helper!($src.read_i8(), $dest)

    });
    ($src:expr, $method:ident, $dest:expr) => ({
        dec_helper!($src.$method::<BigEndian>(), $dest)

    });
}

impl FromByte for i8 {
    type R = i8;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        decode!(buffer, self)
    }
}

impl FromByte for i16 {
    type R = i16;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        decode!(buffer, read_i16, self)
    }
}

impl FromByte for i32 {
    type R = i32;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        decode!(buffer, read_i32, self)
    }
}

impl FromByte for i64 {
    type R = i64;
    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        decode!(buffer, read_i64, self)
    }
}

impl FromByte for String {
    type R = String;
    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        let mut length: i16 = 0;
        if let Err(e) = decode!(buffer, read_i16, &mut length) {
            return Err(e);
        }
        if length <= 0 { return Ok(()); }
        self.reserve(length as usize);
        let _ = buffer.take(length as u64).read_to_string(self);
        if self.len() != length as usize {
            return Err(Error::UnexpectedEOF);
        }
        Ok(())
    }
}

impl <V: FromByte + Default> FromByte for Vec<V>{
    type R = Vec<V>;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        let mut length: i32 = 0;
        if let Err(e) = decode!(buffer, read_i32, &mut length) {
            return Err(e);
        }
        if length <= 0 { return Ok(()); }
        self.reserve(length as usize);
        for _ in 0..length {
            let mut e: V = Default::default();
            try!(e.decode(buffer));
            self.push(e);
        }
        Ok(())
    }
}

impl FromByte for Vec<u8>{
    type R = Vec<u8>;

    fn decode<T: Read>(&mut self, buffer: &mut T) -> Result<()> {
        let mut length: i32 = 0;
        match decode!(buffer, read_i32, &mut length) {
            Ok(_) => {},
            Err(e) => return Err(e)
        }
        if length <= 0 {return Ok(());}
        self.reserve(length as usize);
        match buffer.take(length as u64).read_to_end(self) {
            Ok(size) => {
                if size < length as usize {
                    return Err(Error::UnexpectedEOF)
                } else {
                    Ok(())
                }
            },
            Err(e) => Err(From::from(e))
        }
    }
}

#[test]
fn codec_i8() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: i8 = 5;

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [5]);

    // Read from buffer into existing variable
    let mut dec1: i8 = 0;
    dec1.decode(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = i8::decode_new(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_i16() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: i16 = 5;

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 5]);

    // Read from buffer into existing variable
    let mut dec1: i16 = 0;
    dec1.decode(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = i16::decode_new(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_32() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: i32 = 5;

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 0, 0, 5]);

    // Read from buffer into existing variable
    let mut dec1: i32 = 0;
    dec1.decode(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = i32::decode_new(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_i64() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: i64 = 5;

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 0, 0, 0, 0, 0, 0, 5]);

    // Read from buffer into existing variable
    let mut dec1: i64 = 0;
    dec1.decode(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = i64::decode_new(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_string() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig = "test".to_owned();

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 4, 116, 101, 115, 116]);

    // Read from buffer into existing variable
    let mut dec1 = String::new();
    dec1.decode(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = String::decode_new(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_vec_u8() {
    use std::io::Cursor;
    let mut buf = vec!();
    let orig: Vec<u8> = vec!(1, 2, 3);

    // Encode into buffer
    orig.encode(&mut buf).unwrap();
    assert_eq!(buf, [0, 0, 0, 3, 1, 2, 3]);

    // Read from buffer into existing variable
    let mut dec1: Vec<u8> = vec!();
    dec1.decode(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec1, orig);

    // Read from buffer into new variable
    let dec2 = Vec::<u8>::decode_new(&mut Cursor::new(&buf[..])).unwrap();
    assert_eq!(dec2, orig);
}

#[test]
fn codec_as_strings() {

    macro_rules! enc_dec_cmp {
        ($orig:expr) => {{
            use std::io::Cursor;

            let orig = $orig;

            // Encode into buffer
            let mut buf = Vec::new();
            AsStrings(&orig).encode(&mut buf).unwrap();
            assert_eq!(buf, [0, 0, 0, 2,
                             0, 3, b'a', b'b', b'c',
                             0, 4, b'd', b'e', b'f', b'g']);

            // Decode from buffer into existing value
            {
                let mut dec: Vec<String> = Vec::new();
                dec.decode(&mut Cursor::new(&buf[..])).unwrap();
                assert_eq!(dec, orig);
            }

            // Read from buffer into new variable
            {
                let dec = Vec::<String>::decode_new(&mut Cursor::new(&buf[..])).unwrap();
                assert_eq!(dec, orig);
            }
        }}
    }

    { // slice of &str
        let orig: &[&str] = &["abc", "defg"];
        enc_dec_cmp!(orig);
    }

    { // vec of &str
        let orig: Vec<&str> = vec!["abc", "defg"];
        enc_dec_cmp!(orig);
    }

    { // vec of String
        let orig: Vec<String> = vec!["abc".to_owned(), "defg".to_owned()];
        enc_dec_cmp!(orig);
    }
}
<|endoftext|>


<commit_before>// implements http://rosettacode.org/wiki/Zig-zag_matrix
// with the sorting indexes algorithm
// explained in the discussion page
// http://rosettacode.org/wiki/Talk:Zig-zag_matrix

#[deriving(Show, PartialEq, Eq)]
struct SortIndex {
    x:  uint,
    y:  uint
}

impl SortIndex {
    fn new(x:uint, y:uint) -> SortIndex {
        SortIndex{x:x, y:y}
    }
}

impl PartialOrd for SortIndex {
    fn lt(&self, other: &SortIndex) -> bool {
        if self.x + self.y == other.x + other.y {
            if (self.x + self.y) % 2 == 0 {
                self.x < other.x
            } else {
                self.y < other.y
            }
        } else {
            (self.x + self.y) < (other.x + other.y)
        }
    }
}

impl Ord for SortIndex {
    fn cmp(&self, other: &SortIndex) -> Ordering {
        if self < other { Less }
        else if self > other { Greater }
        else {Equal}
    }
}

fn zigzag(n:uint) -> Vec<Vec<uint>> {
    let mut l:Vec<SortIndex> = range(0u, n*n).map(|i| SortIndex::new(i%n,i/n)).collect();
    l.sort();

    let mut result : Vec<Vec<uint>> = Vec::from_elem(n, Vec::from_elem(n,0u));
    for t_ind in l.iter().enumerate() {
        let (i,&SortIndex{x,y}) = t_ind;
        *result.get_mut(y).get_mut(x) = i
    }
    result
}

#[cfg(not(test))]
fn main() {
    println!("{}", zigzag(5));
}

#[test]
fn result() {
   let exp =vec![vec![0,  1, 5, 6,14],
                 vec![2,  4, 7,13,15],
                 vec![3,  8,12,16,21],
                 vec![9, 11,17,20,22],
                 vec![10,18,19,23,24]];
    assert_eq!(zigzag(5), exp);
}
<commit_msg>Moved destructuring of SortIndex in the for<commit_after>// implements http://rosettacode.org/wiki/Zig-zag_matrix
// with the sorting indexes algorithm
// explained in the discussion page
// http://rosettacode.org/wiki/Talk:Zig-zag_matrix

#[deriving(Show, PartialEq, Eq)]
struct SortIndex {
    x:  uint,
    y:  uint
}

impl SortIndex {
    fn new(x:uint, y:uint) -> SortIndex {
        SortIndex{x:x, y:y}
    }
}

impl PartialOrd for SortIndex {
    fn lt(&self, other: &SortIndex) -> bool {
        if self.x + self.y == other.x + other.y {
            if (self.x + self.y) % 2 == 0 {
                self.x < other.x
            } else {
                self.y < other.y
            }
        } else {
            (self.x + self.y) < (other.x + other.y)
        }
    }
}

impl Ord for SortIndex {
    fn cmp(&self, other: &SortIndex) -> Ordering {
        if self < other { Less }
        else if self > other { Greater }
        else {Equal}
    }
}

fn zigzag(n:uint) -> Vec<Vec<uint>> {
    let mut l:Vec<SortIndex> = range(0u, n*n).map(|i| SortIndex::new(i%n,i/n)).collect();
    l.sort();

    let mut result : Vec<Vec<uint>> = Vec::from_elem(n, Vec::from_elem(n,0u));
    for (i,&SortIndex{x,y}) in l.iter().enumerate() {
        *result.get_mut(y).get_mut(x) = i
    }
    result
}

#[cfg(not(test))]
fn main() {
    println!("{}", zigzag(5));
}

#[test]
fn result() {
   let exp =vec![vec![0,  1, 5, 6,14],
                 vec![2,  4, 7,13,15],
                 vec![3,  8,12,16,21],
                 vec![9, 11,17,20,22],
                 vec![10,18,19,23,24]];
    assert_eq!(zigzag(5), exp);
}
<|endoftext|>


<commit_before>use clap::{App, Arg, ArgMatches};
use libc::{c_int, isatty};
use std::io;
use std::fs::File;

#[derive(Clone)]
pub struct Config {
    initial_query: Option<String>,
    pub input_file_path: Option<String>,
}

impl Config {
    pub fn with_args() -> Self {
        let m = get_arg_matches();
        Config {
            initial_query: m.value_of("query").map(|s| s.to_string()),
            input_file_path: m.value_of("INPUT").map(|s| s.to_string()),
        }
    }

    pub fn initial_query(&self) -> Option<&str> {
        self.initial_query.as_ref().map(|s| s.as_ref())
    }

    pub fn input_source(&self) -> Box<io::Read> {
        if let Some(ref path) = self.input_file_path {
            if let Ok(f) = File::open(path) {
                return Box::new(f);
            }
        } else if !stdin_is_tty() {
            return Box::new(io::stdin());
        }
        Box::new(io::empty())
    }
}

fn get_arg_matches<'a>() -> ArgMatches<'a, 'a> {
    App::new("eru")
        .arg(Arg::with_name("INPUT")
             .index(1))
        .arg(Arg::with_name("query")
             .long("query")
             .short("q")
             .takes_value(true))
        .get_matches()
}

fn stdin_is_tty() -> bool {
    unsafe { isatty(0 as c_int) == (1 as c_int) }
}
<commit_msg>Make file_input_path field private<commit_after>use clap::{App, Arg, ArgMatches};
use libc::{c_int, isatty};
use std::io;
use std::fs::File;

#[derive(Clone)]
pub struct Config {
    initial_query: Option<String>,
    input_file_path: Option<String>,
}

impl Config {
    pub fn with_args() -> Self {
        let m = get_arg_matches();
        Config {
            initial_query: m.value_of("query").map(|s| s.to_string()),
            input_file_path: m.value_of("INPUT").map(|s| s.to_string()),
        }
    }

    pub fn initial_query(&self) -> Option<&str> {
        self.initial_query.as_ref().map(|s| s.as_ref())
    }

    pub fn input_source(&self) -> Box<io::Read> {
        if let Some(ref path) = self.input_file_path {
            if let Ok(f) = File::open(path) {
                return Box::new(f);
            }
        } else if !stdin_is_tty() {
            return Box::new(io::stdin());
        }
        Box::new(io::empty())
    }
}

fn get_arg_matches<'a>() -> ArgMatches<'a, 'a> {
    App::new("eru")
        .arg(Arg::with_name("INPUT")
             .index(1))
        .arg(Arg::with_name("query")
             .long("query")
             .short("q")
             .takes_value(true))
        .get_matches()
}

fn stdin_is_tty() -> bool {
    unsafe { isatty(0 as c_int) == (1 as c_int) }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

use regex;
use regex::{Regex, RegexBuilder};
use serde_yaml;

error_chain! {
    foreign_links {
        ParseError(::serde_yaml::Error);
        IOError(::std::io::Error);
    }

    errors {
        NoHomeError {
            description("could not locate home directory")
        }

        BadEntryError(browser: String, profile: String) {
            description("bad configuration")
            display("bad configuration: no such browser '{}' defined for profile '{}'",
                    browser,
                    profile)
        }
    }
}

#[doc(hidden)]
/// A regex that is equivalent to the "*." wildcard pattern.
///
/// This regular expression matches any subdomains (and subdomains of subdomains, etc.). It replaces
/// the "*." in entries such as "*.example.com"
static WC_REPLACEMENT: &'static str = r"(?:.+\.)?";

#[doc(hidden)]
/// The prefix for the generated regular expression.
///
/// This prefix will make the regular expression match both HTTP and HTTPs URLs.
static RE_PREFIX: &'static str = r"^https?://(?:";

#[doc(hidden)]
/// The suffix for the generated regular expression.
///
/// This is the corresponding closing parenthesis for the opening parenthesis in `RE_PREFIX`.
static RE_SUFFIX: char = ')';

#[doc(hidden)]
/// Transform a string into a regular expression that will match that URL.
///
/// URLs of the form "*.example.com" will match any subdomains of "example.com" in addition to
/// "example.com".
fn escape_url(url: &str) -> String {
    if url.starts_with("*.") {
        let rest = url.split_at(2).1;
        let mut escaped = String::with_capacity(WC_REPLACEMENT.len() + url.len() - 2);

        escaped.push_str(WC_REPLACEMENT);
        escaped.push_str(&regex::escape(&rest));
        escaped
    } else {
        regex::escape(&url)
    }
}

#[doc(hidden)]
/// Transform a list of URLs to a regular expression that matches them.
///
/// URLs should not include the scheme: the resulting regular expression will match both HTTP and
/// HTTPs URLs.
///
/// If the list is empty, no regular expression is returned.
fn urls_to_regex(urls: &Vec<String>) -> Option<Regex> {
    if urls.is_empty() {
        None
    } else {
        let re_body = urls.iter()
            .map(|url| escape_url(url))
            .collect::<Vec<_>>()
            .join("|");

        let mut pattern = String::with_capacity(RE_PREFIX.len() + re_body.len() + 1);
        pattern.push_str(RE_PREFIX);
        pattern.push_str(&re_body);
        pattern.push(RE_SUFFIX);

        // build() returns a ::std::result::Result<regex::Regex, regex::Error>, but panicing is not
        // possible because we escape all user input (and we therefore cannot generate an invalid
        // regular expression).
        Some(RegexBuilder::new(&pattern)
            .case_insensitive(true)
            .build()
            .unwrap())
    }
}

#[derive(Debug, Deserialize)]
/// A default browser and profile combination.
pub struct DefaultProfile {
    /// The default browser.
    pub browser: String,

    /// The default profile to use for the browser.
    pub profile: String,
}

#[derive(Debug, Deserialize)]
/// A configuration entry.
///
/// Each entry maps a regular expression to a browser and profile. If a URL matches the given
/// regular expression it will be launched using the corresponding browser and profile.
pub struct Entry {
    /// The browser to use.
    ///
    /// This must be defined in the list of browsers in the parent [`Config`](struct.Config.html)
    /// struct.
    pub browser: String,

    /// The profile to use.
    pub profile: String,

    /// The list of URLs that this profile matches.
    ///
    /// This list is used to generate the regular expression.
    pub urls: Vec<String>,

    /// The regular expression to match against.
    ///
    /// If a URL matches this regular expression, the corresponding browser will be launched with
    /// the corresponding profile.
    ///
    /// If the list of URLs is empty, this will be `None`.
    #[serde(skip_deserializing)]
    pub regex: Option<Regex>,
}

#[derive(Debug, Deserialize)]
/// Metabrowser configuration.
///
/// The configuration specifies the set of browsers and how they can be launched, as well as the
pub struct Config {
    /// A mapping of browser names to their command line parameters for launching with a specified
    /// profile.
    pub browsers: HashMap<String, Vec<String>>,

    /// The default browser and profile to use for URLs that do not match any regular expressions in
    /// the list of profiles.
    pub default: DefaultProfile,

    /// The specified browser-profile pairs and their corresponding regular expressions.
    #[serde(rename="profiles")]
    pub entries: Vec<Entry>,
}

impl Config {
    /// Read the configuration from the file.
    pub fn from_file(p: &Path) -> Result<Config> {

        let mut buf = String::new();
        let mut f = try!(File::open(p));
        try!(f.read_to_string(&mut buf));

        let mut config = try!(serde_yaml::from_str::<Self>(&buf)
            .map_err(Error::from)
            .and_then(Config::validate));

        for entry in &mut config.entries {
            entry.regex = urls_to_regex(&entry.urls);
        }

        Ok(config)
    }

    #[doc(hidden)]
    /// Validate a parsed configuration.
    ///
    /// This function will ensure that all entries match up with the list of available browsers.
    fn validate(mut self) -> Result<Self> {
        for i in 0..self.entries.len() {
            if !self.browsers.contains_key(&self.entries[i].browser) {
                let browser_profile = self.entries.swap_remove(i);
                return Err(Error::from(ErrorKind::BadEntryError(browser_profile.browser,
                                                                browser_profile.profile)));
            }
        }

        Ok(self)
    }
}
<commit_msg>Fix trailing whitespace in config.rs<commit_after>use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

use regex;
use regex::{Regex, RegexBuilder};
use serde_yaml;

error_chain! {
    foreign_links {
        ParseError(::serde_yaml::Error);
        IOError(::std::io::Error);
    }

    errors {
        NoHomeError {
            description("could not locate home directory")
        }

        BadEntryError(browser: String, profile: String) {
            description("bad configuration")
            display("bad configuration: no such browser '{}' defined for profile '{}'",
                    browser,
                    profile)
        }
    }
}

#[doc(hidden)]
/// A regex that is equivalent to the "*." wildcard pattern.
///
/// This regular expression matches any subdomains (and subdomains of subdomains, etc.). It replaces
/// the "*." in entries such as "*.example.com"
static WC_REPLACEMENT: &'static str = r"(?:.+\.)?";

#[doc(hidden)]
/// The prefix for the generated regular expression.
///
/// This prefix will make the regular expression match both HTTP and HTTPs URLs.
static RE_PREFIX: &'static str = r"^https?://(?:";

#[doc(hidden)]
/// The suffix for the generated regular expression.
///
/// This is the corresponding closing parenthesis for the opening parenthesis in `RE_PREFIX`.
static RE_SUFFIX: char = ')';

#[doc(hidden)]
/// Transform a string into a regular expression that will match that URL.
///
/// URLs of the form "*.example.com" will match any subdomains of "example.com" in addition to
/// "example.com".
fn escape_url(url: &str) -> String {
    if url.starts_with("*.") {
        let rest = url.split_at(2).1;
        let mut escaped = String::with_capacity(WC_REPLACEMENT.len() + url.len() - 2);

        escaped.push_str(WC_REPLACEMENT);
        escaped.push_str(&regex::escape(&rest));
        escaped
    } else {
        regex::escape(&url)
    }
}

#[doc(hidden)]
/// Transform a list of URLs to a regular expression that matches them.
///
/// URLs should not include the scheme: the resulting regular expression will match both HTTP and
/// HTTPs URLs.
///
/// If the list is empty, no regular expression is returned.
fn urls_to_regex(urls: &Vec<String>) -> Option<Regex> {
    if urls.is_empty() {
        None
    } else {
        let re_body = urls.iter()
            .map(|url| escape_url(url))
            .collect::<Vec<_>>()
            .join("|");

        let mut pattern = String::with_capacity(RE_PREFIX.len() + re_body.len() + 1);
        pattern.push_str(RE_PREFIX);
        pattern.push_str(&re_body);
        pattern.push(RE_SUFFIX);

        // build() returns a ::std::result::Result<regex::Regex, regex::Error>, but panicing is not
        // possible because we escape all user input (and we therefore cannot generate an invalid
        // regular expression).
        Some(RegexBuilder::new(&pattern)
            .case_insensitive(true)
            .build()
            .unwrap())
    }
}

#[derive(Debug, Deserialize)]
/// A default browser and profile combination.
pub struct DefaultProfile {
    /// The default browser.
    pub browser: String,

    /// The default profile to use for the browser.
    pub profile: String,
}

#[derive(Debug, Deserialize)]
/// A configuration entry.
///
/// Each entry maps a regular expression to a browser and profile. If a URL matches the given
/// regular expression it will be launched using the corresponding browser and profile.
pub struct Entry {
    /// The browser to use.
    ///
    /// This must be defined in the list of browsers in the parent [`Config`](struct.Config.html)
    /// struct.
    pub browser: String,

    /// The profile to use.
    pub profile: String,

    /// The list of URLs that this profile matches.
    ///
    /// This list is used to generate the regular expression.
    pub urls: Vec<String>,

    /// The regular expression to match against.
    ///
    /// If a URL matches this regular expression, the corresponding browser will be launched with
    /// the corresponding profile.
    ///
    /// If the list of URLs is empty, this will be `None`.
    #[serde(skip_deserializing)]
    pub regex: Option<Regex>,
}

#[derive(Debug, Deserialize)]
/// Metabrowser configuration.
///
/// The configuration specifies the set of browsers and how they can be launched, as well as the
pub struct Config {
    /// A mapping of browser names to their command line parameters for launching with a specified
    /// profile.
    pub browsers: HashMap<String, Vec<String>>,

    /// The default browser and profile to use for URLs that do not match any regular expressions in
    /// the list of profiles.
    pub default: DefaultProfile,

    /// The specified browser-profile pairs and their corresponding regular expressions.
    #[serde(rename="profiles")]
    pub entries: Vec<Entry>,
}

impl Config {
    /// Read the configuration from the file.
    pub fn from_file(p: &Path) -> Result<Config> {

        let mut buf = String::new();
        let mut f = try!(File::open(p));
        try!(f.read_to_string(&mut buf));

        let mut config = try!(serde_yaml::from_str::<Self>(&buf)
            .map_err(Error::from)
            .and_then(Config::validate));

        for entry in &mut config.entries {
            entry.regex = urls_to_regex(&entry.urls);
        }

        Ok(config)
    }

    #[doc(hidden)]
    /// Validate a parsed configuration.
    ///
    /// This function will ensure that all entries match up with the list of available browsers.
    fn validate(mut self) -> Result<Self> {
        for i in 0..self.entries.len() {
            if !self.browsers.contains_key(&self.entries[i].browser) {
                let browser_profile = self.entries.swap_remove(i);
                return Err(Error::from(ErrorKind::BadEntryError(browser_profile.browser,
                                                                browser_profile.profile)));
            }
        }

        Ok(self)
    }
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::collections::VecDeque;
use std::vec::Vec;

use traits::{Weight, WeightOps};

struct BallotState<W> {
    level: usize,
    prev: usize,
    edge_flow: Box<[W]>,
    count: i32,
}

#[derive(Clone)]
struct CandidateState {
    level: usize,
    prev: usize,
    count: i32,
}

pub fn strength<W, Ballot>(num_seats: usize, ballots: &[(Ballot, W)]) -> W
    where W: Weight,
          for<'w> &'w W: WeightOps<W>,
          Ballot: Borrow<[usize]>
{
    let ballot_candidates = &mut ballots.iter()
        .map(|&(ref cs, _)| Vec::with_capacity(1 + cs.borrow().len()))
        .collect::<Vec<_>>()[..];
    let candidate_ballots = &mut vec![Vec::new(); num_seats][..];
    for (b, &(ref cs, _)) in ballots.iter().enumerate() {
        ballot_candidates[b].push((!0, !0));
        for (i, &c) in cs.borrow().iter().enumerate() {
            ballot_candidates[b].push((c, candidate_ballots[c].len()));
            candidate_ballots[c].push((b, i + 1));
        }
    }
    let ballot_states = &mut ballots.iter()
        .map(|&(ref cs, ref w)| {
            let mut edge_flow = vec![W::zero(); 1 + cs.borrow().len()].into_boxed_slice();
            edge_flow[0] = w.clone();
            BallotState {
                level: !0,
                prev: !0,
                edge_flow: edge_flow,
                count: 0,
            }
        })
        .collect::<Vec<_>>()[..];
    let candidate_states = &mut vec![CandidateState {
        level: !0,
        prev: !0,
        count: 0,
    }; num_seats][..];

    let mut total_flow = W::zero();
    let mut queue = VecDeque::with_capacity(ballots.len());
    let mut found = Vec::with_capacity(num_seats);

    loop {
        for (b, bs) in ballot_states.iter_mut().enumerate() {
            if !bs.edge_flow[0].is_zero() {
                bs.level = 0;
                bs.prev = 0;
                queue.push_back(b);
            }
        }

        'search: loop {
            match queue.pop_front() {
                None => {
                    return total_flow;
                }
                Some(b) => {
                    let level = ballot_states[b].level;
                    for &(c, j) in ballot_candidates[b].iter().skip(1) {
                        if candidate_states[c].prev != !0 {
                            continue;
                        }
                        candidate_states[c].level = level + 1;
                        candidate_states[c].prev = j;
                        found.push(c);
                        if found.len() == num_seats {
                            break 'search;
                        }
                        for &(b1, i1) in &candidate_ballots[c] {
                            if ballot_states[b1].edge_flow[i1].is_zero() ||
                               ballot_states[b1].prev != !0 {
                                continue;
                            }
                            ballot_states[b1].level = level + 2;
                            ballot_states[b1].prev = i1;
                            queue.push_back(b1);
                        }
                    }
                }
            }
        }

        'iterate: loop {
            let mut sunk = 0;
            for &c in found.iter().rev() {
                let j = candidate_states[c].prev;
                let (b, _) = candidate_ballots[c][j];
                let count = candidate_states[c].count + 1;
                ballot_states[b].count += count;
                let i1 = ballot_states[b].prev;
                if i1 == 0 {
                    sunk += count;
                } else {
                    let (c1, _) = ballot_candidates[b][i1];
                    candidate_states[c1].count += count;
                }
            }
            debug_assert_eq!(sunk, num_seats as i32);

            let (flow, flow_times_count, count) = {
                let (flow, flow_times_count, count) = found.iter()
                    .map(|&c| {
                        let j = candidate_states[c].prev;
                        let (b, _) = candidate_ballots[c][j];
                        let flow_times_count = &ballot_states[b].edge_flow[ballot_states[b].prev];
                        let count = ballot_states[b].count;
                        (flow_times_count / W::from_i64(count as i64), flow_times_count, count)
                    })
                    .min()
                    .unwrap();
                (flow, flow_times_count.clone(), count)
            };
            debug_assert!(!flow.is_zero());
            total_flow = total_flow + &flow;

            for &c in &found {
                let j = candidate_states[c].prev;
                let (b, i) = candidate_ballots[c][j];
                {
                    let edge_flow = &mut ballot_states[b].edge_flow[i];
                    if candidate_states[c].count + 1 == count {
                        *edge_flow = &*edge_flow + &flow_times_count;
                    } else {
                        *edge_flow = &*edge_flow +
                                     &flow * W::from_i64(candidate_states[c].count as i64 + 1);
                    }
                }
                if ballot_states[b].count != 0 {
                    let edge_flow = &mut ballot_states[b].edge_flow[ballot_states[b].prev];
                    if ballot_states[b].count == count {
                        *edge_flow = &*edge_flow - &flow_times_count;
                    } else {
                        *edge_flow = &*edge_flow -
                                     &flow * W::from_i64(ballot_states[b].count as i64);
                    }
                    ballot_states[b].count = 0;
                }

                candidate_states[c].count = 0;
            }

            for &c in &found {
                candidate_states[c].prev = (candidate_states[c].prev..candidate_ballots[c].len())
                    .find(|&j| {
                        let (b, _) = candidate_ballots[c][j];
                        let i1 = ballot_states[b].prev;
                        if i1 != !0 {
                            ballot_states[b].prev = (i1..ballot_candidates[b].len())
                                .find(|&i1| {
                                    let (c1, _) = ballot_candidates[b][i1];
                                    !ballot_states[b].edge_flow[i1].is_zero() &&
                                    (i1 == 0 || candidate_states[c1].level < ballot_states[b].level)
                                })
                                .unwrap_or(!0);
                            ballot_states[b].prev != !0 &&
                            ballot_states[b].level < candidate_states[c].level
                        } else {
                            false
                        }
                    })
                    .unwrap_or(!0);

                if candidate_states[c].prev == !0 {
                    break 'iterate;
                }
            }
        }

        for cs in &mut *candidate_states {
            cs.level = !0;
            cs.prev = !0;
            debug_assert_eq!(cs.count, 0);
        }

        for bs in &mut *ballot_states {
            bs.level = !0;
            bs.prev = !0;
            debug_assert_eq!(bs.count, 0);
        }
        queue.clear();
        found.clear();
    }
}

#[cfg(test)]
mod tests {
    use super::strength;
    use gmp::mpq::Mpq;

    const Q: fn(i64) -> Mpq = Mpq::from;

    #[test]
    fn test_strength_1() {
        // Wikipedia
        let ballots: &[(&[usize], Mpq)] =
            &[(&[0], Q(12)), (&[1], Q(0)), (&[0, 1], Q(51)), (&[], Q(27))];
        assert_eq!(strength(2, ballots), Q(63) / Q(2));
    }

    #[test]
    fn test_strength_2() {
        // Wikipedia
        let ballots: &[(&[usize], Mpq)] = &[(&[0], Q(38)), (&[1], Q(27)), (&[0, 1], Q(12))];
        assert_eq!(strength(2, ballots), Q(77) / Q(2));
    }

    #[test]
    fn test_strength_3() {
        // Schulze’s calcul02.pdf
        let ballots: &[(&[usize], Mpq)] = &[(&[0, 1, 2, 3], Q(36_597383) / Q(1_000000)),
                                            (&[0, 1, 2], Q(5_481150) / Q(1_000000)),
                                            (&[0, 1, 3], Q(13_279131) / Q(1_000000)),
                                            (&[0, 1], Q(4_859413) / Q(1_000000)),
                                            (&[0, 2, 3], Q(35_425375) / Q(1_000000)),
                                            (&[0, 2], Q(5_490934) / Q(1_000000)),
                                            (&[0, 3], Q(22_855333) / Q(1_000000)),
                                            (&[0], Q(19_835570) / Q(1_000000)),
                                            (&[1, 2, 3], Q(22_928716) / Q(1_000000)),
                                            (&[1, 2], Q(5_538309) / Q(1_000000)),
                                            (&[1, 3], Q(13_130227) / Q(1_000000)),
                                            (&[1], Q(6_056291) / Q(1_000000)),
                                            (&[2, 3], Q(23_992772) / Q(1_000000)),
                                            (&[2], Q(16_699207) / Q(1_000000)),
                                            (&[3], Q(98_165759) / Q(1_000000)),
                                            (&[], Q(129_664430) / Q(1_000000))];
        assert_eq!(strength(4, ballots), Q(77_389937) / Q(1_000000));
    }
}
<commit_msg>Convert to i64 with i64::from<commit_after>use std::borrow::Borrow;
use std::collections::VecDeque;
use std::vec::Vec;

use traits::{Weight, WeightOps};

struct BallotState<W> {
    level: usize,
    prev: usize,
    edge_flow: Box<[W]>,
    count: i32,
}

#[derive(Clone)]
struct CandidateState {
    level: usize,
    prev: usize,
    count: i32,
}

pub fn strength<W, Ballot>(num_seats: usize, ballots: &[(Ballot, W)]) -> W
    where W: Weight,
          for<'w> &'w W: WeightOps<W>,
          Ballot: Borrow<[usize]>
{
    let ballot_candidates = &mut ballots.iter()
        .map(|&(ref cs, _)| Vec::with_capacity(1 + cs.borrow().len()))
        .collect::<Vec<_>>()[..];
    let candidate_ballots = &mut vec![Vec::new(); num_seats][..];
    for (b, &(ref cs, _)) in ballots.iter().enumerate() {
        ballot_candidates[b].push((!0, !0));
        for (i, &c) in cs.borrow().iter().enumerate() {
            ballot_candidates[b].push((c, candidate_ballots[c].len()));
            candidate_ballots[c].push((b, i + 1));
        }
    }
    let ballot_states = &mut ballots.iter()
        .map(|&(ref cs, ref w)| {
            let mut edge_flow = vec![W::zero(); 1 + cs.borrow().len()].into_boxed_slice();
            edge_flow[0] = w.clone();
            BallotState {
                level: !0,
                prev: !0,
                edge_flow: edge_flow,
                count: 0,
            }
        })
        .collect::<Vec<_>>()[..];
    let candidate_states = &mut vec![CandidateState {
        level: !0,
        prev: !0,
        count: 0,
    }; num_seats][..];

    let mut total_flow = W::zero();
    let mut queue = VecDeque::with_capacity(ballots.len());
    let mut found = Vec::with_capacity(num_seats);

    loop {
        for (b, bs) in ballot_states.iter_mut().enumerate() {
            if !bs.edge_flow[0].is_zero() {
                bs.level = 0;
                bs.prev = 0;
                queue.push_back(b);
            }
        }

        'search: loop {
            match queue.pop_front() {
                None => {
                    return total_flow;
                }
                Some(b) => {
                    let level = ballot_states[b].level;
                    for &(c, j) in ballot_candidates[b].iter().skip(1) {
                        if candidate_states[c].prev != !0 {
                            continue;
                        }
                        candidate_states[c].level = level + 1;
                        candidate_states[c].prev = j;
                        found.push(c);
                        if found.len() == num_seats {
                            break 'search;
                        }
                        for &(b1, i1) in &candidate_ballots[c] {
                            if ballot_states[b1].edge_flow[i1].is_zero() ||
                               ballot_states[b1].prev != !0 {
                                continue;
                            }
                            ballot_states[b1].level = level + 2;
                            ballot_states[b1].prev = i1;
                            queue.push_back(b1);
                        }
                    }
                }
            }
        }

        'iterate: loop {
            let mut sunk = 0;
            for &c in found.iter().rev() {
                let j = candidate_states[c].prev;
                let (b, _) = candidate_ballots[c][j];
                let count = candidate_states[c].count + 1;
                ballot_states[b].count += count;
                let i1 = ballot_states[b].prev;
                if i1 == 0 {
                    sunk += count;
                } else {
                    let (c1, _) = ballot_candidates[b][i1];
                    candidate_states[c1].count += count;
                }
            }
            debug_assert_eq!(sunk, num_seats as i32);

            let (flow, flow_times_count, count) = {
                let (flow, flow_times_count, count) = found.iter()
                    .map(|&c| {
                        let j = candidate_states[c].prev;
                        let (b, _) = candidate_ballots[c][j];
                        let flow_times_count = &ballot_states[b].edge_flow[ballot_states[b].prev];
                        let count = ballot_states[b].count;
                        (flow_times_count / W::from_i64(i64::from(count)), flow_times_count, count)
                    })
                    .min()
                    .unwrap();
                (flow, flow_times_count.clone(), count)
            };
            debug_assert!(!flow.is_zero());
            total_flow = total_flow + &flow;

            for &c in &found {
                let j = candidate_states[c].prev;
                let (b, i) = candidate_ballots[c][j];
                {
                    let edge_flow = &mut ballot_states[b].edge_flow[i];
                    if candidate_states[c].count + 1 == count {
                        *edge_flow = &*edge_flow + &flow_times_count;
                    } else {
                        *edge_flow = &*edge_flow +
                                     &flow * W::from_i64(i64::from(candidate_states[c].count) + 1);
                    }
                }
                if ballot_states[b].count != 0 {
                    let edge_flow = &mut ballot_states[b].edge_flow[ballot_states[b].prev];
                    if ballot_states[b].count == count {
                        *edge_flow = &*edge_flow - &flow_times_count;
                    } else {
                        *edge_flow = &*edge_flow -
                                     &flow * W::from_i64(i64::from(ballot_states[b].count));
                    }
                    ballot_states[b].count = 0;
                }

                candidate_states[c].count = 0;
            }

            for &c in &found {
                candidate_states[c].prev = (candidate_states[c].prev..candidate_ballots[c].len())
                    .find(|&j| {
                        let (b, _) = candidate_ballots[c][j];
                        let i1 = ballot_states[b].prev;
                        if i1 != !0 {
                            ballot_states[b].prev = (i1..ballot_candidates[b].len())
                                .find(|&i1| {
                                    let (c1, _) = ballot_candidates[b][i1];
                                    !ballot_states[b].edge_flow[i1].is_zero() &&
                                    (i1 == 0 || candidate_states[c1].level < ballot_states[b].level)
                                })
                                .unwrap_or(!0);
                            ballot_states[b].prev != !0 &&
                            ballot_states[b].level < candidate_states[c].level
                        } else {
                            false
                        }
                    })
                    .unwrap_or(!0);

                if candidate_states[c].prev == !0 {
                    break 'iterate;
                }
            }
        }

        for cs in &mut *candidate_states {
            cs.level = !0;
            cs.prev = !0;
            debug_assert_eq!(cs.count, 0);
        }

        for bs in &mut *ballot_states {
            bs.level = !0;
            bs.prev = !0;
            debug_assert_eq!(bs.count, 0);
        }
        queue.clear();
        found.clear();
    }
}

#[cfg(test)]
mod tests {
    use super::strength;
    use gmp::mpq::Mpq;

    const Q: fn(i64) -> Mpq = Mpq::from;

    #[test]
    fn test_strength_1() {
        // Wikipedia
        let ballots: &[(&[usize], Mpq)] =
            &[(&[0], Q(12)), (&[1], Q(0)), (&[0, 1], Q(51)), (&[], Q(27))];
        assert_eq!(strength(2, ballots), Q(63) / Q(2));
    }

    #[test]
    fn test_strength_2() {
        // Wikipedia
        let ballots: &[(&[usize], Mpq)] = &[(&[0], Q(38)), (&[1], Q(27)), (&[0, 1], Q(12))];
        assert_eq!(strength(2, ballots), Q(77) / Q(2));
    }

    #[test]
    fn test_strength_3() {
        // Schulze’s calcul02.pdf
        let ballots: &[(&[usize], Mpq)] = &[(&[0, 1, 2, 3], Q(36_597383) / Q(1_000000)),
                                            (&[0, 1, 2], Q(5_481150) / Q(1_000000)),
                                            (&[0, 1, 3], Q(13_279131) / Q(1_000000)),
                                            (&[0, 1], Q(4_859413) / Q(1_000000)),
                                            (&[0, 2, 3], Q(35_425375) / Q(1_000000)),
                                            (&[0, 2], Q(5_490934) / Q(1_000000)),
                                            (&[0, 3], Q(22_855333) / Q(1_000000)),
                                            (&[0], Q(19_835570) / Q(1_000000)),
                                            (&[1, 2, 3], Q(22_928716) / Q(1_000000)),
                                            (&[1, 2], Q(5_538309) / Q(1_000000)),
                                            (&[1, 3], Q(13_130227) / Q(1_000000)),
                                            (&[1], Q(6_056291) / Q(1_000000)),
                                            (&[2, 3], Q(23_992772) / Q(1_000000)),
                                            (&[2], Q(16_699207) / Q(1_000000)),
                                            (&[3], Q(98_165759) / Q(1_000000)),
                                            (&[], Q(129_664430) / Q(1_000000))];
        assert_eq!(strength(4, ballots), Q(77_389937) / Q(1_000000));
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLInputElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLInputElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::{ErrorResult, Fallible};
use dom::document::Document;
use dom::element::HTMLInputElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLInputElement {
    pub htmlelement: HTMLElement,
}

impl HTMLInputElementDerived for EventTarget {
    fn is_htmlinputelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLInputElementTypeId))
    }
}

impl HTMLInputElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLInputElement {
        HTMLInputElement {
            htmlelement: HTMLElement::new_inherited(HTMLInputElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLInputElement> {
        let element = HTMLInputElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLInputElementBinding::Wrap)
    }
}

pub trait HTMLInputElementMethods {
    fn Accept(&self) -> DOMString;
    fn SetAccept(&mut self, _accept: DOMString) -> ErrorResult;
    fn Alt(&self) -> DOMString;
    fn SetAlt(&mut self, _alt: DOMString) -> ErrorResult;
    fn Autocomplete(&self) -> DOMString;
    fn SetAutocomplete(&mut self, _autocomple: DOMString) -> ErrorResult;
    fn Autofocus(&self) -> bool;
    fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult;
    fn DefaultChecked(&self) -> bool;
    fn SetDefaultChecked(&mut self, _default_checked: bool) -> ErrorResult;
    fn Checked(&self) -> bool;
    fn SetChecked(&mut self, _checked: bool);
    fn Disabled(&self) -> bool;
    fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult;
    fn FormAction(&self) -> DOMString;
    fn SetFormAction(&mut self, _form_action: DOMString) -> ErrorResult;
    fn FormEnctype(&self) -> DOMString;
    fn SetFormEnctype(&mut self, _form_enctype: DOMString) -> ErrorResult;
    fn FormMethod(&self) -> DOMString;
    fn SetFormMethod(&mut self, _form_method: DOMString) -> ErrorResult;
    fn FormNoValidate(&self) -> bool;
    fn SetFormNoValidate(&mut self, _form_no_validate: bool) -> ErrorResult;
    fn FormTarget(&self) -> DOMString;
    fn SetFormTarget(&mut self, _form_target: DOMString) -> ErrorResult;
    fn Height(&self) -> u32;
    fn SetHeight(&mut self, _height: u32) -> ErrorResult;
    fn Indeterminate(&self) -> bool;
    fn SetIndeterminate(&mut self, _indeterminate: bool);
    fn InputMode(&self) -> DOMString;
    fn SetInputMode(&mut self, _input_mode: DOMString) -> ErrorResult;
    fn Max(&self) -> DOMString;
    fn SetMax(&mut self, _max: DOMString) -> ErrorResult;
    fn MaxLength(&self) -> i32;
    fn SetMaxLength(&mut self, _max_length: i32) -> ErrorResult;
    fn Min(&self) -> DOMString;
    fn SetMin(&mut self, _min: DOMString) -> ErrorResult;
    fn Multiple(&self) -> bool;
    fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult;
    fn Name(&self) -> DOMString;
    fn SetName(&mut self, _name: DOMString) -> ErrorResult;
    fn Pattern(&self) -> DOMString;
    fn SetPattern(&mut self, _pattern: DOMString) -> ErrorResult;
    fn Placeholder(&self) -> DOMString;
    fn SetPlaceholder(&mut self, _placeholder: DOMString) -> ErrorResult;
    fn ReadOnly(&self) -> bool;
    fn SetReadOnly(&mut self, _read_only: bool) -> ErrorResult;
    fn Required(&self) -> bool;
    fn SetRequired(&mut self, _required: bool) -> ErrorResult;
    fn Size(&self) -> u32;
    fn SetSize(&mut self, _size: u32) -> ErrorResult;
    fn Src(&self) -> DOMString;
    fn SetSrc(&mut self, _src: DOMString) -> ErrorResult;
    fn Step(&self) -> DOMString;
    fn SetStep(&mut self, _step: DOMString) -> ErrorResult;
    fn Type(&self) -> DOMString;
    fn SetType(&mut self, _type: DOMString) -> ErrorResult;
    fn DefaultValue(&self) -> DOMString;
    fn SetDefaultValue(&mut self, _default_value: DOMString) -> ErrorResult;
    fn Value(&self) -> DOMString;
    fn SetValue(&mut self, _value: DOMString) -> ErrorResult;
    fn Width(&self) -> u32;
    fn SetWidth(&mut self, _width: u32);
    fn WillValidate(&self) -> bool;
    fn SetWillValidate(&self, _will_validate: bool);
    fn GetValidationMessage(&self) -> Fallible<DOMString>;
    fn CheckValidity(&self) -> bool;
    fn SetCustomValidity(&self, _error: DOMString);
    fn Select(&self);
    fn GetSelectionStart(&self) -> Fallible<i32>;
    fn SetSelectionStart(&mut self, _selection_start: i32) -> ErrorResult;
    fn GetSelectionEnd(&self) -> Fallible<i32>;
    fn SetSelectionEnd(&mut self, _selection_end: i32) -> ErrorResult;
    fn GetSelectionDirection(&self) -> Fallible<DOMString>;
    fn SetSelectionDirection(&mut self, _selection_direction: DOMString) -> ErrorResult;
    fn Align(&self) -> DOMString;
    fn SetAlign(&mut self, _align: DOMString) -> ErrorResult;
    fn UseMap(&self) -> DOMString;
    fn SetUseMap(&mut self, _align: DOMString) -> ErrorResult;
}

impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
    fn Accept(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAccept(&mut self, _accept: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Alt(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAlt(&mut self, _alt: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Autocomplete(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAutocomplete(&mut self, _autocomple: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Autofocus(&self) -> bool {
        false
    }

    fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult {
        Ok(())
    }

    fn DefaultChecked(&self) -> bool {
        false
    }

    fn SetDefaultChecked(&mut self, _default_checked: bool) -> ErrorResult {
        Ok(())
    }

    fn Checked(&self) -> bool {
        false
    }

    fn SetChecked(&mut self, _checked: bool) {
    }

    fn Disabled(&self) -> bool {
        false
    }

    fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult {
        Ok(())
    }

    fn FormAction(&self) -> DOMString {
        "".to_owned()
    }

    fn SetFormAction(&mut self, _form_action: DOMString) -> ErrorResult {
        Ok(())
    }

    fn FormEnctype(&self) -> DOMString {
        "".to_owned()
    }

    fn SetFormEnctype(&mut self, _form_enctype: DOMString) -> ErrorResult {
        Ok(())
    }

    fn FormMethod(&self) -> DOMString {
        "".to_owned()
    }

    fn SetFormMethod(&mut self, _form_method: DOMString) -> ErrorResult {
        Ok(())
    }

    fn FormNoValidate(&self) -> bool {
        false
    }

    fn SetFormNoValidate(&mut self, _form_no_validate: bool) -> ErrorResult {
        Ok(())
    }

    fn FormTarget(&self) -> DOMString {
        "".to_owned()
    }

    fn SetFormTarget(&mut self, _form_target: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Height(&self) -> u32 {
        0
    }

    fn SetHeight(&mut self, _height: u32) -> ErrorResult {
        Ok(())
    }

    fn Indeterminate(&self) -> bool {
        false
    }

    fn SetIndeterminate(&mut self, _indeterminate: bool) {
    }

    fn InputMode(&self) -> DOMString {
        "".to_owned()
    }

    fn SetInputMode(&mut self, _input_mode: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Max(&self) -> DOMString {
        "".to_owned()
    }

    fn SetMax(&mut self, _max: DOMString) -> ErrorResult {
        Ok(())
    }

    fn MaxLength(&self) -> i32 {
        0
    }

    fn SetMaxLength(&mut self, _max_length: i32) -> ErrorResult {
        Ok(())
    }

    fn Min(&self) -> DOMString {
        "".to_owned()
    }

    fn SetMin(&mut self, _min: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Multiple(&self) -> bool {
        false
    }

    fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult {
        Ok(())
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&mut self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Pattern(&self) -> DOMString {
        "".to_owned()
    }

    fn SetPattern(&mut self, _pattern: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Placeholder(&self) -> DOMString {
        "".to_owned()
    }

    fn SetPlaceholder(&mut self, _placeholder: DOMString) -> ErrorResult {
        Ok(())
    }

    fn ReadOnly(&self) -> bool {
        false
    }

    fn SetReadOnly(&mut self, _read_only: bool) -> ErrorResult {
        Ok(())
    }

    fn Required(&self) -> bool {
        false
    }

    fn SetRequired(&mut self, _required: bool) -> ErrorResult {
        Ok(())
    }

    fn Size(&self) -> u32 {
        0
    }

    fn SetSize(&mut self, _size: u32) -> ErrorResult {
        Ok(())
    }

    fn Src(&self) -> DOMString {
        "".to_owned()
    }

    fn SetSrc(&mut self, _src: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Step(&self) -> DOMString {
        "".to_owned()
    }

    fn SetStep(&mut self, _step: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Type(&self) -> DOMString {
        "".to_owned()
    }

    fn SetType(&mut self, _type: DOMString) -> ErrorResult {
        Ok(())
    }

    fn DefaultValue(&self) -> DOMString {
        "".to_owned()
    }

    fn SetDefaultValue(&mut self, _default_value: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Value(&self) -> DOMString {
        "".to_owned()
    }

    fn SetValue(&mut self, _value: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Width(&self) -> u32 {
        0
    }

    fn SetWidth(&mut self, _width: u32) {
    }

    fn WillValidate(&self) -> bool {
        false
    }

    fn SetWillValidate(&self, _will_validate: bool) {
    }

    fn GetValidationMessage(&self) -> Fallible<DOMString> {
        Ok("".to_owned())
    }

    fn CheckValidity(&self) -> bool {
        false
    }

    fn SetCustomValidity(&self, _error: DOMString) {
    }

    fn Select(&self) {
    }

    fn GetSelectionStart(&self) -> Fallible<i32> {
        Ok(0)
    }

    fn SetSelectionStart(&mut self, _selection_start: i32) -> ErrorResult {
        Ok(())
    }

    fn GetSelectionEnd(&self) -> Fallible<i32> {
        Ok(0)
    }

    fn SetSelectionEnd(&mut self, _selection_end: i32) -> ErrorResult {
        Ok(())
    }

    fn GetSelectionDirection(&self) -> Fallible<DOMString> {
        Ok("".to_owned())
    }

    fn SetSelectionDirection(&mut self, _selection_direction: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Align(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAlign(&mut self, _align: DOMString) -> ErrorResult {
        Ok(())
    }

    fn UseMap(&self) -> DOMString {
        "".to_owned()
    }

    fn SetUseMap(&mut self, _align: DOMString) -> ErrorResult {
        Ok(())
    }
}
<commit_msg>Remove needless '&mut self' from HTMLInputElementMethods.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLInputElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLInputElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::{ErrorResult, Fallible};
use dom::document::Document;
use dom::element::HTMLInputElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLInputElement {
    pub htmlelement: HTMLElement,
}

impl HTMLInputElementDerived for EventTarget {
    fn is_htmlinputelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLInputElementTypeId))
    }
}

impl HTMLInputElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLInputElement {
        HTMLInputElement {
            htmlelement: HTMLElement::new_inherited(HTMLInputElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLInputElement> {
        let element = HTMLInputElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLInputElementBinding::Wrap)
    }
}

pub trait HTMLInputElementMethods {
    fn Accept(&self) -> DOMString;
    fn SetAccept(&self, _accept: DOMString) -> ErrorResult;
    fn Alt(&self) -> DOMString;
    fn SetAlt(&self, _alt: DOMString) -> ErrorResult;
    fn Autocomplete(&self) -> DOMString;
    fn SetAutocomplete(&self, _autocomple: DOMString) -> ErrorResult;
    fn Autofocus(&self) -> bool;
    fn SetAutofocus(&self, _autofocus: bool) -> ErrorResult;
    fn DefaultChecked(&self) -> bool;
    fn SetDefaultChecked(&self, _default_checked: bool) -> ErrorResult;
    fn Checked(&self) -> bool;
    fn SetChecked(&self, _checked: bool);
    fn Disabled(&self) -> bool;
    fn SetDisabled(&self, _disabled: bool) -> ErrorResult;
    fn FormAction(&self) -> DOMString;
    fn SetFormAction(&self, _form_action: DOMString) -> ErrorResult;
    fn FormEnctype(&self) -> DOMString;
    fn SetFormEnctype(&self, _form_enctype: DOMString) -> ErrorResult;
    fn FormMethod(&self) -> DOMString;
    fn SetFormMethod(&self, _form_method: DOMString) -> ErrorResult;
    fn FormNoValidate(&self) -> bool;
    fn SetFormNoValidate(&self, _form_no_validate: bool) -> ErrorResult;
    fn FormTarget(&self) -> DOMString;
    fn SetFormTarget(&self, _form_target: DOMString) -> ErrorResult;
    fn Height(&self) -> u32;
    fn SetHeight(&self, _height: u32) -> ErrorResult;
    fn Indeterminate(&self) -> bool;
    fn SetIndeterminate(&self, _indeterminate: bool);
    fn InputMode(&self) -> DOMString;
    fn SetInputMode(&self, _input_mode: DOMString) -> ErrorResult;
    fn Max(&self) -> DOMString;
    fn SetMax(&self, _max: DOMString) -> ErrorResult;
    fn MaxLength(&self) -> i32;
    fn SetMaxLength(&self, _max_length: i32) -> ErrorResult;
    fn Min(&self) -> DOMString;
    fn SetMin(&self, _min: DOMString) -> ErrorResult;
    fn Multiple(&self) -> bool;
    fn SetMultiple(&self, _multiple: bool) -> ErrorResult;
    fn Name(&self) -> DOMString;
    fn SetName(&self, _name: DOMString) -> ErrorResult;
    fn Pattern(&self) -> DOMString;
    fn SetPattern(&self, _pattern: DOMString) -> ErrorResult;
    fn Placeholder(&self) -> DOMString;
    fn SetPlaceholder(&self, _placeholder: DOMString) -> ErrorResult;
    fn ReadOnly(&self) -> bool;
    fn SetReadOnly(&self, _read_only: bool) -> ErrorResult;
    fn Required(&self) -> bool;
    fn SetRequired(&self, _required: bool) -> ErrorResult;
    fn Size(&self) -> u32;
    fn SetSize(&self, _size: u32) -> ErrorResult;
    fn Src(&self) -> DOMString;
    fn SetSrc(&self, _src: DOMString) -> ErrorResult;
    fn Step(&self) -> DOMString;
    fn SetStep(&self, _step: DOMString) -> ErrorResult;
    fn Type(&self) -> DOMString;
    fn SetType(&self, _type: DOMString) -> ErrorResult;
    fn DefaultValue(&self) -> DOMString;
    fn SetDefaultValue(&self, _default_value: DOMString) -> ErrorResult;
    fn Value(&self) -> DOMString;
    fn SetValue(&self, _value: DOMString) -> ErrorResult;
    fn Width(&self) -> u32;
    fn SetWidth(&self, _width: u32);
    fn WillValidate(&self) -> bool;
    fn SetWillValidate(&self, _will_validate: bool);
    fn GetValidationMessage(&self) -> Fallible<DOMString>;
    fn CheckValidity(&self) -> bool;
    fn SetCustomValidity(&self, _error: DOMString);
    fn Select(&self);
    fn GetSelectionStart(&self) -> Fallible<i32>;
    fn SetSelectionStart(&self, _selection_start: i32) -> ErrorResult;
    fn GetSelectionEnd(&self) -> Fallible<i32>;
    fn SetSelectionEnd(&self, _selection_end: i32) -> ErrorResult;
    fn GetSelectionDirection(&self) -> Fallible<DOMString>;
    fn SetSelectionDirection(&self, _selection_direction: DOMString) -> ErrorResult;
    fn Align(&self) -> DOMString;
    fn SetAlign(&self, _align: DOMString) -> ErrorResult;
    fn UseMap(&self) -> DOMString;
    fn SetUseMap(&self, _align: DOMString) -> ErrorResult;
}

impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
    fn Accept(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAccept(&self, _accept: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Alt(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAlt(&self, _alt: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Autocomplete(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAutocomplete(&self, _autocomple: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Autofocus(&self) -> bool {
        false
    }

    fn SetAutofocus(&self, _autofocus: bool) -> ErrorResult {
        Ok(())
    }

    fn DefaultChecked(&self) -> bool {
        false
    }

    fn SetDefaultChecked(&self, _default_checked: bool) -> ErrorResult {
        Ok(())
    }

    fn Checked(&self) -> bool {
        false
    }

    fn SetChecked(&self, _checked: bool) {
    }

    fn Disabled(&self) -> bool {
        false
    }

    fn SetDisabled(&self, _disabled: bool) -> ErrorResult {
        Ok(())
    }

    fn FormAction(&self) -> DOMString {
        "".to_owned()
    }

    fn SetFormAction(&self, _form_action: DOMString) -> ErrorResult {
        Ok(())
    }

    fn FormEnctype(&self) -> DOMString {
        "".to_owned()
    }

    fn SetFormEnctype(&self, _form_enctype: DOMString) -> ErrorResult {
        Ok(())
    }

    fn FormMethod(&self) -> DOMString {
        "".to_owned()
    }

    fn SetFormMethod(&self, _form_method: DOMString) -> ErrorResult {
        Ok(())
    }

    fn FormNoValidate(&self) -> bool {
        false
    }

    fn SetFormNoValidate(&self, _form_no_validate: bool) -> ErrorResult {
        Ok(())
    }

    fn FormTarget(&self) -> DOMString {
        "".to_owned()
    }

    fn SetFormTarget(&self, _form_target: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Height(&self) -> u32 {
        0
    }

    fn SetHeight(&self, _height: u32) -> ErrorResult {
        Ok(())
    }

    fn Indeterminate(&self) -> bool {
        false
    }

    fn SetIndeterminate(&self, _indeterminate: bool) {
    }

    fn InputMode(&self) -> DOMString {
        "".to_owned()
    }

    fn SetInputMode(&self, _input_mode: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Max(&self) -> DOMString {
        "".to_owned()
    }

    fn SetMax(&self, _max: DOMString) -> ErrorResult {
        Ok(())
    }

    fn MaxLength(&self) -> i32 {
        0
    }

    fn SetMaxLength(&self, _max_length: i32) -> ErrorResult {
        Ok(())
    }

    fn Min(&self) -> DOMString {
        "".to_owned()
    }

    fn SetMin(&self, _min: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Multiple(&self) -> bool {
        false
    }

    fn SetMultiple(&self, _multiple: bool) -> ErrorResult {
        Ok(())
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Pattern(&self) -> DOMString {
        "".to_owned()
    }

    fn SetPattern(&self, _pattern: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Placeholder(&self) -> DOMString {
        "".to_owned()
    }

    fn SetPlaceholder(&self, _placeholder: DOMString) -> ErrorResult {
        Ok(())
    }

    fn ReadOnly(&self) -> bool {
        false
    }

    fn SetReadOnly(&self, _read_only: bool) -> ErrorResult {
        Ok(())
    }

    fn Required(&self) -> bool {
        false
    }

    fn SetRequired(&self, _required: bool) -> ErrorResult {
        Ok(())
    }

    fn Size(&self) -> u32 {
        0
    }

    fn SetSize(&self, _size: u32) -> ErrorResult {
        Ok(())
    }

    fn Src(&self) -> DOMString {
        "".to_owned()
    }

    fn SetSrc(&self, _src: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Step(&self) -> DOMString {
        "".to_owned()
    }

    fn SetStep(&self, _step: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Type(&self) -> DOMString {
        "".to_owned()
    }

    fn SetType(&self, _type: DOMString) -> ErrorResult {
        Ok(())
    }

    fn DefaultValue(&self) -> DOMString {
        "".to_owned()
    }

    fn SetDefaultValue(&self, _default_value: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Value(&self) -> DOMString {
        "".to_owned()
    }

    fn SetValue(&self, _value: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Width(&self) -> u32 {
        0
    }

    fn SetWidth(&self, _width: u32) {
    }

    fn WillValidate(&self) -> bool {
        false
    }

    fn SetWillValidate(&self, _will_validate: bool) {
    }

    fn GetValidationMessage(&self) -> Fallible<DOMString> {
        Ok("".to_owned())
    }

    fn CheckValidity(&self) -> bool {
        false
    }

    fn SetCustomValidity(&self, _error: DOMString) {
    }

    fn Select(&self) {
    }

    fn GetSelectionStart(&self) -> Fallible<i32> {
        Ok(0)
    }

    fn SetSelectionStart(&self, _selection_start: i32) -> ErrorResult {
        Ok(())
    }

    fn GetSelectionEnd(&self) -> Fallible<i32> {
        Ok(0)
    }

    fn SetSelectionEnd(&self, _selection_end: i32) -> ErrorResult {
        Ok(())
    }

    fn GetSelectionDirection(&self) -> Fallible<DOMString> {
        Ok("".to_owned())
    }

    fn SetSelectionDirection(&self, _selection_direction: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Align(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAlign(&self, _align: DOMString) -> ErrorResult {
        Ok(())
    }

    fn UseMap(&self) -> DOMString {
        "".to_owned()
    }

    fn SetUseMap(&self, _align: DOMString) -> ErrorResult {
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::fmt::{Show,Formatter};
use std::fmt;
use std::hash::Hasher;
use std::hash::sip::SipHasher;
use std::str;

use core::source::{Source, SourceId, GitKind, Location, Remote, Local};
use core::{Package,PackageId,Summary};
use util::{CargoResult, Config, to_hex};
use sources::PathSource;
use sources::git::utils::{GitReference,GitRemote,Master,Other};

/* TODO: Refactor GitSource to delegate to a PathSource
 */
pub struct GitSource<'a, 'b> {
    remote: GitRemote,
    reference: GitReference,
    db_path: Path,
    checkout_path: Path,
    path_source: PathSource,
    config: &'a mut Config<'b>
}

impl<'a, 'b> GitSource<'a, 'b> {
    pub fn new<'a, 'b>(source_id: &SourceId, config: &'a mut Config<'b>) -> GitSource<'a, 'b> {
        assert!(source_id.is_git(), "id is not git, id={}", source_id);

        let reference = match source_id.kind {
            GitKind(ref reference) => reference,
            _ => fail!("Not a git source; id={}", source_id)
        };

        let remote = GitRemote::new(source_id.get_location());
        let ident = ident(source_id.get_location());

        let db_path = config.git_db_path()
            .join(ident.as_slice());

        let checkout_path = config.git_checkout_path()
            .join(ident.as_slice()).join(reference.as_slice());

        let path_source = PathSource::new(&checkout_path, source_id);

        GitSource {
            remote: remote,
            reference: GitReference::for_str(reference.as_slice()),
            db_path: db_path,
            checkout_path: checkout_path,
            path_source: path_source,
            config: config
        }
    }

    pub fn get_namespace<'a>(&'a self) -> &'a Location {
        self.remote.get_location()
    }
}

fn ident(location: &Location) -> String {
    let hasher = SipHasher::new_with_keys(0,0);

    // FIXME: this really should be able to not use to_str() everywhere, but the
    //        compiler seems to currently ask for static lifetimes spuriously.
    //        Perhaps related to rust-lang/rust#15144
    let ident = match *location {
        Local(ref path) => {
            let last = path.components().last().unwrap();
            str::from_utf8(last).unwrap().to_str()
        }
        Remote(ref url) => {
            let path = canonicalize_url(url.path.as_slice());
            path.as_slice().split('/').last().unwrap().to_str()
        }
    };

    let ident = if ident.as_slice() == "" {
        "_empty".to_string()
    } else {
        ident
    };

    let location = canonicalize_url(location.to_str().as_slice());

    format!("{}-{}", ident, to_hex(hasher.hash(&location.as_slice())))
}

fn strip_trailing_slash<'a>(path: &'a str) -> &'a str {
    // Remove the trailing '/' so that 'split' doesn't give us
    // an empty string, making '../foo/' and '../foo' both
    // result in the name 'foo' (#84)
    if path.as_bytes().last() != Some(&('/' as u8)) {
        path.clone()
    } else {
        path.slice(0, path.len() - 1)
    }
}

// Some hacks and heuristics for making equivalent URLs hash the same
pub fn canonicalize_url(url: &str) -> String {
    let url = strip_trailing_slash(url);

    // HACKHACK: For github URL's specifically just lowercase
    // everything.  GitHub traits both the same, but they hash
    // differently, and we're gonna be hashing them. This wants a more
    // general solution, and also we're almost certainly not using the
    // same case conversion rules that GitHub does. (#84)

    let lower_url = url.chars().map(|c|c.to_lowercase()).collect::<String>();
    let url = if lower_url.as_slice().contains("github.com") {
        if lower_url.as_slice().starts_with("https") {
            lower_url
        } else {
            let pos = lower_url.as_slice().find_str("://").unwrap_or(0);
            "https".to_string() + lower_url.as_slice().slice_from(pos)
        }
    } else {
        url.to_string()
    };

    // Repos generally can be accessed with or w/o '.git'
    let url = if !url.as_slice().ends_with(".git") {
        url
    } else {
        url.as_slice().slice(0, url.len() - 4).to_string()
    };

    return url;
}

impl<'a, 'b> Show for GitSource<'a, 'b> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        try!(write!(f, "git repo at {}", self.remote.get_location()));

        match self.reference {
            Master => Ok(()),
            Other(ref reference) => write!(f, " ({})", reference)
        }
    }
}

impl<'a, 'b> Source for GitSource<'a, 'b> {
    fn update(&mut self) -> CargoResult<()> {
        let should_update = self.config.update_remotes() || {
            !self.remote.has_ref(&self.db_path, self.reference.as_slice()).is_ok()
        };

        let repo = if should_update {
            try!(self.config.shell().status("Updating",
                format!("git repository `{}`", self.remote.get_location())));

            log!(5, "updating git source `{}`", self.remote);
            try!(self.remote.checkout(&self.db_path))
        } else {
            self.remote.db_at(&self.db_path)
        };

        try!(repo.copy_to(self.reference.as_slice(), &self.checkout_path));

        self.path_source.update()
    }

    fn list(&self) -> CargoResult<Vec<Summary>> {
        self.path_source.list()
    }

    fn download(&self, _: &[PackageId]) -> CargoResult<()> {
        // TODO: assert! that the PackageId is contained by the source
        Ok(())
    }

    fn get(&self, ids: &[PackageId]) -> CargoResult<Vec<Package>> {
        log!(5, "getting packages for package ids `{}` from `{}`", ids, self.remote);
        self.path_source.get(ids)
    }

    fn fingerprint(&self, _pkg: &Package) -> CargoResult<String> {
        let db = self.remote.db_at(&self.db_path);
        db.rev_for(self.reference.as_slice())
    }
}

#[cfg(test)]
mod test {
    use url;
    use url::Url;
    use core::source::Remote;
    use super::ident;

    #[test]
    pub fn test_url_to_path_ident_with_path() {
        let ident = ident(&Remote(url("https://github.com/carlhuda/cargo")));
        assert_eq!(ident.as_slice(), "cargo-0eed735c8ffd7c88");
    }

    #[test]
    pub fn test_url_to_path_ident_without_path() {
        let ident = ident(&Remote(url("https://github.com")));
        assert_eq!(ident.as_slice(), "_empty-fc065c9b6b16fc00");
    }

    #[test]
    fn test_canonicalize_idents_by_stripping_trailing_url_slash() {
        let ident1 = ident(&Remote(url("https://github.com/PistonDevelopers/piston/")));
        let ident2 = ident(&Remote(url("https://github.com/PistonDevelopers/piston")));
        assert_eq!(ident1, ident2);
    }

    #[test]
    fn test_canonicalize_idents_by_lowercasing_github_urls() {
        let ident1 = ident(&Remote(url("https://github.com/PistonDevelopers/piston")));
        let ident2 = ident(&Remote(url("https://github.com/pistondevelopers/piston")));
        assert_eq!(ident1, ident2);
    }

    #[test]
    fn test_canonicalize_idents_by_stripping_dot_git() {
        let ident1 = ident(&Remote(url("https://github.com/PistonDevelopers/piston")));
        let ident2 = ident(&Remote(url("https://github.com/PistonDevelopers/piston.git")));
        assert_eq!(ident1, ident2);
    }

    #[test]
    fn test_canonicalize_idents_different_protocls() {
        let ident1 = ident(&Remote(url("https://github.com/PistonDevelopers/piston")));
        let ident2 = ident(&Remote(url("git://github.com/PistonDevelopers/piston")));
        assert_eq!(ident1, ident2);
    }

    fn url(s: &str) -> Url {
        url::from_str(s).unwrap()
    }
}
<commit_msg>url.path is now a Path, not a String<commit_after>use std::fmt::{Show,Formatter};
use std::fmt;
use std::hash::Hasher;
use std::hash::sip::SipHasher;
use std::str;

use core::source::{Source, SourceId, GitKind, Location, Remote, Local};
use core::{Package,PackageId,Summary};
use util::{CargoResult, Config, to_hex};
use sources::PathSource;
use sources::git::utils::{GitReference,GitRemote,Master,Other};

/* TODO: Refactor GitSource to delegate to a PathSource
 */
pub struct GitSource<'a, 'b> {
    remote: GitRemote,
    reference: GitReference,
    db_path: Path,
    checkout_path: Path,
    path_source: PathSource,
    config: &'a mut Config<'b>
}

impl<'a, 'b> GitSource<'a, 'b> {
    pub fn new<'a, 'b>(source_id: &SourceId, config: &'a mut Config<'b>) -> GitSource<'a, 'b> {
        assert!(source_id.is_git(), "id is not git, id={}", source_id);

        let reference = match source_id.kind {
            GitKind(ref reference) => reference,
            _ => fail!("Not a git source; id={}", source_id)
        };

        let remote = GitRemote::new(source_id.get_location());
        let ident = ident(source_id.get_location());

        let db_path = config.git_db_path()
            .join(ident.as_slice());

        let checkout_path = config.git_checkout_path()
            .join(ident.as_slice()).join(reference.as_slice());

        let path_source = PathSource::new(&checkout_path, source_id);

        GitSource {
            remote: remote,
            reference: GitReference::for_str(reference.as_slice()),
            db_path: db_path,
            checkout_path: checkout_path,
            path_source: path_source,
            config: config
        }
    }

    pub fn get_namespace<'a>(&'a self) -> &'a Location {
        self.remote.get_location()
    }
}

fn ident(location: &Location) -> String {
    let hasher = SipHasher::new_with_keys(0,0);

    // FIXME: this really should be able to not use to_str() everywhere, but the
    //        compiler seems to currently ask for static lifetimes spuriously.
    //        Perhaps related to rust-lang/rust#15144
    let ident = match *location {
        Local(ref path) => {
            let last = path.components().last().unwrap();
            str::from_utf8(last).unwrap().to_str()
        }
        Remote(ref url) => {
            let path = canonicalize_url(url.path.path.as_slice());
            path.as_slice().split('/').last().unwrap().to_str()
        }
    };

    let ident = if ident.as_slice() == "" {
        "_empty".to_string()
    } else {
        ident
    };

    let location = canonicalize_url(location.to_str().as_slice());

    format!("{}-{}", ident, to_hex(hasher.hash(&location.as_slice())))
}

fn strip_trailing_slash<'a>(path: &'a str) -> &'a str {
    // Remove the trailing '/' so that 'split' doesn't give us
    // an empty string, making '../foo/' and '../foo' both
    // result in the name 'foo' (#84)
    if path.as_bytes().last() != Some(&('/' as u8)) {
        path.clone()
    } else {
        path.slice(0, path.len() - 1)
    }
}

// Some hacks and heuristics for making equivalent URLs hash the same
pub fn canonicalize_url(url: &str) -> String {
    let url = strip_trailing_slash(url);

    // HACKHACK: For github URL's specifically just lowercase
    // everything.  GitHub traits both the same, but they hash
    // differently, and we're gonna be hashing them. This wants a more
    // general solution, and also we're almost certainly not using the
    // same case conversion rules that GitHub does. (#84)

    let lower_url = url.chars().map(|c|c.to_lowercase()).collect::<String>();
    let url = if lower_url.as_slice().contains("github.com") {
        if lower_url.as_slice().starts_with("https") {
            lower_url
        } else {
            let pos = lower_url.as_slice().find_str("://").unwrap_or(0);
            "https".to_string() + lower_url.as_slice().slice_from(pos)
        }
    } else {
        url.to_string()
    };

    // Repos generally can be accessed with or w/o '.git'
    let url = if !url.as_slice().ends_with(".git") {
        url
    } else {
        url.as_slice().slice(0, url.len() - 4).to_string()
    };

    return url;
}

impl<'a, 'b> Show for GitSource<'a, 'b> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        try!(write!(f, "git repo at {}", self.remote.get_location()));

        match self.reference {
            Master => Ok(()),
            Other(ref reference) => write!(f, " ({})", reference)
        }
    }
}

impl<'a, 'b> Source for GitSource<'a, 'b> {
    fn update(&mut self) -> CargoResult<()> {
        let should_update = self.config.update_remotes() || {
            !self.remote.has_ref(&self.db_path, self.reference.as_slice()).is_ok()
        };

        let repo = if should_update {
            try!(self.config.shell().status("Updating",
                format!("git repository `{}`", self.remote.get_location())));

            log!(5, "updating git source `{}`", self.remote);
            try!(self.remote.checkout(&self.db_path))
        } else {
            self.remote.db_at(&self.db_path)
        };

        try!(repo.copy_to(self.reference.as_slice(), &self.checkout_path));

        self.path_source.update()
    }

    fn list(&self) -> CargoResult<Vec<Summary>> {
        self.path_source.list()
    }

    fn download(&self, _: &[PackageId]) -> CargoResult<()> {
        // TODO: assert! that the PackageId is contained by the source
        Ok(())
    }

    fn get(&self, ids: &[PackageId]) -> CargoResult<Vec<Package>> {
        log!(5, "getting packages for package ids `{}` from `{}`", ids, self.remote);
        self.path_source.get(ids)
    }

    fn fingerprint(&self, _pkg: &Package) -> CargoResult<String> {
        let db = self.remote.db_at(&self.db_path);
        db.rev_for(self.reference.as_slice())
    }
}

#[cfg(test)]
mod test {
    use url;
    use url::Url;
    use core::source::Remote;
    use super::ident;

    #[test]
    pub fn test_url_to_path_ident_with_path() {
        let ident = ident(&Remote(url("https://github.com/carlhuda/cargo")));
        assert_eq!(ident.as_slice(), "cargo-0eed735c8ffd7c88");
    }

    #[test]
    pub fn test_url_to_path_ident_without_path() {
        let ident = ident(&Remote(url("https://github.com")));
        assert_eq!(ident.as_slice(), "_empty-fc065c9b6b16fc00");
    }

    #[test]
    fn test_canonicalize_idents_by_stripping_trailing_url_slash() {
        let ident1 = ident(&Remote(url("https://github.com/PistonDevelopers/piston/")));
        let ident2 = ident(&Remote(url("https://github.com/PistonDevelopers/piston")));
        assert_eq!(ident1, ident2);
    }

    #[test]
    fn test_canonicalize_idents_by_lowercasing_github_urls() {
        let ident1 = ident(&Remote(url("https://github.com/PistonDevelopers/piston")));
        let ident2 = ident(&Remote(url("https://github.com/pistondevelopers/piston")));
        assert_eq!(ident1, ident2);
    }

    #[test]
    fn test_canonicalize_idents_by_stripping_dot_git() {
        let ident1 = ident(&Remote(url("https://github.com/PistonDevelopers/piston")));
        let ident2 = ident(&Remote(url("https://github.com/PistonDevelopers/piston.git")));
        assert_eq!(ident1, ident2);
    }

    #[test]
    fn test_canonicalize_idents_different_protocls() {
        let ident1 = ident(&Remote(url("https://github.com/PistonDevelopers/piston")));
        let ident2 = ident(&Remote(url("git://github.com/PistonDevelopers/piston")));
        assert_eq!(ident1, ident2);
    }

    fn url(s: &str) -> Url {
        url::from_str(s).unwrap()
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "nightly", plugin(clippy))]
#![cfg_attr(feature = "nightly", allow(used_underscore_binding))]
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))]

extern crate aster;
extern crate quasi;

#[cfg(feature = "with-syntex")]
extern crate syntex;

#[cfg(feature = "with-syntex")]
extern crate syntex_syntax as syntax;

#[cfg(not(feature = "with-syntex"))]
extern crate syntax;

#[cfg(not(feature = "with-syntex"))]
extern crate rustc_plugin;

#[cfg(not(feature = "with-syntex"))]
use syntax::feature_gate::AttributeType;

#[cfg(feature = "with-syntex")]
include!(concat!(env!("OUT_DIR"), "/lib.rs"));

#[cfg(not(feature = "with-syntex"))]
include!("lib.rs.in");

#[cfg(feature = "with-syntex")]
pub fn register(reg: &mut syntex::Registry) {
    use syntax::{ast, fold};

    reg.add_attr("feature(custom_derive)");
    reg.add_attr("feature(custom_attribute)");

    reg.add_decorator("derive_Serialize", ser::expand_derive_serialize);
    reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize);

    reg.add_post_expansion_pass(strip_attributes);

    /// Strip the serde attributes from the crate.
    #[cfg(feature = "with-syntex")]
    fn strip_attributes(krate: ast::Crate) -> ast::Crate {
        /// Helper folder that strips the serde attributes after the extensions have been expanded.
        struct StripAttributeFolder;

        impl fold::Folder for StripAttributeFolder {
            fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
                match attr.node.value.node {
                    ast::MetaList(ref n, _) if n == &"serde" => { return None; }
                    _ => {}
                }

                Some(attr)
            }

            fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
                fold::noop_fold_mac(mac, self)
            }
        }

        fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
    }
}

#[cfg(not(feature = "with-syntex"))]
pub fn register(reg: &mut rustc_plugin::Registry) {
    reg.register_syntax_extension(
        syntax::parse::token::intern("derive_Serialize"),
        syntax::ext::base::MultiDecorator(
            Box::new(ser::expand_derive_serialize)));

    reg.register_syntax_extension(
        syntax::parse::token::intern("derive_Deserialize"),
        syntax::ext::base::MultiDecorator(
            Box::new(de::expand_derive_deserialize)));

    reg.register_attribute("serde".to_owned(), AttributeType::Normal);
}
<commit_msg>fix(codegen): Fix clippy cfg_attr<commit_after>#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly", allow(used_underscore_binding))]
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))]

extern crate aster;
extern crate quasi;

#[cfg(feature = "with-syntex")]
extern crate syntex;

#[cfg(feature = "with-syntex")]
extern crate syntex_syntax as syntax;

#[cfg(not(feature = "with-syntex"))]
extern crate syntax;

#[cfg(not(feature = "with-syntex"))]
extern crate rustc_plugin;

#[cfg(not(feature = "with-syntex"))]
use syntax::feature_gate::AttributeType;

#[cfg(feature = "with-syntex")]
include!(concat!(env!("OUT_DIR"), "/lib.rs"));

#[cfg(not(feature = "with-syntex"))]
include!("lib.rs.in");

#[cfg(feature = "with-syntex")]
pub fn register(reg: &mut syntex::Registry) {
    use syntax::{ast, fold};

    reg.add_attr("feature(custom_derive)");
    reg.add_attr("feature(custom_attribute)");

    reg.add_decorator("derive_Serialize", ser::expand_derive_serialize);
    reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize);

    reg.add_post_expansion_pass(strip_attributes);

    /// Strip the serde attributes from the crate.
    #[cfg(feature = "with-syntex")]
    fn strip_attributes(krate: ast::Crate) -> ast::Crate {
        /// Helper folder that strips the serde attributes after the extensions have been expanded.
        struct StripAttributeFolder;

        impl fold::Folder for StripAttributeFolder {
            fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
                match attr.node.value.node {
                    ast::MetaList(ref n, _) if n == &"serde" => { return None; }
                    _ => {}
                }

                Some(attr)
            }

            fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
                fold::noop_fold_mac(mac, self)
            }
        }

        fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
    }
}

#[cfg(not(feature = "with-syntex"))]
pub fn register(reg: &mut rustc_plugin::Registry) {
    reg.register_syntax_extension(
        syntax::parse::token::intern("derive_Serialize"),
        syntax::ext::base::MultiDecorator(
            Box::new(ser::expand_derive_serialize)));

    reg.register_syntax_extension(
        syntax::parse::token::intern("derive_Deserialize"),
        syntax::ext::base::MultiDecorator(
            Box::new(de::expand_derive_deserialize)));

    reg.register_attribute("serde".to_owned(), AttributeType::Normal);
}
<|endoftext|>