<commit_before>#![allow(unused_variables)]
#![allow(unused_imports)]

/// Note: Fred must be compiled with the `enable-tls` feature for this to work.

extern crate fred;
extern crate tokio_core;
extern crate futures;

use fred::RedisClient;
use fred::types::*;

use tokio_core::reactor::Core;
use futures::Future;

fn main() {
  let config = RedisConfig::Centralized {
    // Note: this must match the hostname tied to the cert
    host: "foo.bar.com".into(),
    port: 6379,
    key: Some("key".into()),
    // if compiled without `enable-tls` setting this to `true` does nothing, which is done to avoid requiring TLS dependencies unless necessary
    tls: true,
    max_value_size: None
  };

  // otherwise usage is the same as the non-tls client...

  let mut core = Core::new().unwrap();
  let handle = core.handle();

  println!("Connecting to {:?}...", config);

  let client = RedisClient::new(config);
  let connection = client.connect(&handle);

  let commands = client.on_connect().and_then(|client| {
    println!("Client connected.");

    client.select(0)
  })
  .and_then(|client| {
    println!("Selected database.");

    client.info(None)
  })
  .and_then(|(client, info)| {
    println!("Redis server info: {}", info);

    client.get("foo")
  })
  .and_then(|(client, result)| {
    println!("Got foo: {:?}", result);

    client.set("foo", "bar", Some(Expiration::PX(1000)), Some(SetOptions::NX))
  })
  .and_then(|(client, result)| {
    println!("Set 'bar' at 'foo'? {}. Subscribing to 'baz'...", result);

    client.subscribe("baz")
  })
  .and_then(|(client, result)| {
    println!("Subscribed to 'baz'. Now subscribed to {} channels. Now exiting...", result);

    client.quit()
  });

  let (reason, client) = match core.run(connection.join(commands)) {
    Ok((r, c)) => (r, c),
    Err(e) => panic!("Connection closed abruptly: {}", e)
  };

  println!("Connection closed gracefully with error: {:?}", reason);
}<commit_msg>update tls<commit_after>#![allow(unused_variables)]
#![allow(unused_imports)]

/// Note: Fred must be compiled with the `enable-tls` feature for this to work.

extern crate fred;
extern crate tokio_core;
extern crate futures;

use fred::RedisClient;
use fred::types::*;

use tokio_core::reactor::Core;
use futures::Future;

fn main() {
  let config = RedisConfig::Centralized {
    // Note: this must match the hostname tied to the cert
    host: "foo.bar.com".into(),
    port: 6379,
    key: Some("key".into()),
    // if compiled without `enable-tls` setting this to `true` does nothing, which is done to avoid requiring TLS dependencies unless necessary
    tls: true,
    max_value_size: None
  };

  // otherwise usage is the same as the non-tls client...

  let mut core = Core::new().unwrap();
  let handle = core.handle();

  println!("Connecting to {:?}...", config);

  let client = RedisClient::new(config);
  let connection = client.connect(&handle);

  let commands = client.on_connect().and_then(|client| {
    println!("Client connected.");

    client.select(0)
  })
  .and_then(|client| {
    println!("Selected database.");cargo

    client.info(None)
  })
  .and_then(|(client, info)| {
    println!("Redis server info: {}", info);

    client.get("foo")
  })
  .and_then(|(client, result)| {
    println!("Got foo: {:?}", result);

    client.set("foo", "bar", Some(Expiration::PX(1000)), Some(SetOptions::NX))
  })
  .and_then(|(client, result)| {
    println!("Set 'bar' at 'foo'? {}. Subscribing to 'baz'...", result);

    client.subscribe("baz")
  })
  .and_then(|(client, result)| {
    println!("Subscribed to 'baz'. Now subscribed to {} channels. Now exiting...", result);

    client.quit()
  });

  let (reason, client) = match core.run(connection.join(commands)) {
    Ok((r, c)) => (r, c),
    Err(e) => panic!("Connection closed abruptly: {}", e)
  };

  println!("Connection closed gracefully with error: {:?}", reason);
}<|endoftext|>


<commit_before>use super::{Canvas, Color, GraphicsContext, LinearColor, Rect};
use crate::context::Has;

/// A struct that represents where to put a drawable object.
///
/// This can either be a set of individual components, or
/// a single `Matrix4` transform.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Transform {
    /// Transform made of individual values
    Values {
        /// The position to draw the graphic expressed as a `Point2`.
        dest: mint::Point2<f32>,
        /// The orientation of the graphic in radians.
        rotation: f32,
        /// The x/y scale factors expressed as a `Vector2`.
        scale: mint::Vector2<f32>,
        /// An offset, which is applied before scaling and rotation happen.
        ///
        /// For most objects this works as a relative offset (meaning `[0.5,0.5]` is an offset which
        /// centers the object on the destination). These objects are:
        /// * `Image`, `Canvas`, `Text` and the sprites inside an `InstanceArray` (as long as you're
        /// not making an instanced mesh-draw)
        offset: mint::Point2<f32>,
    },
    /// Transform made of an arbitrary matrix.
    ///
    /// It should represent the final model matrix of the given drawable.  This is useful for
    /// situations where, for example, you build your own hierarchy system, where you calculate
    /// matrices of each hierarchy item and store a calculated world-space model matrix of an item.
    /// This lets you implement transform stacks, skeletal animations, etc.
    Matrix(mint::ColumnMatrix4<f32>),
}

impl Default for Transform {
    fn default() -> Self {
        Transform::Values {
            dest: mint::Point2 { x: 0.0, y: 0.0 },
            rotation: 0.0,
            scale: mint::Vector2 { x: 1.0, y: 1.0 },
            offset: mint::Point2 { x: 0.0, y: 0.0 },
        }
    }
}

impl Transform {
    /// Crunches the transform down to a single matrix, if it's not one already.
    pub fn to_matrix(self) -> Self {
        Transform::Matrix(self.to_bare_matrix())
    }

    /// Same as `to_matrix()` but just returns a bare `mint` matrix.
    pub fn to_bare_matrix(self) -> mint::ColumnMatrix4<f32> {
        match self {
            Transform::Matrix(m) => m,
            Transform::Values {
                dest,
                rotation,
                scale,
                offset,
            } => {
                // Calculate a matrix equivalent to doing this:
                // type Vec3 = na::Vector3<f32>;
                // let o = offset;
                // let translate = na::Matrix4::new_translation(&Vec3::new(dest.x, dest.y, 0.0));
                // let offset = na::Matrix4::new_translation(&Vec3::new(offset.x, offset.y, 0.0));
                // let offset_inverse =
                //     na::Matrix4::new_translation(&Vec3::new(-o.x, -o.y, 0.0));
                // let axis_angle = Vec3::z() * *rotation;
                // let rotation = na::Matrix4::new_rotation(axis_angle);
                // let scale = na::Matrix4::new_nonuniform_scaling(&Vec3::new(scale.x, scale.y, 1.0));
                // translate * rotation * scale * offset_inverse
                //
                // Doing the bits manually is faster though, or at least was last I checked.
                let (sinr, cosr) = rotation.sin_cos();
                let m00 = cosr * scale.x;
                let m01 = -sinr * scale.y;
                let m10 = sinr * scale.x;
                let m11 = cosr * scale.y;
                let m03 = offset.x * (-m00) - offset.y * m01 + dest.x;
                let m13 = offset.y * (-m11) - offset.x * m10 + dest.y;
                // Welp, this transpose fixes some bug that makes nothing draw,
                // that was introduced in commit 2c6b3cc03f34fb240f4246f5a68c75bd85b60eae.
                // The best part is, I don't know if this code is wrong, or whether there's
                // some reversed matrix multiply or such somewhere else that this cancel
                // out.  Probably the former though.
                glam::Mat4::from_cols_array(&[
                    m00, m01, 0.0, m03, // oh rustfmt you so fine
                    m10, m11, 0.0, m13, // you so fine you blow my mind
                    0.0, 0.0, 1.0, 0.0, // but leave my matrix formatting alone
                    0.0, 0.0, 0.0, 1.0, // plz
                ])
                .transpose()
                .into()
            }
        }
    }
}

/// Value describing the Z "coordinate" of a draw.
///
/// Greater values correspond to the foreground, and lower values
/// correspond to the background.
///
/// [`InstanceArray`](crate::graphics::InstanceArray)s internally uphold this order for their instances, _if_ they're created with
/// `ordered` set to `true`.
pub type ZIndex = i32;

/// A struct containing all the necessary info for drawing with parameters.
///
/// This struct implements the `Default` trait, so to set only some parameter
/// you can just do:
///
/// ```rust
/// # use ggez::*;
/// # use ggez::graphics::*;
/// # fn t(canvas: &mut Canvas, image: Image) {
/// let my_dest = glam::vec2(13.0, 37.0);
/// canvas.draw(&image, DrawParam::default().dest(my_dest));
/// # }
/// ```
///
/// As a shortcut, it also implements [`From` for `Into<Point2<f32>>`](#impl-From<P>).
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct DrawParam {
    /// A portion of the drawable to clip, as a fraction of the whole image.
    /// Defaults to the whole image (\[0.0, 0.0\] to \[1.0, 1.0\]) if omitted.
    pub src: Rect,
    /// Default: white.
    pub color: Color,
    /// Where to put the object.
    pub transform: Transform,
    /// The Z coordinate of the draw.
    pub z: ZIndex,
}

impl Default for DrawParam {
    fn default() -> Self {
        DrawParam {
            src: Rect::one(),
            color: Color::WHITE,
            transform: Transform::default(),
            z: 0,
        }
    }
}

impl DrawParam {
    /// Create a new DrawParam with default values.
    pub fn new() -> Self {
        Self::default()
    }

    /// Set the source rect.
    pub fn src(mut self, src: Rect) -> Self {
        self.src = src;
        self
    }

    pub(crate) fn get_dest_mut(&mut self) -> &mut mint::Point2<f32> {
        if let Transform::Values { dest, .. } = &mut self.transform {
            dest
        } else {
            panic!("Cannot calculate destination value for a DrawParam matrix")
        }
    }

    /// Set the dest point.
    pub fn dest<P>(mut self, dest: P) -> Self
    where
        P: Into<mint::Point2<f32>>,
    {
        *self.get_dest_mut() = dest.into();
        self
    }

    /// Set the `dest` and `scale` together.
    pub fn dest_rect(self, rect: Rect) -> Self {
        self.dest(rect.point()).scale(rect.size())
    }

    /// Set the color. This will be blended with whatever
    /// color the drawn object already is.
    pub fn color(mut self, color: impl Into<Color>) -> Self {
        self.color = color.into();
        self
    }

