<commit_before>use std::io::{fs, UserRWX, File};
use std::os;

use support::{execs, paths, cargo_dir, ResultTest};
use hamcrest::{assert_that, existing_file, existing_dir};

use cargo::util::{process, ProcessBuilder};

fn setup() {
}

fn my_process(s: &str) -> ProcessBuilder {
    process(s)
        .cwd(paths::root())
        .env("HOME", Some(paths::home()))
}

fn cargo_process(s: &str) -> ProcessBuilder {
    process(cargo_dir().join("cargo")).arg(s)
        .cwd(paths::root())
        .env("HOME", Some(paths::home()))
}

test!(simple_lib {
    os::setenv("USER", "foo");
    assert_that(cargo_process("new").arg("foo"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());

    assert_that(cargo_process("build").cwd(paths::root().join("foo")),
                execs().with_status(0));
})

test!(simple_bin {
    os::setenv("USER", "foo");
    assert_that(cargo_process("new").arg("foo").arg("--bin"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/main.rs"), existing_file());

    assert_that(cargo_process("build").cwd(paths::root().join("foo")),
                execs().with_status(0));
    assert_that(&paths::root().join(format!("foo/target/foo{}",
                                            os::consts::EXE_SUFFIX)),
                existing_file());
})

test!(simple_git {
    os::setenv("USER", "foo");
    assert_that(cargo_process("new").arg("foo").arg("--git"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());
    assert_that(&paths::root().join("foo/.git"), existing_dir());
    assert_that(&paths::root().join("foo/.gitignore"), existing_file());

    assert_that(cargo_process("build").cwd(paths::root().join("foo")),
                execs().with_status(0));
})

test!(no_argument {
    assert_that(cargo_process("new"),
                execs().with_status(1)
                       .with_stderr("Invalid arguments.
Usage:
    cargo new [options] <path>
    cargo new -h | --help
"));
})

test!(existing {
    let dst = paths::root().join("foo");
    fs::mkdir(&dst, UserRWX).assert();
    assert_that(cargo_process("new").arg("foo"),
                execs().with_status(101)
                       .with_stderr(format!("Destination `{}` already exists\n",
                                            dst.display())));
})

test!(finds_author_user {
    assert_that(cargo_process("new").arg("foo").env("USER", Some("foo")),
                execs().with_status(0));

    let toml = paths::root().join("foo/Cargo.toml");
    let toml = File::open(&toml).read_to_string().assert();
    assert!(toml.as_slice().contains(r#"authors = ["foo"]"#));
})

test!(finds_author_git {
    my_process("git").args(["config", "--global", "user.name", "bar"])
                     .exec().assert();
    my_process("git").args(["config", "--global", "user.email", "baz"])
                     .exec().assert();
    assert_that(cargo_process("new").arg("foo").env("USER", Some("foo")),
                execs().with_status(0));

    let toml = paths::root().join("foo/Cargo.toml");
    let toml = File::open(&toml).read_to_string().assert();
    assert!(toml.as_slice().contains(r#"authors = ["bar <baz>"]"#));
})
<commit_msg>cargo/new: add a test for the `--travis` flag<commit_after>use std::io::{fs, UserRWX, File};
use std::os;

use support::{execs, paths, cargo_dir, ResultTest};
use hamcrest::{assert_that, existing_file, existing_dir};

use cargo::util::{process, ProcessBuilder};

fn setup() {
}

fn my_process(s: &str) -> ProcessBuilder {
    process(s)
        .cwd(paths::root())
        .env("HOME", Some(paths::home()))
}

fn cargo_process(s: &str) -> ProcessBuilder {
    process(cargo_dir().join("cargo")).arg(s)
        .cwd(paths::root())
        .env("HOME", Some(paths::home()))
}

test!(simple_lib {
    os::setenv("USER", "foo");
    assert_that(cargo_process("new").arg("foo"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());

    assert_that(cargo_process("build").cwd(paths::root().join("foo")),
                execs().with_status(0));
})

test!(simple_bin {
    os::setenv("USER", "foo");
    assert_that(cargo_process("new").arg("foo").arg("--bin"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/main.rs"), existing_file());

    assert_that(cargo_process("build").cwd(paths::root().join("foo")),
                execs().with_status(0));
    assert_that(&paths::root().join(format!("foo/target/foo{}",
                                            os::consts::EXE_SUFFIX)),
                existing_file());
})

test!(simple_git {
    os::setenv("USER", "foo");
    assert_that(cargo_process("new").arg("foo").arg("--git"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());
    assert_that(&paths::root().join("foo/.git"), existing_dir());
    assert_that(&paths::root().join("foo/.gitignore"), existing_file());

    assert_that(cargo_process("build").cwd(paths::root().join("foo")),
                execs().with_status(0));
})

test!(simple_travis {
    os::setenv("USER", "foo");
    assert_that(cargo_process("new").arg("foo").arg("--travis"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());
    assert_that(&paths::root().join("foo/.travis.yml"), existing_file());

    assert_that(cargo_process("build").cwd(paths::root().join("foo")),
                execs().with_status(0));
})

test!(no_argument {
    assert_that(cargo_process("new"),
                execs().with_status(1)
                       .with_stderr("Invalid arguments.
Usage:
    cargo new [options] <path>
    cargo new -h | --help
"));
})

test!(existing {
    let dst = paths::root().join("foo");
    fs::mkdir(&dst, UserRWX).assert();
    assert_that(cargo_process("new").arg("foo"),
                execs().with_status(101)
                       .with_stderr(format!("Destination `{}` already exists\n",
                                            dst.display())));
})

test!(finds_author_user {
    assert_that(cargo_process("new").arg("foo").env("USER", Some("foo")),
                execs().with_status(0));

    let toml = paths::root().join("foo/Cargo.toml");
    let toml = File::open(&toml).read_to_string().assert();
    assert!(toml.as_slice().contains(r#"authors = ["foo"]"#));
})

test!(finds_author_git {
    my_process("git").args(["config", "--global", "user.name", "bar"])
                     .exec().assert();
    my_process("git").args(["config", "--global", "user.email", "baz"])
                     .exec().assert();
    assert_that(cargo_process("new").arg("foo").env("USER", Some("foo")),
                execs().with_status(0));

    let toml = paths::root().join("foo/Cargo.toml");
    let toml = File::open(&toml).read_to_string().assert();
    assert!(toml.as_slice().contains(r#"authors = ["bar <baz>"]"#));
})
<|endoftext|>


<commit_before>extern crate num;

#[allow(dead_code)]
pub struct ZeroPaddedSignal<T> {
	values: Vec<T>,
}

impl<T: num::traits::Num + Clone> ZeroPaddedSignal<T> {
	/**
		Returns the number of initialized values.
	*/
	#[allow(dead_code)]
	pub fn size(&self) -> usize {
		self.values.len()
	}

	/**
		Returns the value at the given index, zero if index
		is negative or uninitialized.
	*/
	#[allow(dead_code)]
	pub fn get(&self, idx: isize) -> T {
		/* Check for negative index: */
		if idx < 0 {
			/* Negative, return zero: */
			T::zero()
		} else {
			/* Not negative, cast to unsigned: */
			let idx = idx as usize;
			/* Check if the index is initialized: */
			if let Some(v) = self.values.get(idx).cloned() {
				/* It is, return the value: */
				v
			} else {
				/* It's not, return zero: */
				T::zero()
			}
		}
	}

	/**
		Returns a vector of signal values, starting with index start,
		ending with index end.
	*/
	#[allow(dead_code)]
	pub fn to_vector(&self, start: isize, end: isize) -> Vec<T> {
		/* Create an empty vector: */
		let mut x: Vec<T> = Vec::new();
		/* Loop through the given range: */
		for i in start..(end+1) {
			/* Add the values to the vector: */
			x.push(self.get(i));
		}
		/* Make the vector immutable: */
		let x = x;
		/* Return the vector: */
		x
	}

	/**
		Creates a new signal by doing Linear Prediction using
		the given coefficients.
	*/
	#[allow(dead_code)]
	pub fn linear_prediction(&self, a: Vec<T>) -> ZeroPaddedSignal<T> {
		/* Create a vector for the values: */
		let mut vals: Vec<T> = Vec::new();
		/* Calculate the size of the new signal: */
		let size: usize = self.size() + a.len();
		/* Iterate over the new indices: */
		for i in 0..size {
			let mut val: T = T::zero();
			/* ... and the coefficients: */
			for j in 0..a.len() {
				/* Calculate and typecast the index in the old signal: */
				let idx = (i as isize) - ((j+1) as isize);
				/* Weight the value and add it up: */
				if let Some(v) = a.get(j).cloned() {
					val = val + v*self.get(idx);
				}
			}
			/* Add the value to the vector: */
			vals.push(val);
		}
		/* Create a signal from the vector and return it: */
		let x: ZeroPaddedSignal<T> = ZeroPaddedSignal { values: vals };
		x
	}
}

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

	#[test]
	fn zero_padded_signal() {
		/* Create test signals: */
		let x1: ZeroPaddedSignal<u32> = ZeroPaddedSignal { values: vec![42,7,11] };
		/* Test size method: */
		assert_eq!( 3, x1.size());
		/* Test get method: */
		assert_eq!( 0, x1.get(  -1));
		assert_eq!(42, x1.get(   0));
		assert_eq!( 7, x1.get(   1));
		assert_eq!(11, x1.get(   2));
		assert_eq!( 0, x1.get(   3));
		assert_eq!( 0, x1.get( 100));
		assert_eq!( 0, x1.get(-100));
		/* Test to_vector method: */
		assert_eq!(vec![0,0,0,42,7,11,0], x1.to_vector(-3,3));
		assert_eq!(0, x1.to_vector(3,-3).len());
	}

	#[test]
	fn linear_prediction() {
		/* Create test signals: */
		let x2: ZeroPaddedSignal<f64> = ZeroPaddedSignal { values: vec![1.,1.,1.,1.,1.,1.] };
		/* Test linear_prediction method: */
		assert_eq_floatvec!(vec![0.,0.8,0.8,0.8,0.7,0.7,0.7,-0.1,-0.1,-0.1], x2.linear_prediction(vec![0.8,0.,0.,-0.1]).values, 1e-15);
	}
}
<commit_msg>signals.rs: fixed indentation<commit_after>extern crate num;

#[allow(dead_code)]
pub struct ZeroPaddedSignal<T> {
  values: Vec<T>,
}

impl<T: num::traits::Num + Clone> ZeroPaddedSignal<T> {
  /**
    Returns the number of initialized values.
  */
  #[allow(dead_code)]
  pub fn size(&self) -> usize {
    self.values.len()
  }

  /**
    Returns the value at the given index, zero if index
    is negative or uninitialized.
  */
  #[allow(dead_code)]
  pub fn get(&self, idx: isize) -> T {
    /* Check for negative index: */
    if idx < 0 {
      /* Negative, return zero: */
      T::zero()
    } else {
      /* Not negative, cast to unsigned: */
      let idx = idx as usize;
      /* Check if the index is initialized: */
      if let Some(v) = self.values.get(idx).cloned() {
        /* It is, return the value: */
        v
      } else {
        /* It's not, return zero: */
        T::zero()
      }
    }
  }

  /**
    Returns a vector of signal values, starting with index start,
    ending with index end.
  */
  #[allow(dead_code)]
  pub fn to_vector(&self, start: isize, end: isize) -> Vec<T> {
    /* Create an empty vector: */
    let mut x: Vec<T> = Vec::new();
    /* Loop through the given range: */
    for i in start..(end+1) {
      /* Add the values to the vector: */
      x.push(self.get(i));
    }
    /* Make the vector immutable: */
    let x = x;
    /* Return the vector: */
    x
  }

  /**
    Creates a new signal by doing Linear Prediction using
    the given coefficients.
  */
  #[allow(dead_code)]
  pub fn linear_prediction(&self, a: Vec<T>) -> ZeroPaddedSignal<T> {
    /* Create a vector for the values: */
    let mut vals: Vec<T> = Vec::new();
    /* Calculate the size of the new signal: */
    let size: usize = self.size() + a.len();
    /* Iterate over the new indices: */
    for i in 0..size {
      let mut val: T = T::zero();
      /* ... and the coefficients: */
      for j in 0..a.len() {
        /* Calculate and typecast the index in the old signal: */
        let idx = (i as isize) - ((j+1) as isize);
        /* Weight the value and add it up: */
        if let Some(v) = a.get(j).cloned() {
          val = val + v*self.get(idx);
        }
      }
      /* Add the value to the vector: */
      vals.push(val);
    }
    /* Create a signal from the vector and return it: */
    let x: ZeroPaddedSignal<T> = ZeroPaddedSignal { values: vals };
    x
  }
}

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

  #[test]
  fn zero_padded_signal() {
    /* Create test signals: */
    let x1: ZeroPaddedSignal<u32> = ZeroPaddedSignal { values: vec![42,7,11] };
    /* Test size method: */
    assert_eq!( 3, x1.size());
    /* Test get method: */
    assert_eq!( 0, x1.get(  -1));
    assert_eq!(42, x1.get(   0));
    assert_eq!( 7, x1.get(   1));
    assert_eq!(11, x1.get(   2));
    assert_eq!( 0, x1.get(   3));
    assert_eq!( 0, x1.get( 100));
    assert_eq!( 0, x1.get(-100));
    /* Test to_vector method: */
    assert_eq!(vec![0,0,0,42,7,11,0], x1.to_vector(-3,3));
    assert_eq!(0, x1.to_vector(3,-3).len());
  }

  #[test]
  fn linear_prediction() {
    /* Create test signals: */
    let x2: ZeroPaddedSignal<f64> = ZeroPaddedSignal { values: vec![1.,1.,1.,1.,1.,1.] };
    /* Test linear_prediction method: */
    assert_eq_floatvec!(vec![0.,0.8,0.8,0.8,0.7,0.7,0.7,-0.1,-0.1,-0.1], x2.linear_prediction(vec![0.8,0.,0.,-0.1]).values, 1e-15);
  }
}
<|endoftext|>


<commit_before>//! A trait to allow interpolation over spatial structures.

use std::num::Float;

/// Used for interpolation over spatial structures.
pub trait Spatial {
    /// The scalar type.
    type Scalar;

    /// Add
    fn add(&self, other: &Self) -> Self;
    /// Subtract
    fn sub(&self, other: &Self) -> Self;
    /// Scales with a scalar.
    fn scale(&self, scalar: &<Self as Spatial>::Scalar) -> Self;
}

impl<T> Spatial for T
    where
        T: Float
{
    type Scalar = T;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        *self + *other
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        *self - *other
    }

    #[inline(always)]
    fn scale(&self, other: &<Self as Spatial>::Scalar) -> Self {
        *self * *other
    }
}

impl<T> Spatial for [T; 2]
    where
        T: Spatial
{
    type Scalar = <T as Spatial>::Scalar;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        [
            self[0].add(&other[0]),
            self[1].add(&other[1])
        ]
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        [
            self[0].sub(&other[0]),
            self[1].sub(&other[1])
        ]
    }

    #[inline(always)]
    fn scale(&self, scalar: &<Self as Spatial>::Scalar) -> Self {
        [
            self[0].scale(scalar),
            self[1].scale(scalar),
        ]
    }
}

impl<T> Spatial for [T; 3]
    where
        T: Spatial
{
    type Scalar = <T as Spatial>::Scalar;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        [
            self[0].add(&other[0]),
            self[1].add(&other[1]),
            self[2].add(&other[2])
        ]
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        [
            self[0].sub(&other[0]),
            self[1].sub(&other[1]),
            self[2].sub(&other[2])
        ]
    }

    #[inline(always)]
    fn scale(&self, scalar: &<Self as Spatial>::Scalar) -> Self {
        [
            self[0].scale(scalar),
            self[1].scale(scalar),
            self[2].scale(scalar)
        ]
    }
}

impl<T> Spatial for [T; 4]
    where
        T: Spatial
{
    type Scalar = <T as Spatial>::Scalar;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        [
            self[0].add(&other[0]),
            self[1].add(&other[1]),
            self[2].add(&other[2]),
            self[3].add(&other[3])
        ]
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        [
            self[0].sub(&other[0]),
            self[1].sub(&other[1]),
            self[2].sub(&other[2]),
            self[3].sub(&other[3])
        ]
    }

    #[inline(always)]
    fn scale(&self, scalar: &<Self as Spatial>::Scalar) -> Self {
        [
            self[0].scale(scalar),
            self[1].scale(scalar),
            self[2].scale(scalar),
            self[3].scale(scalar)
        ]
    }
}
<commit_msg>Added implementation of Spatial for integer primitives, closes #27<commit_after>//! A trait to allow interpolation over spatial structures.

use std::num::Float;

/// Used for interpolation over spatial structures.
pub trait Spatial {
    /// The scalar type.
    type Scalar;

    /// Add
    fn add(&self, other: &Self) -> Self;
    /// Subtract
    fn sub(&self, other: &Self) -> Self;
    /// Scales with a scalar.
    fn scale(&self, scalar: &<Self as Spatial>::Scalar) -> Self;
}

impl<T> Spatial for T
    where
        T: Float
{
    type Scalar = T;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        *self + *other
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        *self - *other
    }

    #[inline(always)]
    fn scale(&self, other: &<Self as Spatial>::Scalar) -> Self {
        *self * *other
    }
}

/// Implementation of spatial for signed integers.
/// `scale` will cast the uint to the Scalar before multiplying and rounding to the nearest value.
macro_rules! impl_spatial_for_int {
    ($int: ident, $scalar: ident) => (
        impl Spatial for $int {
            type Scalar = $scalar;

            #[inline(always)]
            fn add(&self, other: &$int) -> $int {
                *self + *other
            }

            #[inline(always)]
            fn sub(&self, other: &$int) -> $int {
                *self - *other
            }

            #[inline(always)]
            fn scale(&self, other: &$scalar) -> $int {
                use std::num::Float;
                ((*self as $scalar) * *other).round() as $int
            }
        }
    )
}

impl_spatial_for_int!(i8,  f32);
impl_spatial_for_int!(i16, f32);
impl_spatial_for_int!(i32, f32);
impl_spatial_for_int!(i64, f64);

/// Implementation of spatial for unsigned integers.
/// `scale` will cast the uint to the Scalar before multiplying and rounding to the nearest value.
macro_rules! impl_spatial_for_uint {
    ($uint: ident, $scalar: ident) => (
        impl Spatial for $uint {
            type Scalar = $scalar;

            #[inline(always)]
            fn add(&self, other: &$uint) -> $uint {
                *self + *other
            }

            #[inline(always)]
            fn sub(&self, other: &$uint) -> $uint {
                // Find the absolute difference to avoid underflow.
                if *self >= *other {
                    *self - *other
                } else {
                    *other - *self
                }
            }

            #[inline(always)]
            fn scale(&self, other: &$scalar) -> $uint {
                use std::num::Float;
                ((*self as $scalar) * *other).round() as $uint
            }
        }
    )
}

impl_spatial_for_uint!(u8,  f32);
impl_spatial_for_uint!(u16, f32);
impl_spatial_for_uint!(u32, f32);
impl_spatial_for_uint!(u64, f64);

impl<T> Spatial for [T; 2]
    where
        T: Spatial
{
    type Scalar = <T as Spatial>::Scalar;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        [
            self[0].add(&other[0]),
            self[1].add(&other[1])
        ]
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        [
            self[0].sub(&other[0]),
            self[1].sub(&other[1])
        ]
    }

    #[inline(always)]
    fn scale(&self, scalar: &<Self as Spatial>::Scalar) -> Self {
        [
            self[0].scale(scalar),
            self[1].scale(scalar),
        ]
    }
}

impl<T> Spatial for [T; 3]
    where
        T: Spatial
{
    type Scalar = <T as Spatial>::Scalar;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        [
            self[0].add(&other[0]),
            self[1].add(&other[1]),
            self[2].add(&other[2])
        ]
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        [
            self[0].sub(&other[0]),
            self[1].sub(&other[1]),
            self[2].sub(&other[2])
        ]
    }

    #[inline(always)]
    fn scale(&self, scalar: &<Self as Spatial>::Scalar) -> Self {
        [
            self[0].scale(scalar),
            self[1].scale(scalar),
            self[2].scale(scalar)
        ]
    }
}

impl<T> Spatial for [T; 4]
    where
        T: Spatial
{
    type Scalar = <T as Spatial>::Scalar;

    #[inline(always)]
    fn add(&self, other: &Self) -> Self {
        [
            self[0].add(&other[0]),
            self[1].add(&other[1]),
            self[2].add(&other[2]),
            self[3].add(&other[3])
        ]
    }

    #[inline(always)]
    fn sub(&self, other: &Self) -> Self {
        [
            self[0].sub(&other[0]),
            self[1].sub(&other[1]),
            self[2].sub(&other[2]),
            self[3].sub(&other[3])
        ]
    }

    #[inline(always)]
    fn scale(&self, scalar: &<Self as Spatial>::Scalar) -> Self {
        [
            self[0].scale(scalar),
            self[1].scale(scalar),
            self[2].scale(scalar),
            self[3].scale(scalar)
        ]
    }
}
<|endoftext|>


<commit_before><commit_msg>Add method for returning interactions to ReplyState<commit_after><|endoftext|>


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

fn get_duplicated(boundary: i32, exp: i32) -> i32 {
    let mut duplicates = Vec::new();

    for n in 2..boundary + 1 {
        let mut tmp_exp = exp - 1;
        while tmp_exp > 0 {
            if (exp * n) % tmp_exp == 0 && (exp * n) / tmp_exp <= boundary {
                duplicates.push(n);
            }
            tmp_exp -= 1;
        }
    }

    duplicates.sort();
    duplicates.dedup();
    return duplicates.len() as i32;
}

fn main() {
    let boundary = 100; // boundary >= 2

    let max_base = (boundary as f64).sqrt() as i32;

    let mut max_power = 0;
    let mut tmp_boundary = boundary;
    while tmp_boundary >= 2 {
        tmp_boundary /= 2;
        max_power += 1;
    }

    let mut records: HashMap<i32, i32> = HashMap::new();
    for n in 2..max_power + 1 {
        for c in 2..max_base + 1 {
            let key = c.pow(n as u32);
            if key <= boundary {
                records.insert(key, n);
            }
        }
    }

    let mut result = (boundary - 1) * (boundary - 1);
    for exp in records.values() {
        result -= get_duplicated(boundary, *exp);
    }

    println!("{}", result);
}
<commit_msg>optimize algorithm<commit_after>use std::collections::HashMap;

fn get_duplicated(boundary: i32, exp: i32) -> i32 {
    let mut duplicates = Vec::new();

    for n in 2..boundary + 1 {
        let mut tmp_exp = exp - 1;
        while tmp_exp > 0 {
            if (exp * n) % tmp_exp == 0 && (exp * n) / tmp_exp <= boundary {
                duplicates.push(n);
            }
            tmp_exp -= 1;
        }
    }

    duplicates.sort();
    duplicates.dedup();
    return duplicates.len() as i32;
}

fn main() {
    let boundary = 100; // boundary >= 2

    let max_base = (boundary as f64).sqrt() as i32;

    // find max power(when base == 2) and max tmp_boundary(boundary's root)
    let mut max_power = 0;
    let mut tmp_boundary = boundary;
    while tmp_boundary >= 2 {
        tmp_boundary /= 2;
        max_power += 1;
    }

    // find the max power of a number that equals x ^ y
    let mut records: HashMap<i32, i32> = HashMap::new();
    for n in 2..max_power + 1 {
        for c in 2..max_base + 1 {
            let key = c.pow(n as u32);
            if key <= boundary {
                records.insert(key, n);
            }
        }
    }

    // group by power, since get_duplicated() gets the same answer when tuple (boundary, power) is given
    let mut counts: HashMap<i32, i32> = HashMap::new();
    for exp in records.values() {
        if counts.contains_key(exp) {
            let tmp_count = counts[exp] + 1;
            counts.insert(*exp, tmp_count);
        } else {
            counts.insert(*exp, 1);
        }
    }

    // total
    let mut result = (boundary - 1) * (boundary - 1);
    for (power, power_count) in &counts {
        result -= get_duplicated(boundary, *power) * power_count;
    }

    println!("{}", result);
}
<|endoftext|>


<commit_before>use bt_messages::Message;
use buffered_reader::BufferedReader;
use std::net::TcpStream;
use std::sync::mpsc::Sender;
use std::io::Write;

const BLOCK_LENGTH:usize = 16384; //block length in bytes

/// Handles messages. This is a cheap way to force reactive style
pub trait Handler {
    type MessageType;
    fn handle(&mut self, message: Self::MessageType, peer: &mut Peer);
}

//TODO: state probably shouldn't be stored here in the handler... eventually move it back in main. for each
//torrent
pub struct DefaultHandler {
    //the global piece count
    gpc: Vec<u16>,
    //pieces owned by self. (as a bitfield)
    owned: Vec<u8>,
    //outgoing requests
    request_map: Vec<u8>
}

impl DefaultHandler {
    pub fn new () -> DefaultHandler {
        DefaultHandler {
            gpc: vec![],
            owned: vec![],
            request_map: vec![]
        }
    }

    /// Increases the value of gpc[piece_index] by n
    #[inline]
    pub fn gpc_incr (&mut self, piece_index: usize, n: u16) {
        //starting to regret making the bitfield variable in size... maybe i can preallocate. will come back and re-eval
        let len = self.gpc.len();
        if piece_index >= len {
            self.gpc.extend((0..piece_index+1 - len).map(|_| 0));
        }
        self.gpc[piece_index] += n;
    }

    /// Returns the index of the rarest piece that isn't owned or currently being requested.
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest (&self) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        for (index, byte) in self.unclaimed_fields().iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// Returns the index of the rarest piece that is owned by the peer and isn't both owned
    /// and currently being requested
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest_wrt_peer (&self, peer_bitfield: &Vec<u8>) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        let eligible = and_slice_vbr_len(&self.unclaimed_fields(), &peer_bitfield);
        for (index, byte) in eligible.iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// returns a complete bitfield of pieces that aren't owned or being requested
    /// this is done almost as strictly as possible - and might be a little of a waste as it isn't
    /// really necessary to get a complete picture to get a request chunk
    /// additionally the definitions of owned and request_map are not strict yet - currently they
    /// are growable, and impelementers should take note of that
    #[inline]
    pub fn unclaimed_fields (&self) -> Vec<u8> {
        nand_slice_vbr_len(&self.owned, &self.request_map)
    }
}

/// The default algorithm
impl Handler for DefaultHandler {
    type MessageType = Message;
    #[inline]
    fn handle (&mut self, message: Message, peer: &mut Peer) {
        println!("{:?}", message);
        match message {
            Message::Have{piece_index: index} => {
                let i = index as usize;
                self.gpc_incr(i, 1);
                peer.state.set_have(i);
            },
            Message::Choke => {
                peer.state.set_us_choked(true);
            },
            Message::Unchoke => {
                peer.state.set_us_choked(false);
            },
            Message::Interested => {
                peer.state.set_us_interested(true);
            },
            Message::Bitfield(bitfield) => {
                for (index, byte) in bitfield.iter().enumerate() {
                    for i in 0..8 { //cast up so i don't have to deal with overflows
                        let n = 1 & (((*byte as u16) << i) >> (8-i));
                        self.gpc_incr(index*8+i, n);
                    }
                }
                peer.state.set_bitfield(bitfield);

                let candidates = self.unclaimed_fields();
                let request = peer.get_request(&candidates);
                println!("{:?}", request);

            },
            _ => {
            }
        };
    }
}

pub struct Peer {
    pub id: String,
    stream: TcpStream,
    pub state: State
}

impl Peer {
    pub fn new (id:String, stream: TcpStream) -> Peer {
        Peer {
            id: id,
            stream: stream,
            state: State::new()
        }
    }

    pub fn send_message (&mut self, message: Message) {
        let as_bytes = message.to_byte_array();
        let _ = self.stream.write_all(&as_bytes);
    }
}

trait RequestGenerator {
    /// Given a bitfield of eligible candidates, returns if possible the (index, begin, and length)
    /// corresponding to the fields in Message::Request
    fn get_request(&self, candidate_field: &[u8]) -> Option<(u32, u32, u32)>;
}

impl RequestGenerator for Peer {
    fn get_request(&self, candidate_field: &[u8]) -> Option<(u32, u32, u32)> {
        Some((1, 1, 1))
    }
}

#[derive(Debug)]
pub struct State {
    //are we choked by them?
    us_choked: bool,
    //are we interested in them?
    us_interested: bool,
    //are they choked by us?
    is_choked: bool,
    //are they interested in us?
    is_interested: bool,
    //the intention is that eventually we will support growable files. so going with vector
    bitfield: Vec<u8>
}

impl State {
    fn new () -> State {
        State {
            us_choked: true,
            us_interested: false,
            is_choked: true,
            is_interested: false,
            bitfield: vec![]
        }
    }

    pub fn set_us_interested (&mut self, us_interested: bool) {
        self.us_interested = us_interested;
    }

    fn set_bitfield (&mut self, bitfield: Vec<u8>) {
        self.bitfield = bitfield;
    }

    fn set_have (&mut self, index: usize) {
        set_have_bitfield(&mut self.bitfield, index);
    }

    fn set_us_choked (&mut self, us_choked: bool) {
        self.us_choked = us_choked;
    }
}

#[inline]
fn set_have_bitfield (bitfield: &mut Vec<u8>, index: usize) {
    let chunk_index = index/8;
    let chunk_posit = index % 8;
    let chunk_mask = 128 >> chunk_posit;

    //bounds check needs to be here because the bitfield is a variable size - which we want in
    //the future
    if chunk_index+1 > bitfield.len() {
        bitfield.extend((0..chunk_index).map(|_| 0));
    }

    bitfield[chunk_index] = bitfield[chunk_index] | chunk_mask;
}

/// Zip-maps a generic func over two byte slices with variable lengths
#[inline]
pub fn apply_bitwise_slice_vbr_len <F, T:Clone> (lhs: &[T], rhs: &[T], default: T, func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    if lhs.len() == rhs.len() {
        bitwise_byte_slice(lhs, rhs, func)
    } else {
        if lhs.len() < rhs.len() {
            let mut vec = bitwise_byte_slice(&rhs[..lhs.len()], lhs, func);
            vec.extend((0..rhs.len()-lhs.len()).map(|_| default.clone()));
            vec
        } else {
            let mut vec = bitwise_byte_slice(rhs, &lhs[..rhs.len()], func);
            vec.extend((0..lhs.len()-rhs.len()).map(|_| default.clone()));
            vec
        }
    }
}

/// Zip-maps a generic func (intended bitwise) over two byte slices
#[inline]
pub fn bitwise_byte_slice <F, T> (lhs: &[T], rhs: &[T], func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    assert!(lhs.len() == rhs.len());
    lhs.iter().zip(rhs)
              .map(func)
              .collect::<Vec<T>>()
}

#[inline]
pub fn nand_slice_vbr_len (lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    apply_bitwise_slice_vbr_len(lhs, rhs, 255, |(a, b)| !a & !b)
}

#[inline]
pub fn and_slice_vbr_len(lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    apply_bitwise_slice_vbr_len(lhs, rhs, 0, |(a, b)| a & b)
}

#[test]
fn test_nand_slice() {
    let a = vec![0, 0];
    let b = vec![0, 1];
    let c = nand_slice_vbr_len(&a, &b);

    assert_eq!(c, vec![255, 254]);
}

#[test]
fn test_unclaimed_fields() {
    let mut handler = DefaultHandler::new();

    handler.owned = vec![0, 0, 0];
    handler.request_map = vec![1, 0];

    let c = handler.unclaimed_fields();
    assert_eq!(c, vec![254, 255, 255]);
}

#[test]
fn test_set_have_singleton_bitfield() {
    let mut state = State::new();

    state.set_bitfield(vec![0]);
    state.set_have(2);

    assert_eq!(state.bitfield[0], 32);
}

#[test]
fn test_set_have_longer_bitfiled() {
    let mut state = State::new();

    state.set_bitfield(vec![0, 0, 0, 0]);
    state.set_have(23);

    assert_eq!(state.bitfield[0], 0);
    assert_eq!(state.bitfield[1], 0);
    assert_eq!(state.bitfield[2], 1);
    assert_eq!(state.bitfield[3], 0);
}

#[test]
fn test_set_have_out_of_bounds() {
    let mut state = State::new();

    state.set_bitfield(vec![0, 1]);
    state.set_have(31);

    assert_eq!(state.bitfield[0], 0);
    assert_eq!(state.bitfield[1], 1);
    assert_eq!(state.bitfield[2], 0);
    assert_eq!(state.bitfield[3], 1);
}
<commit_msg>bitwise slice errors<commit_after>use bt_messages::Message;
use buffered_reader::BufferedReader;
use std::net::TcpStream;
use std::sync::mpsc::Sender;
use std::io::Write;

const BLOCK_LENGTH:usize = 16384; //block length in bytes

/// Handles messages. This is a cheap way to force reactive style
pub trait Handler {
    type MessageType;
    fn handle(&mut self, message: Self::MessageType, peer: &mut Peer);
}

//TODO: state probably shouldn't be stored here in the handler... eventually move it back in main. for each
//torrent
pub struct DefaultHandler {
    //the global piece count
    gpc: Vec<u16>,
    //pieces owned by self. (as a bitfield)
    owned: Vec<u8>,
    //outgoing requests
    request_map: Vec<u8>
}

impl DefaultHandler {
    pub fn new () -> DefaultHandler {
        DefaultHandler {
            gpc: vec![],
            owned: vec![],
            request_map: vec![]
        }
    }

    /// Increases the value of gpc[piece_index] by n
    #[inline]
    pub fn gpc_incr (&mut self, piece_index: usize, n: u16) {
        //starting to regret making the bitfield variable in size... maybe i can preallocate. will come back and re-eval
        let len = self.gpc.len();
        if piece_index >= len {
            self.gpc.extend((0..piece_index+1 - len).map(|_| 0));
        }
        self.gpc[piece_index] += n;
    }

    /// Returns the index of the rarest piece that isn't owned or currently being requested.
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest (&self) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        for (index, byte) in self.unclaimed_fields().iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// Returns the index of the rarest piece that is owned by the peer and isn't both owned
    /// and currently being requested
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest_wrt_peer (&self, peer_bitfield: &Vec<u8>) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        let eligible = and_slice_vbr_len(&self.unclaimed_fields(), &peer_bitfield);
        for (index, byte) in eligible.iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                //println!("n: {}", n);
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// returns a complete bitfield of pieces that aren't owned or being requested
    /// this is done almost as strictly as possible - and might be a little of a waste as it isn't
    /// really necessary to get a complete picture to get a request chunk
    /// additionally the definitions of owned and request_map are not strict yet - currently they
    /// are growable, and impelementers should take note of that
    #[inline]
    pub fn unclaimed_fields (&self) -> Vec<u8> {
        nand_slice_vbr_len(&self.owned, &self.request_map)
    }

    #[inline]
    pub fn req (&mut self, peer_bitfield: &Vec<u8>) {
        let index = self.rarest_wrt_peer(peer_bitfield);
        println!("REQ: {:?}", index);
    }
}

/// The default algorithm
impl Handler for DefaultHandler {
    type MessageType = Message;
    #[inline]
    fn handle (&mut self, message: Message, peer: &mut Peer) {
        println!("{:?}", message);
        match message {
            Message::Have{piece_index: index} => {
                let i = index as usize;
                self.gpc_incr(i, 1);
                peer.state.set_have(i);
                self.req(&peer.state.bitfield);
            },
            Message::Choke => {
                peer.state.set_us_choked(true);
            },
            Message::Unchoke => {
                peer.state.set_us_choked(false);
            },
            Message::Interested => {
                peer.state.set_us_interested(true);
            },
            Message::Bitfield(bitfield) => {
                for (index, byte) in bitfield.iter().enumerate() {
                    for i in 0..8 { //cast up so i don't have to deal with overflows
                        let n = 1 & (((*byte as u16) << i) >> (8-i));
                        self.gpc_incr(index*8+i, n);
                    }
                }
                peer.state.set_bitfield(bitfield);

                /*
                let candidates = self.unclaimed_fields();
                let request = peer.get_request(&candidates);
                */

                self.req(&peer.state.bitfield);
            },
            _ => {
            }
        };
    }
}

pub struct Peer {
    pub id: String,
    stream: TcpStream,
    pub state: State
}

impl Peer {
    pub fn new (id:String, stream: TcpStream) -> Peer {
        Peer {
            id: id,
            stream: stream,
            state: State::new()
        }
    }

    pub fn send_message (&mut self, message: Message) {
        let as_bytes = message.to_byte_array();
        let _ = self.stream.write_all(&as_bytes);
    }
}

trait RequestGenerator {
    /// Given a bitfield of eligible candidates, returns if possible the (index, begin, and length)
    /// corresponding to the fields in Message::Request
    fn get_request(&self, candidate_field: &[u8]) -> Option<(u32, u32, u32)>;
}

impl RequestGenerator for Peer {
    fn get_request(&self, candidate_field: &[u8]) -> Option<(u32, u32, u32)> {
        Some((1, 1, 1))
    }
}

#[derive(Debug)]
pub struct State {
    //are we choked by them?
    us_choked: bool,
    //are we interested in them?
    us_interested: bool,
    //are they choked by us?
    is_choked: bool,
    //are they interested in us?
    is_interested: bool,
    //the intention is that eventually we will support growable files. so going with vector
    bitfield: Vec<u8>
}

impl State {
    fn new () -> State {
        State {
            us_choked: true,
            us_interested: false,
            is_choked: true,
            is_interested: false,
            bitfield: vec![]
        }
    }

    pub fn set_us_interested (&mut self, us_interested: bool) {
        self.us_interested = us_interested;
    }

    fn set_bitfield (&mut self, bitfield: Vec<u8>) {
        self.bitfield = bitfield;
    }

    fn set_have (&mut self, index: usize) {
        set_have_bitfield(&mut self.bitfield, index);
    }

    fn set_us_choked (&mut self, us_choked: bool) {
        self.us_choked = us_choked;
    }
}

#[inline]
fn set_have_bitfield (bitfield: &mut Vec<u8>, index: usize) {
    let chunk_index = index/8;
    let chunk_posit = index % 8;
    let chunk_mask = 128 >> chunk_posit;

    //bounds check needs to be here because the bitfield is a variable size - which we want in
    //the future
    if chunk_index+1 > bitfield.len() {
        bitfield.extend((0..chunk_index).map(|_| 0));
    }

    bitfield[chunk_index] = bitfield[chunk_index] | chunk_mask;
}

/// Zip-maps a generic func over two byte slices with variable lengths
#[inline]
pub fn apply_bitwise_slice_vbr_len <F, T:Clone> (lhs: &[T], rhs: &[T], default: T, func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    if lhs.len() == rhs.len() {
        bitwise_byte_slice(lhs, rhs, func)
    } else {
        if lhs.len() < rhs.len() {
            //let mut a = (&rhs[..lhs.len()]).to_owned();
            let mut a = lhs.to_owned();
            a.extend((0..rhs.len()-lhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(&a, rhs, func)
        } else {
            let mut b = rhs.to_owned();
            b.extend((0..lhs.len()-rhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(lhs, &b, func)
        }
    }
}

/// Zip-maps a generic func (intended bitwise) over two byte slices
#[inline]
pub fn bitwise_byte_slice <F, T> (lhs: &[T], rhs: &[T], func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    println!("llen: {}, rlen: {}", lhs.len(), rhs.len());
    assert!(lhs.len() == rhs.len());
    lhs.iter().zip(rhs)
              .map(func)
              .collect::<Vec<T>>()
}

#[inline]
pub fn nand_slice_vbr_len (lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    apply_bitwise_slice_vbr_len(lhs, rhs, 0, |(a, b)| !a & !b)
}

#[inline]
pub fn and_slice_vbr_len(lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    println!("lhs: {:?}", lhs);
    println!("rhs: {:?}", rhs);
    apply_bitwise_slice_vbr_len(lhs, rhs, 255, |(a, b)| a & b)
}

#[test]
fn test_nand_slice() {
    let a = vec![0, 0];
    let b = vec![0, 1];
    let c = nand_slice_vbr_len(&a, &b);

    assert_eq!(c, vec![255, 254]);
}

#[test]
fn test_unclaimed_fields() {
    let mut handler = DefaultHandler::new();

    handler.owned = vec![0, 0, 0];
    handler.request_map = vec![1, 0];

    let c = handler.unclaimed_fields();
    assert_eq!(c, vec![254, 255, 255]);
}

#[test]
fn test_set_have_singleton_bitfield() {
    let mut state = State::new();

    state.set_bitfield(vec![0]);
    state.set_have(2);

    assert_eq!(state.bitfield[0], 32);
}

#[test]
fn test_set_have_longer_bitfiled() {
    let mut state = State::new();

    state.set_bitfield(vec![0, 0, 0, 0]);
    state.set_have(23);

    assert_eq!(state.bitfield[0], 0);
    assert_eq!(state.bitfield[1], 0);
    assert_eq!(state.bitfield[2], 1);
    assert_eq!(state.bitfield[3], 0);
}

#[test]
fn test_set_have_out_of_bounds() {
    let mut state = State::new();

    state.set_bitfield(vec![0, 1]);
    state.set_have(31);

    assert_eq!(state.bitfield[0], 0);
    assert_eq!(state.bitfield[1], 1);
    assert_eq!(state.bitfield[2], 0);
    assert_eq!(state.bitfield[3], 1);
}
<|endoftext|>


<commit_before>use base::{
    AbstractCFTypeRef,
    CFAllocatorRef,
    CFIndex,
    CFRange,
    CFTypeRef,
    CFWrapper,
    kCFAllocatorDefault,
};
use libc::c_void;

pub type CFArrayRetainCallBack = *u8;
pub type CFArrayReleaseCallBack = *u8;
pub type CFArrayCopyDescriptionCallBack = *u8;
pub type CFArrayEqualCallBack = *u8;

pub struct CFArrayCallBacks {
    version: CFIndex,
    retain: CFArrayRetainCallBack,
    release: CFArrayReleaseCallBack,
    copyDescription: CFArrayCopyDescriptionCallBack,
    equal: CFArrayEqualCallBack,
}

struct __CFArray { private: () }
pub type CFArrayRef = *__CFArray;

pub impl CFArrayRef : AbstractCFTypeRef {
    pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
}

pub type CFArray<ElemRefType: AbstractCFTypeRef> = CFWrapper<CFArrayRef, ElemRefType, ()>;

pub impl<ElemRefType:AbstractCFTypeRef> CFArray<ElemRefType> {
    static fn new(elems: &[ElemRefType]) -> CFArray<ElemRefType> {
        let array_ref : CFArrayRef;
        let elems_refs = do vec::map(elems) |e: &ElemRefType| { e.as_type_ref() };

        unsafe {
            array_ref = CFArrayCreate(kCFAllocatorDefault,
                                      cast::transmute(vec::raw::to_ptr(elems_refs)),
                                      elems.len() as CFIndex,
                                      ptr::to_unsafe_ptr(&kCFTypeArrayCallBacks));
        }
        return move CFWrapper::wrap_owned(array_ref);
    }

    pub fn each_ref<A>(cb: fn&(ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(self[i]); }
    }

    pub fn eachi_ref<A>(cb: fn&(uint, ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(i, self[i]); }
    }

    // Careful; the callback must wrap the reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pub fn each<A>(cb: fn&(&ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(&self[i]); }
    }

    // Careful; the callback must wrap the reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pub fn eachi<A>(cb: fn&(uint, &ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(i, &self[i]); }
    }

    pub pure fn len() -> uint {
        unsafe { return CFArrayGetCount(*self.borrow_ref()) as uint; }
    }

    // Careful; the caller must wrap any returned reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pure fn index(idx: uint) -> ElemRefType {
        assert idx < self.len();
        unsafe {
            let elem = CFArrayGetValueAtIndex(*self.borrow_ref(), idx as CFIndex);
            // Don't return a wrapped thing, since we don't know whether
            // it needs base::wrap_shared() or base::wrap_owned()
            return cast::transmute(elem);
        }
    }
}

#[link_args="-framework CoreFoundation"]
#[nolink]
extern {
    /*
     * CFArray.h
     */
    const kCFTypeArrayCallBacks: CFArrayCallBacks;

    fn CFArrayCreate(allocator: CFAllocatorRef, values: **c_void,
                     numValues: CFIndex, callBacks: *CFArrayCallBacks) -> CFArrayRef;

    fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *c_void;
    fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex;
}

#[test]
fn should_box_and_unbox() {
    use number::{CFNumber, CFNumberRef};

    let arr = CFArray::new([
        CFNumber::new(1 as i32),
        CFNumber::new(2 as i32),
        CFNumber::new(3 as i32),
        CFNumber::new(4 as i32),
        CFNumber::new(5 as i32)]);

    let mut sum = 0i32;
    // TODO: not always safe to re-wrap, unless we addref the element
    for arr.each |elem| {
        sum += elem.to_i32();
    }

    assert sum == 15;

    for arr.each_ref |elem: CFNumberRef| {
        let n: CFNumber = base::wrap(elem);
        sum += n.to_i32();
    }

    assert sum == 30;
}
<commit_msg>Fix CFArray test.<commit_after>use base::{
    AbstractCFTypeRef,
    CFAllocatorRef,
    CFIndex,
    CFRange,
    CFTypeRef,
    CFWrapper,
    kCFAllocatorDefault,
};
use libc::c_void;

pub type CFArrayRetainCallBack = *u8;
pub type CFArrayReleaseCallBack = *u8;
pub type CFArrayCopyDescriptionCallBack = *u8;
pub type CFArrayEqualCallBack = *u8;

pub struct CFArrayCallBacks {
    version: CFIndex,
    retain: CFArrayRetainCallBack,
    release: CFArrayReleaseCallBack,
    copyDescription: CFArrayCopyDescriptionCallBack,
    equal: CFArrayEqualCallBack,
}

struct __CFArray { private: () }
pub type CFArrayRef = *__CFArray;

pub impl CFArrayRef : AbstractCFTypeRef {
    pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
}

pub type CFArray<ElemRefType: AbstractCFTypeRef> = CFWrapper<CFArrayRef, ElemRefType, ()>;

pub impl<ElemRefType:AbstractCFTypeRef> CFArray<ElemRefType> {
    static fn new(elems: &[ElemRefType]) -> CFArray<ElemRefType> {
        let array_ref : CFArrayRef;
        let elems_refs = do vec::map(elems) |e: &ElemRefType| { e.as_type_ref() };

        unsafe {
            array_ref = CFArrayCreate(kCFAllocatorDefault,
                                      cast::transmute(vec::raw::to_ptr(elems_refs)),
                                      elems.len() as CFIndex,
                                      ptr::to_unsafe_ptr(&kCFTypeArrayCallBacks));
        }
        return move CFWrapper::wrap_owned(array_ref);
    }

    pub fn each_ref<A>(cb: fn&(ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(self[i]); }
    }

    pub fn eachi_ref<A>(cb: fn&(uint, ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(i, self[i]); }
    }

    // Careful; the callback must wrap the reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pub fn each<A>(cb: fn&(&ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(&self[i]); }
    }

    // Careful; the callback must wrap the reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pub fn eachi<A>(cb: fn&(uint, &ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(i, &self[i]); }
    }

    pub pure fn len() -> uint {
        unsafe { return CFArrayGetCount(*self.borrow_ref()) as uint; }
    }

    // Careful; the caller must wrap any returned reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pure fn index(idx: uint) -> ElemRefType {
        assert idx < self.len();
        unsafe {
            let elem = CFArrayGetValueAtIndex(*self.borrow_ref(), idx as CFIndex);
            // Don't return a wrapped thing, since we don't know whether
            // it needs base::wrap_shared() or base::wrap_owned()
            return cast::transmute(elem);
        }
    }
}

#[link_args="-framework CoreFoundation"]
#[nolink]
extern {
    /*
     * CFArray.h
     */
    const kCFTypeArrayCallBacks: CFArrayCallBacks;

    fn CFArrayCreate(allocator: CFAllocatorRef, values: **c_void,
                     numValues: CFIndex, callBacks: *CFArrayCallBacks) -> CFArrayRef;

    fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *c_void;
    fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex;
}

#[test]
fn should_box_and_unbox() {
    use number::{CFNumber, CFNumberRef};

    let one = CFNumber::new(1 as i32);
    let two = CFNumber::new(2 as i32);
    let thr = CFNumber::new(3 as i32);
    let fou = CFNumber::new(4 as i32);
    let fiv = CFNumber::new(5 as i32);

    let arr = CFArray::new([
        *one.borrow_ref(),
        *two.borrow_ref(),
        *thr.borrow_ref(),
        *fou.borrow_ref(),
        *fiv.borrow_ref()]);

    let mut sum = 0i32;

    for arr.each |elem: &CFNumberRef| {
        sum += CFWrapper::wrap_shared(*elem).to_i32();
    }

    assert sum == 15;

    for arr.each |elem: &CFNumberRef| {
        sum += CFWrapper::wrap_shared(*elem).to_i32();
    }

    assert sum == 30;
}
<|endoftext|>


<commit_before>//! Types and methods for setting shader uniforms

// External crates.
use std::ffi::CString;
use gl;
use gl::types::{GLboolean, GLint};
use std::marker::PhantomData;

// Local crate.
use back_end::GlGraphics;

/// Describes a shader uniform of a given type.
#[derive(Clone, Copy)]
pub struct ShaderUniform<T : ?Sized>{
    location : GLint,
    phantom : PhantomData<T>,
}

/// Shader uniform type
///
/// For now a small subset
pub trait UniformType {}

/// Shader uniform float
pub trait SUFloat : UniformType {}

/// Shader uniform integer
pub trait SUInt : UniformType {}

/// Shader uniform vector of size 2
/// Vector elements are floats
pub trait SUVec2 : UniformType {}

/// Shader uniform vector of size 3
/// Vector elements are floats
pub trait SUVec3 : UniformType {}

/// Shader uniform vector of size 4
/// Vector elements are floats
pub trait SUVec4 : UniformType {}

/// Shader uniform 2x2 matrix
/// Matrix elements are floats
pub trait SUMat2x2 : UniformType {}

/// Shader uniform 3x3 matrix
/// Matrix elements are floats
pub trait SUMat3x3 : UniformType {}

/// Shader uniform 4x4 matrix
/// Matrix elements are floats
pub trait SUMat4x4 : UniformType {}

impl GlGraphics {
    /// Try to get uniform from the current shader of a given name.
    pub fn get_uniform<T : UniformType + ?Sized>(&self, name : &str) -> Option<ShaderUniform<T>> {
        self.get_current_program().and_then( |p| {
            match unsafe {gl::GetUniformLocation(p, CString::new(name).unwrap().
                                                  as_ptr())} {
                -1 => None,
                location => {
                    Some(ShaderUniform{
                        location : location,
                        phantom : PhantomData,
                    })
                },
            }
        })
    }
}

impl ShaderUniform<SUFloat> {
    /// Set the value of the float uniform.
    pub fn set(&self, gl : &GlGraphics, value : f32) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform1f(p, self.location, value)}
        });
    }
}

impl ShaderUniform<SUInt> {
    /// Set the value of the integer uniform.
    pub fn set(&self, gl : &GlGraphics, value : i32) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform1i(p, self.location, value)}
        });
    }
}

impl ShaderUniform<SUVec2> {
    /// Set the value of the vector 2 uniform.
    pub fn set(&self, gl : &GlGraphics, value : &[f32; 2]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform2f(p, self.location, value[0], value[1])}
        });
    }
}

