<commit_before>use std::ops::Mul;
use na::{self, Matrix4, Matrix2, Similarity3, U3};

use {Vector2f, Vector3f, Point3f, gamma};

#[derive(Debug)]
pub struct Transform {
    pub m: Matrix4<f32>,
    pub m_inv: Matrix4<f32>,
}

impl Transform {
    pub fn new(t: Vector3f, r: Vector3f, s: f32) -> Transform {
        Transform::from_similarity(&Similarity3::new(t, r, s))
    }

    pub fn from_similarity(s: &Similarity3<f32>) -> Transform {
        Transform {
            m: s.to_homogeneous(),
            m_inv: s.inverse().to_homogeneous(),
        }
    }

    pub fn inverse(&self) -> Self {
        Transform {
            m: self.m_inv,
            m_inv: self.m,
        }
    }
}

impl Default for Transform {
    fn default() -> Self {
        Transform {
            m: na::one(),
            m_inv: na::one(),
        }
    }
}

impl<'a> Mul<&'a Point3f> for Transform {
    type Output = Point3f;

    fn mul(self, p: &'a Point3f) -> Point3f {
        let x = p.x;
        let y = p.y;
        let z = p.z;
        let xp = self.m[(0, 0)] * x + self.m[(0, 1)] * y + self.m[(0, 2)] * z + self.m[(0, 3)];
        let yp = self.m[(1, 0)] * x + self.m[(1, 1)] * y + self.m[(1, 2)] * z + self.m[(1, 3)];
        let zp = self.m[(2, 0)] * x + self.m[(2, 1)] * y + self.m[(2, 2)] * z + self.m[(2, 3)];
        let wp = self.m[(3, 0)] * x + self.m[(3, 1)] * y + self.m[(3, 2)] * z + self.m[(3, 3)];

        assert!(wp != 0.0);

        if wp == 1.0 {
            Point3f::new(xp, yp, zp)
        } else {
            Point3f::new(xp, yp, zp) / wp
        }
    }
}

impl<'a, 'b> Mul<&'a Point3f> for &'b Transform {
    type Output = Point3f;

    fn mul(self, p: &'a Point3f) -> Point3f {
        let x = p.x;
        let y = p.y;
        let z = p.z;
        let xp = self.m[(0, 0)] * x + self.m[(0, 1)] * y + self.m[(0, 2)] * z + self.m[(0, 3)];
        let yp = self.m[(1, 0)] * x + self.m[(1, 1)] * y + self.m[(1, 2)] * z + self.m[(1, 3)];
        let zp = self.m[(2, 0)] * x + self.m[(2, 1)] * y + self.m[(2, 2)] * z + self.m[(2, 3)];
        let wp = self.m[(3, 0)] * x + self.m[(3, 1)] * y + self.m[(3, 2)] * z + self.m[(3, 3)];

        assert!(wp != 0.0);

        if wp == 1.0 {
            Point3f::new(xp, yp, zp)
        } else {
            Point3f::new(xp, yp, zp) / wp
        }
    }
}

impl<'a> Mul<&'a Vector3f> for Transform {
    type Output = Vector3f;

    fn mul(self, v: &'a Vector3f) -> Vector3f {
        let x = v.x;
        let y = v.y;
        let z = v.z;

        Vector3f::new(self.m[(0, 0)] * x + self.m[(0, 1)] * y + self.m[(0, 2)] * z,
                      self.m[(1, 0)] * x + self.m[(1, 1)] * y + self.m[(1, 2)] * z,
                      self.m[(2, 0)] * x + self.m[(2, 1)] * y + self.m[(2, 2)] * z)

    }
}

impl<'a, 'b> Mul<&'a Vector3f> for &'b Transform {
    type Output = Vector3f;

    fn mul(self, v: &'a Vector3f) -> Vector3f {
        let x = v.x;
        let y = v.y;
        let z = v.z;

        Vector3f::new(self.m[(0, 0)] * x + self.m[(0, 1)] * y + self.m[(0, 2)] * z,
                      self.m[(1, 0)] * x + self.m[(1, 1)] * y + self.m[(1, 2)] * z,
                      self.m[(2, 0)] * x + self.m[(2, 1)] * y + self.m[(2, 2)] * z)

    }
}

#[allow(non_snake_case)]
pub fn solve_linear_system2x2(A: &Matrix2<f32>, B: &Vector2f) -> Option<(f32, f32)> {
    let det = A.determinant();
    if det.abs() < 1e-10 {
        return None;
    }
    let x0 = (A[(1, 1)] * B[0] - A[(0, 1)] * B[1]) / det;
    let x1 = (A[(0, 0)] * B[1] - A[(1, 0)] * B[0]) / det;

    if x0.is_nan() || x1.is_nan() {
        return None;
    }
    return Some((x0, x1));
}

/// Transform the given point using the given transformation and also return a vector of the
/// absolute error introduced for each coordinate.
pub fn transform_point(t: &Transform, p: &Point3f) -> (Point3f, Vector3f) {
    let (x, y, z) = (p.x, p.y, p.z);
    let tp = t * p;
    let m: Matrix4<f32> = t.m;
    let x_abs_sum = (m[(0, 0)] * x).abs() + (m[(0, 1)] * y).abs() + (m[(0, 2)] * z).abs() +
                    m[(0, 3)].abs();
    let y_abs_sum = (m[(1, 0)] * x).abs() + (m[(1, 1)] * y).abs() + (m[(1, 2)] * z).abs() +
                    m[(1, 3)].abs();
    let z_abs_sum = (m[(2, 0)] * x).abs() + (m[(2, 1)] * y).abs() + (m[(2, 2)] * z).abs() +
                    m[(2, 3)].abs();
    let p_err = gamma(3) * Vector3f::new(x_abs_sum, y_abs_sum, z_abs_sum);

    (tp, p_err)
}

pub fn transform_point_with_error(t: &Transform,
                                  p: &Point3f,
                                  p_error: &Vector3f)
                                  -> (Point3f, Vector3f) {
    let (x, y, z) = (p.x, p.y, p.z);
    let tp = t * p;
    let m: Matrix4<f32> = t.m;
    let x_abs_err = (gamma(3) + 1.0) *
                    ((m[(0, 0)] * p_error.x).abs() + (m[(0, 1)] * p_error.y).abs() +
                     (m[(0, 2)] * p_error.z).abs()) +
                    gamma(3) *
                    ((m[(0, 0)] * x).abs() + (m[(0, 1)] * y).abs() + (m[(0, 2)] * z).abs() +
                     m[(0, 3)].abs());
    let y_abs_err = (gamma(3) + 1.0) *
                    ((m[(1, 0)] * p_error.x).abs() + (m[(1, 1)] * p_error.y).abs() +
                     (m[(1, 2)] * p_error.z).abs()) +
                    gamma(3) *
                    ((m[(1, 0)] * x).abs() + (m[(1, 1)] * y).abs() + (m[(1, 2)] * z).abs() +
                     m[(1, 3)].abs());
    let z_abs_err = (gamma(3) + 1.0) *
                    ((m[(2, 0)] * p_error.x).abs() + (m[(2, 1)] * p_error.y).abs() +
                     (m[(2, 2)] * p_error.z).abs()) +
                    gamma(3) *
                    ((m[(2, 0)] * x).abs() + (m[(2, 1)] * y).abs() + (m[(2, 2)] * z).abs() +
                     m[(2, 3)].abs());
    let p_err = Vector3f::new(x_abs_err, y_abs_err, z_abs_err);

    (tp, p_err)
}

/// Transform the given point using the given transformation and also return a vector of the
/// absolute error introduced for each coordinate.
pub fn transform_vector(t: &Transform, v: &Vector3f) -> (Vector3f, Vector3f) {
    let (x, y, z) = (v.x, v.y, v.z);
    let tv = t * v;
    let m: Matrix4<f32> = t.m;
    let x_abs_sum = na::abs(&(m[(0, 0)] * x)) + na::abs(&(m[(0, 1)] * y)) +
                    na::abs(&(m[(0, 2)] * z)) + na::abs(&m[(0, 3)]);
    let y_abs_sum = na::abs(&(m[(1, 0)] * x)) + na::abs(&(m[(1, 1)] * y)) +
                    na::abs(&(m[(1, 2)] * z)) + na::abs(&m[(1, 3)]);
    let z_abs_sum = na::abs(&(m[(2, 0)] * x)) + na::abs(&(m[(2, 1)] * y)) +
                    na::abs(&(m[(2, 2)] * z)) + na::abs(&m[(2, 3)]);
    let v_err = gamma(3) * Vector3f::new(x_abs_sum, y_abs_sum, z_abs_sum);

    (tv, v_err)
}

pub fn transform_normal(normal: &Vector3f, transform: &Transform) -> Vector3f {
    let m = transform.m_inv.transpose();
    m.fixed_slice::<U3, U3>(0, 0) * *normal
}

pub fn rot_x(angle: f32) -> Transform {
    Transform::new(na::zero(), Vector3f::x() * angle.to_radians(), 1.0)
}

pub fn rot_y(angle: f32) -> Transform {
    Transform::new(na::zero(), Vector3f::y() * angle.to_radians(), 1.0)
}

pub fn rot_z(angle: f32) -> Transform {
    Transform::new(na::zero(), Vector3f::z() * angle.to_radians(), 1.0)
}

pub fn rot(ax: f32, ay: f32, az: f32) -> Transform {
    Transform::new(na::zero(), Vector3f::new(ax, ay, az), 1.0)
}

pub fn translate_x(t: f32) -> Transform {
    Transform::new(Vector3f::x() * t, na::zero(), 1.0)
}

pub fn translate_y(t: f32) -> Transform {
    Transform::new(Vector3f::y() * t, na::zero(), 1.0)
}

pub fn translate_z(t: f32) -> Transform {
    Transform::new(Vector3f::z() * t, na::zero(), 1.0)
}

