<commit_before>use std::fmt;
use std::ops::Index;
use std::slice::Iter;
use std::vec::Vec;

use itertools::Itertools;

use types::*;

pub type ColumnId = usize;

#[derive(Clone, PartialEq, Debug)]
pub struct Constraint
{
  pub nullable: bool,
  pub unique: bool,
  pub sorted: bool
}

#[derive(Clone, PartialEq, Debug)]
pub struct Identifier
{
  pub name: String,
  pub quoted: bool
}

impl Identifier
{
  pub fn new<T: AsRef<str>>(name: T) -> Identifier
  {
    Identifier {
      name: name.as_ref().to_string(),
      quoted: false
    }
  }

  pub fn new_quoted<T: AsRef<str>>(name: T, quoted: bool) -> Identifier
  {
    Identifier {
      name: name.as_ref().to_string(),
      quoted: quoted
    }
  }

  pub fn as_str(&self) -> &str { &self.name }
}

#[inline]
pub fn name<T: AsRef<str>>(name: T) -> Identifier { Identifier::new(name.as_ref()) }

impl fmt::Display for Identifier
{
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
  {
    write!(f, "{}", self.name)
  }
}

#[derive(Clone, PartialEq, Debug)]
pub struct Field
{
  pub name: Identifier,
  pub decl: FieldDecl,
  pub cstr: Option<Constraint>
}

impl Field
{
  pub fn new(name: Identifier, decl: FieldDecl) -> Field
  {
    Field {
      name: name,
      decl: decl,
      cstr: None,
    }
  }

  pub fn scalar(name: Identifier, ty: Ty) -> Field
  {
    Field::new(name, FieldDecl::Scalar(ty))
  }

  pub fn array(name: Identifier, decl: FieldDecl) -> Field
  {
    Field::new(name, FieldDecl::Array(Box::new(decl)))
  }

  pub fn map(name: Identifier, key_ty: FieldDecl, val_ty: FieldDecl) -> Field
  {
    Field::new(name, FieldDecl::Map(Box::new(key_ty), Box::new(val_ty)))
  }

  pub fn record(name: Identifier, fields: Vec<Field>) -> Field
  {
    Field::new(name, FieldDecl::Record(fields))
  }

  #[inline]
  pub fn name(&self) -> &str { &self.name.as_str() }

  pub fn identifier(&self) -> &Identifier { &self.name }
}

impl fmt::Display for Field
{
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
  {
    write!(f, "{}", display_field(self))
  }
}

#[inline]
fn display_field(f: &Field) -> String { format!("{} {}", f.name, f.decl) }

#[inline]
fn display_fields(fields: &Vec<Field>) -> String
{
  fields.iter().map(|f| display_field(f)).join(", ")
}

#[derive(Clone, PartialEq, Debug)]
pub enum FieldDecl
{
  Scalar (Ty),
  Record (Vec<Field>),
  Array  (Box<FieldDecl>),
  Map    (Box<FieldDecl>, Box<FieldDecl>)
}

impl FieldDecl
{
  pub fn scalar(ty: Ty) -> FieldDecl { FieldDecl::Scalar(ty) }

  pub fn record(fields: Vec<Field>) -> FieldDecl
  {
    FieldDecl::Record(fields)
  }
}

impl fmt::Display for FieldDecl
{
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
  {
    write!(f, "{}", display_field_decl(self))
  }
}

fn display_field_decl(decl: &FieldDecl) -> String
{
  match *decl {
    FieldDecl::Scalar(ref ty)         => ty.name().to_owned(),
    FieldDecl::Record(ref fields)     => format!("record ({})", display_fields(fields)),
    FieldDecl::Array (ref vt)         => format!("array<{}>", vt),
    FieldDecl::Map   (ref kt, ref vt) => format!("map<{},{}>", kt, vt)
  }
}

/// Root schema
#[derive(Clone, PartialEq, Debug)]
pub struct Schema { fields: Vec<Field> }

impl Schema
{
  pub fn new(fields: Vec<Field>) -> Schema { Schema {fields: fields} }

  pub fn size(&self) -> usize { self.fields.len() }

  pub fn find_id(&self, name: &str) -> Option<ColumnId>
  {
    self.fields.iter().position(|f| f.name() == name)
  }

  pub fn find_by_name(&self, name : &str) -> Option<&Field>
  {
    self.fields.iter().filter(|&f| f.name() == name).next()
  }

  pub fn iter(&self) -> Iter<Field>
  {
    self.fields.iter()
  }
}

impl Index<ColumnId> for Schema
{
  type Output = Field;
  fn index<'a>(&'a self, id: ColumnId) -> &'a Field
  {
    debug_assert!(id < self.fields.len(), "Field index is out of range");
    &self.fields[id]
  }
}

impl fmt::Display for Schema
{
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
  {
    write!(f, "{}", display_fields(&self.fields))
  }
}

#[allow(dead_code)]
fn create_test_schema() -> Schema
{
	Schema::new(vec![
    Field::scalar(name("col1"), *INT4_TY),
    Field::record(name("col2"), vec![
        Field::scalar(name("col3"), *INT4_TY),
        Field::scalar(name("col4"), *INT4_TY)
      ]
    ),
    Field::record(name("col5"), vec![
        Field::array(name("col6"), FieldDecl::scalar(*INT8_TY)),
        Field::array(name("col7"), FieldDecl::scalar(*INT8_TY)),
      ]
    ),
    Field::map(name("col8"), FieldDecl::scalar(*INT4_TY), FieldDecl::record(
      vec![
        Field::scalar(name("col9"),  *TEXT_TY),
        Field::scalar(name("col10"), *TEXT_TY),
      ])
    )
  ])
}

#[test]
fn test_schema_creation()
{
  let schema = create_test_schema();
  assert_eq!(vec![
    "col1 int4, col2 record (col3 int4, col4 int4), col5 record (col6 array<int8>, ",
    "col7 array<int8>), col8 map<int4,record (col9 text, col10 text)>"
    ].concat(), format!("{}", schema));
}
<commit_msg>add field method in Schema.<commit_after>use std::fmt;
use std::slice::Iter;
use std::vec::Vec;

use itertools::Itertools;

use types::*;

pub type ColumnId = usize;

#[derive(Clone, PartialEq, Debug)]
pub struct Constraint
{
  pub nullable: bool,
  pub unique: bool,
  pub sorted: bool
}

#[derive(Clone, PartialEq, Debug)]
pub struct Identifier
{
  pub name: String,
  pub quoted: bool
}

impl Identifier
{
  pub fn new<T: AsRef<str>>(name: T) -> Identifier
  {
    Identifier {
      name: name.as_ref().to_string(),
      quoted: false
    }
  }

  pub fn new_quoted<T: AsRef<str>>(name: T, quoted: bool) -> Identifier
  {
    Identifier {
      name: name.as_ref().to_string(),
      quoted: quoted
    }
  }

  pub fn as_str(&self) -> &str { &self.name }
}

#[inline]
pub fn name<T: AsRef<str>>(name: T) -> Identifier { Identifier::new(name.as_ref()) }

impl fmt::Display for Identifier
{
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
  {
    write!(f, "{}", self.name)
  }
}

#[derive(Clone, PartialEq, Debug)]
pub struct Field
{
  pub name: Identifier,
  pub decl: FieldDecl,
  pub cstr: Option<Constraint>
}

impl Field
{
  pub fn new(name: Identifier, decl: FieldDecl) -> Field
  {
    Field {
      name: name,
      decl: decl,
      cstr: None,
    }
  }

  pub fn scalar(name: Identifier, ty: Ty) -> Field
  {
    Field::new(name, FieldDecl::Scalar(ty))
  }

  pub fn array(name: Identifier, decl: FieldDecl) -> Field
  {
    Field::new(name, FieldDecl::Array(Box::new(decl)))
  }

  pub fn map(name: Identifier, key_ty: FieldDecl, val_ty: FieldDecl) -> Field
  {
    Field::new(name, FieldDecl::Map(Box::new(key_ty), Box::new(val_ty)))
  }

  pub fn record(name: Identifier, fields: Vec<Field>) -> Field
  {
    Field::new(name, FieldDecl::Record(fields))
  }

  #[inline]
  pub fn name(&self) -> &str { &self.name.as_str() }

  pub fn identifier(&self) -> &Identifier { &self.name }
}

impl fmt::Display for Field
{
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
  {
    write!(f, "{}", display_field(self))
  }
}

#[inline]
fn display_field(f: &Field) -> String { format!("{} {}", f.name, f.decl) }

#[inline]
fn display_fields(fields: &Vec<Field>) -> String
{
  fields.iter().map(|f| display_field(f)).join(", ")
}

#[derive(Clone, PartialEq, Debug)]
pub enum FieldDecl
{
  Scalar (Ty),
  Record (Vec<Field>),
  Array  (Box<FieldDecl>),
  Map    (Box<FieldDecl>, Box<FieldDecl>)
}

impl FieldDecl
{
  pub fn scalar(ty: Ty) -> FieldDecl { FieldDecl::Scalar(ty) }

  pub fn record(fields: Vec<Field>) -> FieldDecl
  {
    FieldDecl::Record(fields)
  }
}

impl fmt::Display for FieldDecl
{
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
  {
    write!(f, "{}", display_field_decl(self))
  }
}

fn display_field_decl(decl: &FieldDecl) -> String
{
  match *decl {
    FieldDecl::Scalar(ref ty)         => ty.name().to_owned(),
    FieldDecl::Record(ref fields)     => format!("record ({})", display_fields(fields)),
    FieldDecl::Array (ref vt)         => format!("array<{}>", vt),
    FieldDecl::Map   (ref kt, ref vt) => format!("map<{},{}>", kt, vt)
  }
}

/// Root schema
#[derive(Clone, PartialEq, Debug)]
pub struct Schema { fields: Vec<Field> }

impl Schema
{
  pub fn new(fields: Vec<Field>) -> Schema { Schema {fields: fields} }

  pub fn size(&self) -> usize { self.fields.len() }

  pub fn field<'a>(&'a self, id: ColumnId) -> &'a Field
  {
    debug_assert!(id < self.fields.len(), "Field index is out of range");
    &self.fields[id]
  }

  pub fn find_id(&self, name: &str) -> Option<ColumnId>
  {
    self.fields.iter().position(|f| f.name() == name)
  }

  pub fn find_by_name(&self, name : &str) -> Option<&Field>
  {
    self.fields.iter().filter(|&f| f.name() == name).next()
  }

  pub fn iter(&self) -> Iter<Field>
  {
    self.fields.iter()
  }
}

impl fmt::Display for Schema
{
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
  {
    write!(f, "{}", display_fields(&self.fields))
  }
}

#[allow(dead_code)]
fn create_test_schema() -> Schema
{
	Schema::new(vec![
    Field::scalar(name("col1"), *INT4_TY),
    Field::record(name("col2"), vec![
        Field::scalar(name("col3"), *INT4_TY),
        Field::scalar(name("col4"), *INT4_TY)
      ]
    ),
    Field::record(name("col5"), vec![
        Field::array(name("col6"), FieldDecl::scalar(*INT8_TY)),
        Field::array(name("col7"), FieldDecl::scalar(*INT8_TY)),
      ]
    ),
    Field::map(name("col8"), FieldDecl::scalar(*INT4_TY), FieldDecl::record(
      vec![
        Field::scalar(name("col9"),  *TEXT_TY),
        Field::scalar(name("col10"), *TEXT_TY),
      ])
    )
  ])
}