impl ShaderUniform<SUVec3> {
    /// Set the value of the vector 3 uniform.
    pub fn set(&self, gl : &GlGraphics, value : &[f32; 3]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform3f(p, self.location, value[0], value[1], value[2])}
        });
    }
}

impl ShaderUniform<SUVec4> {
    /// Set the value of the vector 4 uniform.
    pub fn set(&self, gl : &GlGraphics, value : &[f32; 4]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform4f(p, self.location, value[0], value[1], value[2], value[3])}
        });
    }
}

impl ShaderUniform<SUMat2x2> {
    /// Set the value of the 2x2 matrix uniform.
    pub fn set(&self, gl : &GlGraphics, values : &[f32; 4]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniformMatrix2fv(p, self.location, 1 as GLint, false as GLboolean, values.as_ptr())}
        });
    }
}

impl ShaderUniform<SUMat3x3> {
    /// Set the value of the 3x3 matrix uniform.
    pub fn set(&self, gl : &GlGraphics, values : &[f32; 9]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniformMatrix3fv(p, self.location, 1 as GLint, false as GLboolean, values.as_ptr())}
        });
    }
}

impl ShaderUniform<SUMat4x4> {
    /// Set the value of the 4x4 matrix uniform.
    pub fn set(&self, gl : &GlGraphics, values : &[f32; 16]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniformMatrix4fv(p, self.location, 1 as GLint, false as GLboolean, values.as_ptr())}
        });
    }
}
<commit_msg>Change uniform type traits to structs, drop c string<commit_after>//! Types and methods for setting shader uniforms