#[test]
fn test_normal_transform() {
    let t = Transform::new(Vector3f::new(0.0, 0.0, 0.0),
                           Vector3f::new(4.0, 5.0, 6.0),
                           4.0);
    let t_inv = t.inverse();

    let v = Vector3f::x();
    let n = Vector3f::y();
    println!("v = {}, n = {}", v, n);
    assert_eq!(v.dot(&n), 0.0);

    let v2 = t * v;
    let n2 = transform_normal(&n, &t_inv);
    println!("v = {}, n = {}", v2, n2);
    relative_eq!(v2.dot(&n2), 0.0);
}
<commit_msg>Fix test compilation<commit_after>use std::ops::Mul;
use na::{self, Matrix4, Matrix2, Similarity3, U3};

use {Vector2f, Vector3f, Point3f, gamma};

#[derive(Debug)]
pub struct Transform {
    pub m: Matrix4<f32>,
    pub m_inv: Matrix4<f32>,
}

impl Transform {
    pub fn new(t: Vector3f, r: Vector3f, s: f32) -> Transform {
        Transform::from_similarity(&Similarity3::new(t, r, s))
    }

    pub fn from_similarity(s: &Similarity3<f32>) -> Transform {
        Transform {
            m: s.to_homogeneous(),
            m_inv: s.inverse().to_homogeneous(),
        }
    }

    pub fn inverse(&self) -> Self {
        Transform {
            m: self.m_inv,
            m_inv: self.m,
        }
    }
}

impl Default for Transform {
    fn default() -> Self {
        Transform {
            m: na::one(),
            m_inv: na::one(),
        }
    }
}

impl<'a> Mul<&'a Point3f> for Transform {
    type Output = Point3f;

    fn mul(self, p: &'a Point3f) -> Point3f {
        let x = p.x;
        let y = p.y;
        let z = p.z;
        let xp = self.m[(0, 0)] * x + self.m[(0, 1)] * y + self.m[(0, 2)] * z + self.m[(0, 3)];
        let yp = self.m[(1, 0)] * x + self.m[(1, 1)] * y + self.m[(1, 2)] * z + self.m[(1, 3)];
        let zp = self.m[(2, 0)] * x + self.m[(2, 1)] * y + self.m[(2, 2)] * z + self.m[(2, 3)];
        let wp = self.m[(3, 0)] * x + self.m[(3, 1)] * y + self.m[(3, 2)] * z + self.m[(3, 3)];

        assert!(wp != 0.0);

        if wp == 1.0 {
            Point3f::new(xp, yp, zp)
        } else {
            Point3f::new(xp, yp, zp) / wp
        }
    }
}

impl<'a, 'b> Mul<&'a Point3f> for &'b Transform {
    type Output = Point3f;

    fn mul(self, p: &'a Point3f) -> Point3f {
        let x = p.x;
        let y = p.y;
        let z = p.z;
        let xp = self.m[(0, 0)] * x + self.m[(0, 1)] * y + self.m[(0, 2)] * z + self.m[(0, 3)];
        let yp = self.m[(1, 0)] * x + self.m[(1, 1)] * y + self.m[(1, 2)] * z + self.m[(1, 3)];
        let zp = self.m[(2, 0)] * x + self.m[(2, 1)] * y + self.m[(2, 2)] * z + self.m[(2, 3)];
        let wp = self.m[(3, 0)] * x + self.m[(3, 1)] * y + self.m[(3, 2)] * z + self.m[(3, 3)];

        assert!(wp != 0.0);

        if wp == 1.0 {
            Point3f::new(xp, yp, zp)
        } else {
            Point3f::new(xp, yp, zp) / wp
        }
    }
}

impl<'a> Mul<&'a Vector3f> for Transform {
    type Output = Vector3f;

    fn mul(self, v: &'a Vector3f) -> Vector3f {
        let x = v.x;
        let y = v.y;
        let z = v.z;

        Vector3f::new(self.m[(0, 0)] * x + self.m[(0, 1)] * y + self.m[(0, 2)] * z,
                      self.m[(1, 0)] * x + self.m[(1, 1)] * y + self.m[(1, 2)] * z,
                      self.m[(2, 0)] * x + self.m[(2, 1)] * y + self.m[(2, 2)] * z)

    }
}

impl<'a, 'b> Mul<&'a Vector3f> for &'b Transform {
    type Output = Vector3f;

    fn mul(self, v: &'a Vector3f) -> Vector3f {
        let x = v.x;
        let y = v.y;
        let z = v.z;

        Vector3f::new(self.m[(0, 0)] * x + self.m[(0, 1)] * y + self.m[(0, 2)] * z,
                      self.m[(1, 0)] * x + self.m[(1, 1)] * y + self.m[(1, 2)] * z,
                      self.m[(2, 0)] * x + self.m[(2, 1)] * y + self.m[(2, 2)] * z)

    }
}

#[allow(non_snake_case)]
pub fn solve_linear_system2x2(A: &Matrix2<f32>, B: &Vector2f) -> Option<(f32, f32)> {
    let det = A.determinant();
    if det.abs() < 1e-10 {
        return None;
    }
    let x0 = (A[(1, 1)] * B[0] - A[(0, 1)] * B[1]) / det;
    let x1 = (A[(0, 0)] * B[1] - A[(1, 0)] * B[0]) / det;

    if x0.is_nan() || x1.is_nan() {
        return None;
    }
    return Some((x0, x1));
}

/// Transform the given point using the given transformation and also return a vector of the
/// absolute error introduced for each coordinate.
pub fn transform_point(t: &Transform, p: &Point3f) -> (Point3f, Vector3f) {
    let (x, y, z) = (p.x, p.y, p.z);
    let tp = t * p;
    let m: Matrix4<f32> = t.m;
    let x_abs_sum = (m[(0, 0)] * x).abs() + (m[(0, 1)] * y).abs() + (m[(0, 2)] * z).abs() +
                    m[(0, 3)].abs();
    let y_abs_sum = (m[(1, 0)] * x).abs() + (m[(1, 1)] * y).abs() + (m[(1, 2)] * z).abs() +
                    m[(1, 3)].abs();
    let z_abs_sum = (m[(2, 0)] * x).abs() + (m[(2, 1)] * y).abs() + (m[(2, 2)] * z).abs() +
                    m[(2, 3)].abs();
    let p_err = gamma(3) * Vector3f::new(x_abs_sum, y_abs_sum, z_abs_sum);

    (tp, p_err)
}

pub fn transform_point_with_error(t: &Transform,
                                  p: &Point3f,
                                  p_error: &Vector3f)
                                  -> (Point3f, Vector3f) {
    let (x, y, z) = (p.x, p.y, p.z);
    let tp = t * p;
    let m: Matrix4<f32> = t.m;
    let x_abs_err = (gamma(3) + 1.0) *
                    ((m[(0, 0)] * p_error.x).abs() + (m[(0, 1)] * p_error.y).abs() +
                     (m[(0, 2)] * p_error.z).abs()) +
                    gamma(3) *
                    ((m[(0, 0)] * x).abs() + (m[(0, 1)] * y).abs() + (m[(0, 2)] * z).abs() +
                     m[(0, 3)].abs());
    let y_abs_err = (gamma(3) + 1.0) *
                    ((m[(1, 0)] * p_error.x).abs() + (m[(1, 1)] * p_error.y).abs() +
                     (m[(1, 2)] * p_error.z).abs()) +
                    gamma(3) *
                    ((m[(1, 0)] * x).abs() + (m[(1, 1)] * y).abs() + (m[(1, 2)] * z).abs() +
                     m[(1, 3)].abs());
    let z_abs_err = (gamma(3) + 1.0) *
                    ((m[(2, 0)] * p_error.x).abs() + (m[(2, 1)] * p_error.y).abs() +
                     (m[(2, 2)] * p_error.z).abs()) +
                    gamma(3) *
                    ((m[(2, 0)] * x).abs() + (m[(2, 1)] * y).abs() + (m[(2, 2)] * z).abs() +
                     m[(2, 3)].abs());
    let p_err = Vector3f::new(x_abs_err, y_abs_err, z_abs_err);

    (tp, p_err)
}

/// Transform the given point using the given transformation and also return a vector of the
/// absolute error introduced for each coordinate.
pub fn transform_vector(t: &Transform, v: &Vector3f) -> (Vector3f, Vector3f) {
    let (x, y, z) = (v.x, v.y, v.z);
    let tv = t * v;
    let m: Matrix4<f32> = t.m;
    let x_abs_sum = na::abs(&(m[(0, 0)] * x)) + na::abs(&(m[(0, 1)] * y)) +
                    na::abs(&(m[(0, 2)] * z)) + na::abs(&m[(0, 3)]);
    let y_abs_sum = na::abs(&(m[(1, 0)] * x)) + na::abs(&(m[(1, 1)] * y)) +
                    na::abs(&(m[(1, 2)] * z)) + na::abs(&m[(1, 3)]);
    let z_abs_sum = na::abs(&(m[(2, 0)] * x)) + na::abs(&(m[(2, 1)] * y)) +
                    na::abs(&(m[(2, 2)] * z)) + na::abs(&m[(2, 3)]);
    let v_err = gamma(3) * Vector3f::new(x_abs_sum, y_abs_sum, z_abs_sum);

    (tv, v_err)
}

pub fn transform_normal(normal: &Vector3f, transform: &Transform) -> Vector3f {
    let m = transform.m_inv.transpose();
    m.fixed_slice::<U3, U3>(0, 0) * *normal
}

pub fn rot_x(angle: f32) -> Transform {
    Transform::new(na::zero(), Vector3f::x() * angle.to_radians(), 1.0)
}

pub fn rot_y(angle: f32) -> Transform {
    Transform::new(na::zero(), Vector3f::y() * angle.to_radians(), 1.0)
}

pub fn rot_z(angle: f32) -> Transform {
    Transform::new(na::zero(), Vector3f::z() * angle.to_radians(), 1.0)
}

pub fn rot(ax: f32, ay: f32, az: f32) -> Transform {
    Transform::new(na::zero(), Vector3f::new(ax, ay, az), 1.0)
}

pub fn translate_x(t: f32) -> Transform {
    Transform::new(Vector3f::x() * t, na::zero(), 1.0)
}

pub fn translate_y(t: f32) -> Transform {
    Transform::new(Vector3f::y() * t, na::zero(), 1.0)
}