#[test]
fn test_schema_creation()
{
  let schema = create_test_schema();
  assert_eq!(vec![
    "col1 int4, col2 record (col3 int4, col4 int4), col5 record (col6 array<int8>, ",
    "col7 array<int8>), col8 map<int4,record (col9 text, col10 text)>"
    ].concat(), format!("{}", schema));
}
<|endoftext|>


<commit_before>use std::cell::Cell;

use cairo::MatrixTrait;
use cssparser;
use markup5ever::local_name;
use nalgebra::Vector3;

use crate::error::AttributeResultExt;
use crate::filters::context::FilterContext;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers;
use crate::property_bag::PropertyBag;
use crate::util::clamp;

/// A light source node (`feDistantLight`, `fePointLight` or `feSpotLight`).
#[derive(Clone)]
pub enum LightSource {
    Distant {
        azimuth: Cell<f64>,
        elevation: Cell<f64>,
    },
    Point {
        x: Cell<f64>,
        y: Cell<f64>,
        z: Cell<f64>,
    },
    Spot {
        x: Cell<f64>,
        y: Cell<f64>,
        z: Cell<f64>,
        points_at_x: Cell<f64>,
        points_at_y: Cell<f64>,
        points_at_z: Cell<f64>,
        specular_exponent: Cell<f64>,
        limiting_cone_angle: Cell<Option<f64>>,
    },
}

/// A light source node with affine transformations applied.
pub enum TransformedLightSource {
    Distant {
        azimuth: f64,
        elevation: f64,
    },
    Point {
        origin: Vector3<f64>,
    },
    Spot {
        origin: Vector3<f64>,
        direction: Vector3<f64>,
        specular_exponent: f64,
        limiting_cone_angle: Option<f64>,
    },
}

impl LightSource {
    /// Constructs a new `feDistantLight` with empty properties.
    #[inline]
    pub fn new_distant_light() -> LightSource {
        LightSource::Distant {
            azimuth: Cell::new(0.0),
            elevation: Cell::new(0.0),
        }
    }

    /// Constructs a new `fePointLight` with empty properties.
    #[inline]
    pub fn new_point_light() -> LightSource {
        LightSource::Point {
            x: Cell::new(0.0),
            y: Cell::new(0.0),
            z: Cell::new(0.0),
        }
    }

    /// Constructs a new `feSpotLight` with empty properties.
    #[inline]
    pub fn new_spot_light() -> LightSource {
        LightSource::Spot {
            x: Cell::new(0.0),
            y: Cell::new(0.0),
            z: Cell::new(0.0),
            points_at_x: Cell::new(0.0),
            points_at_y: Cell::new(0.0),
            points_at_z: Cell::new(0.0),
            specular_exponent: Cell::new(0.0),
            limiting_cone_angle: Cell::new(None),
        }
    }

    /// Returns a `TransformedLightSource` according to the given `FilterContext`.
    #[inline]
    pub fn transform(&self, ctx: &FilterContext) -> TransformedLightSource {
        match self {
            LightSource::Distant { azimuth, elevation } => TransformedLightSource::Distant {
                azimuth: azimuth.get(),
                elevation: elevation.get(),
            },
            LightSource::Point { x, y, z } => {
                let (x, y) = ctx.paffine().transform_point(x.get(), y.get());
                let z = ctx.transform_dist(z.get());

                TransformedLightSource::Point {
                    origin: Vector3::new(x, y, z),
                }
            }
            LightSource::Spot {
                x,
                y,
                z,
                points_at_x,
                points_at_y,
                points_at_z,
                specular_exponent,
                limiting_cone_angle,
            } => {
                let (x, y) = ctx.paffine().transform_point(x.get(), y.get());
                let z = ctx.transform_dist(z.get());
                let (points_at_x, points_at_y) = ctx
                    .paffine()
                    .transform_point(points_at_x.get(), points_at_y.get());
                let points_at_z = ctx.transform_dist(points_at_z.get());

                let origin = Vector3::new(x, y, z);
                let mut direction = Vector3::new(points_at_x, points_at_y, points_at_z) - origin;
                let _ = direction.try_normalize_mut(0.0);

                TransformedLightSource::Spot {
                    origin,
                    direction,
                    specular_exponent: specular_exponent.get(),
                    limiting_cone_angle: limiting_cone_angle.get(),
                }
            }
        }
    }
}

impl TransformedLightSource {
    /// Returns the unit (or null) vector from the image sample to the light.
    #[inline]
    pub fn vector(&self, x: f64, y: f64, z: f64) -> Vector3<f64> {
        match self {
            TransformedLightSource::Distant { azimuth, elevation } => {
                let azimuth = azimuth.to_radians();
                let elevation = elevation.to_radians();
                Vector3::new(
                    azimuth.cos() * elevation.cos(),
                    azimuth.sin() * elevation.cos(),
                    elevation.sin(),
                )
            }
            TransformedLightSource::Point { origin }
            | TransformedLightSource::Spot { origin, .. } => {
                let mut v = origin - Vector3::new(x, y, z);
                let _ = v.try_normalize_mut(0.0);
                v
            }
        }
    }

    /// Returns the color of the light.
    #[inline]
    pub fn color(
        &self,
        lighting_color: cssparser::RGBA,
        light_vector: Vector3<f64>,
    ) -> cssparser::RGBA {
        match self {
            TransformedLightSource::Spot {
                direction,
                specular_exponent,
                limiting_cone_angle,
                ..
            } => {
                let minus_l_dot_s = -light_vector.dot(&direction);
                if minus_l_dot_s <= 0.0 {
                    return cssparser::RGBA::transparent();
                }

                if let Some(limiting_cone_angle) = limiting_cone_angle {
                    if minus_l_dot_s < limiting_cone_angle.to_radians().cos() {
                        return cssparser::RGBA::transparent();
                    }
                }

                let factor = minus_l_dot_s.powf(*specular_exponent);
                let compute = |x| (clamp(f64::from(x) * factor, 0.0, 255.0) + 0.5) as u8;

                cssparser::RGBA {
                    red: compute(lighting_color.red),
                    green: compute(lighting_color.green),
                    blue: compute(lighting_color.blue),
                    alpha: 255,
                }
            }
            _ => lighting_color,
        }
    }
}

impl NodeTrait for LightSource {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match self {
                LightSource::Distant {
                    ref azimuth,
                    ref elevation,
                } => match attr {
                    local_name!("azimuth") => azimuth.set(parsers::number(value).attribute(attr)?),
                    local_name!("elevation") => {
                        elevation.set(parsers::number(value).attribute(attr)?)
                    }
                    _ => (),
                },
                LightSource::Point {
                    ref x,
                    ref y,
                    ref z,
                } => match attr {
                    local_name!("x") => x.set(parsers::number(value).attribute(attr)?),
                    local_name!("y") => y.set(parsers::number(value).attribute(attr)?),
                    local_name!("z") => z.set(parsers::number(value).attribute(attr)?),
                    _ => (),
                },
                LightSource::Spot {
                    ref x,
                    ref y,
                    ref z,
                    ref points_at_x,
                    ref points_at_y,
                    ref points_at_z,
                    ref specular_exponent,
                    ref limiting_cone_angle,
                } => match attr {
                    local_name!("x") => x.set(parsers::number(value).attribute(attr)?),
                    local_name!("y") => y.set(parsers::number(value).attribute(attr)?),
                    local_name!("z") => z.set(parsers::number(value).attribute(attr)?),
                    local_name!("pointsAtX") => {
                        points_at_x.set(parsers::number(value).attribute(attr)?)
                    }
                    local_name!("pointsAtY") => {
                        points_at_y.set(parsers::number(value).attribute(attr)?)
                    }
                    local_name!("pointsAtZ") => {
                        points_at_z.set(parsers::number(value).attribute(attr)?)
                    }
                    local_name!("specularExponent") => {
                        specular_exponent.set(parsers::number(value).attribute(attr)?)
                    }
                    local_name!("limitingConeAngle") => {
                        limiting_cone_angle.set(Some(parsers::number(value).attribute(attr)?))
                    }
                    _ => (),
                },
            }
        }

        Ok(())
    }
}
<commit_msg>filters/light/light_source: remove interior mutability<commit_after>use cairo::MatrixTrait;
use cssparser;
use markup5ever::local_name;
use nalgebra::Vector3;

use crate::error::AttributeResultExt;
use crate::filters::context::FilterContext;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers;
use crate::property_bag::PropertyBag;
use crate::util::clamp;

/// A light source node (`feDistantLight`, `fePointLight` or `feSpotLight`).
#[derive(Clone)]
pub enum LightSource {
    Distant {
        azimuth: f64,
        elevation: f64,
    },
    Point {
        x: f64,
        y: f64,
        z: f64,
    },
    Spot {
        x: f64,
        y: f64,
        z: f64,
        points_at_x: f64,
        points_at_y: f64,
        points_at_z: f64,
        specular_exponent: f64,
        limiting_cone_angle: Option<f64>,
    },
}

/// A light source node with affine transformations applied.
pub enum TransformedLightSource {
    Distant {
        azimuth: f64,
        elevation: f64,
    },
    Point {
        origin: Vector3<f64>,
    },
    Spot {
        origin: Vector3<f64>,
        direction: Vector3<f64>,
        specular_exponent: f64,
        limiting_cone_angle: Option<f64>,
    },
}

impl LightSource {
    /// Constructs a new `feDistantLight` with empty properties.
    #[inline]
    pub fn new_distant_light() -> LightSource {
        LightSource::Distant {
            azimuth: 0.0,
            elevation: 0.0,
        }
    }

    /// Constructs a new `fePointLight` with empty properties.
    #[inline]
    pub fn new_point_light() -> LightSource {
        LightSource::Point {
            x: 0.0,
            y: 0.0,
            z: 0.0,
        }
    }

    /// Constructs a new `feSpotLight` with empty properties.
    #[inline]
    pub fn new_spot_light() -> LightSource {
        LightSource::Spot {
            x: 0.0,
            y: 0.0,
            z: 0.0,
            points_at_x: 0.0,
            points_at_y: 0.0,
            points_at_z: 0.0,
            specular_exponent: 0.0,
            limiting_cone_angle: None,
        }
    }

    /// Returns a `TransformedLightSource` according to the given `FilterContext`.
    #[inline]
    pub fn transform(&self, ctx: &FilterContext) -> TransformedLightSource {
        match *self {
            LightSource::Distant { azimuth, elevation } => {
                TransformedLightSource::Distant { azimuth, elevation }
            }
            LightSource::Point { x, y, z } => {
                let (x, y) = ctx.paffine().transform_point(x, y);
                let z = ctx.transform_dist(z);

                TransformedLightSource::Point {
                    origin: Vector3::new(x, y, z),
                }
            }
            LightSource::Spot {
                x,
                y,
                z,
                points_at_x,
                points_at_y,
                points_at_z,
                specular_exponent,
                limiting_cone_angle,
            } => {
                let (x, y) = ctx.paffine().transform_point(x, y);
                let z = ctx.transform_dist(z);
                let (points_at_x, points_at_y) =
                    ctx.paffine().transform_point(points_at_x, points_at_y);
                let points_at_z = ctx.transform_dist(points_at_z);

                let origin = Vector3::new(x, y, z);
                let mut direction = Vector3::new(points_at_x, points_at_y, points_at_z) - origin;
                let _ = direction.try_normalize_mut(0.0);

                TransformedLightSource::Spot {
                    origin,
                    direction,
                    specular_exponent,
                    limiting_cone_angle,
                }
            }
        }
    }
}