// External crates.
use std::ffi::CString;
use gl;
use gl::types::{GLboolean, GLint};
use std::marker::PhantomData;

// Local crate.
use back_end::GlGraphics;

/// Describes a shader uniform of a given type.
#[derive(Clone, Copy)]
pub struct ShaderUniform<T : ?Sized>{
    location : GLint,
    phantom : PhantomData<T>,
}

/// Shader uniform type
///
/// For now a small subset
pub trait UniformType {}

/// Shader uniform float
#[derive(Clone, Copy)]
pub struct SUFloat {}
impl UniformType for SUFloat {}

/// Shader uniform integer
#[derive(Clone, Copy)]
pub struct SUInt {}
impl UniformType for SUInt {}

/// Shader uniform vector of size 2
/// Vector elements are floats
#[derive(Clone, Copy)]
pub struct SUVec2 {}
impl UniformType for SUVec2 {}

/// Shader uniform vector of size 3
/// Vector elements are floats
#[derive(Clone, Copy)]
pub struct SUVec3 {}
impl UniformType for SUVec3 {}

/// Shader uniform vector of size 4
/// Vector elements are floats
#[derive(Clone, Copy)]
pub struct SUVec4 {}
impl UniformType for SUVec4 {}

/// Shader uniform 2x2 matrix
/// Matrix elements are floats
#[derive(Clone, Copy)]
pub struct SUMat2x2 {}
impl UniformType for SUMat2x2 {}