pub fn translate_z(t: f32) -> Transform {
    Transform::new(Vector3f::z() * t, na::zero(), 1.0)
}

#[test]
fn test_normal_transform() {
    let t = Transform::new(Vector3f::new(0.0, 0.0, 0.0),
                           Vector3f::new(4.0, 5.0, 6.0),
                           4.0);
    let t_inv = t.inverse();

    let v = Vector3f::x();
    let n = Vector3f::y();
    println!("v = {}, n = {}", v, n);
    assert_eq!(v.dot(&n), 0.0);

    let v2 = t * &v;
    let n2 = transform_normal(&n, &t_inv);
    println!("v = {}, n = {}", v2, n2);
    relative_eq!(v2.dot(&n2), 0.0);
}
<|endoftext|>


<commit_before>use std::io;

use mio::net::TcpListener;
use tokio_core::reactor::PollEvented;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::codec::{Framed, Encoder, Decoder};
use tokio_proto::streaming::pipeline::Transport;

use codec::PacketCodec;

type GearmanIO = PollEvented<TcpListener>;
type GearmanFramed = Framed<GearmanIO, PacketCodec>;

impl Transport for GearmanFramed
{
    fn tick(&mut self) {
        trace!("tick!");
    }

    fn cancel(&mut self) -> io::Result<()> {
        trace!("cancel!");
    }
}
<commit_msg>Use a newtype for transport<commit_after>use std::io;

use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::codec::{Framed, Encoder, Decoder};
use tokio_proto::streaming::pipeline::Transport;
use futures::{Poll, Sink, StartSend, Stream};

use codec::PacketCodec;

pub struct GearmanFramed<T>(Framed<T, PacketCodec>);

impl<T> Transport for GearmanFramed<T>
    where T: AsyncRead + AsyncWrite + 'static
{
    fn tick(&mut self) {
        trace!("tick!");
    }

    fn cancel(&mut self) -> io::Result<()> {
        trace!("cancel!");
        Ok(())
    }
}

impl<T> Stream for GearmanFramed<T>
    where T: AsyncRead
{
    type Item = <PacketCodec as Decoder>::Item;
    type Error = <PacketCodec as Decoder>::Error;
    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        self.0.poll()
    }
}

impl<T> Sink for GearmanFramed<T>
    where T: AsyncWrite
{
    type SinkItem = <PacketCodec as Encoder>::Item;
    type SinkError = <PacketCodec as Encoder>::Error;
    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        self.0.start_send(item)
    }
    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        self.0.poll_complete()
    }
    fn close(&mut self) -> Poll<(), Self::SinkError> {
        self.0.close()
    }
}
<|endoftext|>


<commit_before>//! Transports for communicating with the docker daemon

extern crate hyper;
extern crate mime;

use hyper::Client;
use hyper::client::Body;
use self::super::{Error, Result};
use self::hyper::buffer::BufReader;
use self::hyper::header::ContentType;
use self::hyper::status::StatusCode;
use hyper::method::Method;
use std::fmt;
use std::io::{Read, Write};
use hyperlocal::DomainUrl;

pub fn tar() -> ContentType {
    ContentType(mime::Mime(mime::TopLevel::Application,
                           mime::SubLevel::Ext(String::from("tar")),
                           vec![]))
}

/// Transports are types which define the means of communication
/// with the docker daemon
pub enum Transport {
    /// A network tcp interface
    Tcp {
        client: Client,
        host: String,
    },
    /// A Unix domain socket
    Unix {
        client: Client,
        path: String,
    },
}

impl fmt::Debug for Transport {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Transport::Tcp { ref host, .. } => write!(f, "Tcp({})", host),
            Transport::Unix { ref path, .. } => write!(f, "Unix({})", path),
        }
    }
}

impl Transport {
    pub fn request<'a, B>(&'a self,
                          method: Method,
                          endpoint: &str,
                          body: Option<(B, ContentType)>)
                          -> Result<String>
        where B: Into<Body<'a>>
    {
        let mut res = match self.stream(method, endpoint, body) {
            Ok(r) => r,
            Err(e) => panic!("failed request {:?}", e),
        };
        let mut body = String::new();
        try!(res.read_to_string(&mut body));
        debug!("{} raw response: {}", endpoint, body);
        Ok(body)
    }

    pub fn stream<'c, B>(&'c self,
                         method: Method,
                         endpoint: &str,
                         body: Option<(B, ContentType)>)
                         -> Result<Box<Read>>
        where B: Into<Body<'c>>
    {
        let req = match *self {
            Transport::Tcp { ref client, ref host } => {
                client.request(method, &format!("{}{}", host, endpoint)[..])
            }
            Transport::Unix {  ref client, ref path } => {
                client.request(method, DomainUrl::new(&path, endpoint))
            }
        };

        let embodied = match body {
            Some((b, c)) => req.header(c).body(b),
            _ => req,
        };
        let res = try!(embodied.send());
        match res.status {
            StatusCode::Ok | StatusCode::Created | StatusCode::SwitchingProtocols => {
                Ok(Box::new(res))
            }
            StatusCode::NoContent => Ok(Box::new(BufReader::new("".as_bytes()))),
            // todo: constantize these
            StatusCode::BadRequest => {
                Err(Error::Fault {
                    code: res.status,
                    message: "bad parameter".to_owned(),
                })
            }
            StatusCode::NotFound => {
                Err(Error::Fault {
                    code: res.status,
                    message: "not found".to_owned(),
                })
            }
            StatusCode::NotAcceptable => {
                Err(Error::Fault {
                    code: res.status,
                    message: "not acceptable".to_owned(),
                })
            }
            StatusCode::Conflict => {
                Err(Error::Fault {
                    code: res.status,
                    message: "conflict found".to_owned(),
                })
            }
            StatusCode::InternalServerError => {
                Err(Error::Fault {
                    code: res.status,
                    message: "internal server error".to_owned(),
                })
            }
            _ => unreachable!(),
        }
    }
}
<commit_msg>don't panic<commit_after>//! Transports for communicating with the docker daemon

extern crate hyper;
extern crate mime;

use hyper::Client;
use hyper::client::Body;
use self::super::{Error, Result};
use self::hyper::buffer::BufReader;
use self::hyper::header::ContentType;
use self::hyper::status::StatusCode;
use hyper::method::Method;
use std::fmt;
use std::io::{Read, Write};
use hyperlocal::DomainUrl;

pub fn tar() -> ContentType {
    ContentType(mime::Mime(mime::TopLevel::Application,
                           mime::SubLevel::Ext(String::from("tar")),
                           vec![]))
}

/// Transports are types which define the means of communication
/// with the docker daemon
pub enum Transport {
    /// A network tcp interface
    Tcp {
        client: Client,
        host: String,
    },
    /// A Unix domain socket
    Unix {
        client: Client,
        path: String,
    },
}

impl fmt::Debug for Transport {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Transport::Tcp { ref host, .. } => write!(f, "Tcp({})", host),
            Transport::Unix { ref path, .. } => write!(f, "Unix({})", path),
        }
    }
}

impl Transport {
    pub fn request<'a, B>(&'a self,
                          method: Method,
                          endpoint: &str,
                          body: Option<(B, ContentType)>)
                          -> Result<String>
        where B: Into<Body<'a>>
    {
        let mut res = try!(self.stream(method, endpoint, body));
        let mut body = String::new();
        try!(res.read_to_string(&mut body));
        debug!("{} raw response: {}", endpoint, body);
        Ok(body)
    }

    pub fn stream<'c, B>(&'c self,
                         method: Method,
                         endpoint: &str,
                         body: Option<(B, ContentType)>)
                         -> Result<Box<Read>>
        where B: Into<Body<'c>>
    {
        let req = match *self {
            Transport::Tcp { ref client, ref host } => {
                client.request(method, &format!("{}{}", host, endpoint)[..])
            }
            Transport::Unix {  ref client, ref path } => {
                client.request(method, DomainUrl::new(&path, endpoint))
            }
        };

        let embodied = match body {
            Some((b, c)) => req.header(c).body(b),
            _ => req,
        };
        let res = try!(embodied.send());
        match res.status {
            StatusCode::Ok | StatusCode::Created | StatusCode::SwitchingProtocols => {
                Ok(Box::new(res))
            }
            StatusCode::NoContent => Ok(Box::new(BufReader::new("".as_bytes()))),
            // todo: constantize these
            StatusCode::BadRequest => {
                Err(Error::Fault {
                    code: res.status,
                    message: "bad parameter".to_owned(),
                })
            }
            StatusCode::NotFound => {
                Err(Error::Fault {
                    code: res.status,
                    message: "not found".to_owned(),
                })
            }
            StatusCode::NotAcceptable => {
                Err(Error::Fault {
                    code: res.status,
                    message: "not acceptable".to_owned(),
                })
            }
            StatusCode::Conflict => {
                Err(Error::Fault {
                    code: res.status,
                    message: "conflict found".to_owned(),
                })
            }
            StatusCode::InternalServerError => {
                Err(Error::Fault {
                    code: res.status,
                    message: "internal server error".to_owned(),
                })
            }
            _ => unreachable!(),
        }
    }
}
<|endoftext|>


<commit_before>
use vertex::{Vertex, VertexProxy};
use edge::{Edge, EdgeProxy};
// define a traversal as a series of stages

struct VertexVisit {
    vertex: VertexProxy
}

struct EdgeVisit {
    edge: EdgeProxy
}

enum TraversalStage {

}

pub enum GraphIterable {
    Vertex(VertexProxy),
    Edge(EdgeProxy)
}

// used to track a single graph traversal
// will be used in conjunction with a GraphQuery

struct Path {
    path: Vec<GraphIterable>
}

impl Path {
    fn new(vertex: VertexProxy) -> Path {
		Path{path:vec![GraphIterable::Vertex(vertex)]}
    }
}

pub struct GraphQuery {
	// many paths
    paths: Vec<Path>
}

impl GraphQuery {
    pub fn new(vertices: Vec<VertexProxy>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let mut paths = Vec::new();
        for p in vertices {
			let mut path = Path::new(p);
            paths.push(path)
        }
        GraphQuery{paths:paths}
    }

    pub fn empty() -> GraphQuery {
        // return an empty graph query
        GraphQuery{paths:Vec::new()}
    }