impl TransformedLightSource {
    /// Returns the unit (or null) vector from the image sample to the light.
    #[inline]
    pub fn vector(&self, x: f64, y: f64, z: f64) -> Vector3<f64> {
        match self {
            TransformedLightSource::Distant { azimuth, elevation } => {
                let azimuth = azimuth.to_radians();
                let elevation = elevation.to_radians();
                Vector3::new(
                    azimuth.cos() * elevation.cos(),
                    azimuth.sin() * elevation.cos(),
                    elevation.sin(),
                )
            }
            TransformedLightSource::Point { origin }
            | TransformedLightSource::Spot { origin, .. } => {
                let mut v = origin - Vector3::new(x, y, z);
                let _ = v.try_normalize_mut(0.0);
                v
            }
        }
    }

    /// Returns the color of the light.
    #[inline]
    pub fn color(
        &self,
        lighting_color: cssparser::RGBA,
        light_vector: Vector3<f64>,
    ) -> cssparser::RGBA {
        match self {
            TransformedLightSource::Spot {
                direction,
                specular_exponent,
                limiting_cone_angle,
                ..
            } => {
                let minus_l_dot_s = -light_vector.dot(&direction);
                if minus_l_dot_s <= 0.0 {
                    return cssparser::RGBA::transparent();
                }

                if let Some(limiting_cone_angle) = limiting_cone_angle {
                    if minus_l_dot_s < limiting_cone_angle.to_radians().cos() {
                        return cssparser::RGBA::transparent();
                    }
                }

                let factor = minus_l_dot_s.powf(*specular_exponent);
                let compute = |x| (clamp(f64::from(x) * factor, 0.0, 255.0) + 0.5) as u8;

                cssparser::RGBA {
                    red: compute(lighting_color.red),
                    green: compute(lighting_color.green),
                    blue: compute(lighting_color.blue),
                    alpha: 255,
                }
            }
            _ => lighting_color,
        }
    }
}

impl NodeTrait for LightSource {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match *self {
                LightSource::Distant {
                    ref mut azimuth,
                    ref mut elevation,
                } => match attr {
                    local_name!("azimuth") => *azimuth = parsers::number(value).attribute(attr)?,
                    local_name!("elevation") => {
                        *elevation = parsers::number(value).attribute(attr)?
                    }
                    _ => (),
                },
                LightSource::Point {
                    ref mut x,
                    ref mut y,
                    ref mut z,
                } => match attr {
                    local_name!("x") => *x = parsers::number(value).attribute(attr)?,
                    local_name!("y") => *y = parsers::number(value).attribute(attr)?,
                    local_name!("z") => *z = parsers::number(value).attribute(attr)?,
                    _ => (),
                },
                LightSource::Spot {
                    ref mut x,
                    ref mut y,
                    ref mut z,
                    ref mut points_at_x,
                    ref mut points_at_y,
                    ref mut points_at_z,
                    ref mut specular_exponent,
                    ref mut limiting_cone_angle,
                } => match attr {
                    local_name!("x") => *x = parsers::number(value).attribute(attr)?,
                    local_name!("y") => *y = parsers::number(value).attribute(attr)?,
                    local_name!("z") => *z = parsers::number(value).attribute(attr)?,
                    local_name!("pointsAtX") => {
                        *points_at_x = parsers::number(value).attribute(attr)?
                    }
                    local_name!("pointsAtY") => {
                        *points_at_y = parsers::number(value).attribute(attr)?
                    }
                    local_name!("pointsAtZ") => {
                        *points_at_z = parsers::number(value).attribute(attr)?
                    }
                    local_name!("specularExponent") => {
                        *specular_exponent = parsers::number(value).attribute(attr)?
                    }
                    local_name!("limitingConeAngle") => {
                        *limiting_cone_angle = Some(parsers::number(value).attribute(attr)?)
                    }
                    _ => (),
                },
            }
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use super::{
    actor::{self, SharedState},
    Probe, Result, State, StateChangeImpl, StateMachine,
};
use chrono::{DateTime, Utc};
use slog_scope::{debug, info};

#[derive(Debug, PartialEq)]
pub(super) struct Poll {}

create_state_step!(Poll => Probe);

/// Implements the state change for `State<Poll>`.
///
/// This state is used to control when to go to the `State<Probe>`.
#[async_trait::async_trait]
impl StateChangeImpl for State<Poll> {
    fn name(&self) -> &'static str {
        "poll"
    }

    async fn handle(
        self,
        shared_state: &mut SharedState,
    ) -> Result<(StateMachine, actor::StepTransition)> {
        crate::logger::start_memory_logging();
        let current_time: DateTime<Utc> = Utc::now();

        if shared_state.runtime_settings.is_polling_forced() {
            debug!("Moving to Probe state as soon as possible.");
            return Ok((StateMachine::Probe(self.into()), actor::StepTransition::Immediate));
        }

        let last_poll = shared_state.runtime_settings.last_polling();

        if last_poll > current_time {
            info!("Forcing to Probe state as last polling seems to happened in future.");
            return Ok((StateMachine::Probe(self.into()), actor::StepTransition::Immediate));
        }

        debug!("Moving to Probe state after delay.");
        Ok((
            StateMachine::Probe(self.into()),
            actor::StepTransition::Delayed(
                shared_state.settings.polling.interval.to_std().unwrap(),
            ),
        ))
    }
}

#[actix_rt::test]
async fn probe_now() {
    use super::*;
    use crate::firmware::tests::{create_fake_metadata, FakeDevice};

    let mut settings = Settings::default();
    settings.polling.enabled = true;

    let mut runtime_settings = RuntimeSettings::default();
    runtime_settings.set_last_polling(Utc::now()).unwrap();
    runtime_settings.force_poll().expect("failed to force polling");

    let firmware = Metadata::from_path(&create_fake_metadata(FakeDevice::NoUpdate)).unwrap();
    let mut shared_state = SharedState { settings, runtime_settings, firmware };

    let machine =
        StateMachine::Poll(State(Poll {})).move_to_next_state(&mut shared_state).await.unwrap().0;

    assert_state!(machine, Probe);
}

#[actix_rt::test]
async fn last_poll_in_future() {
    use super::*;
    use crate::firmware::tests::{create_fake_metadata, FakeDevice};
    use chrono::Duration;

    let mut settings = Settings::default();
    settings.polling.enabled = true;

    let mut runtime_settings = RuntimeSettings::default();
    runtime_settings.set_last_polling(Utc::now() + Duration::days(1)).unwrap();

    let firmware = Metadata::from_path(&create_fake_metadata(FakeDevice::NoUpdate)).unwrap();
    let mut shared_state = SharedState { settings, runtime_settings, firmware };

    let machine =
        StateMachine::Poll(State(Poll {})).move_to_next_state(&mut shared_state).await.unwrap().0;

    assert_state!(machine, Probe);
}

#[actix_rt::test]
async fn interval_1_second() {
    use super::*;
    use crate::firmware::tests::{create_fake_metadata, FakeDevice};
    use chrono::Duration;

    let mut settings = Settings::default();
    settings.polling.enabled = true;
    settings.polling.interval = Duration::seconds(1);

    let mut runtime_settings = RuntimeSettings::default();
    runtime_settings.set_last_polling(Utc::now()).unwrap();

    let firmware = Metadata::from_path(&create_fake_metadata(FakeDevice::NoUpdate)).unwrap();
    let mut shared_state = SharedState { settings, runtime_settings, firmware };

    let machine =
        StateMachine::Poll(State(Poll {})).move_to_next_state(&mut shared_state).await.unwrap().0;

    assert_state!(machine, Probe);
}

#[actix_rt::test]
async fn never_polled() {
    use super::*;
    use crate::firmware::tests::{create_fake_metadata, FakeDevice};
    use chrono::Duration;

    let mut settings = Settings::default();
    settings.polling.enabled = true;
    settings.polling.interval = Duration::seconds(1);

    let runtime_settings = RuntimeSettings::default();
    let firmware = Metadata::from_path(&create_fake_metadata(FakeDevice::NoUpdate)).unwrap();
    let mut shared_state = SharedState { settings, runtime_settings, firmware };

    let machine =
        StateMachine::Poll(State(Poll {})).move_to_next_state(&mut shared_state).await.unwrap().0;

    assert_state!(machine, Probe);
}
<commit_msg>updatehub: Update poll handle logic<commit_after>// Copyright (C) 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use super::{
    actor::{self, SharedState},
    Probe, Result, State, StateChangeImpl, StateMachine,
};
use chrono::Utc;
use slog_scope::{debug, info};

#[derive(Debug, PartialEq)]
pub(super) struct Poll {}

create_state_step!(Poll => Probe);