/// Shader uniform 3x3 matrix
/// Matrix elements are floats
#[derive(Clone, Copy)]
pub struct SUMat3x3 {}
impl UniformType for SUMat3x3 {}

/// Shader uniform 4x4 matrix
/// Matrix elements are floats
#[derive(Clone, Copy)]
pub struct SUMat4x4 {}
impl UniformType for SUMat4x4 {}

impl GlGraphics {
    /// Try to get uniform from the current shader of a given name.
    pub fn get_uniform<T : UniformType + ?Sized>(&self, name : &str) -> Option<ShaderUniform<T>> {
        self.get_current_program().and_then( |p| {
            unsafe {
                let c_source = CString::new(name).ok();
                c_source.and_then(|name| {
                    let uniform = match gl::GetUniformLocation(p, name.as_ptr()) {
                        -1 => None,
                        location => {
                            Some(ShaderUniform{
                                location : location,
                                phantom : PhantomData,
                            })
                        },
                    };
                    drop(name);
                    uniform
                })
            }
        })
    }
}

impl ShaderUniform<SUFloat> {
    /// Set the value of the float uniform.
    pub fn set(&self, gl : &GlGraphics, value : f32) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform1f(p, self.location, value)}
        });
    }
}

impl ShaderUniform<SUInt> {
    /// Set the value of the integer uniform.
    pub fn set(&self, gl : &GlGraphics, value : i32) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform1i(p, self.location, value)}
        });
    }
}