    fn map<F: Fn(Path) -> Vec<Path>>(&self, closure: F) -> GraphQuery  {
        let mut result = GraphQuery::empty(); // result
		for x in self.paths.iter() {

		}
		result
    }

    pub fn outV(&self) -> GraphQuery {
		let f = |path: Path| {
			let mut result : Vec<Path>  = Vec::new();
			result
		};
		self.map(f)
    }

	pub fn inv(&self) -> GraphQuery {
		let g = GraphQuery::empty();
		g
	}
}

<commit_msg>accepting a borrow for path<commit_after>
use vertex::{Vertex, VertexProxy};
use edge::{Edge, EdgeProxy};
// define a traversal as a series of stages

struct VertexVisit {
    vertex: VertexProxy
}

struct EdgeVisit {
    edge: EdgeProxy
}

enum TraversalStage {

}

pub enum GraphIterable {
    Vertex(VertexProxy),
    Edge(EdgeProxy)
}

// used to track a single graph traversal
// will be used in conjunction with a GraphQuery

struct Path {
    path: Vec<GraphIterable>
}

impl Path {
    fn new(vertex: VertexProxy) -> Path {
		Path{path:vec![GraphIterable::Vertex(vertex)]}
    }
}

pub struct GraphQuery {
	// many paths
    paths: Vec<Path>
}

impl GraphQuery {
    pub fn new(vertices: Vec<VertexProxy>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let mut paths = Vec::new();
        for p in vertices {
			let mut path = Path::new(p);
            paths.push(path)
        }
        GraphQuery{paths:paths}
    }

    pub fn empty() -> GraphQuery {
        // return an empty graph query
        GraphQuery{paths:Vec::new()}
    }

    fn map<F: Fn(&Path) -> Vec<Path>>(&self, closure: F) -> GraphQuery  {
        let mut result = GraphQuery::empty(); // result
		for x in self.paths.iter() {
			let mut tmp = closure(x);
			result.paths.append(&mut tmp)
		}
		result
    }

    pub fn outV(&self) -> GraphQuery {
		let f = |path: &Path| {
			let mut result : Vec<Path>  = Vec::new();
			result
		};
		self.map(f)
    }

	pub fn inv(&self) -> GraphQuery {
		let g = GraphQuery::empty();
		g
	}
}

<|endoftext|>


<commit_before>//! The types modules describes all the structures to express FITS files.

use std::str::FromStr;
use std::fmt::{Display, Formatter, Error};

/// Representation of a FITS file.
#[derive(Debug, PartialEq)]
pub struct Fits<'a> {
    /// The primary HDU
    pub primary_hdu: HDU<'a>,
}

impl<'a> Fits<'a> {
    /// Create a Fits structure with a given primary header
    pub fn new(primary_header: Header<'a>) -> Fits<'a> {
        Fits {
            primary_hdu: HDU::new(primary_header),
        }
    }
}

/// Header Data Unit, combination of a header and an optional data array.
#[derive(Debug, PartialEq)]
pub struct HDU<'a> {
    /// The header of this HDU.
    pub header: Header<'a>,
    /// The optional data array of this HDU.
    data_array: Option<DataArray>,
}

impl<'a> HDU<'a> {
    /// Create an HDU with a header, setting the data_array to none.
    pub fn new(header: Header<'a>) -> HDU<'a> {
        HDU { header: header, data_array: Option::None }
    }
}

/// The primary header of a FITS file.
#[derive(Debug, PartialEq)]
pub struct Header<'a> {
    /// The keyword records of the primary header.
    pub keyword_records: Vec<KeywordRecord<'a>>,
}

impl<'a> Header<'a> {
    /// Create a Header with a given set of keyword_records
    pub fn new(keyword_records: Vec<KeywordRecord<'a>>) -> Header<'a> {
        Header { keyword_records: keyword_records }
    }
}

/// Placeholder for DataArray
#[derive(Debug, PartialEq)]
pub struct DataArray;

/// A keyword record contains information about a FITS header. It consists of a
/// keyword, the corresponding value and an optional comment.
#[derive(Debug, PartialEq)]
pub struct KeywordRecord<'a> {
    /// The keyword of this record.
    keyword: Keyword,
    /// The value of this record.
    value: Value<'a>,
    /// The comment of this record.
    comment: Option<&'a str>
}

impl<'a> KeywordRecord<'a> {
    /// Create a `KeywordRecord` from a specific `Keyword`.
    pub fn new(keyword: Keyword, value: Value<'a>, comment: Option<&'a str>) -> KeywordRecord<'a> {
        KeywordRecord { keyword: keyword, value: value, comment: comment }
    }
}

impl<'a> Display for KeywordRecord<'a> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "{:?}= {:?}/{}", self.keyword, self.value, self.comment.unwrap_or(""))
    }
}

/// The possible values of a KeywordRecord.
#[derive(Debug, PartialEq)]
pub enum Value<'a> {
    /// A string enclosed in single quotes `'`.
    CharacterString(&'a str),
    /// A logical constant signified by either an uppercase `F` or an uppercase `T`.
    Logical(bool),
    /// An optionally signed decimal integer.
    Integer(i64),
    /// Fixed format real floating point number.
    Real(f64),
    /// Complex number represented by a real and imaginary component.
    Complex((f64, f64)),
    /// When a value is not present
    Undefined,
}

/// A unit struct that will act as a placeholder for blank records.
#[derive(Debug, PartialEq)]
pub struct BlankRecord;

/// The various keywords that can be found in headers.
#[derive(Debug, PartialEq)]
#[allow(non_camel_case_types, missing_docs)]
pub enum Keyword {
    SIMPLE,
    BITPIX,
    NAXIS,
    NAXISn(u8),
    EXTEND,
    NEXTEND,
    EXTNAME,
    EXTVER,
    ORIGIN,
    DATE,
    CREATOR,
    PROCVER,
    FILEVER,
    TIMVERSN,
    TELESCOP,
    INSTRUME,
    OBJECT,
    KEPLERID,
    CHANNEL,
    MODULE,
    OUTPUT,
    CAMPAIGN,
    DATA_REL,
    OBSMODE,
    MISSION,
    TTABLEID,
    RADESYS,
    RA_OBJ,
    DEC_OBJ,
    EQUINOX,
    PMRA,
    PMDEC,
    PMTOTAL,
    PARALLAX,
    GLON,
    GLAT,
    GMAG,
    RMAG,
    IMAG,
    ZMAG,
    JMAG,
    HMAG,
    KMAG,
    KEPMAG,
    GRCOLOR,
    JKCOLOR,
    GKCOLOR,
    TEFF,
    LOGG,
    FEH,
    EBMINUSV,
    AV,
    RADIUS,
    TMINDEX,
    CHECKSUM,
    DATASUM,
    END,
}

/// Problems that could occur when parsing a `str` for a Keyword are enumerated here.
#[derive(Debug)]
pub enum ParseKeywordError {
    /// When a str can not be recognized as a keyword, this error will be returned
    UnknownKeyword
}