    /// Set the rotation.
    pub fn rotation(mut self, rot: f32) -> Self {
        if let Transform::Values {
            ref mut rotation, ..
        } = self.transform
        {
            *rotation = rot;
            self
        } else {
            panic!("Cannot set values for a DrawParam matrix")
        }
    }

    /// Set the scaling factors.
    pub fn scale<V>(mut self, scale_: V) -> Self
    where
        V: Into<mint::Vector2<f32>>,
    {
        if let Transform::Values { ref mut scale, .. } = self.transform {
            let p: mint::Vector2<f32> = scale_.into();
            *scale = p;
            self
        } else {
            panic!("Cannot set values for a DrawParam matrix")
        }
    }

    /// Set the transformation offset.
    pub fn offset<P>(mut self, offset_: P) -> Self
    where
        P: Into<mint::Point2<f32>>,
    {
        if let Transform::Values { ref mut offset, .. } = self.transform {
            let p: mint::Point2<f32> = offset_.into();
            *offset = p;
            self
        } else {
            panic!("Cannot set values for a DrawParam matrix")
        }
    }

    /// Set the transformation matrix.
    pub fn transform<M>(mut self, transform: M) -> Self
    where
        M: Into<mint::ColumnMatrix4<f32>>,
    {
        self.transform = Transform::Matrix(transform.into());
        self
    }

    /// Set the Z coordinate.
    pub fn z(mut self, z: ZIndex) -> Self {
        self.z = z;
        self
    }
}

/// Create a `DrawParam` from a location, like this:
///
/// ```rust
/// # use ggez::*;
/// # use ggez::graphics::*;
/// # fn t(canvas: &mut Canvas, image: Image) {
/// let my_dest = glam::vec2(13.0, 37.0);
/// canvas.draw(&image, my_dest);
/// # }
/// ```
impl<P> From<P> for DrawParam
where
    P: Into<mint::Point2<f32>>,
{
    fn from(location: P) -> Self {
        DrawParam::new().dest(location)
    }
}

/// All types that can be drawn onto a canvas implement the `Drawable` trait.
pub trait Drawable {
    /// Draws the drawable onto the canvas.
    fn draw(&self, canvas: &mut Canvas, param: impl Into<DrawParam>);

    /// Returns a bounding box in the form of a `Rect`.
    ///
    /// It returns `Option` because some `Drawable`s may have no bounding box,
    /// namely `InstanceArray` (as there is no true bounds for the instances given the instanced mesh can differ).
    fn dimensions(&self, gfx: &impl Has<GraphicsContext>) -> Option<Rect>;
}

#[derive(Debug, Copy, Clone, crevice::std140::AsStd140)]
pub(crate) struct DrawUniforms {
    pub color: mint::Vector4<f32>,
    pub src_rect: mint::Vector4<f32>,
    pub transform: mint::ColumnMatrix4<f32>,
}

#[allow(unsafe_code)]
unsafe impl bytemuck::Zeroable for DrawUniforms {}
#[allow(unsafe_code)]
unsafe impl bytemuck::Pod for DrawUniforms {}

impl DrawUniforms {
    pub fn from_param(param: &DrawParam, image_scale: Option<mint::Vector2<f32>>) -> Self {
        let (scale_x, scale_y) = if let Some(image_scale) = image_scale {
            (image_scale.x * param.src.w, image_scale.y * param.src.h)
        } else {
            (1., 1.)
        };

        let param = match param.transform {
            Transform::Values { scale, .. } => param.scale(mint::Vector2 {
                x: scale.x * scale_x,
                y: scale.y * scale_y,
            }),
            Transform::Matrix(m) => param.transform(
                glam::Mat4::from(m) * glam::Mat4::from_scale(glam::vec3(scale_x, scale_y, 1.)),
            ),
        };

        let color = LinearColor::from(param.color);

        DrawUniforms {
            color: <[f32; 4]>::from(color).into(),
            src_rect: mint::Vector4 {
                x: param.src.x,
                y: param.src.y,
                z: param.src.x + param.src.w,
                w: param.src.y + param.src.h,
            },
            transform: param.transform.to_bare_matrix(),
        }
    }
}
<commit_msg>added information about `DrawParam` methods panicking to the docs<commit_after>use super::{Canvas, Color, GraphicsContext, LinearColor, Rect};
use crate::context::Has;

/// A struct that represents where to put a drawable object.
///
/// This can either be a set of individual components, or
/// a single `Matrix4` transform.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Transform {
    /// Transform made of individual values
    Values {
        /// The position to draw the graphic expressed as a `Point2`.
        dest: mint::Point2<f32>,
        /// The orientation of the graphic in radians.
        rotation: f32,
        /// The x/y scale factors expressed as a `Vector2`.
        scale: mint::Vector2<f32>,
        /// An offset, which is applied before scaling and rotation happen.
        ///
        /// For most objects this works as a relative offset (meaning `[0.5,0.5]` is an offset which
        /// centers the object on the destination). These objects are:
        /// * `Image`, `Canvas`, `Text` and the sprites inside an `InstanceArray` (as long as you're
        /// not making an instanced mesh-draw)
        offset: mint::Point2<f32>,
    },
    /// Transform made of an arbitrary matrix.
    ///
    /// It should represent the final model matrix of the given drawable.  This is useful for
    /// situations where, for example, you build your own hierarchy system, where you calculate
    /// matrices of each hierarchy item and store a calculated world-space model matrix of an item.
    /// This lets you implement transform stacks, skeletal animations, etc.
    Matrix(mint::ColumnMatrix4<f32>),
}

impl Default for Transform {
    fn default() -> Self {
        Transform::Values {
            dest: mint::Point2 { x: 0.0, y: 0.0 },
            rotation: 0.0,
            scale: mint::Vector2 { x: 1.0, y: 1.0 },
            offset: mint::Point2 { x: 0.0, y: 0.0 },
        }
    }
}

impl Transform {
    /// Crunches the transform down to a single matrix, if it's not one already.
    pub fn to_matrix(self) -> Self {
        Transform::Matrix(self.to_bare_matrix())
    }

    /// Same as `to_matrix()` but just returns a bare `mint` matrix.
    pub fn to_bare_matrix(self) -> mint::ColumnMatrix4<f32> {
        match self {
            Transform::Matrix(m) => m,
            Transform::Values {
                dest,
                rotation,
                scale,
                offset,
            } => {
                // Calculate a matrix equivalent to doing this:
                // type Vec3 = na::Vector3<f32>;
                // let o = offset;
                // let translate = na::Matrix4::new_translation(&Vec3::new(dest.x, dest.y, 0.0));
                // let offset = na::Matrix4::new_translation(&Vec3::new(offset.x, offset.y, 0.0));
                // let offset_inverse =
                //     na::Matrix4::new_translation(&Vec3::new(-o.x, -o.y, 0.0));
                // let axis_angle = Vec3::z() * *rotation;
                // let rotation = na::Matrix4::new_rotation(axis_angle);
                // let scale = na::Matrix4::new_nonuniform_scaling(&Vec3::new(scale.x, scale.y, 1.0));
                // translate * rotation * scale * offset_inverse
                //
                // Doing the bits manually is faster though, or at least was last I checked.
                let (sinr, cosr) = rotation.sin_cos();
                let m00 = cosr * scale.x;
                let m01 = -sinr * scale.y;
                let m10 = sinr * scale.x;
                let m11 = cosr * scale.y;
                let m03 = offset.x * (-m00) - offset.y * m01 + dest.x;
                let m13 = offset.y * (-m11) - offset.x * m10 + dest.y;
                // Welp, this transpose fixes some bug that makes nothing draw,
                // that was introduced in commit 2c6b3cc03f34fb240f4246f5a68c75bd85b60eae.
                // The best part is, I don't know if this code is wrong, or whether there's
                // some reversed matrix multiply or such somewhere else that this cancel
                // out.  Probably the former though.
                glam::Mat4::from_cols_array(&[
                    m00, m01, 0.0, m03, // oh rustfmt you so fine
                    m10, m11, 0.0, m13, // you so fine you blow my mind
                    0.0, 0.0, 1.0, 0.0, // but leave my matrix formatting alone
                    0.0, 0.0, 0.0, 1.0, // plz
                ])
                .transpose()
                .into()
            }
        }
    }
}

/// Value describing the Z "coordinate" of a draw.
///
/// Greater values correspond to the foreground, and lower values
/// correspond to the background.
///
/// [`InstanceArray`](crate::graphics::InstanceArray)s internally uphold this order for their instances, _if_ they're created with
/// `ordered` set to `true`.
pub type ZIndex = i32;

/// A struct containing all the necessary info for drawing with parameters.
///
/// This struct implements the `Default` trait, so to set only some parameter
/// you can just do:
///
/// ```rust
/// # use ggez::*;
/// # use ggez::graphics::*;
/// # fn t(canvas: &mut Canvas, image: Image) {
/// let my_dest = glam::vec2(13.0, 37.0);
/// canvas.draw(&image, DrawParam::default().dest(my_dest));
/// # }
/// ```
///
/// As a shortcut, it also implements [`From` for `Into<Point2<f32>>`](#impl-From<P>).
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct DrawParam {
    /// A portion of the drawable to clip, as a fraction of the whole image.
    /// Defaults to the whole image (\[0.0, 0.0\] to \[1.0, 1.0\]) if omitted.
    pub src: Rect,
    /// Default: white.
    pub color: Color,
    /// Where to put the object.
    pub transform: Transform,
    /// The Z coordinate of the draw.
    pub z: ZIndex,
}

impl Default for DrawParam {
    fn default() -> Self {
        DrawParam {
            src: Rect::one(),
            color: Color::WHITE,
            transform: Transform::default(),
            z: 0,
        }
    }
}

impl DrawParam {
    /// Create a new DrawParam with default values.
    pub fn new() -> Self {
        Self::default()
    }

    /// Set the source rect.
    pub fn src(mut self, src: Rect) -> Self {
        self.src = src;
        self
    }

    pub(crate) fn get_dest_mut(&mut self) -> &mut mint::Point2<f32> {
        if let Transform::Values { dest, .. } = &mut self.transform {
            dest
        } else {
            panic!("Cannot calculate destination value for a DrawParam matrix")
        }
    }

    /// Set the dest point.
    ///
    /// # Panics
    ///
    /// Panics if `Transform` is of the `Matrix` variant.
    pub fn dest<P>(mut self, dest: P) -> Self
    where
        P: Into<mint::Point2<f32>>,
    {
        *self.get_dest_mut() = dest.into();
        self
    }