impl ShaderUniform<SUVec2> {
    /// Set the value of the vector 2 uniform.
    pub fn set(&self, gl : &GlGraphics, value : &[f32; 2]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform2f(p, self.location, value[0], value[1])}
        });
    }
}

impl ShaderUniform<SUVec3> {
    /// Set the value of the vector 3 uniform.
    pub fn set(&self, gl : &GlGraphics, value : &[f32; 3]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform3f(p, self.location, value[0], value[1], value[2])}
        });
    }
}

impl ShaderUniform<SUVec4> {
    /// Set the value of the vector 4 uniform.
    pub fn set(&self, gl : &GlGraphics, value : &[f32; 4]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniform4f(p, self.location, value[0], value[1], value[2], value[3])}
        });
    }
}

impl ShaderUniform<SUMat2x2> {
    /// Set the value of the 2x2 matrix uniform.
    pub fn set(&self, gl : &GlGraphics, values : &[f32; 4]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniformMatrix2fv(p, self.location, 1 as GLint, false as GLboolean, values.as_ptr())}
        });
    }
}

impl ShaderUniform<SUMat3x3> {
    /// Set the value of the 3x3 matrix uniform.
    pub fn set(&self, gl : &GlGraphics, values : &[f32; 9]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniformMatrix3fv(p, self.location, 1 as GLint, false as GLboolean, values.as_ptr())}
        });
    }
}