impl FromStr for Keyword {
    type Err = ParseKeywordError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        // TODO parse NAXIS1 correctly
        match s.trim_right() {
            "SIMPLE" => Ok(Keyword::SIMPLE),
            "BITPIX" => Ok(Keyword::BITPIX),
            "NAXIS" => Ok(Keyword::NAXIS),
            "EXTEND" => Ok(Keyword::EXTEND),
            "NEXTEND" => Ok(Keyword::NEXTEND),
            "EXTNAME" => Ok(Keyword::EXTNAME),
            "EXTVER" => Ok(Keyword::EXTVER),
            "ORIGIN" => Ok(Keyword::ORIGIN),
            "DATE" => Ok(Keyword::DATE),
            "CREATOR" => Ok(Keyword::CREATOR),
            "PROCVER" => Ok(Keyword::PROCVER),
            "FILEVER" => Ok(Keyword::FILEVER),
            "TIMVERSN" => Ok(Keyword::TIMVERSN),
            "TELESCOP" => Ok(Keyword::TELESCOP),
            "INSTRUME" => Ok(Keyword::INSTRUME),
            "OBJECT" => Ok(Keyword::OBJECT),
            "KEPLERID" => Ok(Keyword::KEPLERID),
            "CHANNEL" => Ok(Keyword::CHANNEL),
            "MODULE" => Ok(Keyword::MODULE),
            "OUTPUT" => Ok(Keyword::OUTPUT),
            "CAMPAIGN" => Ok(Keyword::CAMPAIGN),
            "DATA_REL" => Ok(Keyword::DATA_REL),
            "OBSMODE" => Ok(Keyword::OBSMODE),
            "MISSION" => Ok(Keyword::MISSION),
            "TTABLEID" => Ok(Keyword::TTABLEID),
            "RADESYS" => Ok(Keyword::RADESYS),
            "RA_OBJ" => Ok(Keyword::RA_OBJ),
            "DEC_OBJ" => Ok(Keyword::DEC_OBJ),
            "EQUINOX" => Ok(Keyword::EQUINOX),
            "PMRA" => Ok(Keyword::PMRA),
            "PMDEC" => Ok(Keyword::PMDEC),
            "PMTOTAL" => Ok(Keyword::PMTOTAL),
            "PARALLAX" => Ok(Keyword::PARALLAX),
            "GLON" => Ok(Keyword::GLON),
            "GLAT" => Ok(Keyword::GLAT),
            "GMAG" => Ok(Keyword::GMAG),
            "RMAG" => Ok(Keyword::RMAG),
            "IMAG" => Ok(Keyword::IMAG),
            "ZMAG" => Ok(Keyword::ZMAG),
            "JMAG" => Ok(Keyword::JMAG),
            "HMAG" => Ok(Keyword::HMAG),
            "KMAG" => Ok(Keyword::KMAG),
            "KEPMAG" => Ok(Keyword::KEPMAG),
            "GRCOLOR" => Ok(Keyword::GRCOLOR),
            "JKCOLOR" => Ok(Keyword::JKCOLOR),
            "GKCOLOR" => Ok(Keyword::GKCOLOR),
            "TEFF" => Ok(Keyword::TEFF),
            "LOGG" => Ok(Keyword::LOGG),
            "FEH" => Ok(Keyword::FEH),
            "EBMINUSV" => Ok(Keyword::EBMINUSV),
            "AV" => Ok(Keyword::AV),
            "RADIUS" => Ok(Keyword::RADIUS),
            "TMINDEX" => Ok(Keyword::TMINDEX),
            "CHECKSUM" => Ok(Keyword::CHECKSUM),
            "DATASUM" => Ok(Keyword::DATASUM),
            "END" => Ok(Keyword::END),
            _ => Err(ParseKeywordError::UnknownKeyword)
        }
    }
}

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

    #[test]
    fn fits_constructed_from_the_new_function_should_eq_hand_construction() {
        assert_eq!(
            Fits {
                primary_hdu: HDU::new(Header::new(vec!())),
            },
            Fits::new(Header::new(vec!()))
        );
    }

    #[test]
    fn header_constructed_from_the_new_function_should_eq_hand_construction() {
        assert_eq!(
            Header { keyword_records: vec!(
                KeywordRecord::new(Keyword::SIMPLE, Value::Logical(true), Option::None),
                KeywordRecord::new(Keyword::NEXTEND, Value::Integer(0i64), Option::Some("no extensions")),
            )},
            Header::new(vec!(
                KeywordRecord::new(Keyword::SIMPLE, Value::Logical(true), Option::None),
                KeywordRecord::new(Keyword::NEXTEND, Value::Integer(0i64), Option::Some("no extensions")),
            ))
        );
    }

    #[test]
    fn keyword_record_constructed_from_the_new_function_should_eq_hand_construction() {
        assert_eq!(
            KeywordRecord { keyword: Keyword::ORIGIN, value: Value::Undefined, comment: Option::None },
            KeywordRecord::new(Keyword::ORIGIN, Value::Undefined, Option::None));
    }

    #[test]
    fn keywords_could_be_constructed_from_str() {
        let data = vec!(
            ("SIMPLE", Keyword::SIMPLE),
            ("BITPIX", Keyword::BITPIX),
            ("NAXIS", Keyword::NAXIS),
            ("EXTEND", Keyword::EXTEND),
            ("NEXTEND", Keyword::NEXTEND),
            ("EXTVER", Keyword::EXTVER),
            ("ORIGIN", Keyword::ORIGIN),
            ("DATE", Keyword::DATE),
            ("CREATOR", Keyword::CREATOR),
            ("PROCVER", Keyword::PROCVER),
            ("FILEVER", Keyword::FILEVER),
            ("TIMVERSN", Keyword::TIMVERSN),
            ("TELESCOP", Keyword::TELESCOP),
            ("INSTRUME", Keyword::INSTRUME),
            ("OBJECT", Keyword::OBJECT),
            ("KEPLERID", Keyword::KEPLERID),
            ("CHANNEL", Keyword::CHANNEL),
            ("MODULE", Keyword::MODULE),
            ("OUTPUT", Keyword::OUTPUT),
            ("CAMPAIGN", Keyword::CAMPAIGN),
            ("DATA_REL", Keyword::DATA_REL),
            ("OBSMODE", Keyword::OBSMODE),
            ("MISSION", Keyword::MISSION),
            ("TTABLEID", Keyword::TTABLEID),
            ("RADESYS", Keyword::RADESYS),
            ("RA_OBJ", Keyword::RA_OBJ),
            ("DEC_OBJ", Keyword::DEC_OBJ),
            ("EQUINOX", Keyword::EQUINOX),
            ("PMRA", Keyword::PMRA),
            ("PMDEC", Keyword::PMDEC),
            ("PMTOTAL", Keyword::PMTOTAL),
            ("PARALLAX", Keyword::PARALLAX),
            ("GLON", Keyword::GLON),
            ("GLAT", Keyword::GLAT),
            ("GMAG", Keyword::GMAG),
            ("RMAG", Keyword::RMAG),
            ("IMAG", Keyword::IMAG),
            ("ZMAG", Keyword::ZMAG),
            ("JMAG", Keyword::JMAG),
            ("HMAG", Keyword::HMAG),
            ("KMAG", Keyword::KMAG),
            ("KEPMAG", Keyword::KEPMAG),
            ("GRCOLOR", Keyword::GRCOLOR),
            ("JKCOLOR", Keyword::JKCOLOR),
            ("GKCOLOR", Keyword::GKCOLOR),
            ("TEFF", Keyword::TEFF),
            ("LOGG", Keyword::LOGG),
            ("FEH", Keyword::FEH),
            ("EBMINUSV", Keyword::EBMINUSV),
            ("AV", Keyword::AV),
            ("RADIUS", Keyword::RADIUS),
            ("TMINDEX", Keyword::TMINDEX),
            ("CHECKSUM", Keyword::CHECKSUM),
            ("DATASUM", Keyword::DATASUM),
            ("END", Keyword::END),
        );

        for (input, expected) in data {
            assert_eq!(Keyword::from_str(input).unwrap(), expected);
        }
    }

    #[test]
    fn should_also_parse_whitespace_keywords() {
        assert_eq!(Keyword::from_str("SIMPLE  ").unwrap(), Keyword::SIMPLE);
    }
}
<commit_msg>Parse NAXISn correctly<commit_after>//! The types modules describes all the structures to express FITS files.

use std::str::FromStr;
use std::fmt::{Display, Formatter, Error};

/// Representation of a FITS file.
#[derive(Debug, PartialEq)]
pub struct Fits<'a> {
    /// The primary HDU
    pub primary_hdu: HDU<'a>,
}

impl<'a> Fits<'a> {
    /// Create a Fits structure with a given primary header
    pub fn new(primary_header: Header<'a>) -> Fits<'a> {
        Fits {
            primary_hdu: HDU::new(primary_header),
        }
    }
}

/// Header Data Unit, combination of a header and an optional data array.
#[derive(Debug, PartialEq)]
pub struct HDU<'a> {
    /// The header of this HDU.
    pub header: Header<'a>,
    /// The optional data array of this HDU.
    data_array: Option<DataArray>,
}

impl<'a> HDU<'a> {
    /// Create an HDU with a header, setting the data_array to none.
    pub fn new(header: Header<'a>) -> HDU<'a> {
        HDU { header: header, data_array: Option::None }
    }
}

/// The primary header of a FITS file.
#[derive(Debug, PartialEq)]
pub struct Header<'a> {
    /// The keyword records of the primary header.
    pub keyword_records: Vec<KeywordRecord<'a>>,
}

impl<'a> Header<'a> {
    /// Create a Header with a given set of keyword_records
    pub fn new(keyword_records: Vec<KeywordRecord<'a>>) -> Header<'a> {
        Header { keyword_records: keyword_records }
    }
}

/// Placeholder for DataArray
#[derive(Debug, PartialEq)]
pub struct DataArray;

/// A keyword record contains information about a FITS header. It consists of a
/// keyword, the corresponding value and an optional comment.
#[derive(Debug, PartialEq)]
pub struct KeywordRecord<'a> {
    /// The keyword of this record.
    keyword: Keyword,
    /// The value of this record.
    value: Value<'a>,
    /// The comment of this record.
    comment: Option<&'a str>
}

impl<'a> KeywordRecord<'a> {
    /// Create a `KeywordRecord` from a specific `Keyword`.
    pub fn new(keyword: Keyword, value: Value<'a>, comment: Option<&'a str>) -> KeywordRecord<'a> {
        KeywordRecord { keyword: keyword, value: value, comment: comment }
    }
}

impl<'a> Display for KeywordRecord<'a> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "{:?}= {:?}/{}", self.keyword, self.value, self.comment.unwrap_or(""))
    }
}

/// The possible values of a KeywordRecord.
#[derive(Debug, PartialEq)]
pub enum Value<'a> {
    /// A string enclosed in single quotes `'`.
    CharacterString(&'a str),
    /// A logical constant signified by either an uppercase `F` or an uppercase `T`.
    Logical(bool),
    /// An optionally signed decimal integer.
    Integer(i64),
    /// Fixed format real floating point number.
    Real(f64),
    /// Complex number represented by a real and imaginary component.
    Complex((f64, f64)),
    /// When a value is not present
    Undefined,
}

/// A unit struct that will act as a placeholder for blank records.
#[derive(Debug, PartialEq)]
pub struct BlankRecord;

/// The various keywords that can be found in headers.
#[derive(Debug, PartialEq)]
#[allow(non_camel_case_types, missing_docs)]
pub enum Keyword {
    SIMPLE,
    BITPIX,
    NAXIS,
    NAXISn(u16),
    EXTEND,
    NEXTEND,
    EXTNAME,
    EXTVER,
    ORIGIN,
    DATE,
    CREATOR,
    PROCVER,
    FILEVER,
    TIMVERSN,
    TELESCOP,
    INSTRUME,
    OBJECT,
    KEPLERID,
    CHANNEL,
    MODULE,
    OUTPUT,
    CAMPAIGN,
    DATA_REL,
    OBSMODE,
    MISSION,
    TTABLEID,
    RADESYS,
    RA_OBJ,
    DEC_OBJ,
    EQUINOX,
    PMRA,
    PMDEC,
    PMTOTAL,
    PARALLAX,
    GLON,
    GLAT,
    GMAG,
    RMAG,
    IMAG,
    ZMAG,
    JMAG,
    HMAG,
    KMAG,
    KEPMAG,
    GRCOLOR,
    JKCOLOR,
    GKCOLOR,
    TEFF,
    LOGG,
    FEH,
    EBMINUSV,
    AV,
    RADIUS,
    TMINDEX,
    CHECKSUM,
    DATASUM,
    END,
}

/// Problems that could occur when parsing a `str` for a Keyword are enumerated here.
#[derive(Debug)]
pub enum ParseKeywordError {
    /// When a str can not be recognized as a keyword, this error will be returned.
    UnknownKeyword,
    /// When `NAXIS<number>` where `<number>` is not an actual number.
    NotAnNaxisNumber,
}