/// Implements the state change for `State<Poll>`.
///
/// This state is used to control when to go to the `State<Probe>`.
#[async_trait::async_trait]
impl StateChangeImpl for State<Poll> {
    fn name(&self) -> &'static str {
        "poll"
    }

    async fn handle(
        self,
        shared_state: &mut SharedState,
    ) -> Result<(StateMachine, actor::StepTransition)> {
        crate::logger::start_memory_logging();

        if shared_state.runtime_settings.is_polling_forced() {
            debug!("Moving to Probe state as soon as possible.");
            return Ok((StateMachine::Probe(self.into()), actor::StepTransition::Immediate));
        }

        let interval = shared_state.settings.polling.interval;
        let delay = interval
            - Utc::now().signed_duration_since(shared_state.runtime_settings.last_polling());

        if delay > interval || delay.num_seconds() < 0 {
            info!("Forcing to Probe state as we are in time");
            return Ok((StateMachine::Probe(self.into()), actor::StepTransition::Immediate));
        }

        debug!("Moving to Probe state after delay.");
        Ok((
            StateMachine::Probe(self.into()),
            actor::StepTransition::Delayed(delay.to_std().unwrap()),
        ))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{
        firmware::{
            tests::{create_fake_metadata, FakeDevice},
            Metadata,
        },
        runtime_settings::RuntimeSettings,
        settings::Settings,
    };
    use chrono::{Duration, Utc};

    #[actix_rt::test]
    async fn normal_delay() {
        let settings = Settings::default();
        let runtime_settings = RuntimeSettings::default();
        let firmware = Metadata::from_path(&create_fake_metadata(FakeDevice::NoUpdate)).unwrap();
        let mut shared_state = SharedState { settings, runtime_settings, firmware };
        shared_state.runtime_settings.polling.last = Utc::now() - Duration::minutes(10);

        let (machine, trans) =
            StateMachine::Poll(State(Poll {})).move_to_next_state(&mut shared_state).await.unwrap();

        assert_state!(machine, Probe);
        match trans {
            actor::StepTransition::Delayed(d)
                if d <= shared_state.settings.polling.interval.to_std().unwrap() => {}
            _ => panic!("Unexpected StepTransition: {:?}", trans),
        }
    }

    #[actix_rt::test]
    async fn update_in_time() {
        let settings = Settings::default();
        let runtime_settings = RuntimeSettings::default();
        let firmware = Metadata::from_path(&create_fake_metadata(FakeDevice::NoUpdate)).unwrap();
        let mut shared_state = SharedState { settings, runtime_settings, firmware };

        let (machine, trans) =
            StateMachine::Poll(State(Poll {})).move_to_next_state(&mut shared_state).await.unwrap();

        assert_state!(machine, Probe);
        match trans {
            actor::StepTransition::Immediate => {}
            _ => panic!("Unexpected StepTransition: {:?}", trans),
        }
    }

    #[actix_rt::test]
    async fn forced_probe() {
        let settings = Settings::default();
        let runtime_settings = RuntimeSettings::default();
        let firmware = Metadata::from_path(&create_fake_metadata(FakeDevice::NoUpdate)).unwrap();
        let mut shared_state = SharedState { settings, runtime_settings, firmware };
        shared_state.runtime_settings.force_poll().unwrap();

        let (machine, trans) =
            StateMachine::Poll(State(Poll {})).move_to_next_state(&mut shared_state).await.unwrap();

        assert_state!(machine, Probe);
        match trans {
            actor::StepTransition::Immediate => {}
            _ => panic!("Unexpected StepTransition: {:?}", trans),
        }
    }

    #[actix_rt::test]
    async fn least_probe_in_the_future() {
        let settings = Settings::default();
        let runtime_settings = RuntimeSettings::default();
        let firmware = Metadata::from_path(&create_fake_metadata(FakeDevice::NoUpdate)).unwrap();
        let mut shared_state = SharedState { settings, runtime_settings, firmware };
        shared_state.runtime_settings.polling.last = Utc::now() + Duration::days(1);

        let (machine, trans) =
            StateMachine::Poll(State(Poll {})).move_to_next_state(&mut shared_state).await.unwrap();

        assert_state!(machine, Probe);
        match trans {
            actor::StepTransition::Immediate => {}
            _ => panic!("Unexpected StepTransition: {:?}", trans),
        }
    }
}
<|endoftext|>


<commit_before>use std::ops::{Mul, Add, Div, Sub, Index};

struct Matrix {
	cols: usize,
	rows: usize,
	data: Vec<f32>
}

impl Matrix {
    fn new(cols: usize, rows: usize, data: Vec<f32>) -> Matrix {
        Matrix {
            cols: cols,
            rows: rows,
            data: data
        }
    }

    fn zeros(cols: usize, rows: usize) -> Matrix {
    	Matrix {
            cols: cols,
            rows: rows,
            data: vec![0.0; cols*rows]
        }
    }

    fn identity(size: usize) -> Matrix {
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = 1.0;
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    fn from_diag(diag: &Vec<f32>) -> Matrix {
    	let size = diag.len();
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = diag[i];
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }
}

impl Mul<f32> for Matrix {
    type Output = Matrix;