    /// Set the `dest` and `scale` together.
    ///
    /// # Panics
    ///
    /// Panics if `Transform` is of the `Matrix` variant.
    pub fn dest_rect(self, rect: Rect) -> Self {
        self.dest(rect.point()).scale(rect.size())
    }

    /// Set the color. This will be blended with whatever
    /// color the drawn object already is.
    pub fn color(mut self, color: impl Into<Color>) -> Self {
        self.color = color.into();
        self
    }

    /// Set the rotation.
    ///
    /// # Panics
    ///
    /// Panics if `Transform` is of the `Matrix` variant.
    pub fn rotation(mut self, rot: f32) -> Self {
        if let Transform::Values {
            ref mut rotation, ..
        } = self.transform
        {
            *rotation = rot;
            self
        } else {
            panic!("Cannot set values for a DrawParam matrix")
        }
    }

    /// Set the scaling factors.
    ///
    /// # Panics
    ///
    /// Panics if `Transform` is of the `Matrix` variant.
    pub fn scale<V>(mut self, scale_: V) -> Self
    where
        V: Into<mint::Vector2<f32>>,
    {
        if let Transform::Values { ref mut scale, .. } = self.transform {
            let p: mint::Vector2<f32> = scale_.into();
            *scale = p;
            self
        } else {
            panic!("Cannot set values for a DrawParam matrix")
        }
    }

    /// Set the transformation offset.
    ///
    /// # Panics
    ///
    /// Panics if `Transform` is of the `Matrix` variant.
    pub fn offset<P>(mut self, offset_: P) -> Self
    where
        P: Into<mint::Point2<f32>>,
    {
        if let Transform::Values { ref mut offset, .. } = self.transform {
            let p: mint::Point2<f32> = offset_.into();
            *offset = p;
            self
        } else {
            panic!("Cannot set values for a DrawParam matrix")
        }
    }

    /// Set the transformation matrix.
    pub fn transform<M>(mut self, transform: M) -> Self
    where
        M: Into<mint::ColumnMatrix4<f32>>,
    {
        self.transform = Transform::Matrix(transform.into());
        self
    }

    /// Set the Z coordinate.
    pub fn z(mut self, z: ZIndex) -> Self {
        self.z = z;
        self
    }
}

/// Create a `DrawParam` from a location, like this:
///
/// ```rust
/// # use ggez::*;
/// # use ggez::graphics::*;
/// # fn t(canvas: &mut Canvas, image: Image) {
/// let my_dest = glam::vec2(13.0, 37.0);
/// canvas.draw(&image, my_dest);
/// # }
/// ```
impl<P> From<P> for DrawParam
where
    P: Into<mint::Point2<f32>>,
{
    fn from(location: P) -> Self {
        DrawParam::new().dest(location)
    }
}

/// All types that can be drawn onto a canvas implement the `Drawable` trait.
pub trait Drawable {
    /// Draws the drawable onto the canvas.
    fn draw(&self, canvas: &mut Canvas, param: impl Into<DrawParam>);

    /// Returns a bounding box in the form of a `Rect`.
    ///
    /// It returns `Option` because some `Drawable`s may have no bounding box,
    /// namely `InstanceArray` (as there is no true bounds for the instances given the instanced mesh can differ).
    fn dimensions(&self, gfx: &impl Has<GraphicsContext>) -> Option<Rect>;
}

#[derive(Debug, Copy, Clone, crevice::std140::AsStd140)]
pub(crate) struct DrawUniforms {
    pub color: mint::Vector4<f32>,
    pub src_rect: mint::Vector4<f32>,
    pub transform: mint::ColumnMatrix4<f32>,
}

#[allow(unsafe_code)]
unsafe impl bytemuck::Zeroable for DrawUniforms {}
#[allow(unsafe_code)]
unsafe impl bytemuck::Pod for DrawUniforms {}

impl DrawUniforms {
    pub fn from_param(param: &DrawParam, image_scale: Option<mint::Vector2<f32>>) -> Self {
        let (scale_x, scale_y) = if let Some(image_scale) = image_scale {
            (image_scale.x * param.src.w, image_scale.y * param.src.h)
        } else {
            (1., 1.)
        };

        let param = match param.transform {
            Transform::Values { scale, .. } => param.scale(mint::Vector2 {
                x: scale.x * scale_x,
                y: scale.y * scale_y,
            }),
            Transform::Matrix(m) => param.transform(
                glam::Mat4::from(m) * glam::Mat4::from_scale(glam::vec3(scale_x, scale_y, 1.)),
            ),
        };

        let color = LinearColor::from(param.color);

        DrawUniforms {
            color: <[f32; 4]>::from(color).into(),
            src_rect: mint::Vector4 {
                x: param.src.x,
                y: param.src.y,
                z: param.src.x + param.src.w,
                w: param.src.y + param.src.h,
            },
            transform: param.transform.to_bare_matrix(),
        }
    }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

pub use self::error::Error;
pub use self::db::{Database, Snapshot, Fork, Patch, Change, Iterator, Iter};

pub use self::leveldb::{LevelDB, LevelDBOptions, LevelDBCache};
pub use self::memorydb::MemoryDB;

pub use self::keys::StorageKey;
pub use self::values::StorageValue;

pub use self::entry::Entry;

pub use self::base_index::{BaseIndex, BaseIndexIter};
pub use self::map_index::MapIndex;
pub use self::list_index::ListIndex;
pub use self::key_set_index::KeySetIndex;
pub use self::value_set_index::ValueSetIndex;
pub use self::proof_list_index::{ProofListIndex, ListProof};
pub use self::proof_map_index::{ProofMapIndex, MapProof};

/// A specialized `Result` type for I/O operations with storage.
pub type Result<T> = ::std::result::Result<T, Error>;

mod error;

mod db;
mod leveldb;
mod memorydb;

mod keys;
mod values;

mod entry;

pub mod base_index;

pub mod map_index;
pub mod list_index;
pub mod key_set_index;
pub mod value_set_index;
pub mod proof_list_index;
pub mod proof_map_index;

#[cfg(test)]
mod tests;
<commit_msg>Docs for storage mod<commit_after>//! A module that provides a high-level interface for working with stored data.
//!
//! # Database
//!
//! A [`Database`] is the underlying type for working with stored data. Internally `Database` is
//! a key-value storage with reading isolation and atomic writing. This is an embedded database,
//! which means that only the Exonum process can access it. You can interact with a `Database` from
//! different threads by cloning it's instance.
//!
//! Exonum provides two types of database: [`LevelDB`] and [`MemoryDB`]. However, you can make your
//! own implementations of [`Database`] trait. See its documentation for more.
//!
//! # Snapshot and Fork
//!
//! There is no way to directly interact with data in the database.
//!
//! If you need to read the data, you can create a [`Snapshot`] using method [`snapshot`][1]
//! of the `Database` instance. Snapshots provide a read isolation, so you are guaranteed to work
//! with consistent values even if the data in the database changes between reads. `Snapshot`
//! provides all the necessary methods for reading data from the database, so `&Storage`
//! is used as a storage view for creating read-only [indices] representation.
//!
//! If you need to make any changes to the data, you need to create a [`Fork`] using method
//! [`fork`][2] of the `Database` instance. As well as `Snapshot`, `Fork` provides a read isolation
//! and also allows you to create a sequence of changes to the database that are specified
//! as [`Patch`]. Later you can atomically merge a patch into the database using method [`merge`].
//!
//! # StorageKey and StorageValue traits
//!
//! If you need to use your own data types as keys or values in storage, you need to implement
//! the [`StorageKey`] or [`StorageValue`] traits respectively. These traits are already
//! implemented for most standard types. See their documentation for more.
//!
//! # Indices
//!
//! Indexes are structures that represent high-level data collections that are stored in a database.
//! This concept is similar to tables in relational databases. All indexes are stored in a single
//! key-value table, but internally the keys of each index will be prefixed with the unique index
//! prefixes, so the data of the different indexes do not conflict with each other. The interfaces
//! of the indexes are similar to ordinary collections (like arrays, maps and sets), but their data
//! is located in persistent storage.
//!
//! Merklized indices support the ability to generate the cryptographic proofs about the inclusion
//! of data in them. Having such proof external client may verify locally that received data was
//! really authorized by the validators without having to replicate the entire blockchain contents.
//!
//! Exonum implements the following indices:
//!
//! - [`Entry`] is a specific index that stores only one value. Useful for global values, such as
//! configuration. Similar to combination of [`Box`] and [`Option`] from standard library.
//! - [`ListIndex`] is a list of items stored in sequential order. Similar to [`Vec`] collection
//! from standard library.
//! - [`MapIndex`] is a map of keys and values. Similar to [`BTreeMap`] collection from standard
//! library.
//! - [`ProofListIndex`] is a Merklized version of `ListIndex` which supports the cryptographic
//! proofs of existence and is implemented as a Merkle tree.
//! - [`ProofMapIndex`] is a Merklized version of `MapIndex` which supports the cryptographic
//! proofs of existence and is implemented as a Merkle Patricia tree.
//! - [`KeySetIndex`] and [`ValueSetIndex`] is a set of items, similar to [`BTreeSet`] and
//! [`HashSet`] from standard library.
//!
//! If necessary, it's possible to implement new specific types of indexes. To do this, you need
//! to create a wrapper over [`BaseIndex`] structure. See their documentation for more.
//!
//! [`Database`]: trait.Database.html
//! [`LevelDB`]: struct.LevelDB.html
//! [`MemoryDB`]: struct.MemoryDB.html
//! [`Snapshot`]: trait.Snapshot.html
//! [`Fork`]: struct.fork.html
//! [`Patch`]: type.Patch.html
//! [1]: trait.Database.html#tymethod.snapshot
//! [2]: trait.Database.html#method.fork
//! [`merge`]: trait.Database.html#tymethod.merge
//! [`StorageKey`]: trait.StorageKey.html
//! [`StorageValue`]: trait.StorageValue.html
//! [`Entry`]: struct.Entry.html
//! [`ListIndex`]: list_index/struct.ListIndex.html
//! [`MapIndex`]: map_index/struct.MapIndex.html
//! [`ProofListIndex`]: proof_list_index/struct.ProofListIndex.html
//! [`ProofMapIndex`]: proof_map_index/struct.ProofMapIndex.html
//! [`KeySetIndex`]: key_set_index/struct.KeySetIndex.html
//! [`ValueSetIndex`]: value_set_index/struct.ValueSetIndex.html
//! [`BaseIndex`]: base_index/struct.BaseIndex.html
//! [indices]: #indices
//! [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html
//! [`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html
//! [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
//! [`BTreeSet`]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html
//! [`HashSet`]: https://doc.rust-lang.org/std/collections/struct.HashSet.html

#![deny(missing_docs)]

pub use self::error::Error;
pub use self::db::{Database, Snapshot, Fork, Patch, Change, Iterator, Iter};

pub use self::leveldb::{LevelDB, LevelDBOptions, LevelDBCache};
pub use self::memorydb::MemoryDB;

pub use self::keys::StorageKey;
pub use self::values::StorageValue;

pub use self::entry::Entry;

pub use self::base_index::{BaseIndex, BaseIndexIter};
pub use self::map_index::MapIndex;
pub use self::list_index::ListIndex;
pub use self::key_set_index::KeySetIndex;
pub use self::value_set_index::ValueSetIndex;
pub use self::proof_list_index::{ProofListIndex, ListProof};
pub use self::proof_map_index::{ProofMapIndex, MapProof};

/// A specialized `Result` type for I/O operations with storage.
pub type Result<T> = ::std::result::Result<T, Error>;

mod error;

mod db;
mod leveldb;
mod memorydb;

mod keys;
mod values;

mod entry;

pub mod base_index;

pub mod map_index;
pub mod list_index;
pub mod key_set_index;
pub mod value_set_index;
pub mod proof_list_index;
pub mod proof_map_index;

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::io::{Read, Write, Result};

// use data::SideData;

#[derive(Debug, Clone, PartialEq)]
pub struct Packet {
    pub data : Vec<u8>,
    pub pts : Option<i64>,
    pub dts : Option<i64>,
    pub pos : Option<usize>,
    pub duration: Option<i64>,
    pub stream_index : isize,