impl FromStr for Keyword {
    type Err = ParseKeywordError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.trim_right() {
            "SIMPLE" => Ok(Keyword::SIMPLE),
            "BITPIX" => Ok(Keyword::BITPIX),
            "NAXIS" => Ok(Keyword::NAXIS),
            "EXTEND" => Ok(Keyword::EXTEND),
            "NEXTEND" => Ok(Keyword::NEXTEND),
            "EXTNAME" => Ok(Keyword::EXTNAME),
            "EXTVER" => Ok(Keyword::EXTVER),
            "ORIGIN" => Ok(Keyword::ORIGIN),
            "DATE" => Ok(Keyword::DATE),
            "CREATOR" => Ok(Keyword::CREATOR),
            "PROCVER" => Ok(Keyword::PROCVER),
            "FILEVER" => Ok(Keyword::FILEVER),
            "TIMVERSN" => Ok(Keyword::TIMVERSN),
            "TELESCOP" => Ok(Keyword::TELESCOP),
            "INSTRUME" => Ok(Keyword::INSTRUME),
            "OBJECT" => Ok(Keyword::OBJECT),
            "KEPLERID" => Ok(Keyword::KEPLERID),
            "CHANNEL" => Ok(Keyword::CHANNEL),
            "MODULE" => Ok(Keyword::MODULE),
            "OUTPUT" => Ok(Keyword::OUTPUT),
            "CAMPAIGN" => Ok(Keyword::CAMPAIGN),
            "DATA_REL" => Ok(Keyword::DATA_REL),
            "OBSMODE" => Ok(Keyword::OBSMODE),
            "MISSION" => Ok(Keyword::MISSION),
            "TTABLEID" => Ok(Keyword::TTABLEID),
            "RADESYS" => Ok(Keyword::RADESYS),
            "RA_OBJ" => Ok(Keyword::RA_OBJ),
            "DEC_OBJ" => Ok(Keyword::DEC_OBJ),
            "EQUINOX" => Ok(Keyword::EQUINOX),
            "PMRA" => Ok(Keyword::PMRA),
            "PMDEC" => Ok(Keyword::PMDEC),
            "PMTOTAL" => Ok(Keyword::PMTOTAL),
            "PARALLAX" => Ok(Keyword::PARALLAX),
            "GLON" => Ok(Keyword::GLON),
            "GLAT" => Ok(Keyword::GLAT),
            "GMAG" => Ok(Keyword::GMAG),
            "RMAG" => Ok(Keyword::RMAG),
            "IMAG" => Ok(Keyword::IMAG),
            "ZMAG" => Ok(Keyword::ZMAG),
            "JMAG" => Ok(Keyword::JMAG),
            "HMAG" => Ok(Keyword::HMAG),
            "KMAG" => Ok(Keyword::KMAG),
            "KEPMAG" => Ok(Keyword::KEPMAG),
            "GRCOLOR" => Ok(Keyword::GRCOLOR),
            "JKCOLOR" => Ok(Keyword::JKCOLOR),
            "GKCOLOR" => Ok(Keyword::GKCOLOR),
            "TEFF" => Ok(Keyword::TEFF),
            "LOGG" => Ok(Keyword::LOGG),
            "FEH" => Ok(Keyword::FEH),
            "EBMINUSV" => Ok(Keyword::EBMINUSV),
            "AV" => Ok(Keyword::AV),
            "RADIUS" => Ok(Keyword::RADIUS),
            "TMINDEX" => Ok(Keyword::TMINDEX),
            "CHECKSUM" => Ok(Keyword::CHECKSUM),
            "DATASUM" => Ok(Keyword::DATASUM),
            "END" => Ok(Keyword::END),
            input @ _ => {
                if input.starts_with("NAXIS") {
                    let (_, representation) = input.split_at(5);
                    match u16::from_str(representation) {
                        Ok(n) => Ok(Keyword::NAXISn(n)),
                        Err(_) => Err(ParseKeywordError::NotAnNaxisNumber)
                    }
                } else {
                    Err(ParseKeywordError::UnknownKeyword)
                }
            }
        }
    }
}

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

    #[test]
    fn fits_constructed_from_the_new_function_should_eq_hand_construction() {
        assert_eq!(
            Fits {
                primary_hdu: HDU::new(Header::new(vec!())),
            },
            Fits::new(Header::new(vec!()))
        );
    }

    #[test]
    fn header_constructed_from_the_new_function_should_eq_hand_construction() {
        assert_eq!(
            Header { keyword_records: vec!(
                KeywordRecord::new(Keyword::SIMPLE, Value::Logical(true), Option::None),
                KeywordRecord::new(Keyword::NEXTEND, Value::Integer(0i64), Option::Some("no extensions")),
            )},
            Header::new(vec!(
                KeywordRecord::new(Keyword::SIMPLE, Value::Logical(true), Option::None),
                KeywordRecord::new(Keyword::NEXTEND, Value::Integer(0i64), Option::Some("no extensions")),
            ))
        );
    }

    #[test]
    fn keyword_record_constructed_from_the_new_function_should_eq_hand_construction() {
        assert_eq!(
            KeywordRecord { keyword: Keyword::ORIGIN, value: Value::Undefined, comment: Option::None },
            KeywordRecord::new(Keyword::ORIGIN, Value::Undefined, Option::None));
    }

    #[test]
    fn keywords_could_be_constructed_from_str() {
        let data = vec!(
            ("SIMPLE", Keyword::SIMPLE),
            ("BITPIX", Keyword::BITPIX),
            ("NAXIS", Keyword::NAXIS),
            ("EXTEND", Keyword::EXTEND),
            ("NEXTEND", Keyword::NEXTEND),
            ("EXTVER", Keyword::EXTVER),
            ("ORIGIN", Keyword::ORIGIN),
            ("DATE", Keyword::DATE),
            ("CREATOR", Keyword::CREATOR),
            ("PROCVER", Keyword::PROCVER),
            ("FILEVER", Keyword::FILEVER),
            ("TIMVERSN", Keyword::TIMVERSN),
            ("TELESCOP", Keyword::TELESCOP),
            ("INSTRUME", Keyword::INSTRUME),
            ("OBJECT", Keyword::OBJECT),
            ("KEPLERID", Keyword::KEPLERID),
            ("CHANNEL", Keyword::CHANNEL),
            ("MODULE", Keyword::MODULE),
            ("OUTPUT", Keyword::OUTPUT),
            ("CAMPAIGN", Keyword::CAMPAIGN),
            ("DATA_REL", Keyword::DATA_REL),
            ("OBSMODE", Keyword::OBSMODE),
            ("MISSION", Keyword::MISSION),
            ("TTABLEID", Keyword::TTABLEID),
            ("RADESYS", Keyword::RADESYS),
            ("RA_OBJ", Keyword::RA_OBJ),
            ("DEC_OBJ", Keyword::DEC_OBJ),
            ("EQUINOX", Keyword::EQUINOX),
            ("PMRA", Keyword::PMRA),
            ("PMDEC", Keyword::PMDEC),
            ("PMTOTAL", Keyword::PMTOTAL),
            ("PARALLAX", Keyword::PARALLAX),
            ("GLON", Keyword::GLON),
            ("GLAT", Keyword::GLAT),
            ("GMAG", Keyword::GMAG),
            ("RMAG", Keyword::RMAG),
            ("IMAG", Keyword::IMAG),
            ("ZMAG", Keyword::ZMAG),
            ("JMAG", Keyword::JMAG),
            ("HMAG", Keyword::HMAG),
            ("KMAG", Keyword::KMAG),
            ("KEPMAG", Keyword::KEPMAG),
            ("GRCOLOR", Keyword::GRCOLOR),
            ("JKCOLOR", Keyword::JKCOLOR),
            ("GKCOLOR", Keyword::GKCOLOR),
            ("TEFF", Keyword::TEFF),
            ("LOGG", Keyword::LOGG),
            ("FEH", Keyword::FEH),
            ("EBMINUSV", Keyword::EBMINUSV),
            ("AV", Keyword::AV),
            ("RADIUS", Keyword::RADIUS),
            ("TMINDEX", Keyword::TMINDEX),
            ("CHECKSUM", Keyword::CHECKSUM),
            ("DATASUM", Keyword::DATASUM),
            ("END", Keyword::END),
        );

        for (input, expected) in data {
            assert_eq!(Keyword::from_str(input).unwrap(), expected);
        }
    }

    #[allow(non_snake_case)]
    #[test]
    fn NAXISn_should_be_parsed_from_str() {
        for n in 1u16..1000u16 {
            let keyword = Keyword::NAXISn(n);
            let representation = format!("NAXIS{}", n);

            assert_eq!(Keyword::from_str(&representation).unwrap(), keyword);
        }
    }

    #[test]
    fn should_also_parse_whitespace_keywords() {
        assert_eq!(Keyword::from_str("SIMPLE  ").unwrap(), Keyword::SIMPLE);
    }
}
<|endoftext|>


<commit_before>use conduit::Request;
use curl::easy::Easy;
use flate2::read::GzDecoder;
use krate::Crate;
use s3;
use semver;
use tar;
use util::{human, internal, CargoResult, ChainError};
use util::{hash, LimitErrorReader, read_le_u32};

use app::{App, RequestApp};
use std::sync::Arc;
use std::fs::{self, File};
use std::env;
use std::io::{Read, Write};

#[derive(Clone, Debug)]
pub enum Uploader {
    /// For production usage, uploads and redirects to s3.
    /// For test usage with a proxy.
    S3 {
        bucket: s3::Bucket,
        cdn: Option<String>,
        proxy: Option<String>,
    },

    /// For development usage only: "uploads" crate files to `dist` and serves them
    /// from there as well to enable local publishing and download
    Local,

    /// For one-off scripts where creating a Config is needed, but uploading is not.
    NoOp,
}

impl Uploader {
    pub fn proxy(&self) -> Option<&str> {
        match *self {
            Uploader::S3 { ref proxy, .. } => proxy.as_ref().map(String::as_str),
            Uploader::Local | Uploader::NoOp => None,
        }
    }