impl ShaderUniform<SUMat4x4> {
    /// Set the value of the 4x4 matrix uniform.
    pub fn set(&self, gl : &GlGraphics, values : &[f32; 16]) {
        gl.get_current_program().map(|p| {
            unsafe {gl::ProgramUniformMatrix4fv(p, self.location, 1 as GLint, false as GLboolean, values.as_ptr())}
        });
    }
}
<|endoftext|>


<commit_before>//! The `css_parse` module parses css stylesheets into css rule datastructures.

use css::{Declaration, Rule, Selector, SimpleSelector, Stylesheet};

use std::iter::Peekable;
use std::str::Chars;

pub struct CssParser<'a> {
    chars: Peekable<Chars<'a>>,
}

impl<'a> CssParser<'a> {
    /// Constructs a new CssParser.
    ///
    /// full_css: the complete css stylesheet to parse.
    pub fn new(full_css: &str) -> CssParser {
        CssParser { chars: full_css.chars().peekable() }
    }

    /// Entry point to parsing css, iterively parse css rules.
    pub fn parse_stylesheet(&mut self) -> Stylesheet {
        let mut stylesheet = Stylesheet::default();

        while self.chars.peek().is_some() {
            let selectors = self.parse_selectors();
            let styles = self.parse_declarations();
            let rule = Rule::new(selectors, styles);

            stylesheet.rules.push(rule);
        }

        stylesheet
    }

    /// Parse the selectors for a single rule.
    fn parse_selectors(&mut self) -> Vec<Selector> {
        let mut selectors = Vec::new();

        while self.chars.peek().map_or(false, |c| *c != '{') {
            let selector = self.parse_selector();
            selectors.push(selector);

            self.consume_while(char::is_whitespace);
            if self.chars.peek().map_or(false, |c| *c == ',') {
                self.chars.next();
            }
        }

        self.chars.next();
        selectors
    }

    /// Parse a single selector in a comma seperated list of selectors.
    fn parse_selector(&mut self) -> Selector {
        let mut sselector = SimpleSelector::default();
        let mut selector = Selector::default();

        self.consume_while(char::is_whitespace);

        sselector.tag_name = match self.chars.peek() {
            Some(&c) if c == '#' || c == '.' => None,
            Some(_) => Some(self.parse_identifier()),
            None => None,
        };

        while self.chars.peek().map_or(false, |c| *c != ',' && *c != '{' && !(*c).is_whitespace()) {
            match self.chars.peek() {
                Some(&c) if c =='#' =>  {
                    self.chars.next();
                    sselector.id = self.parse_id();
                },
                Some(&c) if c == '.' => {
                    self.chars.next();
                    sselector.classes.push(self.parse_identifier());
                },
                _ => panic!("INVALID STATE IN parse_selector"), // TODO handle css errors
            }
        }

        selector.simple.push(sselector);
        selector
    }

    /// Parse a css identifier.
    fn parse_identifier(&mut self) -> String {
        let mut ident = String::new();

        match self.chars.peek() {
            Some(&c) => {
                if is_valid_start_ident(c) {
                    ident.push_str(&self.consume_while(is_valid_ident))
                }
            },
            None => {},
        }

        ident
    }

    /// Parse the id portion of a selector.
    fn parse_id(&mut self) -> Option<String> {
        match &self.parse_identifier()[..] {
            "" => None,
            s @ _ => Some(s.to_string())
        }
    }