    // side_data : SideData;

    pub is_key: bool,
    pub is_corrupted: bool,
}

impl Packet {
    pub fn with_capacity(capacity: usize) -> Self {
        Packet {
            data : Vec::with_capacity(capacity),
            pts : None,
            dts : None,
            pos : None,
            duration: None,
            stream_index : -1,
            is_key: false,
            is_corrupted: false,
        }
    }

    pub fn new() -> Self {
        Self::with_capacity(0)
    }
}

pub trait ReadPacket: Read {
    fn get_packet(&mut self, len: usize) -> Result<Packet> {
        let mut pkt = Packet::with_capacity(len);
        unsafe {
            pkt.data.set_len(len);
            try!(self.read(pkt.data.as_mut_slice()));
        }
        Ok(pkt)
    }
}

pub trait WritePacket: Write {
    fn put_packet(&mut self, pkt: Packet) -> Result<()> {
        self.write_all(pkt.data.as_slice())
    }
}

impl<R: Read + ?Sized> ReadPacket for R {}
impl<W: Write + ?Sized> WritePacket for W {}

#[cfg(test)]
mod test {
    use std::io::Cursor;
    use super::*;

    #[test]
    fn read_packet() {
        let mut buf = Cursor::new(vec![0; 1024]);

        match buf.get_packet(1024) {
            Ok(pkt) => assert!(pkt.data[0] == 0),
            _ => assert!(false)
        }
    }

    #[test]
    fn write_packet() {
        let size = 1024;
        let mut buf = Cursor::new(Vec::with_capacity(size));

        let mut pkt = Packet::with_capacity(size);

        for i in 0..size {
            pkt.data.push(i as u8);
        }

        buf.put_packet(pkt).unwrap();

        let vec = buf.into_inner();

        for i in 0..size {
            println!("{}", vec[i]);
            assert!(vec[i] == i as u8);
        }
    }
}
<commit_msg>packet: Make duration unsigned<commit_after>#![allow(dead_code)]

use std::io::{Read, Write, Result};

// use data::SideData;

#[derive(Debug, Clone, PartialEq)]
pub struct Packet {
    pub data : Vec<u8>,
    pub pts : Option<i64>,
    pub dts : Option<i64>,
    pub pos : Option<usize>,
    pub duration: Option<u64>,
    pub stream_index : isize,

    // side_data : SideData;

    pub is_key: bool,
    pub is_corrupted: bool,
}

impl Packet {
    pub fn with_capacity(capacity: usize) -> Self {
        Packet {
            data : Vec::with_capacity(capacity),
            pts : None,
            dts : None,
            pos : None,
            duration: None,
            stream_index : -1,
            is_key: false,
            is_corrupted: false,
        }
    }

    pub fn new() -> Self {
        Self::with_capacity(0)
    }
}

pub trait ReadPacket: Read {
    fn get_packet(&mut self, len: usize) -> Result<Packet> {
        let mut pkt = Packet::with_capacity(len);
        unsafe {
            pkt.data.set_len(len);
            try!(self.read(pkt.data.as_mut_slice()));
        }
        Ok(pkt)
    }
}

pub trait WritePacket: Write {
    fn put_packet(&mut self, pkt: Packet) -> Result<()> {
        self.write_all(pkt.data.as_slice())
    }
}

impl<R: Read + ?Sized> ReadPacket for R {}
impl<W: Write + ?Sized> WritePacket for W {}

#[cfg(test)]
mod test {
    use std::io::Cursor;
    use super::*;

    #[test]
    fn read_packet() {
        let mut buf = Cursor::new(vec![0; 1024]);

        match buf.get_packet(1024) {
            Ok(pkt) => assert!(pkt.data[0] == 0),
            _ => assert!(false)
        }
    }