    fn mul(self, f: f32) -> Matrix {
        let new_data = self.data.into_iter().map(|v| v * f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Mul<Matrix> for Matrix {
	type Output = Matrix;

	fn mul(self, m: Matrix) -> Matrix {
		// Will use Strassen algorithm if large, traditional otherwise
		return self;
	}
}

impl Add<f32> for Matrix {
	type Output = Matrix;

	fn add(self, f: f32) -> Matrix {
		let new_data = self.data.into_iter().map(|v| v + f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Sub<f32> for Matrix {
	type Output = Matrix;

	fn sub(self, f: f32) -> Matrix {
		let new_data = self.data.into_iter().map(|v| v - f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Add<Matrix> for Matrix {
	type Output = Matrix;

	fn add(self, m: Matrix) -> Matrix {
		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v + m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Sub<Matrix> for Matrix {
	type Output = Matrix;

	fn sub(self, m: Matrix) -> Matrix {
		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v - m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Div<f32> for Matrix {
	type Output = Matrix;

	fn div(self, f: f32) -> Matrix {
		let new_data = self.data.into_iter().map(|v| v / f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}<commit_msg>Basic safety checks<commit_after>use std::ops::{Mul, Add, Div, Sub, Index};

struct Matrix {
	cols: usize,
	rows: usize,
	data: Vec<f32>
}

impl Matrix {
    fn new(cols: usize, rows: usize, data: Vec<f32>) -> Matrix {
        Matrix {
            cols: cols,
            rows: rows,
            data: data
        }
    }

    fn zeros(cols: usize, rows: usize) -> Matrix {
    	Matrix {
            cols: cols,
            rows: rows,
            data: vec![0.0; cols*rows]
        }
    }

    fn identity(size: usize) -> Matrix {
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = 1.0;
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    fn from_diag(diag: &Vec<f32>) -> Matrix {
    	let size = diag.len();
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = diag[i];
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }
}

impl Mul<f32> for Matrix {
    type Output = Matrix;

    fn mul(self, f: f32) -> Matrix {
        let new_data = self.data.into_iter().map(|v| v * f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Mul<Matrix> for Matrix {
	type Output = Matrix;

	fn mul(self, m: Matrix) -> Matrix {
		// Will use Strassen algorithm if large, traditional otherwise
		return self;
	}
}

impl Add<f32> for Matrix {
	type Output = Matrix;

	fn add(self, f: f32) -> Matrix {
		let new_data = self.data.into_iter().map(|v| v + f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Sub<f32> for Matrix {
	type Output = Matrix;

	fn sub(self, f: f32) -> Matrix {
		let new_data = self.data.into_iter().map(|v| v - f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Add<Matrix> for Matrix {
	type Output = Matrix;

	fn add(self, m: Matrix) -> Matrix {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v + m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Sub<Matrix> for Matrix {
	type Output = Matrix;

	fn sub(self, m: Matrix) -> Matrix {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v - m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl Div<f32> for Matrix {
	type Output = Matrix;

	fn div(self, f: f32) -> Matrix {
		assert!(f != 0.0)

		let new_data = self.data.into_iter().map(|v| v / f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}<|endoftext|>


<commit_before>//! Definitions for uclibc on 64bit systems
pub type blkcnt_t = i64;
pub type blksize_t = i64;
pub type clock_t = i64;
pub type c_char = u8;
pub type c_long = i64;
pub type c_ulong = u64;
pub type fsblkcnt_t = ::c_ulong;
pub type fsfilcnt_t = ::c_ulong;
pub type fsword_t = ::c_long;
pub type ino_t = ::c_ulong;
pub type nlink_t = ::c_uint;
pub type off_t = ::c_long;
pub type rlim_t = c_ulong;
// [uClibc docs] Note stat64 has the same shape as stat for x86-64.
pub type stat64 = stat;
pub type suseconds_t = ::c_long;
pub type time_t = ::c_int;
pub type wchar_t = ::c_int;

pub type fsblkcnt64_t = u64;
pub type fsfilcnt64_t = u64;
pub type __u64 = ::c_ulong;

s! {
    pub struct ipc_perm {
        pub __key: ::key_t,
        pub uid: ::uid_t,
        pub gid: ::gid_t,
        pub cuid: ::uid_t,
        pub cgid: ::gid_t,
        pub mode: ::c_ushort, // read / write
        __pad1: ::c_ushort,
        pub __seq: ::c_ushort,
        __pad2: ::c_ushort,
        __unused1: ::c_ulong,
        __unused2: ::c_ulong
    }

    #[cfg(not(target_os = "l4re"))]
    pub struct pthread_attr_t {
        __detachstate: ::c_int,
        __schedpolicy: ::c_int,
        __schedparam: __sched_param,
        __inheritsched: ::c_int,
        __scope: ::c_int,
        __guardsize: ::size_t,
        __stackaddr_set: ::c_int,
        __stackaddr: *mut ::c_void, // better don't use it
        __stacksize: ::size_t,
    }

    pub struct __sched_param {
        __sched_priority: ::c_int,
    }

    pub struct siginfo_t {
        si_signo: ::c_int, // signal number
        si_errno: ::c_int, // if not zero: error value of signal, see errno.h
        si_code: ::c_int,  // signal code
        pub _pad: [::c_int; 28], // unported union
        _align: [usize; 0],
    }

    pub struct shmid_ds {
        pub shm_perm: ::ipc_perm,
        pub shm_segsz: ::size_t, // segment size in bytes
        pub shm_atime: ::time_t, // time of last shmat()
        pub shm_dtime: ::time_t,
        pub shm_ctime: ::time_t,
        pub shm_cpid: ::pid_t,
        pub shm_lpid: ::pid_t,
        pub shm_nattch: ::shmatt_t,
        __unused1: ::c_ulong,
        __unused2: ::c_ulong
    }

    pub struct msqid_ds {
        pub msg_perm: ::ipc_perm,
        pub msg_stime: ::time_t,
        pub msg_rtime: ::time_t,
        pub msg_ctime: ::time_t,
        __msg_cbytes: ::c_ulong,
        pub msg_qnum: ::msgqnum_t,
        pub msg_qbytes: ::msglen_t,
        pub msg_lspid: ::pid_t,
        pub msg_lrpid: ::pid_t,
        __ignored1: ::c_ulong,
        __ignored2: ::c_ulong,
    }

    pub struct sockaddr {
        pub sa_family: ::sa_family_t,
        pub sa_data: [::c_char; 14],
    }

    pub struct sockaddr_in {
        pub sin_family: ::sa_family_t,
        pub sin_port: ::in_port_t,
        pub sin_addr: ::in_addr,
        pub sin_zero: [u8; 8],
    }

    pub struct sockaddr_in6 {
        pub sin6_family: ::sa_family_t,
        pub sin6_port: ::in_port_t,
        pub sin6_flowinfo: u32,
        pub sin6_addr: ::in6_addr,
        pub sin6_scope_id: u32,
    }

    // ------------------------------------------------------------
    // definitions below are *unverified* and might **break** the software
//    pub struct in_addr {
//        pub s_addr: in_addr_t,
//    }
//
//    pub struct in6_addr {
//        pub s6_addr: [u8; 16],
//        #[cfg(not(libc_align))]
//        __align: [u32; 0],
//    }

    pub struct stat {
        pub st_dev: ::c_ulong,
        pub st_ino: ::ino_t,
        // According to uclibc/libc/sysdeps/linux/x86_64/bits/stat.h, order of
        // nlink and mode are swapped on 64 bit systems.
        pub st_nlink: ::nlink_t,
        pub st_mode: ::mode_t,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulong, // dev_t
        pub st_size: off_t, // file size
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::blkcnt_t,
        pub st_atime: ::time_t,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::time_t,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::time_t,
        pub st_ctime_nsec: ::c_ulong,
        st_pad4: [::c_long; 3]
    }

    pub struct sigaction {
        pub sa_handler: ::sighandler_t,
        pub sa_flags: ::c_ulong,
        pub sa_restorer: ::Option<extern fn()>,
        pub sa_mask: ::sigset_t,
    }

    pub struct stack_t { // FIXME
        pub ss_sp: *mut ::c_void,
        pub ss_flags: ::c_int,
        pub ss_size: ::size_t
    }

    pub struct statfs { // FIXME
        pub f_type: fsword_t,
        pub f_bsize: fsword_t,
        pub f_blocks: ::fsblkcnt_t,
        pub f_bfree: ::fsblkcnt_t,
        pub f_bavail: ::fsblkcnt_t,
        pub f_files: ::fsfilcnt_t,
        pub f_ffree: ::fsfilcnt_t,
        pub f_fsid: ::fsid_t,
        pub f_namelen: fsword_t,
        pub f_frsize: fsword_t,
        f_spare: [fsword_t; 5],
    }

    pub struct statfs64 {
        pub f_type: ::c_int,
        pub f_bsize: ::c_int,
        pub f_blocks: ::fsblkcnt64_t,
        pub f_bfree: ::fsblkcnt64_t,
        pub f_bavail: ::fsblkcnt64_t,
        pub f_files: ::fsfilcnt64_t,
        pub f_ffree: ::fsfilcnt64_t,
        pub f_fsid: ::fsid_t,
        pub f_namelen: ::c_int,
        pub f_frsize: ::c_int,
        pub f_flags: ::c_int,
        pub f_spare: [::c_int; 4],
    }

    pub struct statvfs64 {
        pub f_bsize: ::c_ulong,
        pub f_frsize: ::c_ulong,
        pub f_blocks: u64,
        pub f_bfree: u64,
        pub f_bavail: u64,
        pub f_files: u64,
        pub f_ffree: u64,
        pub f_favail: u64,
        pub f_fsid: ::c_ulong,
        __f_unused: ::c_int,
        pub f_flag: ::c_ulong,
        pub f_namemax: ::c_ulong,
        __f_spare: [::c_int; 6],
    }

    pub struct msghdr { // FIXME
        pub msg_name: *mut ::c_void,
        pub msg_namelen: ::socklen_t,
        pub msg_iov: *mut ::iovec,
        pub msg_iovlen: ::size_t,
        pub msg_control: *mut ::c_void,
        pub msg_controllen: ::size_t,
        pub msg_flags: ::c_int,
    }

    pub struct termios { // FIXME
        pub c_iflag: ::tcflag_t,
        pub c_oflag: ::tcflag_t,
        pub c_cflag: ::tcflag_t,
        pub c_lflag: ::tcflag_t,
        pub c_line: ::cc_t,
        pub c_cc: [::cc_t; ::NCCS],
    }

    pub struct sigset_t { // FIXME
        __val: [::c_ulong; 16],
    }

    pub struct sysinfo { // FIXME
        pub uptime: ::c_long,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub _f: [::c_char; 0],
    }

    pub struct glob_t { // FIXME
        pub gl_pathc: ::size_t,
        pub gl_pathv: *mut *mut c_char,
        pub gl_offs: ::size_t,
        pub gl_flags: ::c_int,
        __unused1: *mut ::c_void,
        __unused2: *mut ::c_void,
        __unused3: *mut ::c_void,
        __unused4: *mut ::c_void,
        __unused5: *mut ::c_void,
    }

    pub struct cpu_set_t { // FIXME
        #[cfg(target_pointer_width = "32")]
        bits: [u32; 32],
        #[cfg(target_pointer_width = "64")]
        bits: [u64; 16],
    }

    pub struct fsid_t { // FIXME
        __val: [::c_int; 2],
    }

    // FIXME this is actually a union
    pub struct sem_t {
        #[cfg(target_pointer_width = "32")]
        __size: [::c_char; 16],
        #[cfg(target_pointer_width = "64")]
        __size: [::c_char; 32],
        __align: [::c_long; 0],
    }

    pub struct cmsghdr {
        pub cmsg_len: ::size_t,
        pub cmsg_level: ::c_int,
        pub cmsg_type: ::c_int,
    }
}

s_no_extra_traits! {
    #[allow(missing_debug_implementations)]
    pub struct dirent {
        pub d_ino: ::ino64_t,
        pub d_off: ::off64_t,
        pub d_reclen: u16,
        pub d_type: u8,
        pub d_name: [::c_char; 256],
    }
}

// constants
pub const EADDRINUSE: ::c_int = 98; // Address already in use
pub const EADDRNOTAVAIL: ::c_int = 99; // Cannot assign requested address
pub const ECONNABORTED: ::c_int = 103; // Software caused connection abort
pub const ECONNREFUSED: ::c_int = 111; // Connection refused
pub const ECONNRESET: ::c_int = 104; // Connection reset by peer
pub const EDEADLK: ::c_int = 35; // Resource deadlock would occur
pub const ENOSYS: ::c_int = 38; // Function not implemented
pub const ENOTCONN: ::c_int = 107; // Transport endpoint is not connected
pub const ETIMEDOUT: ::c_int = 110; // connection timed out
pub const EOPNOTSUPP: ::c_int = 0x5f;
pub const ENODATA: ::c_int = 0x3d;
pub const O_APPEND: ::c_int = 02000;
pub const O_ACCMODE: ::c_int = 0003;
pub const O_CLOEXEC: ::c_int = 0x80000;
pub const O_CREAT: ::c_int = 0100;
pub const O_DIRECTORY: ::c_int = 0200000;
pub const O_EXCL: ::c_int = 0200;
pub const O_NONBLOCK: ::c_int = 04000;
pub const O_TRUNC: ::c_int = 01000;
pub const NCCS: usize = 32;
pub const SIG_SETMASK: ::c_int = 2; // Set the set of blocked signals
pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40;
pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
pub const SOCK_DGRAM: ::c_int = 2; // connectionless, unreliable datagrams
pub const SOCK_STREAM: ::c_int = 1; // …/common/bits/socket_type.h
pub const RLIM_INFINITY: u64 = 0xffffffffffffffff;
pub const __SIZEOF_PTHREAD_COND_T: usize = 48;
pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56;
pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;

cfg_if! {
    if #[cfg(target_os = "l4re")] {
        mod l4re;
        pub use self::l4re::*;
    } else {
        mod other;
        pub use other::*;
    }
}
<commit_msg>add more errno constants to uclibc<commit_after>//! Definitions for uclibc on 64bit systems
pub type blkcnt_t = i64;
pub type blksize_t = i64;
pub type clock_t = i64;
pub type c_char = u8;
pub type c_long = i64;
pub type c_ulong = u64;
pub type fsblkcnt_t = ::c_ulong;
pub type fsfilcnt_t = ::c_ulong;
pub type fsword_t = ::c_long;
pub type ino_t = ::c_ulong;
pub type nlink_t = ::c_uint;
pub type off_t = ::c_long;
pub type rlim_t = c_ulong;
// [uClibc docs] Note stat64 has the same shape as stat for x86-64.
pub type stat64 = stat;
pub type suseconds_t = ::c_long;
pub type time_t = ::c_int;
pub type wchar_t = ::c_int;

pub type fsblkcnt64_t = u64;
pub type fsfilcnt64_t = u64;
pub type __u64 = ::c_ulong;

s! {
    pub struct ipc_perm {
        pub __key: ::key_t,
        pub uid: ::uid_t,
        pub gid: ::gid_t,
        pub cuid: ::uid_t,
        pub cgid: ::gid_t,
        pub mode: ::c_ushort, // read / write
        __pad1: ::c_ushort,
        pub __seq: ::c_ushort,
        __pad2: ::c_ushort,
        __unused1: ::c_ulong,
        __unused2: ::c_ulong
    }

    #[cfg(not(target_os = "l4re"))]
    pub struct pthread_attr_t {
        __detachstate: ::c_int,
        __schedpolicy: ::c_int,
        __schedparam: __sched_param,
        __inheritsched: ::c_int,
        __scope: ::c_int,
        __guardsize: ::size_t,
        __stackaddr_set: ::c_int,
        __stackaddr: *mut ::c_void, // better don't use it
        __stacksize: ::size_t,
    }

    pub struct __sched_param {
        __sched_priority: ::c_int,
    }

    pub struct siginfo_t {
        si_signo: ::c_int, // signal number
        si_errno: ::c_int, // if not zero: error value of signal, see errno.h
        si_code: ::c_int,  // signal code
        pub _pad: [::c_int; 28], // unported union
        _align: [usize; 0],
    }

    pub struct shmid_ds {
        pub shm_perm: ::ipc_perm,
        pub shm_segsz: ::size_t, // segment size in bytes
        pub shm_atime: ::time_t, // time of last shmat()
        pub shm_dtime: ::time_t,
        pub shm_ctime: ::time_t,
        pub shm_cpid: ::pid_t,
        pub shm_lpid: ::pid_t,
        pub shm_nattch: ::shmatt_t,
        __unused1: ::c_ulong,
        __unused2: ::c_ulong
    }

    pub struct msqid_ds {
        pub msg_perm: ::ipc_perm,
        pub msg_stime: ::time_t,
        pub msg_rtime: ::time_t,
        pub msg_ctime: ::time_t,
        __msg_cbytes: ::c_ulong,
        pub msg_qnum: ::msgqnum_t,
        pub msg_qbytes: ::msglen_t,
        pub msg_lspid: ::pid_t,
        pub msg_lrpid: ::pid_t,
        __ignored1: ::c_ulong,
        __ignored2: ::c_ulong,
    }

    pub struct sockaddr {
        pub sa_family: ::sa_family_t,
        pub sa_data: [::c_char; 14],
    }

    pub struct sockaddr_in {
        pub sin_family: ::sa_family_t,
        pub sin_port: ::in_port_t,
        pub sin_addr: ::in_addr,
        pub sin_zero: [u8; 8],
    }

    pub struct sockaddr_in6 {
        pub sin6_family: ::sa_family_t,
        pub sin6_port: ::in_port_t,
        pub sin6_flowinfo: u32,
        pub sin6_addr: ::in6_addr,
        pub sin6_scope_id: u32,
    }

    // ------------------------------------------------------------
    // definitions below are *unverified* and might **break** the software
//    pub struct in_addr {
//        pub s_addr: in_addr_t,
//    }
//
//    pub struct in6_addr {
//        pub s6_addr: [u8; 16],
//        #[cfg(not(libc_align))]
//        __align: [u32; 0],
//    }

    pub struct stat {
        pub st_dev: ::c_ulong,
        pub st_ino: ::ino_t,
        // According to uclibc/libc/sysdeps/linux/x86_64/bits/stat.h, order of
        // nlink and mode are swapped on 64 bit systems.
        pub st_nlink: ::nlink_t,
        pub st_mode: ::mode_t,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulong, // dev_t
        pub st_size: off_t, // file size
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::blkcnt_t,
        pub st_atime: ::time_t,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::time_t,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::time_t,
        pub st_ctime_nsec: ::c_ulong,
        st_pad4: [::c_long; 3]
    }

    pub struct sigaction {
        pub sa_handler: ::sighandler_t,
        pub sa_flags: ::c_ulong,
        pub sa_restorer: ::Option<extern fn()>,
        pub sa_mask: ::sigset_t,
    }

    pub struct stack_t { // FIXME
        pub ss_sp: *mut ::c_void,
        pub ss_flags: ::c_int,
        pub ss_size: ::size_t
    }

    pub struct statfs { // FIXME
        pub f_type: fsword_t,
        pub f_bsize: fsword_t,
        pub f_blocks: ::fsblkcnt_t,
        pub f_bfree: ::fsblkcnt_t,
        pub f_bavail: ::fsblkcnt_t,
        pub f_files: ::fsfilcnt_t,
        pub f_ffree: ::fsfilcnt_t,
        pub f_fsid: ::fsid_t,
        pub f_namelen: fsword_t,
        pub f_frsize: fsword_t,
        f_spare: [fsword_t; 5],
    }

    pub struct statfs64 {
        pub f_type: ::c_int,
        pub f_bsize: ::c_int,
        pub f_blocks: ::fsblkcnt64_t,
        pub f_bfree: ::fsblkcnt64_t,
        pub f_bavail: ::fsblkcnt64_t,
        pub f_files: ::fsfilcnt64_t,
        pub f_ffree: ::fsfilcnt64_t,
        pub f_fsid: ::fsid_t,
        pub f_namelen: ::c_int,
        pub f_frsize: ::c_int,
        pub f_flags: ::c_int,
        pub f_spare: [::c_int; 4],
    }

    pub struct statvfs64 {
        pub f_bsize: ::c_ulong,
        pub f_frsize: ::c_ulong,
        pub f_blocks: u64,
        pub f_bfree: u64,
        pub f_bavail: u64,
        pub f_files: u64,
        pub f_ffree: u64,
        pub f_favail: u64,
        pub f_fsid: ::c_ulong,
        __f_unused: ::c_int,
        pub f_flag: ::c_ulong,
        pub f_namemax: ::c_ulong,
        __f_spare: [::c_int; 6],
    }

    pub struct msghdr { // FIXME
        pub msg_name: *mut ::c_void,
        pub msg_namelen: ::socklen_t,
        pub msg_iov: *mut ::iovec,
        pub msg_iovlen: ::size_t,
        pub msg_control: *mut ::c_void,
        pub msg_controllen: ::size_t,
        pub msg_flags: ::c_int,
    }

    pub struct termios { // FIXME
        pub c_iflag: ::tcflag_t,
        pub c_oflag: ::tcflag_t,
        pub c_cflag: ::tcflag_t,
        pub c_lflag: ::tcflag_t,
        pub c_line: ::cc_t,
        pub c_cc: [::cc_t; ::NCCS],
    }

    pub struct sigset_t { // FIXME
        __val: [::c_ulong; 16],
    }

    pub struct sysinfo { // FIXME
        pub uptime: ::c_long,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub _f: [::c_char; 0],
    }

    pub struct glob_t { // FIXME
        pub gl_pathc: ::size_t,
        pub gl_pathv: *mut *mut c_char,
        pub gl_offs: ::size_t,
        pub gl_flags: ::c_int,
        __unused1: *mut ::c_void,
        __unused2: *mut ::c_void,
        __unused3: *mut ::c_void,
        __unused4: *mut ::c_void,
        __unused5: *mut ::c_void,
    }

    pub struct cpu_set_t { // FIXME
        #[cfg(target_pointer_width = "32")]
        bits: [u32; 32],
        #[cfg(target_pointer_width = "64")]
        bits: [u64; 16],
    }

    pub struct fsid_t { // FIXME
        __val: [::c_int; 2],
    }

    // FIXME this is actually a union
    pub struct sem_t {
        #[cfg(target_pointer_width = "32")]
        __size: [::c_char; 16],
        #[cfg(target_pointer_width = "64")]
        __size: [::c_char; 32],
        __align: [::c_long; 0],
    }

    pub struct cmsghdr {
        pub cmsg_len: ::size_t,
        pub cmsg_level: ::c_int,
        pub cmsg_type: ::c_int,
    }
}

s_no_extra_traits! {
    #[allow(missing_debug_implementations)]
    pub struct dirent {
        pub d_ino: ::ino64_t,
        pub d_off: ::off64_t,
        pub d_reclen: u16,
        pub d_type: u8,
        pub d_name: [::c_char; 256],
    }
}

// constants
pub const ENAMETOOLONG: ::c_int = 36; // File name too long
pub const ENOTEMPTY: ::c_int = 39; // Directory not empty
pub const ELOOP: ::c_int = 40; // Too many symbolic links encountered
pub const EADDRINUSE: ::c_int = 98; // Address already in use
pub const EADDRNOTAVAIL: ::c_int = 99; // Cannot assign requested address
pub const ENETDOWN: ::c_int = 100; // Network is down
pub const ENETUNREACH: ::c_int = 101; // Network is unreachable
pub const ECONNABORTED: ::c_int = 103; // Software caused connection abort
pub const ECONNREFUSED: ::c_int = 111; // Connection refused
pub const ECONNRESET: ::c_int = 104; // Connection reset by peer
pub const EDEADLK: ::c_int = 35; // Resource deadlock would occur
pub const ENOSYS: ::c_int = 38; // Function not implemented
pub const ENOTCONN: ::c_int = 107; // Transport endpoint is not connected
pub const ETIMEDOUT: ::c_int = 110; // connection timed out
pub const ESTALE: ::c_int = 116; // Stale file handle
pub const EHOSTUNREACH: ::c_int = 113; // No route to host
pub const EDQUOT: ::c_int = 122; // Quota exceeded
pub const EOPNOTSUPP: ::c_int = 0x5f;
pub const ENODATA: ::c_int = 0x3d;
pub const O_APPEND: ::c_int = 02000;
pub const O_ACCMODE: ::c_int = 0003;
pub const O_CLOEXEC: ::c_int = 0x80000;
pub const O_CREAT: ::c_int = 0100;
pub const O_DIRECTORY: ::c_int = 0200000;
pub const O_EXCL: ::c_int = 0200;
pub const O_NONBLOCK: ::c_int = 04000;
pub const O_TRUNC: ::c_int = 01000;
pub const NCCS: usize = 32;
pub const SIG_SETMASK: ::c_int = 2; // Set the set of blocked signals
pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40;
pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
pub const SOCK_DGRAM: ::c_int = 2; // connectionless, unreliable datagrams
pub const SOCK_STREAM: ::c_int = 1; // …/common/bits/socket_type.h
pub const RLIM_INFINITY: u64 = 0xffffffffffffffff;
pub const __SIZEOF_PTHREAD_COND_T: usize = 48;
pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56;
pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;

cfg_if! {
    if #[cfg(target_os = "l4re")] {
        mod l4re;
        pub use self::l4re::*;
    } else {
        mod other;
        pub use other::*;
    }
}
<|endoftext|>


<commit_before>use crate::Language::*;

define!{
    allstructures => {
        allstructures.arg(Rust, &["-m", "chrono"]);
    },
    alltypes => {
        alltypes.arg(Rust, &["-m", "chrono"]);
    },
    basic => {
    },
    code => {
    },
    enum_ => {
    },
    inner => {
    },
    interfaces => {
    },
    java_grpc => {
        java_grpc.include(Java);
    },
    java_keywords => {
        java_keywords.include(Java);
    },
    csharp_keywords => {
        csharp_keywords.include(Csharp);
    },
    swift_keywords => {
        swift_keywords.include(Swift);
    },
    java_okhttp1 => {
        java_okhttp1.include(Java);
    },
    java_okhttp2 => {
        java_okhttp2.include(Java);
    },
    js_keywords => {
        js_keywords.include(JavaScript);
    },
    python_keywords => {
        python_keywords.include(Python);
    },
    python_requests => {
        python_requests.include(Python);
    },
    service => {
        service.package("service");
        service.arg(Java, &["-m", "grpc"]);
        service.arg(Rust, &["-m", "chrono"]);
        service.include(Java);
        service.include(Rust);
        service.include(OpenApi);
    },
    rust_keywords => {
        rust_keywords.include(Rust);
    },
    rust_reqwest => {
        rust_reqwest.include(Rust);
    },
    tuple => {},
    versions => {},
    default_naming => {},
    ui => {
        ui.discover_checks();
    },
}
<commit_msg>remove old tests declaration<commit_after><|endoftext|>


<commit_before>use std::cell::RefCell;
use std::io;
use std::rc::Rc;
use mio::net::TcpStream;
use mio::{Event, PollOpt, Ready};

use super::selector::{EventHandler, Selector};
use super::ipv4_packet_buffer::IPv4PacketBuffer;

pub struct Client {
    id: u32,
    stream: TcpStream,
    client_to_network: IPv4PacketBuffer,
}

impl Client {
    pub fn new(id: u32, selector: &mut Selector, stream: TcpStream) -> io::Result<Rc<RefCell<Client>>> {
        let rc = Rc::new(RefCell::new(Client {
            id: id,
            stream: stream,
            client_to_network: IPv4PacketBuffer::new(),
        }));
        // on start, we are interested only in writing (we must first send the client id)
        selector.register(&rc.borrow().stream, rc.clone(), Ready::writable(), PollOpt::level())?;
        Ok(rc)
    }
}

impl EventHandler for Client {
    fn on_ready(&mut self, selector: &mut Selector, event: Event) {

    }
}
<commit_msg>Client event handling skeleton<commit_after>use std::cell::RefCell;
use std::io;
use std::rc::Rc;
use mio::net::TcpStream;
use mio::{Event, PollOpt, Ready};

use super::selector::{EventHandler, Selector};
use super::ipv4_packet_buffer::IPv4PacketBuffer;

pub struct Client {
    id: u32,
    stream: TcpStream,
    client_to_network: IPv4PacketBuffer,
    dead: bool,
}

impl Client {
    pub fn new(id: u32, selector: &mut Selector, stream: TcpStream) -> io::Result<Rc<RefCell<Client>>> {
        let rc = Rc::new(RefCell::new(Client {
            id: id,
            stream: stream,
            client_to_network: IPv4PacketBuffer::new(),
            dead: true,
        }));
        // on start, we are interested only in writing (we must first send the client id)
        selector.register(&rc.borrow().stream, rc.clone(), Ready::writable(), PollOpt::level())?;
        Ok(rc)
    }

    fn process_send(&mut self) {

    }

    fn process_receive(&mut self) {

    }

    fn update_interests(&mut self, selector: &mut Selector) {

    }
}

impl EventHandler for Client {
    fn on_ready(&mut self, selector: &mut Selector, event: Event) {
        assert!(!self.dead);
        let ready = event.readiness();
        if ready.is_writable() {
            self.process_send();
        }
        if !self.dead && ready.is_readable() {
            self.process_receive();
        }
        if !self.dead {
            self.update_interests(selector);
        }
    }
}
<|endoftext|>


<commit_before>trait Parser<T, E> {
    fn next(&mut self) -> Option<T>;
    fn preview(&self) -> Option<&T>;
    fn current_pos(&self) -> (i32, i32);
    fn error<S: Into<String>>(&self, message: S) -> E;
}

macro_rules! next {
    ($p:expr) => {
        match $p.next() {
            Some(x) => x,
            None => return Err($p.error("unexpected eof")),
        }
    }
}

macro_rules! predicate {
    ($p:expr, $pred:expr) => {{
        let x = next!($p);
        if $pred(x) {
            x
        } else {
            return Err($p.error(format!("unexpected token {}", x)));
        }
    }}
}

macro_rules! atom {
    ($p:expr, $expected:expr) => {{
        let x = next!($p);
        if x == $expected {
            x
        } else {
            return Err(
                $p.error(format!("unexpected token {}, expected {}", x, $expected))
            );
        }
    }}
}

macro_rules! string {
    ($p:expr, $iter:expr, $t:ident) => {{
        let i = $iter;
        for c in &i {
            atom!($p, *c);
        }
        $t::from_iter(i)
    }}
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::collections::vec_deque::VecDeque;
    use std::iter::FromIterator;

    struct TP {
        input: VecDeque<i32>,
    }

    impl TP {
        fn new(input: &[i32]) -> TP {
            TP { input: VecDeque::from(input.to_vec()) }
        }
    }

    impl Parser<i32, String> for TP {
        fn next(&mut self) -> Option<i32> {
            self.input.pop_front()
        }

        fn preview(&self) -> Option<&i32> {
            self.input.front()
        }

        fn current_pos(&self) -> (i32, i32) {
            (0, 0)
        }

        fn error<S: Into<String>>(&self, message: S) -> String {
            message.into()
        }
    }

    macro_rules! with_res {
        (test $i:ident, $b:block) => {
            #[test]
            fn $i() {
                let result = || {
                    $b;
                    Ok(())
                };
                result().unwrap()
            }
        };
        (panic $e:expr, $i:ident, $b:block) => {
            #[test]
            #[should_panic(expected = $e)]
            fn $i() {
                let result = || {
                    $b;
                    Ok(())
                };
                result().unwrap()
            }
        };
    }

    with_res!(test next_success, {
        let mut p = TP::new(&[1, 2, 3]);
        assert_eq!(next!(p), 1);
        assert_eq!(next!(p), 2);
        assert_eq!(next!(p), 3);
    });

    with_res!(panic "unexpected eof", next_fail_empty, {
        let mut p = TP::new(&[]);
        assert_eq!(next!(p), 1);
    });

    with_res!(test predicate_success, {
        let mut p = TP::new(&[2, 4, 6]);
        assert_eq!(predicate!(p, |x| x % 2 == 0), 2);
        assert_eq!(predicate!(p, |x| x % 2 == 0), 4);
        assert_eq!(predicate!(p, |x| x % 2 == 0), 6);
    });

    with_res!(panic "unexpected eof", predicate_fail_empty, {
        let mut p = TP::new(&[]);
        assert_eq!(predicate!(p, |x| x % 2 == 0), 2);
    });

    with_res!(panic "unexpected token 3", predicate_fail_not_satisfy, {
        let mut p = TP::new(&[3, 5, 7]);
        assert_eq!(predicate!(p, |x| x % 2 == 0), 3);
    });

    with_res!(test atom_success, {
        let mut p = TP::new(&[2, 4, 6]);
        assert_eq!(atom!(p, 2), 2);
        assert_eq!(atom!(p, 4), 4);
        assert_eq!(atom!(p, 6), 6);
    });

    with_res!(panic "unexpected eof", atom_fail_empty, {
        let mut p = TP::new(&[]);
        assert_eq!(atom!(p, 2), 2);
    });

    with_res!(panic "unexpected token 5, expected 4", atom_fail_not_expected, {
        let mut p = TP::new(&[3, 5, 7]);
        assert_eq!(atom!(p, 3), 3);
        assert_eq!(atom!(p, 4), 4);
    });

    with_res!(test string_success, {
        let mut p = TP::new(&[2, 4, 6]);
        assert_eq!(string!(p, vec![2, 4, 6], Vec), vec![2, 4, 6]);
    });

    with_res!(panic "unexpected eof", string_fail_empty, {
        let mut p = TP::new(&[]);
        assert_eq!(string!(p, vec![2, 4, 6], Vec), [2, 4, 6]);
    });

    with_res!(panic "unexpected token 5, expected 4", string_fail_not_expected, {
        let mut p = TP::new(&[2, 5, 6]);
        assert_eq!(string!(p, vec![2, 4, 6], Vec), vec![2, 4, 6]);
    });
}
<commit_msg>Change combinators into trait methods from macros<commit_after>use std::cmp::Eq;
use std::fmt::Display;
use std::iter::FromIterator;

trait Parser<T: Display + Eq, E> {
    fn preview(&self) -> Option<&T>;
    fn consume(&mut self) -> Option<T>;
    fn current_pos(&self) -> (i32, i32);
    fn error<S: Into<String>>(&self, message: S) -> E;

    fn next(&mut self) -> Result<T, E> {
        self.consume().ok_or(self.error("unexpected eof"))
    }

    fn predicate<F>(&mut self, pred: F) -> Result<T, E>
        where F: Fn(&T) -> bool
    {
        self.next()
            .and_then(|x| if pred(&x) {
                          Ok(x)
                      } else {
                          Err(self.error(format!("unexpected token {}", x)))
                      })
    }

    fn atom(&mut self, expected: T) -> Result<T, E> {
        self.next()
            .and_then(|x| if x == expected {
                          Ok(x)
                      } else {
                          Err(self.error(format!("unexpected token {}, expected {}", x, expected)))
                      })
    }

    fn string<S, O>(&mut self, s: S) -> Result<O, E>
        where S: IntoIterator<Item = T>,
              O: FromIterator<T>
    {
        let mut res: Vec<T> = Vec::new();
        for c in s {
            match self.atom(c) {
                Ok(x) => res.push(x),
                Err(err) => return Err(err),
            }
        }
        Ok(O::from_iter(res))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::collections::vec_deque::VecDeque;

    struct TP {
        input: VecDeque<i32>,
    }

    impl TP {
        fn new(input: &[i32]) -> TP {
            TP { input: VecDeque::from(input.to_vec()) }
        }
    }

    impl Parser<i32, String> for TP {
        fn consume(&mut self) -> Option<i32> {
            self.input.pop_front()
        }

        fn preview(&self) -> Option<&i32> {
            self.input.front()
        }

        fn current_pos(&self) -> (i32, i32) {
            (0, 0)
        }

        fn error<S: Into<String>>(&self, message: S) -> String {
            message.into()
        }
    }

    fn err<T>(m: &str) -> Result<T, String> {
        Err(String::from(m))
    }

    #[test]
    fn next_success() {
        let mut p = TP::new(&[1, 2, 3]);
        assert_eq!(p.next(), Ok(1));
        assert_eq!(p.next(), Ok(2));
        assert_eq!(p.next(), Ok(3));
    }

    #[test]
    fn next_fail_empty() {
        let mut p = TP::new(&[]);
        assert_eq!(p.next(), err("unexpected eof"));
    }

    #[test]
    fn predicate_success() {
        let mut p = TP::new(&[2, 4, 6]);
        assert_eq!(p.predicate(|x| x % 2 == 0), Ok(2));
        assert_eq!(p.predicate(|x| x % 2 == 0), Ok(4));
        assert_eq!(p.predicate(|x| x % 2 == 0), Ok(6));
    }

    #[test]
    fn predicate_fail_empty() {
        let mut p = TP::new(&[]);
        assert_eq!(p.predicate(|x| x % 2 == 0), err("unexpected eof"));
    }

    #[test]
    fn predicate_fail_not_satisfy() {
        let mut p = TP::new(&[3, 5, 7]);
        assert_eq!(p.predicate(|x| x % 2 == 0), err("unexpected token 3"));
    }

    #[test]
    fn atom_success() {
        let mut p = TP::new(&[2, 4, 6]);
        assert_eq!(p.atom(2), Ok(2));
        assert_eq!(p.atom(4), Ok(4));
        assert_eq!(p.atom(6), Ok(6));
    }

    #[test]
    fn atom_fail_empty() {
        let mut p = TP::new(&[]);
        assert_eq!(p.atom(2), err("unexpected eof"));
    }

    #[test]
    fn atom_fail_not_expected() {
        let mut p = TP::new(&[3, 5, 7]);
        assert_eq!(p.atom(3), Ok(3));
        assert_eq!(p.atom(4), err("unexpected token 5, expected 4"));
    }

    #[test]
    fn string_success() {
        let mut p = TP::new(&[2, 4, 6]);
        assert_eq!(p.string(vec![2, 4, 6]), Ok(vec![2, 4, 6]));
    }

    #[test]
    fn string_fail_empty() {
        let mut p = TP::new(&[]);
        assert_eq!(p.string(vec![2, 4, 6]) as Result<Vec<i32>, String>,
                   err("unexpected eof"));
    }

    #[test]
    fn string_fail_not_expected() {
        let mut p = TP::new(&[2, 5, 6]);
        assert_eq!(p.string(vec![2, 4, 6]) as Result<Vec<i32>, String>,
                   err("unexpected token 5, expected 4"));
    }
}
<|endoftext|>


<commit_before>//! Many kinds of items or constructs can have generic parameters: functions,
//! structs, impls, traits, etc. This module provides a common HIR for these
//! generic parameters. See also the `Generics` type and the `generics_of` query
//! in rustc.

use std::sync::Arc;

use hir_def::{
    path::Path,
    type_ref::{TypeBound, TypeRef},
};
use hir_expand::name::{self, AsName};
use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner};

use crate::{
    db::{AstDatabase, DefDatabase, HirDatabase},
    Adt, Const, Container, Enum, EnumVariant, Function, HasSource, ImplBlock, Name, Struct, Trait,
    TypeAlias, Union,
};

/// Data about a generic parameter (to a function, struct, impl, ...).
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct GenericParam {
    // FIXME: give generic params proper IDs
    pub(crate) idx: u32,
    pub(crate) name: Name,
    pub(crate) default: Option<Path>,
}

/// Data about the generic parameters of a function, struct, impl, etc.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct GenericParams {
    pub(crate) def: GenericDef,
    pub(crate) parent_params: Option<Arc<GenericParams>>,
    pub(crate) params: Vec<GenericParam>,
    pub(crate) where_predicates: Vec<WherePredicate>,
}

/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
/// It might still result in multiple actual predicates though, because of
/// associated type bindings like `Iterator<Item = u32>`.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct WherePredicate {
    pub(crate) type_ref: TypeRef,
    pub(crate) bound: TypeBound,
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum GenericDef {
    Function(Function),
    Adt(Adt),
    Trait(Trait),
    TypeAlias(TypeAlias),
    ImplBlock(ImplBlock),
    // enum variants cannot have generics themselves, but their parent enums
    // can, and this makes some code easier to write
    EnumVariant(EnumVariant),
    // consts can have type parameters from their parents (i.e. associated consts of traits)
    Const(Const),
}
impl_froms!(
    GenericDef: Function,
    Adt(Struct, Enum, Union),
    Trait,
    TypeAlias,
    ImplBlock,
    EnumVariant,
    Const
);

impl GenericParams {
    pub(crate) fn generic_params_query(
        db: &(impl DefDatabase + AstDatabase),
        def: GenericDef,
    ) -> Arc<GenericParams> {
        let parent = match def {
            GenericDef::Function(it) => it.container(db).map(GenericDef::from),
            GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from),
            GenericDef::Const(it) => it.container(db).map(GenericDef::from),
            GenericDef::EnumVariant(it) => Some(it.parent_enum(db).into()),
            GenericDef::Adt(_) | GenericDef::Trait(_) => None,
            GenericDef::ImplBlock(_) => None,
        };
        let mut generics = GenericParams {
            def,
            params: Vec::new(),
            parent_params: parent.map(|p| db.generic_params(p)),
            where_predicates: Vec::new(),
        };
        let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
        // FIXME: add `: Sized` bound for everything except for `Self` in traits
        match def {
            GenericDef::Function(it) => generics.fill(&it.source(db).ast, start),
            GenericDef::Adt(Adt::Struct(it)) => generics.fill(&it.source(db).ast, start),
            GenericDef::Adt(Adt::Union(it)) => generics.fill(&it.source(db).ast, start),
            GenericDef::Adt(Adt::Enum(it)) => generics.fill(&it.source(db).ast, start),
            GenericDef::Trait(it) => {
                // traits get the Self type as an implicit first type parameter
                generics.params.push(GenericParam {
                    idx: start,
                    name: name::SELF_TYPE,
                    default: None,
                });
                generics.fill(&it.source(db).ast, start + 1);
                // add super traits as bounds on Self
                // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
                let self_param = TypeRef::Path(name::SELF_TYPE.into());
                generics.fill_bounds(&it.source(db).ast, self_param);
            }
            GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start),
            // Note that we don't add `Self` here: in `impl`s, `Self` is not a
            // type-parameter, but rather is a type-alias for impl's target
            // type, so this is handled by the resolver.
            GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start),
            GenericDef::EnumVariant(_) | GenericDef::Const(_) => {}
        }

        Arc::new(generics)
    }

    fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) {
        if let Some(params) = node.type_param_list() {
            self.fill_params(params, start)
        }
        if let Some(where_clause) = node.where_clause() {
            self.fill_where_predicates(where_clause);
        }
    }

    fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) {
        for bound in
            node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
        {
            self.add_where_predicate_from_bound(bound, type_ref.clone());
        }
    }

    fn fill_params(&mut self, params: ast::TypeParamList, start: u32) {
        for (idx, type_param) in params.type_params().enumerate() {
            let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
            // FIXME: Use `Path::from_src`
            let default = type_param.default_type().and_then(|t| t.path()).and_then(Path::from_ast);

            let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default };
            self.params.push(param);

            let type_ref = TypeRef::Path(name.into());
            self.fill_bounds(&type_param, type_ref);
        }
    }

    fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) {
        for pred in where_clause.predicates() {
            let type_ref = match pred.type_ref() {
                Some(type_ref) => type_ref,
                None => continue,
            };
            let type_ref = TypeRef::from_ast(type_ref);
            for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
                self.add_where_predicate_from_bound(bound, type_ref.clone());
            }
        }
    }

    fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) {
        if bound.has_question_mark() {
            // FIXME: remove this bound
            return;
        }
        let bound = TypeBound::from_ast(bound);
        self.where_predicates.push(WherePredicate { type_ref, bound });
    }

    pub(crate) fn find_by_name(&self, name: &Name) -> Option<&GenericParam> {
        self.params.iter().find(|p| &p.name == name)
    }

    pub fn count_parent_params(&self) -> usize {
        self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0)
    }

    pub fn count_params_including_parent(&self) -> usize {
        let parent_count = self.count_parent_params();
        parent_count + self.params.len()
    }

    fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) {
        if let Some(parent) = &self.parent_params {
            parent.for_each_param(f);
        }
        self.params.iter().for_each(f);
    }

    pub fn params_including_parent(&self) -> Vec<&GenericParam> {
        let mut vec = Vec::with_capacity(self.count_params_including_parent());
        self.for_each_param(&mut |p| vec.push(p));
        vec
    }
}

impl GenericDef {
    pub(crate) fn resolver(&self, db: &impl HirDatabase) -> crate::Resolver {
        match self {
            GenericDef::Function(inner) => inner.resolver(db),
            GenericDef::Adt(adt) => adt.resolver(db),
            GenericDef::Trait(inner) => inner.resolver(db),
            GenericDef::TypeAlias(inner) => inner.resolver(db),
            GenericDef::ImplBlock(inner) => inner.resolver(db),
            GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db),
            GenericDef::Const(inner) => inner.resolver(db),
        }
    }
}

impl From<Container> for GenericDef {
    fn from(c: Container) -> Self {
        match c {
            Container::Trait(trait_) => trait_.into(),
            Container::ImplBlock(impl_block) => impl_block.into(),
        }
    }
}

pub trait HasGenericParams: Copy {
    fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>;
}

impl<T> HasGenericParams for T
where
    T: Into<GenericDef> + Copy,
{
    fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> {
        db.generic_params(self.into())
    }
}
<commit_msg>Publicise GenericParams<commit_after>//! Many kinds of items or constructs can have generic parameters: functions,
//! structs, impls, traits, etc. This module provides a common HIR for these
//! generic parameters. See also the `Generics` type and the `generics_of` query
//! in rustc.

use std::sync::Arc;

use hir_def::{
    path::Path,
    type_ref::{TypeBound, TypeRef},
};
use hir_expand::name::{self, AsName};
use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner};

use crate::{
    db::{AstDatabase, DefDatabase, HirDatabase},
    Adt, Const, Container, Enum, EnumVariant, Function, HasSource, ImplBlock, Name, Struct, Trait,
    TypeAlias, Union,
};

/// Data about a generic parameter (to a function, struct, impl, ...).
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct GenericParam {
    // FIXME: give generic params proper IDs
    pub idx: u32,
    pub name: Name,
    pub default: Option<Path>,
}

/// Data about the generic parameters of a function, struct, impl, etc.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct GenericParams {
    pub(crate) def: GenericDef,
    pub(crate) parent_params: Option<Arc<GenericParams>>,
    pub(crate) params: Vec<GenericParam>,
    pub(crate) where_predicates: Vec<WherePredicate>,
}

/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
/// It might still result in multiple actual predicates though, because of
/// associated type bindings like `Iterator<Item = u32>`.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct WherePredicate {
    pub(crate) type_ref: TypeRef,
    pub(crate) bound: TypeBound,
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum GenericDef {
    Function(Function),
    Adt(Adt),
    Trait(Trait),
    TypeAlias(TypeAlias),
    ImplBlock(ImplBlock),
    // enum variants cannot have generics themselves, but their parent enums
    // can, and this makes some code easier to write
    EnumVariant(EnumVariant),
    // consts can have type parameters from their parents (i.e. associated consts of traits)
    Const(Const),
}
impl_froms!(
    GenericDef: Function,
    Adt(Struct, Enum, Union),
    Trait,
    TypeAlias,
    ImplBlock,
    EnumVariant,
    Const
);

impl GenericParams {
    pub(crate) fn generic_params_query(
        db: &(impl DefDatabase + AstDatabase),
        def: GenericDef,
    ) -> Arc<GenericParams> {
        let parent = match def {
            GenericDef::Function(it) => it.container(db).map(GenericDef::from),
            GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from),
            GenericDef::Const(it) => it.container(db).map(GenericDef::from),
            GenericDef::EnumVariant(it) => Some(it.parent_enum(db).into()),
            GenericDef::Adt(_) | GenericDef::Trait(_) => None,
            GenericDef::ImplBlock(_) => None,
        };
        let mut generics = GenericParams {
            def,
            params: Vec::new(),
            parent_params: parent.map(|p| db.generic_params(p)),
            where_predicates: Vec::new(),
        };
        let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
        // FIXME: add `: Sized` bound for everything except for `Self` in traits
        match def {
            GenericDef::Function(it) => generics.fill(&it.source(db).ast, start),
            GenericDef::Adt(Adt::Struct(it)) => generics.fill(&it.source(db).ast, start),
            GenericDef::Adt(Adt::Union(it)) => generics.fill(&it.source(db).ast, start),
            GenericDef::Adt(Adt::Enum(it)) => generics.fill(&it.source(db).ast, start),
            GenericDef::Trait(it) => {
                // traits get the Self type as an implicit first type parameter
                generics.params.push(GenericParam {
                    idx: start,
                    name: name::SELF_TYPE,
                    default: None,
                });
                generics.fill(&it.source(db).ast, start + 1);
                // add super traits as bounds on Self
                // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
                let self_param = TypeRef::Path(name::SELF_TYPE.into());
                generics.fill_bounds(&it.source(db).ast, self_param);
            }
            GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start),
            // Note that we don't add `Self` here: in `impl`s, `Self` is not a
            // type-parameter, but rather is a type-alias for impl's target
            // type, so this is handled by the resolver.
            GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start),
            GenericDef::EnumVariant(_) | GenericDef::Const(_) => {}
        }

        Arc::new(generics)
    }

    fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) {
        if let Some(params) = node.type_param_list() {
            self.fill_params(params, start)
        }
        if let Some(where_clause) = node.where_clause() {
            self.fill_where_predicates(where_clause);
        }
    }

    fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) {
        for bound in
            node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
        {
            self.add_where_predicate_from_bound(bound, type_ref.clone());
        }
    }

    fn fill_params(&mut self, params: ast::TypeParamList, start: u32) {
        for (idx, type_param) in params.type_params().enumerate() {
            let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
            // FIXME: Use `Path::from_src`
            let default = type_param.default_type().and_then(|t| t.path()).and_then(Path::from_ast);

            let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default };
            self.params.push(param);

            let type_ref = TypeRef::Path(name.into());
            self.fill_bounds(&type_param, type_ref);
        }
    }

    fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) {
        for pred in where_clause.predicates() {
            let type_ref = match pred.type_ref() {
                Some(type_ref) => type_ref,
                None => continue,
            };
            let type_ref = TypeRef::from_ast(type_ref);
            for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
                self.add_where_predicate_from_bound(bound, type_ref.clone());
            }
        }
    }

    fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) {
        if bound.has_question_mark() {
            // FIXME: remove this bound
            return;
        }
        let bound = TypeBound::from_ast(bound);
        self.where_predicates.push(WherePredicate { type_ref, bound });
    }

    pub(crate) fn find_by_name(&self, name: &Name) -> Option<&GenericParam> {
        self.params.iter().find(|p| &p.name == name)
    }

    pub fn count_parent_params(&self) -> usize {
        self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0)
    }

    pub fn count_params_including_parent(&self) -> usize {
        let parent_count = self.count_parent_params();
        parent_count + self.params.len()
    }

    fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) {
        if let Some(parent) = &self.parent_params {
            parent.for_each_param(f);
        }
        self.params.iter().for_each(f);
    }

    pub fn params_including_parent(&self) -> Vec<&GenericParam> {
        let mut vec = Vec::with_capacity(self.count_params_including_parent());
        self.for_each_param(&mut |p| vec.push(p));
        vec
    }
}

impl GenericDef {
    pub(crate) fn resolver(&self, db: &impl HirDatabase) -> crate::Resolver {
        match self {
            GenericDef::Function(inner) => inner.resolver(db),
            GenericDef::Adt(adt) => adt.resolver(db),
            GenericDef::Trait(inner) => inner.resolver(db),
            GenericDef::TypeAlias(inner) => inner.resolver(db),
            GenericDef::ImplBlock(inner) => inner.resolver(db),
            GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db),
            GenericDef::Const(inner) => inner.resolver(db),
        }
    }
}

impl From<Container> for GenericDef {
    fn from(c: Container) -> Self {
        match c {
            Container::Trait(trait_) => trait_.into(),
            Container::ImplBlock(impl_block) => impl_block.into(),
        }
    }
}

pub trait HasGenericParams: Copy {
    fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>;
}

impl<T> HasGenericParams for T
where
    T: Into<GenericDef> + Copy,
{
    fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> {
        db.generic_params(self.into())
    }
}
<|endoftext|>