    /// Returns the URL of an uploaded crate's version archive.
    ///
    /// The function doesn't check for the existence of the file.
    /// It returns `None` if the current `Uploader` is `NoOp`.
    pub fn crate_location(&self, crate_name: &str, version: &str) -> Option<String> {
        match *self {
            Uploader::S3 { ref bucket, ref cdn, .. } => {
                let host = match *cdn {
                    Some(ref s) => s.clone(),
                    None => bucket.host(),
                };
                let path = Uploader::crate_path(crate_name, version);
                Some(format!("https://{}/{}", host, path))
            }
            Uploader::Local => Some(format!("/{}", Uploader::crate_path(crate_name, version))),
            Uploader::NoOp => None,
        }
    }

    /// Returns the URL of an uploaded crate's version readme.
    ///
    /// The function doesn't check for the existence of the file.
    /// It returns `None` if the current `Uploader` is `NoOp`.
    pub fn readme_location(&self, crate_name: &str, version: &str) -> Option<String> {
        match *self {
            Uploader::S3 { ref bucket, ref cdn, .. } => {
                let host = match *cdn {
                    Some(ref s) => s.clone(),
                    None => bucket.host(),
                };
                let path = Uploader::readme_path(crate_name, version);
                Some(format!("https://{}/{}", host, path))
            }
            Uploader::Local => Some(format!("/{}", Uploader::readme_path(crate_name, version))),
            Uploader::NoOp => None,
        }
    }

    /// Returns the interna path of an uploaded crate's version archive.
    fn crate_path(name: &str, version: &str) -> String {
        // No slash in front so we can use join
        format!("crates/{}/{}-{}.crate", name, name, version)
    }

    /// Returns the interna path of an uploaded crate's version readme.
    fn readme_path(name: &str, version: &str) -> String {
        format!("readmes/{}/{}-{}.html", name, name, version)
    }

    /// Uploads a file using the configured uploader (either `S3`, `Local` or `NoOp`).
    ///
    /// It returns a a tuple containing the path of the uploaded file
    /// and its checksum.
    pub fn upload(
        &self,
        mut handle: Easy,
        path: &str,
        body: &[u8],
        content_type: &str,
        content_length: u64,
    ) -> CargoResult<(Option<String>, Vec<u8>)> {
        let hash = hash(body);
        match *self {
            Uploader::S3 { ref bucket, .. } => {
                let (response, cksum) = {
                    let mut response = Vec::new();
                    {
                        let mut s3req =
                            bucket.put(&mut handle, path, body, content_type, content_length);
                        s3req
                            .write_function(|data| {
                                response.extend(data);
                                Ok(data.len())
                            })
                            .unwrap();
                        s3req.perform().chain_error(|| {
                            internal(&format_args!("failed to upload to S3: `{}`", path))
                        })?;
                    }
                    (response, hash)
                };
                if handle.response_code().unwrap() != 200 {
                    let response = String::from_utf8_lossy(&response);
                    return Err(internal(&format_args!(
                        "failed to get a 200 response from S3: {}",
                        response
                    )));
                }
                Ok((Some(String::from(path)), cksum))
            }
            Uploader::Local => {
                let filename = env::current_dir().unwrap().join("local_uploads").join(path);
                let dir = filename.parent().unwrap();
                fs::create_dir_all(dir)?;
                let mut file = File::create(&filename)?;
                file.write_all(body)?;
                Ok((filename.to_str().map(String::from), hash))
            }
            Uploader::NoOp => Ok((None, vec![])),
        }
    }

    /// Uploads a crate and its readme. Returns the checksum of the uploaded crate
    /// file, and bombs for the uploaded crate and the uploaded readme.
    pub fn upload_crate(
        &self,
        req: &mut Request,
        krate: &Crate,
        readme: Option<String>,
        max: u64,
        vers: &semver::Version,
    ) -> CargoResult<(Vec<u8>, Bomb, Bomb)> {
        let app = Arc::clone(req.app());
        let (crate_path, checksum) = {
            let path = Uploader::crate_path(&krate.name, &vers.to_string());
            let length = read_le_u32(req.body())?;
            let mut body = Vec::new();
            LimitErrorReader::new(req.body(), max).read_to_end(&mut body)?;
            verify_tarball(krate, vers, &body)?;
            self.upload(
                app.handle(),
                &path,
                &body,
                "application/x-tar",
                u64::from(length),
            )?
        };
        // We create the bomb for the crate file before uploading the readme so that if the
        // readme upload fails, the uploaded crate file is automatically deleted.
        let crate_bomb = Bomb {
            app: Arc::clone(&app),
            path: crate_path,
        };
        let (readme_path, _) = if let Some(rendered) = readme {
            let path = Uploader::readme_path(&krate.name, &vers.to_string());
            let length = rendered.len();
            self.upload(
                app.handle(),
                &path,
                rendered.as_bytes(),
                "text/html",
                length as u64,
            )?
        } else {
            (None, vec![])
        };
        Ok((
            checksum,
            crate_bomb,
            Bomb {
                app: Arc::clone(&app),
                path: readme_path,
            },
        ))
    }

    /// Deletes an uploaded file.
    fn delete(&self, app: Arc<App>, path: &str) -> CargoResult<()> {
        match *self {
            Uploader::S3 { ref bucket, .. } => {
                let mut handle = app.handle();
                bucket.delete(&mut handle, path).perform()?;
                Ok(())
            }
            Uploader::Local => {
                fs::remove_file(path)?;
                Ok(())
            }
            Uploader::NoOp => Ok(()),
        }
    }
}

// Can't derive Debug because of App.
#[allow(missing_debug_implementations)]
pub struct Bomb {
    app: Arc<App>,
    pub path: Option<String>,
}

impl Drop for Bomb {
    fn drop(&mut self) {
        if let Some(ref path) = self.path {
            if let Err(e) = self.app.config.uploader.delete(Arc::clone(&self.app), path) {
                println!("unable to delete {}, {:?}", path, e);
            }
        }
    }
}

fn verify_tarball(krate: &Crate, vers: &semver::Version, tarball: &[u8]) -> CargoResult<()> {
    let decoder = GzDecoder::new(tarball)?;
    let mut archive = tar::Archive::new(decoder);
    let prefix = format!("{}-{}", krate.name, vers);
    for entry in archive.entries()? {
        let entry = entry?;

        // Verify that all entries actually start with `$name-$vers/`.
        // Historically Cargo didn't verify this on extraction so you could
        // upload a tarball that contains both `foo-0.1.0/` source code as well
        // as `bar-0.1.0/` source code, and this could overwrite other crates in
        // the registry!
        if !entry.path()?.starts_with(&prefix) {
            return Err(human("invalid tarball uploaded"));
        }
    }
    Ok(())
}
<commit_msg>cargo fmt<commit_after>use conduit::Request;
use curl::easy::Easy;
use flate2::read::GzDecoder;
use krate::Crate;
use s3;
use semver;
use tar;
use util::{human, internal, CargoResult, ChainError};
use util::{hash, LimitErrorReader, read_le_u32};

use app::{App, RequestApp};
use std::sync::Arc;
use std::fs::{self, File};
use std::env;
use std::io::{Read, Write};

#[derive(Clone, Debug)]
pub enum Uploader {
    /// For production usage, uploads and redirects to s3.
    /// For test usage with a proxy.
    S3 {
        bucket: s3::Bucket,
        cdn: Option<String>,
        proxy: Option<String>,
    },

    /// For development usage only: "uploads" crate files to `dist` and serves them
    /// from there as well to enable local publishing and download
    Local,

    /// For one-off scripts where creating a Config is needed, but uploading is not.
    NoOp,
}

impl Uploader {
    pub fn proxy(&self) -> Option<&str> {
        match *self {
            Uploader::S3 { ref proxy, .. } => proxy.as_ref().map(String::as_str),
            Uploader::Local | Uploader::NoOp => None,
        }
    }

    /// Returns the URL of an uploaded crate's version archive.
    ///
    /// The function doesn't check for the existence of the file.
    /// It returns `None` if the current `Uploader` is `NoOp`.
    pub fn crate_location(&self, crate_name: &str, version: &str) -> Option<String> {
        match *self {
            Uploader::S3 {
                ref bucket,
                ref cdn,
                ..
            } => {
                let host = match *cdn {
                    Some(ref s) => s.clone(),
                    None => bucket.host(),
                };
                let path = Uploader::crate_path(crate_name, version);
                Some(format!("https://{}/{}", host, path))
            }
            Uploader::Local => Some(format!("/{}", Uploader::crate_path(crate_name, version))),
            Uploader::NoOp => None,
        }
    }

    /// Returns the URL of an uploaded crate's version readme.
    ///
    /// The function doesn't check for the existence of the file.
    /// It returns `None` if the current `Uploader` is `NoOp`.
    pub fn readme_location(&self, crate_name: &str, version: &str) -> Option<String> {
        match *self {
            Uploader::S3 {
                ref bucket,
                ref cdn,
                ..
            } => {
                let host = match *cdn {
                    Some(ref s) => s.clone(),
                    None => bucket.host(),
                };
                let path = Uploader::readme_path(crate_name, version);
                Some(format!("https://{}/{}", host, path))
            }
            Uploader::Local => Some(format!("/{}", Uploader::readme_path(crate_name, version))),
            Uploader::NoOp => None,
        }
    }

    /// Returns the interna path of an uploaded crate's version archive.
    fn crate_path(name: &str, version: &str) -> String {
        // No slash in front so we can use join
        format!("crates/{}/{}-{}.crate", name, name, version)
    }

    /// Returns the interna path of an uploaded crate's version readme.
    fn readme_path(name: &str, version: &str) -> String {
        format!("readmes/{}/{}-{}.html", name, name, version)
    }