    #[test]
    fn write_packet() {
        let size = 1024;
        let mut buf = Cursor::new(Vec::with_capacity(size));

        let mut pkt = Packet::with_capacity(size);

        for i in 0..size {
            pkt.data.push(i as u8);
        }

        buf.put_packet(pkt).unwrap();

        let vec = buf.into_inner();

        for i in 0..size {
            println!("{}", vec[i]);
            assert!(vec[i] == i as u8);
        }
    }
}
<|endoftext|>


<commit_before>use std::char::to_digit;
use state::ParseState;
use state::CharClass;
use error::ParseError::*;

// add functionality to
// build in ~str to shift a number
// of characters from the beginning
trait RegexInputStr {
  fn shiftn_char(&mut self, times: uint);
}

impl RegexInputStr for ~str {
  fn shiftn_char(&mut self, times: uint) {
    for _ in range(0, times) {
      self.shift_char();
    }
  }
}

// check for an err,
macro_rules! check_ok(
  ($f: expr) => (
    match $f {
      ParseOk => { }
      e => return e
    }
  );
)

// parse functions
//
// these take in a pointer to a ParseState and an input string,
// and finish / modify the ParseState

fn parse_charclass(t: &mut ~str, ps: &mut ParseState) -> ParseCode {

  let mut cc = CharClass::new();

  // we need to keep track of any [, ( in
  // the input, because we can just ignore
  // them
  let mut nbracket: uint = 0;

  // check to see if the first char following
  // '[' is a '^', if so, it is a negated char
  // class
  let negate = match t.char_at(0) {
    '^' => {
      t.shift_char();
      true
    },
    _ => false
  };

  while (t.len() > 0) {

    match t.char_at(0) {
      '[' => {
        nbracket += 1;
        t.shift_char();
      },
      ']' => {
        t.shift_char();
        if (nbracket > 0) {
          nbracket -= 1;
        } else {
          if (negate) {
            check_ok!(cc.negate());
          }
          ps.pushCharClass(cc);
          return ParseOk;
        }
      }
      c => {
        t.shift_char();

        // check to see if its this is part of a
        // range
        if (t.len() > 1) {
          match t.char_at(0) {
            '-' => {
              if (t.char_at(1) != ']') {
                match cc.addRange(c, t.char_at(1)) {
                  ParseOk => { },
                  e => return e,
                }
                t.shiftn_char(2);
              } else {
                cc.addRange(c, c);
              }
            }
            _ => {
              cc.addRange(c, c);
            }
          }
        } else {
          cc.addRange(c, c);
        }
      }
    }

  }

  ParseExpectedClosingBracket
}

// tries to determine if there
// is a repetition operation
// and parses it
// multiple cases:
// {a,b}: from a to be inclusive
// {a,}:  a unbounded
// {a}:   exactly a
fn parse_repetition(t: &mut ~str, ps: &mut ParseState) -> ParseCode {

  let buf = ~"";

  if (t.len() > 1) {
    let s = match t.char_at(0) {
      x if x > '0' && x < '9' => to_digit(x, 10).unwrap(),
      _ => return ParseOk // not parsable
    };
    match t.char_at(1) {
      ',' => { } // continue
      '}' => {
        t.shiftn_char(2);
        return ps.doBoundedRepetition(s, s);
      }
      _ => return ParseOk // not parsable
    }

    if (t.len() > 2) {
      let e = match t.char_at(2) {
        '}' => {
          t.shiftn_char(3);
          return ps.doUnboundedRepetition(s);
        }
        x if x > '0' && x < '9' => to_digit(x, 10).unwrap(),
        _ => return ParseOk // not parsable
      };
      if (t.len() > 3) {
        match t.char_at(3) {
          '}' => {
            t.shiftn_char(4);
            return ps.doBoundedRepetition(s, e);
          },
          _ => return ParseOk // not parsable
        }
      }
    }
  }

  ParseOk
}

// parse an input string recursively
// ideally, we wouldn't parse an input string recursively
// because rust does not optimize tail end
// recursive calls, but...
// this way is pretty
pub fn parse_recursive(t: &mut ~str, ps: &mut ParseState) -> ParseCode {

  // cases for
  // parsing different characters
  // in the input string
  while (t.len() > 0) {

    match t.char_at(0) {
      '(' => {
        ps.doConcatenation();
        ps.pushLeftParen();

        t.shift_char();
        check_ok!(parse_recursive(t, ps));
        ps.doLeftParen();
      }
      ')' => {
        t.shift_char();
        if (ps.hasUnmatchedParens()) {
          break;
        }
        return ParseUnexpectedClosingParen;
      }

      '|' => {
        ps.doConcatenation();
        ps.pushAlternation();

        t.shift_char();
        check_ok!(parse_recursive(t, ps));
        ps.doAlternation();

        if (ps.hasUnmatchedParens()) {
          break;
        }
      }

      '*' => {
        t.shift_char();
        ps.doKleine();
      }
      '?' => {
        t.shift_char();
        ps.doZeroOrOne();
      }
      '+' => {
        t.shift_char();
        ps.doOneOrMore();
      }

      '{' => {
        t.shift_char();
        check_ok!(parse_repetition(t, ps));
      }

      '[' => {
        t.shift_char();
        check_ok!(parse_charclass(t, ps));
      }

      c => {
        ps.pushLiteral(c.to_str());
        t.shift_char();
      }
    }

    //ps.trace();

  }

  ps.doConcatenation();

  ParseOk
}
<commit_msg>added tests for parsing, caught parenthases parsing bug<commit_after>use std::char::to_digit;
use state::ParseState;
use state::CharClass;
use error::ParseError::*;

// add functionality to
// build in ~str to shift a number
// of characters from the beginning
trait RegexInputStr {
  fn shiftn_char(&mut self, times: uint);
}

impl RegexInputStr for ~str {
  fn shiftn_char(&mut self, times: uint) {
    for _ in range(0, times) {
      self.shift_char();
    }
  }
}

// check for an err,
macro_rules! check_ok(
  ($f: expr) => (
    match $f {
      ParseOk => { }
      e => return e
    }
  );
)

// parse functions
//
// these take in a pointer to a ParseState and an input string,
// and finish / modify the ParseState

fn parse_charclass(t: &mut ~str, ps: &mut ParseState) -> ParseCode {

  let mut cc = CharClass::new();

  // we need to keep track of any [, ( in
  // the input, because we can just ignore
  // them
  let mut nbracket: uint = 0;

  // check to see if the first char following
  // '[' is a '^', if so, it is a negated char
  // class
  let negate = match t.char_at(0) {
    '^' => {
      t.shift_char();
      true
    },
    _ => false
  };

  while (t.len() > 0) {

    match t.char_at(0) {
      '[' => {
        nbracket += 1;
        t.shift_char();
      },
      ']' => {
        t.shift_char();
        if (nbracket > 0) {
          nbracket -= 1;
        } else {
          if (negate) {
            check_ok!(cc.negate());
          }
          ps.pushCharClass(cc);
          return ParseOk;
        }
      }
      c => {
        t.shift_char();

        // check to see if its this is part of a
        // range
        if (t.len() > 1) {
          match t.char_at(0) {
            '-' => {
              if (t.char_at(1) != ']') {
                match cc.addRange(c, t.char_at(1)) {
                  ParseOk => { },
                  e => return e,
                }
                t.shiftn_char(2);
              } else {
                cc.addRange(c, c);
              }
            }
            _ => {
              cc.addRange(c, c);
            }
          }
        } else {
          cc.addRange(c, c);
        }
      }
    }

  }

  ParseExpectedClosingBracket
}

// tries to determine if there
// is a repetition operation
// and parses it
// multiple cases:
// {a,b}: from a to be inclusive
// {a,}:  a unbounded
// {a}:   exactly a
fn parse_repetition(t: &mut ~str, ps: &mut ParseState) -> ParseCode {

  let buf = ~"";

  if (t.len() > 1) {
    let s = match t.char_at(0) {
      x if x > '0' && x < '9' => to_digit(x, 10).unwrap(),
      _ => return ParseOk // not parsable
    };
    match t.char_at(1) {
      ',' => { } // continue
      '}' => {
        t.shiftn_char(2);
        return ps.doBoundedRepetition(s, s);
      }
      _ => return ParseOk // not parsable
    }

    if (t.len() > 2) {
      let e = match t.char_at(2) {
        '}' => {
          t.shiftn_char(3);
          return ps.doUnboundedRepetition(s);
        }
        x if x > '0' && x < '9' => to_digit(x, 10).unwrap(),
        _ => return ParseOk // not parsable
      };
      if (t.len() > 3) {
        match t.char_at(3) {
          '}' => {
            t.shiftn_char(4);
            return ps.doBoundedRepetition(s, e);
          },
          _ => return ParseOk // not parsable
        }
      }
    }
  }

  ParseOk
}

// parse an input string recursively
// ideally, we wouldn't parse an input string recursively
// because rust does not optimize tail end
// recursive calls, but...
// this way is pretty
pub fn parse_recursive(t: &mut ~str, ps: &mut ParseState) -> ParseCode {

  // cases for
  // parsing different characters
  // in the input string
  while (t.len() > 0) {

    match t.char_at(0) {
      '(' => {
        ps.doConcatenation();
        ps.pushLeftParen();

        t.shift_char();
        check_ok!(parse_recursive(t, ps));
      }
      ')' => {
        t.shift_char();
        if (ps.hasUnmatchedParens()) {
          ps.doLeftParen();
          break;
        }
        return ParseUnexpectedClosingParen;
      }

      '|' => {
        ps.doConcatenation();
        ps.pushAlternation();

        t.shift_char();
        check_ok!(parse_recursive(t, ps));
        ps.doAlternation();

        if (ps.hasUnmatchedParens()) {
          break;
        }
      }

      '*' => {
        t.shift_char();
        ps.doKleine();
      }
      '?' => {
        t.shift_char();
        ps.doZeroOrOne();
      }
      '+' => {
        t.shift_char();
        ps.doOneOrMore();
      }

      '{' => {
        t.shift_char();
        check_ok!(parse_repetition(t, ps));
      }

      '[' => {
        t.shift_char();
        check_ok!(parse_charclass(t, ps));
      }

      c => {
        ps.pushLiteral(c.to_str());
        t.shift_char();
      }
    }

    //ps.trace();

  }

  ps.doConcatenation();

  if (ps.hasUnmatchedParens() && t.len() == 0) {
    ParseExpectedClosingParen
  } else {
    ParseOk
  }
}
<|endoftext|>


<commit_before>use markup5ever::local_name;
use cairo::{self, ImageSurface, MatrixTrait};
use std::cell::Cell;

use crate::drawing_ctx::DrawingCtx;
use crate::error::AttributeResultExt;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers;
use crate::property_bag::PropertyBag;
use crate::rect::IRect;
use crate::surface_utils::shared_surface::SharedImageSurface;
use crate::util::clamp;

use super::context::{FilterContext, FilterOutput, FilterResult};
use super::{Filter, FilterError, PrimitiveWithInput};

/// The `feOffset` filter primitive.
pub struct Offset {
    base: PrimitiveWithInput,
    dx: Cell<f64>,
    dy: Cell<f64>,
}

impl Default for Offset {
    /// Constructs a new `Offset` with empty properties.
    #[inline]
    fn default() -> Offset {
        Offset {
            base: PrimitiveWithInput::new::<Self>(),
            dx: Cell::new(0f64),
            dy: Cell::new(0f64),
        }
    }
}

impl NodeTrait for Offset {
    impl_node_as_filter!();

    fn set_atts(&mut self, parent: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        self.base.set_atts(parent, pbag)?;

        for (attr, value) in pbag.iter() {
            match attr {
                local_name!("dx") => self.dx.set(
                    parsers::number(value).attribute(attr)?,
                ),
                local_name!("dy") => self.dy.set(
                    parsers::number(value).attribute(attr)?,
                ),
                _ => (),
            }
        }

        Ok(())
    }
}

impl Filter for Offset {
    fn render(
        &self,
        _node: &RsvgNode,
        ctx: &FilterContext,
        draw_ctx: &mut DrawingCtx,
    ) -> Result<FilterResult, FilterError> {
        let input = self.base.get_input(ctx, draw_ctx)?;
        let bounds = self
            .base
            .get_bounds(ctx)
            .add_input(&input)
            .into_irect(draw_ctx);

        let dx = self.dx.get();
        let dy = self.dy.get();
        let (ox, oy) = ctx.paffine().transform_distance(dx, dy);

        // output_bounds contains all pixels within bounds,
        // for which (x - ox) and (y - oy) also lie within bounds.
        let output_bounds = IRect {
            x0: clamp(bounds.x0 + ox as i32, bounds.x0, bounds.x1),
            y0: clamp(bounds.y0 + oy as i32, bounds.y0, bounds.y1),
            x1: clamp(bounds.x1 + ox as i32, bounds.x0, bounds.x1),
            y1: clamp(bounds.y1 + oy as i32, bounds.y0, bounds.y1),
        };

        let output_surface = ImageSurface::create(
            cairo::Format::ARgb32,
            ctx.source_graphic().width(),
            ctx.source_graphic().height(),
        )?;

        {
            let cr = cairo::Context::new(&output_surface);
            cr.rectangle(
                output_bounds.x0 as f64,
                output_bounds.y0 as f64,
                (output_bounds.x1 - output_bounds.x0) as f64,
                (output_bounds.y1 - output_bounds.y0) as f64,
            );
            cr.clip();

            input.surface().set_as_source_surface(&cr, ox, oy);
            cr.paint();
        }

        Ok(FilterResult {
            name: self.base.result.borrow().clone(),
            output: FilterOutput {
                surface: SharedImageSurface::new(output_surface, input.surface().surface_type())?,
                bounds,
            },
        })
    }

    #[inline]
    fn is_affected_by_color_interpolation_filters(&self) -> bool {
        false
    }
}
<commit_msg>filters/offset: remove interior mutability<commit_after>use cairo::{self, ImageSurface, MatrixTrait};
use markup5ever::local_name;

use crate::drawing_ctx::DrawingCtx;
use crate::error::AttributeResultExt;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers;
use crate::property_bag::PropertyBag;
use crate::rect::IRect;
use crate::surface_utils::shared_surface::SharedImageSurface;
use crate::util::clamp;

use super::context::{FilterContext, FilterOutput, FilterResult};
use super::{Filter, FilterError, PrimitiveWithInput};

/// The `feOffset` filter primitive.
pub struct Offset {
    base: PrimitiveWithInput,
    dx: f64,
    dy: f64,
}

impl Default for Offset {
    /// Constructs a new `Offset` with empty properties.
    #[inline]
    fn default() -> Offset {
        Offset {
            base: PrimitiveWithInput::new::<Self>(),
            dx: 0f64,
            dy: 0f64,
        }
    }
}

impl NodeTrait for Offset {
    impl_node_as_filter!();

    fn set_atts(&mut self, parent: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        self.base.set_atts(parent, pbag)?;

        for (attr, value) in pbag.iter() {
            match attr {
                local_name!("dx") => self.dx = parsers::number(value).attribute(attr)?,
                local_name!("dy") => self.dy = parsers::number(value).attribute(attr)?,
                _ => (),
            }
        }

        Ok(())
    }
}

impl Filter for Offset {
    fn render(
        &self,
        _node: &RsvgNode,
        ctx: &FilterContext,
        draw_ctx: &mut DrawingCtx,
    ) -> Result<FilterResult, FilterError> {
        let input = self.base.get_input(ctx, draw_ctx)?;
        let bounds = self
            .base
            .get_bounds(ctx)
            .add_input(&input)
            .into_irect(draw_ctx);

        let (ox, oy) = ctx.paffine().transform_distance(self.dx, self.dy);

        // output_bounds contains all pixels within bounds,
        // for which (x - ox) and (y - oy) also lie within bounds.
        let output_bounds = IRect {
            x0: clamp(bounds.x0 + ox as i32, bounds.x0, bounds.x1),
            y0: clamp(bounds.y0 + oy as i32, bounds.y0, bounds.y1),
            x1: clamp(bounds.x1 + ox as i32, bounds.x0, bounds.x1),
            y1: clamp(bounds.y1 + oy as i32, bounds.y0, bounds.y1),
        };

        let output_surface = ImageSurface::create(
            cairo::Format::ARgb32,
            ctx.source_graphic().width(),
            ctx.source_graphic().height(),
        )?;

        {
            let cr = cairo::Context::new(&output_surface);
            cr.rectangle(
                output_bounds.x0 as f64,
                output_bounds.y0 as f64,
                (output_bounds.x1 - output_bounds.x0) as f64,
                (output_bounds.y1 - output_bounds.y0) as f64,
            );
            cr.clip();

            input.surface().set_as_source_surface(&cr, ox, oy);
            cr.paint();
        }

        Ok(FilterResult {
            name: self.base.result.borrow().clone(),
            output: FilterOutput {
                surface: SharedImageSurface::new(output_surface, input.surface().surface_type())?,
                bounds,
            },
        })
    }