    /// Parse all the declarations for a rule.
    fn parse_declarations(&mut self) -> Vec<Declaration> {
        let mut declarations = Vec::<Declaration>::new();

        while self.chars.peek().map_or(false, |c| *c != '}') {
            self.consume_while(char::is_whitespace);

            let property = self.consume_while(|x| x != ':');

            self.chars.next();
            self.consume_while(char::is_whitespace);

            //TODO fix for correctness
            let value = self.consume_while(|x| x != ';' && x != '\n' && x != '}');
            let declaration = Declaration::new(property, value);

            declarations.push(declaration);

            if self.chars.peek().map_or(false, |c| *c == ';') {
                self.chars.next();
            }
            self.consume_while(char::is_whitespace);
        }

        self.chars.next();
        declarations
    }

    /// Consumes characters until condition is false or there are no more chars left.
    /// Returns a string of the consumed characters.
    fn consume_while<F>(&mut self, condition: F) -> String where F : Fn(char) -> bool {
        let mut result = String::new();
        while self.chars.peek().map_or(false, |c| condition(*c)) {
            // the check above guarentees there is a value to be consumed
            result.push(self.chars.next().unwrap());
        }

        result
    }
}

/// Returns true if the char is a valid for a css identifier.
fn is_valid_ident(c: char) -> bool {
    is_valid_start_ident(c) || c.is_digit(10) || c == '-'
}

/// Returns true if the char is a valid for the first char of a css identifier.
fn is_valid_start_ident(c: char) -> bool {
    is_letter(c) || is_non_ascii(c) || c == '_'
}

/// Returns true if the char is an ASCII letter.
fn is_letter(c: char) -> bool {
    is_upper_letter(c) || is_lower_letter(c)
}

/// Returns true if the char is an ASCII uppercase char.
fn is_upper_letter(c: char) -> bool {
    c >= 'A' && c <= 'Z'
}

/// Returns true if the char is an ASCII lowercase char.
fn is_lower_letter(c: char) -> bool {
    c >= 'a' && c <= 'z'
}

/// Returns true if the char is non-ascii.
fn is_non_ascii(c: char) -> bool {
    c >= '\u{0080}'
}

//TODO
//  -deal with comments and escaping characters
//  -complex selectors
//  -counter instead of destroy vec elements
//  -cascade
//  -specificity

/// Tests ----------------------------------------------------------------------
#[cfg(test)]
mod tests {
    use super::*;
    use std::iter::Peekable;
    use std::str::Chars;

    /// Test a parser is constructed correctly.
    #[test]
    fn new_parser() {
        let (parser, mut expected_chars) = test_parser("p{lel:kek;}");

        for character in parser.chars {
            assert_eq!(character, expected_chars.next().unwrap());
        }

        assert_eq!(None, expected_chars.peek());
    }

    /// Utility to return a parser for tests.
    fn test_parser<'a>(mock_css: &'a str) -> (CssParser, Peekable<Chars<'a>>) {
        let parser = CssParser::new(mock_css);
        let expected_chars = mock_css.chars().peekable();
        (parser, expected_chars)
    }
}<commit_msg>initial css parsing tests<commit_after>//! The `css_parse` module parses css stylesheets into css rule datastructures.

use css::{Declaration, Rule, Selector, SimpleSelector, Stylesheet};

use std::iter::Peekable;
use std::str::Chars;

pub struct CssParser<'a> {
    chars: Peekable<Chars<'a>>,
}

impl<'a> CssParser<'a> {
    /// Constructs a new CssParser.
    ///
    /// full_css: the complete css stylesheet to parse.
    pub fn new(full_css: &str) -> CssParser {
        CssParser { chars: full_css.chars().peekable() }
    }

    /// Entry point to parsing css, iterively parse css rules.
    pub fn parse_stylesheet(&mut self) -> Stylesheet {
        let mut stylesheet = Stylesheet::default();

        while self.chars.peek().is_some() {
            let selectors = self.parse_selectors();
            let styles = self.parse_declarations();
            let rule = Rule::new(selectors, styles);

            stylesheet.rules.push(rule);
        }

        stylesheet
    }

    /// Parse the selectors for a single rule.
    fn parse_selectors(&mut self) -> Vec<Selector> {
        let mut selectors = Vec::new();

        while self.chars.peek().map_or(false, |c| *c != '{') {
            let selector = self.parse_selector();
            selectors.push(selector);

            self.consume_while(char::is_whitespace);
            if self.chars.peek().map_or(false, |c| *c == ',') {
                self.chars.next();
            }
        }

        self.chars.next();
        selectors
    }

    /// Parse a single selector in a comma seperated list of selectors.
    fn parse_selector(&mut self) -> Selector {
        let mut sselector = SimpleSelector::default();
        let mut selector = Selector::default();

        self.consume_while(char::is_whitespace);

        sselector.tag_name = match self.chars.peek() {
            Some(&c) if c == '#' || c == '.' => None,
            Some(_) => Some(self.parse_identifier()),
            None => None,
        };

        while self.chars.peek().map_or(false, |c| *c != ',' && *c != '{' && !(*c).is_whitespace()) {
            match self.chars.peek() {
                Some(&c) if c =='#' =>  {
                    self.chars.next();
                    sselector.id = self.parse_id();
                },
                Some(&c) if c == '.' => {
                    self.chars.next();
                    sselector.classes.push(self.parse_identifier());
                },
                _ => panic!("INVALID STATE IN parse_selector"), // TODO handle css errors
            }
        }

        selector.simple.push(sselector);
        selector
    }

    /// Parse a css identifier.
    fn parse_identifier(&mut self) -> String {
        let mut ident = String::new();

        match self.chars.peek() {
            Some(&c) => {
                if is_valid_start_ident(c) {
                    ident.push_str(&self.consume_while(is_valid_ident))
                }
            },
            None => {},
        }

        ident
    }

    /// Parse the id portion of a selector.
    fn parse_id(&mut self) -> Option<String> {
        match &self.parse_identifier()[..] {
            "" => None,
            s @ _ => Some(s.to_string())
        }
    }

    /// Parse all the declarations for a rule.
    fn parse_declarations(&mut self) -> Vec<Declaration> {
        let mut declarations = Vec::<Declaration>::new();

        while self.chars.peek().map_or(false, |c| *c != '}') {
            self.consume_while(char::is_whitespace);

            let property = self.consume_while(|x| x != ':');

            self.chars.next();
            self.consume_while(char::is_whitespace);

            //TODO fix for correctness
            let value = self.consume_while(|x| x != ';' && x != '\n' && x != '}');
            let declaration = Declaration::new(property, value);

            declarations.push(declaration);

            if self.chars.peek().map_or(false, |c| *c == ';') {
                self.chars.next();
            }
            self.consume_while(char::is_whitespace);
        }

        self.chars.next();
        declarations
    }

    /// Consumes characters until condition is false or there are no more chars left.
    /// Returns a string of the consumed characters.
    fn consume_while<F>(&mut self, condition: F) -> String where F : Fn(char) -> bool {
        let mut result = String::new();
        while self.chars.peek().map_or(false, |c| condition(*c)) {
            // the check above guarentees there is a value to be consumed
            result.push(self.chars.next().unwrap());
        }

        result
    }
}

/// Returns true if the char is a valid for a css identifier.
fn is_valid_ident(c: char) -> bool {
    is_valid_start_ident(c) || c.is_digit(10) || c == '-'
}

/// Returns true if the char is a valid for the first char of a css identifier.
fn is_valid_start_ident(c: char) -> bool {
    is_letter(c) || is_non_ascii(c) || c == '_'
}

/// Returns true if the char is an ASCII letter.
fn is_letter(c: char) -> bool {
    is_upper_letter(c) || is_lower_letter(c)
}

/// Returns true if the char is an ASCII uppercase char.
fn is_upper_letter(c: char) -> bool {
    c >= 'A' && c <= 'Z'
}

/// Returns true if the char is an ASCII lowercase char.
fn is_lower_letter(c: char) -> bool {
    c >= 'a' && c <= 'z'
}

/// Returns true if the char is non-ascii.
fn is_non_ascii(c: char) -> bool {
    c >= '\u{0080}'
}

//TODO
//  -deal with comments and escaping characters
//  -complex selectors
//  -cascade
//  -specificity

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

    use css::{Declaration};

    /// Test a parser is constructed correctly.
    #[test]
    fn parser_regular() {
        let css = "p{lel:kek;}";
        let mut parser = CssParser::new(css);

        for character in String::from(css).chars() {
            assert_eq!(character, parser.chars.next().unwrap());
        }

        assert_eq!(None, parser.chars.peek());
    }

    /// Test an empty parser is constructed correctly.
    #[test]
    fn parser_empty() {
        let mut parser = CssParser::new("");

        for character in String::from("").chars() {
            assert_eq!(character, parser.chars.next().unwrap());
        }

        assert_eq!(None, parser.chars.peek());
    }

    /// Test declaration parsing
    #[test]
    fn declarations_empty() {
        let mut parser = CssParser::new("");
        assert_eq!(Vec::<Declaration>::new(), parser.parse_declarations());
    }

    /// Test declaration parsing
    #[test]
    fn declarations_end() {
        let mut parser = CssParser::new("}");
        assert_eq!(Vec::<Declaration>::new(), parser.parse_declarations());
    }

    /// Test declaration parsing
    #[test]
    fn declarations_regular() {
        let mut parser = CssParser::new(
            "color:red;
             border-width: 1px;
             background-color: aqua
           }");
        let decl_col = Declaration::new(String::from("color"), String::from("red"));
        let decl_bw = Declaration::new(String::from("border-width"), String::from("1px"));
        let decl_bg_col = Declaration::new(String::from("background-color"), String::from("aqua"));

        let expected = vec![decl_col, decl_bw, decl_bg_col];
        assert_eq!(expected, parser.parse_declarations());
    }

    /// Test declaration parsing
    #[test]
    fn declarations_invalid() {
        let mut parser = CssParser::new(
            "color:red;
             border-width: 1px
             background-color: aqua
           }");
        let decl_col = Declaration::new(String::from("color"), String::from("red"));
        let decl_bg_col = Declaration::new(String::from("background-color"), String::from("aqua"));

        let expected = vec![decl_col, decl_bg_col];
        assert_eq!(expected, parser.parse_declarations());
    }

    /// Test id parsing
    #[test]
    fn id() {

    }

    /// Test identifier parsing
    #[test]
    fn identifier() {

    }

    /// Test selector parsing
    #[test]
    fn selector() {

    }

    /// Test selectors parsing (comma seperated list)
    #[test]
    fn selectors() {

    }

    /// Test stylesheet parsing
    #[test]
    fn stylesheet() {

    }
}
<|endoftext|>