    /// Uploads a file using the configured uploader (either `S3`, `Local` or `NoOp`).
    ///
    /// It returns a a tuple containing the path of the uploaded file
    /// and its checksum.
    pub fn upload(
        &self,
        mut handle: Easy,
        path: &str,
        body: &[u8],
        content_type: &str,
        content_length: u64,
    ) -> CargoResult<(Option<String>, Vec<u8>)> {
        let hash = hash(body);
        match *self {
            Uploader::S3 { ref bucket, .. } => {
                let (response, cksum) = {
                    let mut response = Vec::new();
                    {
                        let mut s3req =
                            bucket.put(&mut handle, path, body, content_type, content_length);
                        s3req
                            .write_function(|data| {
                                response.extend(data);
                                Ok(data.len())
                            })
                            .unwrap();
                        s3req.perform().chain_error(|| {
                            internal(&format_args!("failed to upload to S3: `{}`", path))
                        })?;
                    }
                    (response, hash)
                };
                if handle.response_code().unwrap() != 200 {
                    let response = String::from_utf8_lossy(&response);
                    return Err(internal(&format_args!(
                        "failed to get a 200 response from S3: {}",
                        response
                    )));
                }
                Ok((Some(String::from(path)), cksum))
            }
            Uploader::Local => {
                let filename = env::current_dir().unwrap().join("local_uploads").join(path);
                let dir = filename.parent().unwrap();
                fs::create_dir_all(dir)?;
                let mut file = File::create(&filename)?;
                file.write_all(body)?;
                Ok((filename.to_str().map(String::from), hash))
            }
            Uploader::NoOp => Ok((None, vec![])),
        }
    }

    /// Uploads a crate and its readme. Returns the checksum of the uploaded crate
    /// file, and bombs for the uploaded crate and the uploaded readme.
    pub fn upload_crate(
        &self,
        req: &mut Request,
        krate: &Crate,
        readme: Option<String>,
        max: u64,
        vers: &semver::Version,
    ) -> CargoResult<(Vec<u8>, Bomb, Bomb)> {
        let app = Arc::clone(req.app());
        let (crate_path, checksum) = {
            let path = Uploader::crate_path(&krate.name, &vers.to_string());
            let length = read_le_u32(req.body())?;
            let mut body = Vec::new();
            LimitErrorReader::new(req.body(), max).read_to_end(&mut body)?;
            verify_tarball(krate, vers, &body)?;
            self.upload(
                app.handle(),
                &path,
                &body,
                "application/x-tar",
                u64::from(length),
            )?
        };
        // We create the bomb for the crate file before uploading the readme so that if the
        // readme upload fails, the uploaded crate file is automatically deleted.
        let crate_bomb = Bomb {
            app: Arc::clone(&app),
            path: crate_path,
        };
        let (readme_path, _) = if let Some(rendered) = readme {
            let path = Uploader::readme_path(&krate.name, &vers.to_string());
            let length = rendered.len();
            self.upload(
                app.handle(),
                &path,
                rendered.as_bytes(),
                "text/html",
                length as u64,
            )?
        } else {
            (None, vec![])
        };
        Ok((
            checksum,
            crate_bomb,
            Bomb {
                app: Arc::clone(&app),
                path: readme_path,
            },
        ))
    }

    /// Deletes an uploaded file.
    fn delete(&self, app: Arc<App>, path: &str) -> CargoResult<()> {
        match *self {
            Uploader::S3 { ref bucket, .. } => {
                let mut handle = app.handle();
                bucket.delete(&mut handle, path).perform()?;
                Ok(())
            }
            Uploader::Local => {
                fs::remove_file(path)?;
                Ok(())
            }
            Uploader::NoOp => Ok(()),
        }
    }
}

// Can't derive Debug because of App.
#[allow(missing_debug_implementations)]
pub struct Bomb {
    app: Arc<App>,
    pub path: Option<String>,
}

impl Drop for Bomb {
    fn drop(&mut self) {
        if let Some(ref path) = self.path {
            if let Err(e) = self.app.config.uploader.delete(Arc::clone(&self.app), path) {
                println!("unable to delete {}, {:?}", path, e);
            }
        }
    }
}

fn verify_tarball(krate: &Crate, vers: &semver::Version, tarball: &[u8]) -> CargoResult<()> {
    let decoder = GzDecoder::new(tarball)?;
    let mut archive = tar::Archive::new(decoder);
    let prefix = format!("{}-{}", krate.name, vers);
    for entry in archive.entries()? {
        let entry = entry?;

        // Verify that all entries actually start with `$name-$vers/`.
        // Historically Cargo didn't verify this on extraction so you could
        // upload a tarball that contains both `foo-0.1.0/` source code as well
        // as `bar-0.1.0/` source code, and this could overwrite other crates in
        // the registry!
        if !entry.path()?.starts_with(&prefix) {
            return Err(human("invalid tarball uploaded"));
        }
    }
    Ok(())
}
<|endoftext|>


<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#[macro_use]
extern crate grust;

use grust::boxed;
use grust::gtype;
use grust::value::Value;

#[test]
fn test_string() {
    let mut value = Value::new(gtype::STRING);
    value.set_string(g_str!("Hello"));
    let s = value.get_string().unwrap().to_bytes();
    assert_eq!(s, b"Hello");
}

#[test]
fn test_boxed() {
    let mut value = Value::new(boxed::type_of::<Box<String>>());
    {
        let os = value.deref_boxed::<Box<String>>();
        assert_eq!(os, None);
    }
    {
        let ob = value.dup_boxed::<Box<String>>();
        assert_eq!(ob, None);
    }
    value.take_boxed(Box::new("Hello!".to_string()));
    let value = value.clone();
    {
        let s = value.deref_boxed::<Box<String>>().unwrap();
        assert_eq!(&s[], "Hello!");
    }
    {
        let b = value.dup_boxed::<Box<String>>().unwrap();
        assert_eq!(*b, "Hello!");
    }
}
<commit_msg>Test boxed value panics<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#[macro_use]
extern crate grust;

use grust::boxed;
use grust::gtype;
use grust::value::Value;

#[test]
fn test_string() {
    let mut value = Value::new(gtype::STRING);
    value.set_string(g_str!("Hello"));
    let s = value.get_string().unwrap().to_bytes();
    assert_eq!(s, b"Hello");
}

#[test]
fn test_boxed() {
    let mut value = Value::new(boxed::type_of::<Box<String>>());
    {
        let os = value.deref_boxed::<Box<String>>();
        assert_eq!(os, None);
    }
    {
        let ob = value.dup_boxed::<Box<String>>();
        assert_eq!(ob, None);
    }
    value.take_boxed(Box::new("Hello!".to_string()));
    let value = value.clone();
    {
        let s = value.deref_boxed::<Box<String>>().unwrap();
        assert_eq!(&s[], "Hello!");
    }
    {
        let b = value.dup_boxed::<Box<String>>().unwrap();
        assert_eq!(*b, "Hello!");
    }
}

#[test]
#[should_fail]
fn test_deref_boxed_panic() {
    let value = Value::new(boxed::type_of::<Box<i32>>());
    let _ = value.deref_boxed::<Box<String>>();
}

#[test]
#[should_fail]
fn test_dup_boxed_panic() {
    let value = Value::new(gtype::INT);
    let _ = value.dup_boxed::<Box<i32>>();
}
<|endoftext|>


<commit_before>
#![feature(globs)]

extern crate graphics;
extern crate piston;
extern crate sdl2_game_window;
extern crate opengl_graphics;

use opengl_graphics::{ Gl,Texture };
use sdl2_game_window::WindowSDL2;
use graphics::*;
use piston::{
    EventIterator,
    EventSettings,
    WindowSettings,
    Render,
    Input,
};
use piston::image;
use piston::image::GenericImage;
use piston::input;

fn main() {
    let (width, height) = (300, 300);
    let mut window = WindowSDL2::new(
        piston::shader_version::opengl::OpenGL_3_2,
        WindowSettings {
            title: "Paint".to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let mut image = image::ImageBuf::new(width, height);
    let mut draw = false;
    let mut texture = Texture::from_image(&image);
    let event_settings = EventSettings {
            updates_per_second: 120,
            max_frames_per_second: 60,
        };
    let ref mut gl = Gl::new();
    for e in EventIterator::new(&mut window, &event_settings) {
        match e {
            Render(args) => {
                gl.viewport(0, 0, args.width as i32, args.height as i32);

                let c = Context::abs(args.width as f64, args.height as f64);
                c.rgb(1.0, 1.0, 1.0).draw(gl);
                c.image(&texture).draw(gl);
            },
            Input(input::Press(input::Mouse(input::mouse::Left))) => {
                draw = true
            }
            Input(input::Release(input::Mouse(input::mouse::Left))) => {
                draw = false
            }
            Input(input::Move(input::MouseCursor(x, y))) if draw => {
                image.put_pixel(x as u32, y as u32, image::Rgba(0, 0, 0, 255));
                texture.update(&image);
            }
            _ => {},
        }
    }
}

<commit_msg>Fix an out of bounds crash in paint example.<commit_after>
#![feature(globs)]

extern crate graphics;
extern crate piston;
extern crate sdl2_game_window;
extern crate opengl_graphics;

use opengl_graphics::{ Gl,Texture };
use sdl2_game_window::WindowSDL2;
use graphics::*;
use piston::{
    EventIterator,
    EventSettings,
    WindowSettings,
    Render,
    Input,
};
use piston::image;
use piston::image::GenericImage;
use piston::input;

fn main() {
    let (width, height) = (300, 300);
    let mut window = WindowSDL2::new(
        piston::shader_version::opengl::OpenGL_3_2,
        WindowSettings {
            title: "Paint".to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let mut image = image::ImageBuf::new(width, height);
    let mut draw = false;
    let mut texture = Texture::from_image(&image);
    let event_settings = EventSettings {
            updates_per_second: 120,
            max_frames_per_second: 60,
        };
    let ref mut gl = Gl::new();
    for e in EventIterator::new(&mut window, &event_settings) {
        match e {
            Render(args) => {
                gl.viewport(0, 0, args.width as i32, args.height as i32);

                let c = Context::abs(args.width as f64, args.height as f64);
                c.rgb(1.0, 1.0, 1.0).draw(gl);
                c.image(&texture).draw(gl);
            },
            Input(input::Press(input::Mouse(input::mouse::Left))) => {
                draw = true
            }
            Input(input::Release(input::Mouse(input::mouse::Left))) => {
                draw = false
            }
            Input(input::Move(input::MouseCursor(x, y))) if draw => {
                let (x, y) = (x as u32, y as u32);
                if x < width && y < height {
                    image.put_pixel(x, y, image::Rgba(0, 0, 0, 255));
                    texture.update(&image);
                }
            }
            _ => {},
        }
    }
}

<|endoftext|>