    #[inline]
    fn is_affected_by_color_interpolation_filters(&self) -> bool {
        false
    }
}
<|endoftext|>


<commit_before>//! A set of builders to generate Rust source for PHF data structures at
//! compile time.
//!
//! The provided builders are intended to be used in a Cargo build script to
//! generate a Rust source file that will be included in a library at build
//! time.
//!
//! # Examples
//!
//! build.rs
//!
//! ```rust,no_run
//! extern crate phf_codegen;
//!
//! use std::fs::File;
//! use std::io::{BufWriter, Write};
//! use std::path::Path;
//!
//! fn main() {
//!     let path = Path::new(env!("OUT_DIR")).join("codegen.rs");
//!     let mut file = BufWriter::new(File::create(&path).unwrap());
//!
//!     write!(&mut file, "static KEYWORDS: phf::Map<&'static str, Keyword> = ").unwrap();
//!     phf_codegen::Map::new()
//!         .entry("loop", "Keyword::Loop")
//!         .entry("continue", "Keyword::Continue")
//!         .entry("break", "Keyword::Break")
//!         .entry("fn", "Keyword::Fn")
//!         .entry("extern", "Keyword::Extern")
//!         .build(&mut file)
//!         .unwrap();
//!     write!(&mut file, ";\n").unwrap();
//! }
//! ```
//!
//! lib.rs
//!
//! ```ignore
//! extern crate phf;
//!
//! #[derive(Clone)]
//! enum Keyword {
//!     Loop,
//!     Continue,
//!     Break,
//!     Fn,
//!     Extern,
//! }
//!
//! include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
//!
//! pub fn parse_keyword(keyword: &str) -> Option<Keyword> {
//!     KEYWORDS.get(keyword).cloned()
//! }
//! ```
//!
//! # Note
//!
//! The compiler's stack will overflow when processing extremely long method
//! chains (500+ calls). If generating a large PHF data structure, consider
//! looping over the entries or making each call a separate statement:
//!
//! ```rust
//! let entries = [("hello", "1"), ("world", "2")];
//!
//! let mut builder = phf_codegen::Map::new();
//! for &(key, value) in &entries {
//!     builder.entry(key, value);
//! }
//! // ...
//! ```
//!
//! ```rust
//! let mut builder = phf_codegen::Map::new();
//! builder.entry("hello", "1");
//! builder.entry("world", "2");
//! // ...
//! ```
#![doc(html_root_url="http://sfackler.github.io/rust-phf/doc")]
extern crate phf_shared;
extern crate phf_generator;

use phf_shared::PhfHash;
use std::collections::HashSet;
use std::fmt;
use std::hash::Hash;
use std::io;
use std::io::prelude::*;

/// A builder for the `phf::Map` type.
pub struct Map<K> {
    keys: Vec<K>,
    values: Vec<String>,
}

impl<K: Hash+PhfHash+Eq+fmt::Debug> Map<K> {
    /// Creates a new `phf::Map` builder.
    pub fn new() -> Map<K> {
        Map {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    ///
    /// `value` will be written exactly as provided in the constructed source.
    pub fn entry(&mut self, key: K, value: &str) -> &mut Map<K> {
        self.keys.push(key);
        self.values.push(value.to_string());
        self
    }

    /// Constructs a `phf::Map`, outputting Rust source to the provided writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        let mut set = HashSet::new();
        for key in &self.keys {
            if !set.insert(key) {
                panic!("duplicate key `{:?}`", key);
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        try!(write!(w, "::phf::Map {{
    key: {},
    disps: &[",
                    state.key));
        for &(d1, d2) in &state.disps {
            try!(write!(w, "
        ({}, {}),",
                        d1, d2));
        }
        try!(write!(w, "
    ],
    entries: &["));
        for &idx in &state.map {
            try!(write!(w, "
        ({:?}, {}),",
                        &self.keys[idx], &self.values[idx]));
        }
        write!(w, "
    ]
}}")
    }
}

/// A builder for the `phf::Set` type.
pub struct Set<T> {
    map: Map<T>
}

impl<T: Hash+PhfHash+Eq+fmt::Debug> Set<T> {
    /// Constructs a new `phf::Set` builder.
    pub fn new() -> Set<T> {
        Set {
            map: Map::new()
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut Set<T> {
        self.map.entry(entry, "()");
        self
    }

    /// Constructs a `phf::Set`, outputting Rust source to the provided writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        try!(write!(w, "::phf::Set {{ map: "));
        try!(self.map.build(w));
        write!(w, " }}")
    }
}

/// A builder for the `phf::OrderedMap` type.
pub struct OrderedMap<K> {
    keys: Vec<K>,
    values: Vec<String>,
}

impl<K: Hash+PhfHash+Eq+fmt::Debug> OrderedMap<K> {
    /// Constructs a enw `phf::OrderedMap` builder.
    pub fn new() -> OrderedMap<K> {
        OrderedMap {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    ///
    /// `value` will be written exactly as provided in the constructed source.
    pub fn entry(&mut self, key: K, value: &str) -> &mut OrderedMap<K> {
        self.keys.push(key);
        self.values.push(value.to_string());
        self
    }

    /// Constructs a `phf::OrderedMap`, outputting Rust source to the provided
    /// writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        let mut set = HashSet::new();
        for key in &self.keys {
            if !set.insert(key) {
                panic!("duplicate key `{:?}`", key);
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        try!(write!(w, "::phf::OrderedMap {{
    key: {},
    disps: &[",
                    state.key));
        for &(d1, d2) in &state.disps {
            try!(write!(w, "
        ({}, {}),",
                        d1, d2));
        }
        try!(write!(w, "
    ],
    idxs: &["));
        for &idx in &state.map {
            try!(write!(w, "
        {},",
                        idx));
        }
        try!(write!(w, "
    ],
    entries: &["));
        for (key, value) in self.keys.iter().zip(self.values.iter()) {
            try!(write!(w, "
        ({:?}, {}),",
                        key, value));
        }
        write!(w, "
    ]
}}")
    }
}

/// A builder for the `phf::OrderedSet` type.
pub struct OrderedSet<T> {
    map: OrderedMap<T>
}

impl<T: Hash+PhfHash+Eq+fmt::Debug> OrderedSet<T> {
    /// Constructs a new `phf::OrderedSet` builder.
    pub fn new() -> OrderedSet<T> {
        OrderedSet {
            map: OrderedMap::new()
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut OrderedSet<T> {
        self.map.entry(entry, "()");
        self
    }

    /// Constructs a `phf::OrderedSet`, outputting Rust source to the provided
    /// writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        try!(write!(w, "::phf::OrderedSet {{ map: "));
        try!(self.map.build(w));
        write!(w, " }}")
    }
}
<commit_msg>Doc tweak<commit_after>//! A set of builders to generate Rust source for PHF data structures at
//! compile time.
//!
//! The provided builders are intended to be used in a Cargo build script to
//! generate a Rust source file that will be included in a library at build
//! time.
//!
//! # Examples
//!
//! build.rs
//!
//! ```rust,no_run
//! extern crate phf_codegen;
//!
//! use std::fs::File;
//! use std::io::{BufWriter, Write};
//! use std::path::Path;
//!
//! fn main() {
//!     let path = Path::new(env!("OUT_DIR")).join("codegen.rs");
//!     let mut file = BufWriter::new(File::create(&path).unwrap());
//!
//!     write!(&mut file, "static KEYWORDS: phf::Map<&'static str, Keyword> = ").unwrap();
//!     phf_codegen::Map::new()
//!         .entry("loop", "Keyword::Loop")
//!         .entry("continue", "Keyword::Continue")
//!         .entry("break", "Keyword::Break")
//!         .entry("fn", "Keyword::Fn")
//!         .entry("extern", "Keyword::Extern")
//!         .build(&mut file)
//!         .unwrap();
//!     write!(&mut file, ";\n").unwrap();
//! }
//! ```
//!
//! lib.rs
//!
//! ```ignore
//! extern crate phf;
//!
//! #[derive(Clone)]
//! enum Keyword {
//!     Loop,
//!     Continue,
//!     Break,
//!     Fn,
//!     Extern,
//! }
//!
//! include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
//!
//! pub fn parse_keyword(keyword: &str) -> Option<Keyword> {
//!     KEYWORDS.get(keyword).cloned()
//! }
//! ```
//!
//! # Note
//!
//! The compiler's stack will overflow when processing extremely long method
//! chains (500+ calls). When generating large PHF data structures, consider
//! looping over the entries or making each call a separate statement:
//!
//! ```rust
//! let entries = [("hello", "1"), ("world", "2")];
//!
//! let mut builder = phf_codegen::Map::new();
//! for &(key, value) in &entries {
//!     builder.entry(key, value);
//! }
//! // ...
//! ```
//!
//! ```rust
//! let mut builder = phf_codegen::Map::new();
//! builder.entry("hello", "1");
//! builder.entry("world", "2");
//! // ...
//! ```
#![doc(html_root_url="http://sfackler.github.io/rust-phf/doc")]
extern crate phf_shared;
extern crate phf_generator;

use phf_shared::PhfHash;
use std::collections::HashSet;
use std::fmt;
use std::hash::Hash;
use std::io;
use std::io::prelude::*;

/// A builder for the `phf::Map` type.
pub struct Map<K> {
    keys: Vec<K>,
    values: Vec<String>,
}

impl<K: Hash+PhfHash+Eq+fmt::Debug> Map<K> {
    /// Creates a new `phf::Map` builder.
    pub fn new() -> Map<K> {
        Map {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    ///
    /// `value` will be written exactly as provided in the constructed source.
    pub fn entry(&mut self, key: K, value: &str) -> &mut Map<K> {
        self.keys.push(key);
        self.values.push(value.to_string());
        self
    }

    /// Constructs a `phf::Map`, outputting Rust source to the provided writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        let mut set = HashSet::new();
        for key in &self.keys {
            if !set.insert(key) {
                panic!("duplicate key `{:?}`", key);
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        try!(write!(w, "::phf::Map {{
    key: {},
    disps: &[",
                    state.key));
        for &(d1, d2) in &state.disps {
            try!(write!(w, "
        ({}, {}),",
                        d1, d2));
        }
        try!(write!(w, "
    ],
    entries: &["));
        for &idx in &state.map {
            try!(write!(w, "
        ({:?}, {}),",
                        &self.keys[idx], &self.values[idx]));
        }
        write!(w, "
    ]
}}")
    }
}

/// A builder for the `phf::Set` type.
pub struct Set<T> {
    map: Map<T>
}

impl<T: Hash+PhfHash+Eq+fmt::Debug> Set<T> {
    /// Constructs a new `phf::Set` builder.
    pub fn new() -> Set<T> {
        Set {
            map: Map::new()
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut Set<T> {
        self.map.entry(entry, "()");
        self
    }

    /// Constructs a `phf::Set`, outputting Rust source to the provided writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        try!(write!(w, "::phf::Set {{ map: "));
        try!(self.map.build(w));
        write!(w, " }}")
    }
}

/// A builder for the `phf::OrderedMap` type.
pub struct OrderedMap<K> {
    keys: Vec<K>,
    values: Vec<String>,
}

impl<K: Hash+PhfHash+Eq+fmt::Debug> OrderedMap<K> {
    /// Constructs a enw `phf::OrderedMap` builder.
    pub fn new() -> OrderedMap<K> {
        OrderedMap {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    ///
    /// `value` will be written exactly as provided in the constructed source.
    pub fn entry(&mut self, key: K, value: &str) -> &mut OrderedMap<K> {
        self.keys.push(key);
        self.values.push(value.to_string());
        self
    }

    /// Constructs a `phf::OrderedMap`, outputting Rust source to the provided
    /// writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        let mut set = HashSet::new();
        for key in &self.keys {
            if !set.insert(key) {
                panic!("duplicate key `{:?}`", key);
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        try!(write!(w, "::phf::OrderedMap {{
    key: {},
    disps: &[",
                    state.key));
        for &(d1, d2) in &state.disps {
            try!(write!(w, "
        ({}, {}),",
                        d1, d2));
        }
        try!(write!(w, "
    ],
    idxs: &["));
        for &idx in &state.map {
            try!(write!(w, "
        {},",
                        idx));
        }
        try!(write!(w, "
    ],
    entries: &["));
        for (key, value) in self.keys.iter().zip(self.values.iter()) {
            try!(write!(w, "
        ({:?}, {}),",
                        key, value));
        }
        write!(w, "
    ]
}}")
    }
}

/// A builder for the `phf::OrderedSet` type.
pub struct OrderedSet<T> {
    map: OrderedMap<T>
}

impl<T: Hash+PhfHash+Eq+fmt::Debug> OrderedSet<T> {
    /// Constructs a new `phf::OrderedSet` builder.
    pub fn new() -> OrderedSet<T> {
        OrderedSet {
            map: OrderedMap::new()
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut OrderedSet<T> {
        self.map.entry(entry, "()");
        self
    }

    /// Constructs a `phf::OrderedSet`, outputting Rust source to the provided
    /// writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        try!(write!(w, "::phf::OrderedSet {{ map: "));
        try!(self.map.build(w));
        write!(w, " }}")
    }
}
<|endoftext|>


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

///////////////////////////////////////////////////////////////////////////////

pub trait Serialize<S, R> {
    fn serialize(&self, state: &mut S) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub trait Serializer<S, R> {
    fn serialize<T: Serialize<S, R>>(&mut self, value: &T) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub trait Visitor<R> {
    fn visit_null(&mut self) -> R;

    fn visit_bool(&mut self, v: bool) -> R;

    #[inline]
    fn visit_int(&mut self, v: int) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i8(&mut self, v: i8) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i16(&mut self, v: i16) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i32(&mut self, v: i32) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i64(&mut self, v: i64) -> R;

    #[inline]
    fn visit_uint(&mut self, v: uint) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u8(&mut self, v: u8) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u16(&mut self, v: u16) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u32(&mut self, v: u32) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u64(&mut self, v: u64) -> R;

    #[inline]
    fn visit_f32(&mut self, v: f32) -> R {
        self.visit_f64(v as f64)
    }

    fn visit_f64(&mut self, v: f64) -> R;

    fn visit_char(&mut self, value: char) -> R;

    fn visit_str(&mut self, value: &str) -> R;

    fn visit_seq<
        V: SeqVisitor<Self, R>,
    >(&mut self, visitor: V) -> R;

    #[inline]
    fn visit_named_seq<
        V: SeqVisitor<Self, R>,
    >(&mut self, _name: &'static str, visitor: V) -> R {
        self.visit_seq(visitor)
    }

    #[inline]
    fn visit_enum<
        V: SeqVisitor<Self, R>,
    >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> R {
        self.visit_seq(visitor)
    }

    fn visit_seq_elt<
        T: Serialize<Self, R>,
    >(&mut self, first: bool, value: T) -> R;

    fn visit_map<
        V: MapVisitor<Self, R>,
    >(&mut self, visitor: V) -> R;

    #[inline]
    fn visit_named_map<
        V: MapVisitor<Self, R>,
    >(&mut self, _name: &'static str, visitor: V) -> R {
        self.visit_map(visitor)
    }

    fn visit_map_elt<
        K: Serialize<Self, R>,
        V: Serialize<Self, R>,
    >(&mut self, first: bool, key: K, value: V) -> R;
}

pub trait SeqVisitor<S, R> {
    fn visit(&mut self, state: &mut S) -> Option<R>;

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        (0, None)
    }
}

pub trait MapVisitor<S, R> {
    fn visit(&mut self, state: &mut S) -> Option<R>;

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        (0, None)
    }
}

///////////////////////////////////////////////////////////////////////////////

macro_rules! impl_serialize {
    ($ty:ty, $method:ident) => {
        impl<S: Visitor<R>, R> Serialize<S, R> for $ty {
            #[inline]
            fn serialize(&self, state: &mut S) -> R {
                state.$method(*self)
            }
        }
    }
}

impl_serialize!(bool, visit_bool)
impl_serialize!(int, visit_int)
impl_serialize!(i8, visit_i8)
impl_serialize!(i16, visit_i16)
impl_serialize!(i32, visit_i32)
impl_serialize!(i64, visit_i64)
impl_serialize!(uint, visit_uint)
impl_serialize!(u8, visit_u8)
impl_serialize!(u16, visit_u16)
impl_serialize!(u32, visit_u32)
impl_serialize!(u64, visit_u64)
impl_serialize!(f32, visit_f32)
impl_serialize!(f64, visit_f64)
impl_serialize!(char, visit_char)

///////////////////////////////////////////////////////////////////////////////

impl<'a, S: Visitor<R>, R> Serialize<S, R> for &'a str {
    #[inline]
    fn serialize(&self, s: &mut S) -> R {
        s.visit_str(*self)
    }
}

impl<S: Visitor<R>, R> Serialize<S, R> for String {
    #[inline]
    fn serialize(&self, s: &mut S) -> R {
        s.visit_str(self.as_slice())
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct SeqIteratorVisitor<Iter> {
    iter: Iter,
    first: bool,
}

impl<T, Iter: Iterator<T>> SeqIteratorVisitor<Iter> {
    #[inline]
    pub fn new(iter: Iter) -> SeqIteratorVisitor<Iter> {
        SeqIteratorVisitor {
            iter: iter,
            first: true,
        }
    }
}

impl<
    T: Serialize<S, R>,
    Iter: Iterator<T>,
    S: Visitor<R>,
    R
> SeqVisitor<S, R> for SeqIteratorVisitor<Iter> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        let first = self.first;
        self.first = false;

        match self.iter.next() {
            Some(value) => Some(state.visit_seq_elt(first, value)),
            None => None
        }
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        self.iter.size_hint()
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<
    S: Visitor<R>,
    R,
    T: Serialize<S, R>
> Serialize<S, R> for Vec<T> {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_seq(SeqIteratorVisitor::new(self.iter()))
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct MapIteratorVisitor<Iter> {
    iter: Iter,
    first: bool,
}

impl<K, V, Iter: Iterator<(K, V)>> MapIteratorVisitor<Iter> {
    #[inline]
    pub fn new(iter: Iter) -> MapIteratorVisitor<Iter> {
        MapIteratorVisitor {
            iter: iter,
            first: true,
        }
    }
}

impl<
    K: Serialize<S, R>,
    V: Serialize<S, R>,
    Iter: Iterator<(K, V)>,
    S: Visitor<R>,
    R
> MapVisitor<S, R> for MapIteratorVisitor<Iter> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        let first = self.first;
        self.first = false;

        match self.iter.next() {
            Some((key, value)) => Some(state.visit_map_elt(first, key, value)),
            None => None
        }
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        self.iter.size_hint()
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<
    S: Visitor<R>,
    R,
    K: Serialize<S, R> + Ord,
    V: Serialize<S, R>
> Serialize<S, R> for TreeMap<K, V> {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_map(MapIteratorVisitor::new(self.iter()))
    }
}

impl<
    'a,
    S: Visitor<R>,
    R,
    T0: Serialize<S, R>,
    T1: Serialize<S, R>
> Serialize<S, R> for (T0, T1) {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_seq(Tuple2Serialize { value: self, state: 0 })
    }
}

struct Tuple2Serialize<'a, T0: 'a, T1: 'a> {
    value: &'a (T0, T1),
    state: uint,
}

impl<
    'a,
    S: Visitor<R>,
    R,
    T0: Serialize<S, R>,
    T1: Serialize<S, R>
> SeqVisitor<S, R> for Tuple2Serialize<'a, T0, T1> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        match self.state {
            0 => {
                self.state += 1;
                let (ref value, _) = *self.value;
                Some(state.visit_seq_elt(true, value))
            }
            1 => {
                self.state += 1;
                let (_, ref value) = *self.value;
                Some(state.visit_seq_elt(false, value))
            }
            _ => {
                None
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        let size = 2 - self.state;
        (size, Some(size))
    }
}

impl<
    'a,
    S: Visitor<R>,
    R,
    T: Serialize<S, R>
> Serialize<S, R> for &'a T {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        (**self).serialize(state)
    }
}

/*
///////////////////////////////////////////////////////////////////////////////

#[deriving(Show)]
pub enum Token<'a> {
    Null,
    Bool(bool),
    Int(int),
    I64(i64),
    U64(u64),
    F64(f64),
    Char(char),
    Str(&'a str),
    String(String),
    SeqStart(uint),
    MapStart(uint),
    StructStart(&'static str, uint),
    End,
}

pub trait TokenState<'a, R>: Visitor<R> {
    fn serialize(&mut self, token: Token<'a>) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub struct GatherTokens<'a> {
    tokens: Vec<Token<'a>>,
}

impl<'a> GatherTokens<'a> {
    pub fn new() -> GatherTokens<'a> {
        GatherTokens {
            tokens: Vec::new(),
        }
    }

    pub fn unwrap(self) -> Vec<Token<'a>> {
        self.tokens
    }
}

impl<'a> TokenState<'a, ()> for GatherTokens<'a> {
    fn serialize(&mut self, token: Token<'a>) -> () {
        self.tokens.push(token);
    }
}

impl<'a> Visitor<()> for GatherTokens<'a> {
    fn visit_null(&mut self) -> () {
        self.serialize(Null)
    }

    fn visit_bool(&mut self, value: bool) -> () {
        self.serialize(Bool(value))
    }

    fn visit_i64(&mut self, value: i64) -> () {
        self.serialize(I64(value))
    }

    fn visit_u64(&mut self, value: u64) -> () {
        self.serialize(U64(value))
    }

    fn visit_f64(&mut self, value: f64) -> () {
        self.serialize(F64(value))
    }

    fn visit_char(&mut self, value: char) -> () {
        self.serialize(Char(value))
    }

    fn visit_str(&mut self, value: &str) -> () {
        self.serialize(String(value.to_string()))
    }

    fn visit_seq<
        V: Visitor<GatherTokens<'a>, ()>
    >(&mut self, mut visitor: V) -> () {
        let (len, _) = visitor.size_hint();
        self.tokens.push(SeqStart(len));
        loop {
            match visitor.visit(self) {
                Some(()) => { }
                None => { break; }
            }
        }
        self.tokens.push(End)
    }

    fn visit_seq_elt<
        T: Serialize<GatherTokens<'a>, ()>
    >(&mut self, _first: bool, value: T) -> () {
        value.serialize(self)
    }

    fn visit_map<
        V: Visitor<GatherTokens<'a>, ()>
    >(&mut self, mut visitor: V) -> () {
        let (len, _) = visitor.size_hint();
        self.serialize(MapStart(len));
        loop {
            match visitor.visit(self) {
                Some(()) => { }
                None => { break; }
            }
        }
        self.serialize(End)
    }

    fn visit_named_map<
        V: Visitor<GatherTokens<'a>, ()>
    >(&mut self, name: &'static str, mut visitor: V) -> () {
        let (len, _) = visitor.size_hint();
        self.serialize(StructStart(name, len));
        loop {
            match visitor.visit(self) {
                Some(()) => { }
                None => { break; }
            }
        }
        self.serialize(End)
    }

    fn visit_map_elt<
        K: Serialize<GatherTokens<'a>, ()>,
        V: Serialize<GatherTokens<'a>, ()>
    >(&mut self, _first: bool, key: K, value: V) -> () {
        key.serialize(self);
        value.serialize(self)
    }
}
*/
<commit_msg>Minor cleanup<commit_after>use std::collections::TreeMap;

///////////////////////////////////////////////////////////////////////////////

pub trait Serialize<S, R> {
    fn serialize(&self, state: &mut S) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub trait Serializer<S, R> {
    fn serialize<T: Serialize<S, R>>(&mut self, value: &T) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub trait Visitor<R> {
    fn visit_null(&mut self) -> R;

    fn visit_bool(&mut self, v: bool) -> R;

    #[inline]
    fn visit_int(&mut self, v: int) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i8(&mut self, v: i8) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i16(&mut self, v: i16) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i32(&mut self, v: i32) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i64(&mut self, v: i64) -> R;

    #[inline]
    fn visit_uint(&mut self, v: uint) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u8(&mut self, v: u8) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u16(&mut self, v: u16) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u32(&mut self, v: u32) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u64(&mut self, v: u64) -> R;

    #[inline]
    fn visit_f32(&mut self, v: f32) -> R {
        self.visit_f64(v as f64)
    }

    fn visit_f64(&mut self, v: f64) -> R;

    fn visit_char(&mut self, value: char) -> R;

    fn visit_str(&mut self, value: &str) -> R;

    fn visit_seq<
        V: SeqVisitor<Self, R>,
    >(&mut self, visitor: V) -> R;

    #[inline]
    fn visit_named_seq<
        V: SeqVisitor<Self, R>,
    >(&mut self, _name: &'static str, visitor: V) -> R {
        self.visit_seq(visitor)
    }

    #[inline]
    fn visit_enum<
        V: SeqVisitor<Self, R>,
    >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> R {
        self.visit_seq(visitor)
    }

    fn visit_seq_elt<
        T: Serialize<Self, R>,
    >(&mut self, first: bool, value: T) -> R;

    fn visit_map<
        V: MapVisitor<Self, R>,
    >(&mut self, visitor: V) -> R;

    #[inline]
    fn visit_named_map<
        V: MapVisitor<Self, R>,
    >(&mut self, _name: &'static str, visitor: V) -> R {
        self.visit_map(visitor)
    }

    fn visit_map_elt<
        K: Serialize<Self, R>,
        V: Serialize<Self, R>,
    >(&mut self, first: bool, key: K, value: V) -> R;
}

pub trait SeqVisitor<S, R> {
    fn visit(&mut self, state: &mut S) -> Option<R>;

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        (0, None)
    }
}

pub trait MapVisitor<S, R> {
    fn visit(&mut self, state: &mut S) -> Option<R>;

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        (0, None)
    }
}

///////////////////////////////////////////////////////////////////////////////

macro_rules! impl_serialize {
    ($ty:ty, $method:ident) => {
        impl<S: Visitor<R>, R> Serialize<S, R> for $ty {
            #[inline]
            fn serialize(&self, state: &mut S) -> R {
                state.$method(*self)
            }
        }
    }
}

impl_serialize!(bool, visit_bool)
impl_serialize!(int, visit_int)
impl_serialize!(i8, visit_i8)
impl_serialize!(i16, visit_i16)
impl_serialize!(i32, visit_i32)
impl_serialize!(i64, visit_i64)
impl_serialize!(uint, visit_uint)
impl_serialize!(u8, visit_u8)
impl_serialize!(u16, visit_u16)
impl_serialize!(u32, visit_u32)
impl_serialize!(u64, visit_u64)
impl_serialize!(f32, visit_f32)
impl_serialize!(f64, visit_f64)
impl_serialize!(char, visit_char)

///////////////////////////////////////////////////////////////////////////////

impl<'a, S: Visitor<R>, R> Serialize<S, R> for &'a str {
    #[inline]
    fn serialize(&self, s: &mut S) -> R {
        s.visit_str(*self)
    }
}

impl<S: Visitor<R>, R> Serialize<S, R> for String {
    #[inline]
    fn serialize(&self, s: &mut S) -> R {
        s.visit_str(self.as_slice())
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct SeqIteratorVisitor<Iter> {
    iter: Iter,
    first: bool,
}

impl<T, Iter: Iterator<T>> SeqIteratorVisitor<Iter> {
    #[inline]
    pub fn new(iter: Iter) -> SeqIteratorVisitor<Iter> {
        SeqIteratorVisitor {
            iter: iter,
            first: true,
        }
    }
}

impl<
    T: Serialize<S, R>,
    Iter: Iterator<T>,
    S: Visitor<R>,
    R
> SeqVisitor<S, R> for SeqIteratorVisitor<Iter> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        let first = self.first;
        self.first = false;

        match self.iter.next() {
            Some(value) => Some(state.visit_seq_elt(first, value)),
            None => None
        }
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        self.iter.size_hint()
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<
    S: Visitor<R>,
    R,
    T: Serialize<S, R>
> Serialize<S, R> for Vec<T> {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_seq(SeqIteratorVisitor::new(self.iter()))
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<
    'a,
    S: Visitor<R>,
    R,
    T0: Serialize<S, R>,
    T1: Serialize<S, R>
> Serialize<S, R> for (T0, T1) {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        struct Visitor<'a, T0: 'a, T1: 'a> {
            value: &'a (T0, T1),
            state: uint,
        }

        impl<
            'a,
            S: self::Visitor<R>,
            R,
            T0: Serialize<S, R>,
            T1: Serialize<S, R>,
        > SeqVisitor<S, R> for Visitor<'a, T0, T1> {
            #[inline]
            fn visit(&mut self, state: &mut S) -> Option<R> {
                match self.state {
                    0 => {
                        self.state += 1;
                        let (ref value, _) = *self.value;
                        Some(state.visit_seq_elt(true, value))
                    }
                    1 => {
                        self.state += 1;
                        let (_, ref value) = *self.value;
                        Some(state.visit_seq_elt(false, value))
                    }
                    _ => {
                        None
                    }
                }
            }

            #[inline]
            fn size_hint(&self) -> (uint, Option<uint>) {
                let size = 2 - self.state;
                (size, Some(size))
            }
        }

        state.visit_seq(Visitor { value: self, state: 0 })
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct MapIteratorVisitor<Iter> {
    iter: Iter,
    first: bool,
}

impl<K, V, Iter: Iterator<(K, V)>> MapIteratorVisitor<Iter> {
    #[inline]
    pub fn new(iter: Iter) -> MapIteratorVisitor<Iter> {
        MapIteratorVisitor {
            iter: iter,
            first: true,
        }
    }
}

impl<
    K: Serialize<S, R>,
    V: Serialize<S, R>,
    Iter: Iterator<(K, V)>,
    S: Visitor<R>,
    R
> MapVisitor<S, R> for MapIteratorVisitor<Iter> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        let first = self.first;
        self.first = false;

        match self.iter.next() {
            Some((key, value)) => Some(state.visit_map_elt(first, key, value)),
            None => None
        }
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        self.iter.size_hint()
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<
    S: Visitor<R>,
    R,
    K: Serialize<S, R> + Ord,
    V: Serialize<S, R>
> Serialize<S, R> for TreeMap<K, V> {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_map(MapIteratorVisitor::new(self.iter()))
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<
    'a,
    S: Visitor<R>,
    R,
    T: Serialize<S, R>
> Serialize<S, R> for &'a T {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        (**self).serialize(state)
    }
}
<|endoftext|>