<commit_before>#![crate_type = "rlib"]

//! Macro to create a "view box", a box containing immutable data plus
//! a "view" struct that can have interior references into the data.
//! The view box can be moved around as an atomic unit.  I haven't
//! convinced myself this is memory safe yet.  Known issues:
//!
//! * If the view type implements Drop (via #[unsafe_destructor]), it
//! could potentially observe dangling references depending on the
//! order in which struct fields are destroyed.  Currently, struct
//! fields seem to be destroyed in reverse order, which means things
//! should work fine as-is, but this depends on implementation details
//! of the compiler.  This could be fixed trivially by changing the
//! struct internals and adding a Drop impl that forces the view
//! to be destroyed first (e.g. by putting it in an Option and calling
//! .take()) at the cost of memory usage.
#![feature(macro_rules, globs)]

#[macro_export]
macro_rules! viewbox(
    (struct $name:ident<$d:ty, $v:ident>;) => (
        pub struct $name {
            data: Box<$d>,
            view: $v<'static>
        }

        #[allow(dead_code)]
        impl $name {
            pub fn new(data: $d, f: <'a>|&'a mut $d| -> $v<'a>) -> $name {
                let mut d = box data;
                let v = unsafe { ::std::mem::transmute(f(&mut *d)) };

                $name { data: d, view: v }
            }

            pub fn new_result<E>(data: $d,
                                 f: <'a>|&'a mut $d|
                                    -> ::std::result::Result<$v<'a>,E>)
                                 -> ::std::result::Result<$name,($d,E)> {
                let mut d = box data;
                match f(&mut *d).map(|v| unsafe { ::std::mem::transmute(v) }) {
                    Ok(v) => Ok($name { data: d, view: v }),
                    Err(e) => Err((*d,e))
                }
            }

            pub fn unwrap(self)-> $d {
                let $name { data: box data, .. } = self;
                data
            }

            pub fn view<'a>(&'a self) -> &'a $v<'a> {
                unsafe { ::std::mem::transmute(&self.view) }
            }

            pub fn mut_view<'a>(&'a mut self) -> &'a mut $v<'a> {
                unsafe { ::std::mem::transmute(&mut self.view) }
            }
        }
    );
    (#[deriving(PartialEq $(,$derive:ident)*)] struct $name:ident<$d:ty, $v:ident>;) => (
        impl ::std::cmp::PartialEq for $name {
            fn eq(&self, other: &$name) -> bool { self.view() == other.view(); }
        }
        viewbox!(struct $name<$d,$v>;)
    );
    (#[deriving(Show $(,$derive:ident)*)] struct $name:ident<$d:ty, $v:ident>;) => (
        impl ::std::fmt::Show for $name {
            fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
                   -> ::std::result::Result<(), ::std::fmt::FormatError> {
                self.view().fmt(fmt)
            }
        }
        viewbox!(struct $name<$d,$v>;)
    );
    (#[deriving()] struct $name:ident<$d:ty, $v:ident>;) => (
        viewbox!(struct $name<$d,$v>;)
    );
)

#[cfg(test)]
mod test {
    // Test data structure
    #[deriving(PartialEq,Show)]
    struct TestData {
        foo: i32,
        bar: String
    }

    // View structure that has references into the boxed data
    struct TestView<'a> {
        x: &'a i32,
        y: &'a str
    }

    // Create TestBox which combines TestData and TestView
    viewbox! {
        struct TestBox<TestData,TestView>;
    }

    // Mutable view into string
    struct MutView<'a> {
        x: &'a mut String
    }

    // MutBox combines TestData and MutView
    viewbox! {
        struct MutBox<TestData, MutView>;
    }

    #[test]
    fn basic() {
        // Create some data
        let t = TestData { foo: 42, bar: "Hello".to_string() };
        // Move it into box, creating a view with interior references
        let v = TestBox::new(t, |d| TestView { x: &d.foo, y: d.bar.as_slice() });

        // We can access the boxed data via the view
        assert_eq!(v.view().x, &42i32);
        assert_eq!(v.view().y, "Hello");
        // We can unwrap the view to get the data back
        let t = v.unwrap();
        assert_eq!(t.foo, 42i32);
        assert_eq!(t.bar, "Hello".to_string());
    }

    #[test]
    fn mutation() {
        let t = TestData { foo: 42, bar: "Hello".to_string() };
        let mut v = MutBox::new(t, |d| MutView { x: &mut d.bar });

        *v.mut_view().x = "Goodbye".to_string();
        let t = v.unwrap();
        assert_eq!(t.bar, "Goodbye".to_string());
    }

    #[test]
    fn error() {
        let t = TestData { foo: 42, bar: "Hello".to_string() };
        let v = MutBox::new_result(t, |_| Err("Nope")).err().unwrap();
        assert_eq!(v, (TestData { foo: 42, bar: "Hello".to_string() }, "Nope"))
    }
}
<commit_msg>Make mutation test borrow both fields<commit_after>#![crate_type = "rlib"]

//! Macro to create a "view box", a box containing immutable data plus
//! a "view" struct that can have interior references into the data.
//! The view box can be moved around as an atomic unit.  I haven't
//! convinced myself this is memory safe yet.  Known issues:
//!
//! * If the view type implements Drop (via #[unsafe_destructor]), it
//! could potentially observe dangling references depending on the
//! order in which struct fields are destroyed.  Currently, struct
//! fields seem to be destroyed in reverse order, which means things
//! should work fine as-is, but this depends on implementation details
//! of the compiler.  This could be fixed trivially by changing the
//! struct internals and adding a Drop impl that forces the view
//! to be destroyed first (e.g. by putting it in an Option and calling
//! .take()) at the cost of memory usage.
#![feature(macro_rules, globs)]

#[macro_export]
macro_rules! viewbox(
    (struct $name:ident<$d:ty, $v:ident>;) => (
        pub struct $name {
            data: Box<$d>,
            view: $v<'static>
        }

        #[allow(dead_code)]
        impl $name {
            pub fn new(data: $d, f: <'a>|&'a mut $d| -> $v<'a>) -> $name {
                let mut d = box data;
                let v = unsafe { ::std::mem::transmute(f(&mut *d)) };

                $name { data: d, view: v }
            }

            pub fn new_result<E>(data: $d,
                                 f: <'a>|&'a mut $d|
                                    -> ::std::result::Result<$v<'a>,E>)
                                 -> ::std::result::Result<$name,($d,E)> {
                let mut d = box data;
                match f(&mut *d).map(|v| unsafe { ::std::mem::transmute(v) }) {
                    Ok(v) => Ok($name { data: d, view: v }),
                    Err(e) => Err((*d,e))
                }
            }

            pub fn unwrap(self)-> $d {
                let $name { data: box data, .. } = self;
                data
            }

            pub fn view<'a>(&'a self) -> &'a $v<'a> {
                unsafe { ::std::mem::transmute(&self.view) }
            }

            pub fn mut_view<'a>(&'a mut self) -> &'a mut $v<'a> {
                unsafe { ::std::mem::transmute(&mut self.view) }
            }
        }
    );
    (#[deriving(PartialEq $(,$derive:ident)*)] struct $name:ident<$d:ty, $v:ident>;) => (
        impl ::std::cmp::PartialEq for $name {
            fn eq(&self, other: &$name) -> bool { self.view() == other.view(); }
        }
        viewbox!(struct $name<$d,$v>;)
    );
    (#[deriving(Show $(,$derive:ident)*)] struct $name:ident<$d:ty, $v:ident>;) => (
        impl ::std::fmt::Show for $name {
            fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
                   -> ::std::result::Result<(), ::std::fmt::FormatError> {
                self.view().fmt(fmt)
            }
        }
        viewbox!(struct $name<$d,$v>;)
    );
    (#[deriving()] struct $name:ident<$d:ty, $v:ident>;) => (
        viewbox!(struct $name<$d,$v>;)
    );
)

#[cfg(test)]
mod test {
    // Test data structure
    #[deriving(PartialEq,Show)]
    struct TestData {
        foo: i32,
        bar: String
    }

    // View structure that has references into the boxed data
    struct TestView<'a> {
        x: &'a i32,
        y: &'a str
    }

    // Create TestBox which combines TestData and TestView
    viewbox! {
        struct TestBox<TestData,TestView>;
    }

    // Mutable view into TestData
    struct MutView<'a> {
        x: &'a mut i32,
        y: &'a mut String
    }

    // MutBox combines TestData and MutView
    viewbox! {
        struct MutBox<TestData, MutView>;
    }

    #[test]
    fn basic() {
        // Create some data
        let t = TestData { foo: 42, bar: "Hello".to_string() };
        // Move it into box, creating a view with interior references
        let v = TestBox::new(t, |d| TestView { x: &d.foo, y: d.bar.as_slice() });

        // We can access the boxed data via the view
        assert_eq!(v.view().x, &42i32);
        assert_eq!(v.view().y, "Hello");
        // We can unwrap the view to get the data back
        let t = v.unwrap();
        assert_eq!(t.foo, 42i32);
        assert_eq!(t.bar, "Hello".to_string());
    }

    #[test]
    fn mutation() {
        let t = TestData { foo: 42, bar: "Hello".to_string() };
        let mut v = MutBox::new(t, |d| MutView { x: &mut d.foo, y: &mut d.bar });

        *v.mut_view().x = 5;
        *v.mut_view().y = "Goodbye".to_string();
        let t = v.unwrap();
        assert_eq!(t, TestData { foo: 5, bar: "Goodbye".to_string() });
    }

    #[test]
    fn error() {
        let t = TestData { foo: 42, bar: "Hello".to_string() };
        let v = MutBox::new_result(t, |_| Err("Nope")).err().unwrap();
        assert_eq!(v, (TestData { foo: 42, bar: "Hello".to_string() }, "Nope"))
    }
}
<|endoftext|>