<commit_before>use cgmath::{Point, Point3, Vector, Vector3};
use cgmath::Aabb3;
use std::cmp::{min, max, partial_min, partial_max};
use std::iter::range_inclusive;
use std::num::Int;
use std::sync::Mutex;

use common::block_position::BlockPosition;
use common::entity::EntityId;
use common::id_allocator::IdAllocator;
use common::lod::LODIndex;
use common::stopwatch::TimerSet;
use common::terrain_block::{TerrainBlock, BLOCK_WIDTH, LOD_QUALITY, tri};

use terrain::heightmap::HeightMap;
use terrain::terrain::{Fracu8, Fraci8, Voxel, VoxelVertex, VoxelNormal, Edge};
use voxel_tree;
use voxel_tree::{VoxelBounds, VoxelTree};

#[cfg(test)]
use test;

fn generate_voxel<FieldContains, GetNormal>(
  timers: &TimerSet,
  field_contains: &mut FieldContains,
  get_normal: &mut GetNormal,
  voxel: VoxelBounds,
) -> Option<Voxel>
  where
    FieldContains: FnMut(f32, f32, f32) -> bool,
    GetNormal: FnMut(f32, f32, f32) -> Vector3<f32>,
{
  timers.time("generate_voxel", || {
    let d = 1 << voxel.lg_size;
    let x1 = voxel.x as f32;
    let x2 = (voxel.x + d) as f32;
    let y1 = voxel.y as f32;
    let y2 = (voxel.y + d) as f32;
    let z1 = voxel.z as f32;
    let z2 = (voxel.z + d) as f32;
    // corners[x][y][z]
    let corners = [
      [
        [ field_contains(x1, y1, z1), field_contains(x1, y1, z2) ],
        [ field_contains(x1, y2, z1), field_contains(x1, y2, z2) ],
      ],
      [
        [ field_contains(x2, y1, z1), field_contains(x2, y1, z2) ],
        [ field_contains(x2, y2, z1), field_contains(x2, y2, z2) ],
      ],
    ];

    let edge = |x1:usize, y1:usize, z1:usize, x2:usize, y2:usize, z2:usize| {
      let is_crossed = corners[x1][y1][z1] != corners[x2][y2][z2];
      Edge {
        is_crossed: is_crossed,
        direction: corners[x2][y2][z2],
      }
    };

    let x_edges = [
      [ edge(0,0,0, 1,0,0), edge(0,0,1, 1,0,1) ],
      [ edge(0,1,0, 1,1,0), edge(0,1,1, 1,1,1) ],
    ];
    let y_edges = [
      [ edge(0,0,0, 0,1,0), edge(1,0,0, 1,1,0) ],
      [ edge(0,0,1, 0,1,1), edge(1,0,1, 1,1,1) ],
    ];
    let z_edges = [
      [ edge(0,0,0, 0,0,1), edge(1,0,0, 1,0,1) ],
      [ edge(0,1,0, 0,1,1), edge(1,1,0, 1,1,1) ],
    ];

    let mut vertex = Vector3::new(0, 0, 0);
    let mut n = 0;
    let half = 0x80;

    for y in range_inclusive(0, 1) {
    for z in range_inclusive(0, 1) {
      if x_edges[y][z].is_crossed {
        vertex.add_self_v(&Vector3::new(half, y << 8, z << 8));
        n += 1;
      }
    }}

    for x in range_inclusive(0, 1) {
    for z in range_inclusive(0, 1) {
      if y_edges[x][z].is_crossed {
        vertex.add_self_v(&Vector3::new(x << 8, half, z << 8));
        n += 1;
      }
    }}

    for x in range_inclusive(0, 1) {
    for y in range_inclusive(0, 1) {
      if z_edges[x][y].is_crossed {
        vertex.add_self_v(&Vector3::new(x << 8, y << 8, half));
        n += 1;
      }
    }}

    if n == 0 {
      return None
    }

    let vertex = vertex.div_s(n);
    let vertex =
      VoxelVertex {
        x: Fracu8::of(vertex.x as u8),
        y: Fracu8::of(vertex.y as u8),
        z: Fracu8::of(vertex.z as u8),
      };

    let normal;
    {
      // Okay, this is silly to have right after we construct the vertex.
      let vertex = vertex.to_world_vertex(voxel);
      normal = get_normal(vertex.x, vertex.y, vertex.z).mul_s(127.0);
    }

    let normal = Vector3::new(normal.x as i32, normal.y as i32, normal.z as i32);
    let normal =
      Vector3::new(
        max(-127, min(127, normal.x)) as i8,
        max(-127, min(127, normal.y)) as i8,
        max(-127, min(127, normal.z)) as i8,
      );

    let normal =
      VoxelNormal {
        x: Fraci8::of(normal.x),
        y: Fraci8::of(normal.y),
        z: Fraci8::of(normal.z),
      };

    Some(Voxel {
      vertex: vertex,
      normal: normal,
      x_edges: x_edges,
      y_edges: y_edges,
      z_edges: z_edges,
    })
  })
}

#[bench]
fn bench_generate_interesting_voxel(bencher: &mut test::Bencher) {
  let timers = TimerSet::new();
  bencher.iter(|| {
    let voxel = generate_voxel(&timers, VoxelBounds::new(0, 0, 0, 6));
    assert!(voxel.is_some());
  });
}

#[bench]
fn bench_generate_empty_voxel(bencher: &mut test::Bencher) {
  let timers = TimerSet::new();
  bencher.iter(|| {
    let voxel = generate_voxel(&timers, VoxelBounds::new(0, 0, 0, 4));
    assert!(voxel.is_none());
  });
}

pub fn generate_block(
  timers: &TimerSet,
  id_allocator: &Mutex<IdAllocator<EntityId>>,
  heightmap: &HeightMap,
  voxels: &mut VoxelTree<Voxel>,
  position: &BlockPosition,
  lod_index: LODIndex,
) -> TerrainBlock {
  timers.time("update.generate_block", || {
    let mut block = TerrainBlock::empty();

    let position = position.to_world_position();
    let iposition = Point3::new(position.x as i32, position.y as i32, position.z as i32);

    let lateral_samples = LOD_QUALITY[lod_index.0 as usize] as i32;
    assert!(lateral_samples <= BLOCK_WIDTH, "Sub-unit voxels not supported yet.");
    assert!(BLOCK_WIDTH % lateral_samples == 0, "Block width doesn't sample cleanly.");

    let voxel_size = BLOCK_WIDTH / lateral_samples;
    let lg_size = Int::trailing_zeros(voxel_size);
    assert!(1 << lg_size == voxel_size, "voxel_size should be an exponent of 2");
    assert!(lg_size < 31, "2^{} is too a huge voxel.", lg_size);
    let lg_size = lg_size as u8;

    {
      let mut add_poly =
        |v1: Point3<f32>, n1, v2: Point3<f32>, n2, center: Point3<f32>, center_normal| {
          let id = id_allocator.lock().unwrap().allocate();

          let minx = partial_min(v1.x, v2.x);
          let minx = minx.and_then(|m| partial_min(m, center.x));
          let minx = minx.unwrap();

          let maxx = partial_max(v1.x, v2.x);
          let maxx = maxx.and_then(|m| partial_max(m, center.x));
          let maxx = maxx.unwrap();

          let miny = partial_min(v1.y, v2.y);
          let miny = miny.and_then(|m| partial_min(m, center.y));
          let miny = miny.unwrap();

          let maxy = partial_max(v1.y, v2.y);
          let maxy = maxy.and_then(|m| partial_max(m, center.y));
          let maxy = maxy.unwrap();

          let minz = partial_min(v1.z, v2.z);
          let minz = minz.and_then(|m| partial_min(m, center.z));
          let minz = minz.unwrap();

          let maxz = partial_max(v1.z, v2.z);
          let maxz = maxz.and_then(|m| partial_max(m, center.z));
          let maxz = maxz.unwrap();

          block.vertex_coordinates.push(tri(v1, v2, center));
          block.normals.push(tri(n1, n2, center_normal));
          block.ids.push(id);

          block.bounds.push((
            id,
            Aabb3::new(
              // TODO: Remove this - 1.0. It's a temporary hack until voxel collisions work.
              Point3::new(minx, miny - 1.0, minz),
              Point3::new(maxx, maxy, maxz),
            ),
          ));
        };

      let mut field_contains = |x, y, z| {
        heightmap.height_at(x, z) >= y
      };

      let mut get_normal = |x, _, z| {
        heightmap.normal_at(x, z, voxel_size as f32)
      };

      macro_rules! get_voxel(($bounds:expr) => {{
        let branch = voxels.get_mut($bounds);
        match branch {
          &mut voxel_tree::TreeBody::Leaf(v) => Some(v),
          &mut voxel_tree::TreeBody::Empty => {
            // TODO: Add a "yes this is empty I checked" flag so we don't regen every time.
            generate_voxel(timers, &mut field_contains, &mut get_normal, $bounds).map(|v| {
              *branch = voxel_tree::TreeBody::Leaf(v);
              v
            })
          },
          &mut voxel_tree::TreeBody::Branch(_) => {
            // Overwrite existing for now.
            // TODO: Don't do ^that.
            generate_voxel(timers, &mut field_contains, &mut get_normal, $bounds).map(|v| {
              *branch = voxel_tree::TreeBody::Leaf(v);
              v
            })
          },
        }
      }});

      macro_rules! get_vertex(($v:expr) => {{
        let bounds = VoxelBounds::new($v.x, $v.y, $v.z, lg_size);
        let voxel = get_voxel!(bounds).unwrap();
        (voxel.vertex.to_world_vertex(bounds), voxel.normal.to_world_normal())
      }});

      macro_rules! extract((
        $edges:ident,
        $facing:expr,
        $d1:expr,
        $d2:expr,
      ) => (
          for x in 0..lateral_samples {
          for y in 0..lateral_samples {
          for z in 0..lateral_samples {
            let w = iposition.add_v(&Vector3::new(x << lg_size, y << lg_size, z << lg_size));
            let voxel;
            let bounds = VoxelBounds::new(w.x, w.y, w.z, lg_size);
            match get_voxel!(bounds) {
              None => continue,
              Some(v) => voxel = v,
            }

            let edge = voxel.$edges[0][0];
            if !edge.is_crossed {
              continue
            }

            // Make a quad out of the vertices from the 4 voxels adjacent to this edge.
            // We know they have vertices in them because if the surface crosses an edge,
            // it must cross that edge's neighbors.

            let (v1, n1) = get_vertex!(w.add_v(&$d1).add_v(&$d2));
            let (v2, n2) = get_vertex!(w.add_v(&$d1));
            let v3 = voxel.vertex.to_world_vertex(bounds);
            let n3 = voxel.normal.to_world_normal();
            let (v4, n4) = get_vertex!(w.add_v(&$d2));

            // Put a vertex at the average of the vertices.
            let center =
              v1.add_v(&v2.to_vec()).add_v(&v3.to_vec()).add_v(&v4.to_vec()).div_s(4.0);
            let center_normal = n1.add_v(&n2).add_v(&n3).add_v(&n4).div_s(4.0);

            let mut add_poly = |v1, n1, v2, n2| add_poly(v1, n1, v2, n2, center, center_normal);

            if edge.direction {
              // The polys are visible from negative infinity.
              add_poly(v1, n1, v2, n2);
              add_poly(v2, n2, v3, n3);
              add_poly(v3, n3, v4, n4);
              add_poly(v4, n4, v1, n1);
            } else {
              // The polys are visible from positive infinity.
              add_poly(v1, n1, v4, n4);
              add_poly(v4, n4, v3, n3);
              add_poly(v3, n3, v2, n2);
              add_poly(v2, n2, v1, n1);
            }
          }}}
        )
      );

      extract!(
        x_edges, 0,
        Vector3::new(0, -voxel_size, 0),
        Vector3::new(0, 0, -voxel_size),
      );

      extract!(
        y_edges, 1,
        Vector3::new(0, 0, -voxel_size),
        Vector3::new(-voxel_size, 0, 0),
      );

      extract!(
        z_edges, 2,
        Vector3::new(0, -voxel_size, 0),
        Vector3::new(-voxel_size, 0, 0),
      );
    }

    block
  })
}
<commit_msg>Fix: Polys for z-edges were facing the wrong way.<commit_after>use cgmath::{Point, Point3, Vector, Vector3};
use cgmath::Aabb3;
use std::cmp::{min, max, partial_min, partial_max};
use std::iter::range_inclusive;
use std::num::Int;
use std::sync::Mutex;

use common::block_position::BlockPosition;
use common::entity::EntityId;
use common::id_allocator::IdAllocator;
use common::lod::LODIndex;
use common::stopwatch::TimerSet;
use common::terrain_block::{TerrainBlock, BLOCK_WIDTH, LOD_QUALITY, tri};

use terrain::heightmap::HeightMap;
use terrain::terrain::{Fracu8, Fraci8, Voxel, VoxelVertex, VoxelNormal, Edge};
use voxel_tree;
use voxel_tree::{VoxelBounds, VoxelTree};

#[cfg(test)]
use test;

fn generate_voxel<FieldContains, GetNormal>(
  timers: &TimerSet,
  field_contains: &mut FieldContains,
  get_normal: &mut GetNormal,
  voxel: VoxelBounds,
) -> Option<Voxel>
  where
    FieldContains: FnMut(f32, f32, f32) -> bool,
    GetNormal: FnMut(f32, f32, f32) -> Vector3<f32>,
{
  timers.time("generate_voxel", || {
    let d = 1 << voxel.lg_size;
    let x1 = voxel.x as f32;
    let x2 = (voxel.x + d) as f32;
    let y1 = voxel.y as f32;
    let y2 = (voxel.y + d) as f32;
    let z1 = voxel.z as f32;
    let z2 = (voxel.z + d) as f32;
    // corners[x][y][z]
    let corners = [
      [
        [ field_contains(x1, y1, z1), field_contains(x1, y1, z2) ],
        [ field_contains(x1, y2, z1), field_contains(x1, y2, z2) ],
      ],
      [
        [ field_contains(x2, y1, z1), field_contains(x2, y1, z2) ],
        [ field_contains(x2, y2, z1), field_contains(x2, y2, z2) ],
      ],
    ];

    let edge = |x1:usize, y1:usize, z1:usize, x2:usize, y2:usize, z2:usize| {
      let is_crossed = corners[x1][y1][z1] != corners[x2][y2][z2];
      Edge {
        is_crossed: is_crossed,
        direction: corners[x2][y2][z2],
      }
    };

    let x_edges = [
      [ edge(0,0,0, 1,0,0), edge(0,0,1, 1,0,1) ],
      [ edge(0,1,0, 1,1,0), edge(0,1,1, 1,1,1) ],
    ];
    let y_edges = [
      [ edge(0,0,0, 0,1,0), edge(1,0,0, 1,1,0) ],
      [ edge(0,0,1, 0,1,1), edge(1,0,1, 1,1,1) ],
    ];
    let z_edges = [
      [ edge(0,0,0, 0,0,1), edge(1,0,0, 1,0,1) ],
      [ edge(0,1,0, 0,1,1), edge(1,1,0, 1,1,1) ],
    ];

    let mut vertex = Vector3::new(0, 0, 0);
    let mut n = 0;
    let half = 0x80;

    for y in range_inclusive(0, 1) {
    for z in range_inclusive(0, 1) {
      if x_edges[y][z].is_crossed {
        vertex.add_self_v(&Vector3::new(half, y << 8, z << 8));
        n += 1;
      }
    }}

    for x in range_inclusive(0, 1) {
    for z in range_inclusive(0, 1) {
      if y_edges[x][z].is_crossed {
        vertex.add_self_v(&Vector3::new(x << 8, half, z << 8));
        n += 1;
      }
    }}

    for x in range_inclusive(0, 1) {
    for y in range_inclusive(0, 1) {
      if z_edges[x][y].is_crossed {
        vertex.add_self_v(&Vector3::new(x << 8, y << 8, half));
        n += 1;
      }
    }}

    if n == 0 {
      return None
    }

    let vertex = vertex.div_s(n);
    let vertex =
      VoxelVertex {
        x: Fracu8::of(vertex.x as u8),
        y: Fracu8::of(vertex.y as u8),
        z: Fracu8::of(vertex.z as u8),
      };

    let normal;
    {
      // Okay, this is silly to have right after we construct the vertex.
      let vertex = vertex.to_world_vertex(voxel);
      normal = get_normal(vertex.x, vertex.y, vertex.z).mul_s(127.0);
    }

    let normal = Vector3::new(normal.x as i32, normal.y as i32, normal.z as i32);
    let normal =
      Vector3::new(
        max(-127, min(127, normal.x)) as i8,
        max(-127, min(127, normal.y)) as i8,
        max(-127, min(127, normal.z)) as i8,
      );

    let normal =
      VoxelNormal {
        x: Fraci8::of(normal.x),
        y: Fraci8::of(normal.y),
        z: Fraci8::of(normal.z),
      };

    Some(Voxel {
      vertex: vertex,
      normal: normal,
      x_edges: x_edges,
      y_edges: y_edges,
      z_edges: z_edges,
    })
  })
}

#[bench]
fn bench_generate_interesting_voxel(bencher: &mut test::Bencher) {
  let timers = TimerSet::new();
  bencher.iter(|| {
    let voxel = generate_voxel(&timers, VoxelBounds::new(0, 0, 0, 6));
    assert!(voxel.is_some());
  });
}

#[bench]
fn bench_generate_empty_voxel(bencher: &mut test::Bencher) {
  let timers = TimerSet::new();
  bencher.iter(|| {
    let voxel = generate_voxel(&timers, VoxelBounds::new(0, 0, 0, 4));
    assert!(voxel.is_none());
  });
}

pub fn generate_block(
  timers: &TimerSet,
  id_allocator: &Mutex<IdAllocator<EntityId>>,
  heightmap: &HeightMap,
  voxels: &mut VoxelTree<Voxel>,
  position: &BlockPosition,
  lod_index: LODIndex,
) -> TerrainBlock {
  timers.time("update.generate_block", || {
    let mut block = TerrainBlock::empty();

    let position = position.to_world_position();
    let iposition = Point3::new(position.x as i32, position.y as i32, position.z as i32);

    let lateral_samples = LOD_QUALITY[lod_index.0 as usize] as i32;
    assert!(lateral_samples <= BLOCK_WIDTH, "Sub-unit voxels not supported yet.");
    assert!(BLOCK_WIDTH % lateral_samples == 0, "Block width doesn't sample cleanly.");

    let voxel_size = BLOCK_WIDTH / lateral_samples;
    let lg_size = Int::trailing_zeros(voxel_size);
    assert!(1 << lg_size == voxel_size, "voxel_size should be an exponent of 2");
    assert!(lg_size < 31, "2^{} is too a huge voxel.", lg_size);
    let lg_size = lg_size as u8;

    {
      let mut add_poly =
        |v1: Point3<f32>, n1, v2: Point3<f32>, n2, center: Point3<f32>, center_normal| {
          let id = id_allocator.lock().unwrap().allocate();

          let minx = partial_min(v1.x, v2.x);
          let minx = minx.and_then(|m| partial_min(m, center.x));
          let minx = minx.unwrap();

          let maxx = partial_max(v1.x, v2.x);
          let maxx = maxx.and_then(|m| partial_max(m, center.x));
          let maxx = maxx.unwrap();

          let miny = partial_min(v1.y, v2.y);
          let miny = miny.and_then(|m| partial_min(m, center.y));
          let miny = miny.unwrap();

          let maxy = partial_max(v1.y, v2.y);
          let maxy = maxy.and_then(|m| partial_max(m, center.y));
          let maxy = maxy.unwrap();

          let minz = partial_min(v1.z, v2.z);
          let minz = minz.and_then(|m| partial_min(m, center.z));
          let minz = minz.unwrap();

          let maxz = partial_max(v1.z, v2.z);
          let maxz = maxz.and_then(|m| partial_max(m, center.z));
          let maxz = maxz.unwrap();

          block.vertex_coordinates.push(tri(v1, v2, center));
          block.normals.push(tri(n1, n2, center_normal));
          block.ids.push(id);

          block.bounds.push((
            id,
            Aabb3::new(
              // TODO: Remove this - 1.0. It's a temporary hack until voxel collisions work.
              Point3::new(minx, miny - 1.0, minz),
              Point3::new(maxx, maxy, maxz),
            ),
          ));
        };

      let mut field_contains = |x, y, z| {
        heightmap.height_at(x, z) >= y
      };

      let mut get_normal = |x, _, z| {
        heightmap.normal_at(x, z, voxel_size as f32)
      };

      macro_rules! get_voxel(($bounds:expr) => {{
        let branch = voxels.get_mut($bounds);
        match branch {
          &mut voxel_tree::TreeBody::Leaf(v) => Some(v),
          &mut voxel_tree::TreeBody::Empty => {
            // TODO: Add a "yes this is empty I checked" flag so we don't regen every time.
            generate_voxel(timers, &mut field_contains, &mut get_normal, $bounds).map(|v| {
              *branch = voxel_tree::TreeBody::Leaf(v);
              v
            })
          },
          &mut voxel_tree::TreeBody::Branch(_) => {
            // Overwrite existing for now.
            // TODO: Don't do ^that.
            generate_voxel(timers, &mut field_contains, &mut get_normal, $bounds).map(|v| {
              *branch = voxel_tree::TreeBody::Leaf(v);
              v
            })
          },
        }
      }});

      macro_rules! get_vertex(($v:expr) => {{
        let bounds = VoxelBounds::new($v.x, $v.y, $v.z, lg_size);
        let voxel = get_voxel!(bounds).unwrap();
        (voxel.vertex.to_world_vertex(bounds), voxel.normal.to_world_normal())
      }});

      macro_rules! extract((
        $edges:ident,
        $facing:expr,
        $d1:expr,
        $d2:expr,
      ) => (
          for x in 0..lateral_samples {
          for y in 0..lateral_samples {
          for z in 0..lateral_samples {
            let w = iposition.add_v(&Vector3::new(x << lg_size, y << lg_size, z << lg_size));
            let voxel;
            let bounds = VoxelBounds::new(w.x, w.y, w.z, lg_size);
            match get_voxel!(bounds) {
              None => continue,
              Some(v) => voxel = v,
            }

            let edge = voxel.$edges[0][0];
            if !edge.is_crossed {
              continue
            }

            // Make a quad out of the vertices from the 4 voxels adjacent to this edge.
            // We know they have vertices in them because if the surface crosses an edge,
            // it must cross that edge's neighbors.

            let (v1, n1) = get_vertex!(w.add_v(&$d1).add_v(&$d2));
            let (v2, n2) = get_vertex!(w.add_v(&$d1));
            let v3 = voxel.vertex.to_world_vertex(bounds);
            let n3 = voxel.normal.to_world_normal();
            let (v4, n4) = get_vertex!(w.add_v(&$d2));

            // Put a vertex at the average of the vertices.
            let center =
              v1.add_v(&v2.to_vec()).add_v(&v3.to_vec()).add_v(&v4.to_vec()).div_s(4.0);
            let center_normal = n1.add_v(&n2).add_v(&n3).add_v(&n4).div_s(4.0);

            let mut add_poly = |v1, n1, v2, n2| add_poly(v1, n1, v2, n2, center, center_normal);

            if edge.direction {
              // The polys are visible from negative infinity.
              add_poly(v1, n1, v2, n2);
              add_poly(v2, n2, v3, n3);
              add_poly(v3, n3, v4, n4);
              add_poly(v4, n4, v1, n1);
            } else {
              // The polys are visible from positive infinity.
              add_poly(v1, n1, v4, n4);
              add_poly(v4, n4, v3, n3);
              add_poly(v3, n3, v2, n2);
              add_poly(v2, n2, v1, n1);
            }
          }}}
        )
      );

      extract!(
        x_edges, 0,
        Vector3::new(0, -voxel_size, 0),
        Vector3::new(0, 0, -voxel_size),
      );

      extract!(
        y_edges, 1,
        Vector3::new(0, 0, -voxel_size),
        Vector3::new(-voxel_size, 0, 0),
      );

      extract!(
        z_edges, 2,
        Vector3::new(-voxel_size, 0, 0),
        Vector3::new(0, -voxel_size, 0),
      );
    }

    block
  })
}
<|endoftext|>


<commit_before>use std::ops::Drop;

use std::path::PathBuf;
use std::fs::File;
use std::error::Error;

use runtime::Runtime;

/*
 * A Temporary file in /tmp where the editor is launched on, so we can grap the contents and put
 * into the store
 */
pub struct TempFile {
    path: Option<PathBuf>,
    file: Option<File>,
}

impl TempFile {

    pub fn new(rt: &Runtime) -> TempFile {
        debug!("Building new TempFile");
        unimplemented!()
    }

    pub fn edit(&mut self, editor: Option<String>) -> TempFile {
        debug!("Editing TempFile");
        unimplemented!()
    }

    pub fn content(&self) -> Result<String, TempFileError> {
        debug!("Fetching content of TempFile");
        unimplemented!()
    }

}

/*
 * Implement Drop, so we ensure to remove the tempfile
 *
 * (is this neccessary if we use a real tempfile)
 */
impl Drop for TempFile {

    fn drop(&mut self) {
        unimplemented!()
    }

}

pub struct TempFileError {
    cause: Option<Box<Error>>,
}
<commit_msg>Implement TempFileError and traits for it<commit_after>use std::ops::Drop;

use std::path::PathBuf;
use std::fs::File;
use std::error::Error;

use std::fmt::{Debug, Display, Formatter};
use std::fmt;

use runtime::Runtime;

/*
 * A Temporary file in /tmp where the editor is launched on, so we can grap the contents and put
 * into the store
 */
pub struct TempFile {
    path: Option<PathBuf>,
    file: Option<File>,
}

impl TempFile {

    pub fn new(rt: &Runtime) -> TempFile {
        debug!("Building new TempFile");
        unimplemented!()
    }

    pub fn edit(&mut self, editor: Option<String>) -> TempFile {
        debug!("Editing TempFile");
        unimplemented!()
    }

    pub fn content(&self) -> Result<String, TempFileError> {
        debug!("Fetching content of TempFile");
        unimplemented!()
    }

}

/*
 * Implement Drop, so we ensure to remove the tempfile
 *
 * (is this neccessary if we use a real tempfile)
 */
impl Drop for TempFile {

    fn drop(&mut self) {
        unimplemented!()
    }

}

pub struct TempFileError {
    desc: &'static str,
    caused_by: Option<Box<Error>>,
}

impl TempFileError {

    pub fn new(s: &'static str) -> TempFileError {
        TempFileError {
            desc: s,
            caused_by: None,
        }
    }

    pub fn with_cause(s: &'static str, c: Box<Error>) -> TempFileError {
        TempFileError {
            desc: s,
            caused_by: Some(c),
        }
    }

}

impl Display for TempFileError {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt, "TempFileError: '{}'", self.desc);
        Ok(())
    }
}

impl Debug for TempFileError {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt, "TempFileError: '{}'", self.desc);

        if let Some(ref e) = self.caused_by {
            write!(fmt, "  cause: {:?}\n\n", e);
        }

        Ok(())
    }
}

impl Error for TempFileError {

    fn description(&self) -> &str {
        self.desc
    }

    fn cause(&self) -> Option<&Error> {
        self.caused_by.as_ref().map(|e| &**e)
    }

}

<|endoftext|>


<commit_before>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_type = "proc-macro"]
#![feature(proc_macro, proc_macro_lib)]

extern crate syn;
#[macro_use]
extern crate quote;
extern crate proc_macro;

use proc_macro::TokenStream;

use syn::Body::Enum;
use syn::VariantData::Unit;

#[proc_macro_derive(FromPrimitive)]
pub fn from_primitive(input: TokenStream) -> TokenStream {
    let source = input.to_string();

    let ast = syn::parse_macro_input(&source).unwrap();
    let name = &ast.ident;

    let variants = match ast.body {
        Enum(ref variants) => variants,
        _ => {
            panic!("`FromPrimitive` can be applied only to the enums, {} is not an enum",
                   name)
        }
    };

    let mut idx = 0;
    let variants: Vec<_> = variants.iter()
        .map(|variant| {
            let ident = &variant.ident;
            match variant.data {
                Unit => (),
                _ => {
                    panic!("`FromPrimitive` can be applied only to unitary enums, {}::{} is either struct or tuple", name, ident)
                },
            }
            if let Some(val) = variant.discriminant {
                idx = val.value;
            }
            let tt = quote!(#idx => Some(#name::#ident));
            idx += 1;
            tt
        })
        .collect();

    let res = quote! {
        #ast

        impl ::num::traits::FromPrimitive for #name {
            fn from_i64(n: i64) -> Option<Self> {
                Self::from_u64(n as u64)
            }

            fn from_u64(n: u64) -> Option<Self> {
                match n {
                    #(variants,)*
                    _ => None,
                }
            }
        }
    };

    res.to_string().parse().unwrap()
}
<commit_msg>fix(num_derive): code duplication error<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_type = "proc-macro"]
#![feature(proc_macro, proc_macro_lib)]

extern crate syn;
#[macro_use]
extern crate quote;
extern crate proc_macro;

use proc_macro::TokenStream;

use syn::Body::Enum;
use syn::VariantData::Unit;

#[proc_macro_derive(FromPrimitive)]
pub fn from_primitive(input: TokenStream) -> TokenStream {
    let source = input.to_string();

    let ast = syn::parse_macro_input(&source).unwrap();
    let name = &ast.ident;

    let variants = match ast.body {
        Enum(ref variants) => variants,
        _ => panic!("`FromPrimitive` can be applied only to the enums, {} is not an enum", name)
    };

    let mut idx = 0;
    let variants: Vec<_> = variants.iter()
        .map(|variant| {
            let ident = &variant.ident;
            match variant.data {
                Unit => (),
                _ => {
                    panic!("`FromPrimitive` can be applied only to unitary enums, {}::{} is either struct or tuple", name, ident)
                },
            }
            if let Some(val) = variant.discriminant {
                idx = val.value;
            }
            let tt = quote!(#idx => Some(#name::#ident));
            idx += 1;
            tt
        })
        .collect();

    let res = quote! {
        impl ::num::traits::FromPrimitive for #name {
            fn from_i64(n: i64) -> Option<Self> {
                Self::from_u64(n as u64)
            }

            fn from_u64(n: u64) -> Option<Self> {
                match n {
                    #(variants,)*
                    _ => None,
                }
            }
        }
    };

    res.to_string().parse().unwrap()
}
<|endoftext|>


<commit_before>//
// Copyright (c) Pirmin Kalberer. All rights reserved.
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//

use datasource::DatasourceInput;
use gdal;
use gdal::vector::{Dataset, FieldValue};
use core::feature::{Feature, FeatureAttr, FeatureAttrValType};
use core::geom::{self, GeometryType};
use core::grid::Extent;
use core::grid::Grid;
use core::layer::Layer;
use std::path::Path;

pub struct GdalDatasource {
    pub path: String,
}

impl GdalDatasource {
    pub fn new(path: &str) -> GdalDatasource {
        GdalDatasource { path: path.to_string() }
    }
}

struct VectorFeature<'a> {
    layer: &'a Layer,
    fields_defn: &'a Vec<gdal::vector::Field<'a>>,
    feature: &'a gdal::vector::Feature<'a>,
}

impl<'a> Feature for VectorFeature<'a> {
    fn fid(&self) -> Option<u64> {
        None // TODO
    }
    fn attributes(&self) -> Vec<FeatureAttr> {
        let mut attrs = Vec::new();
        for (_i, field) in self.fields_defn.into_iter().enumerate() {
            let field_value = self.feature.field(&field.name()); //TODO: get by index
            let val = match field_value {
                Ok(FieldValue::StringValue(v)) => Some(FeatureAttrValType::String(v)),
                Ok(FieldValue::IntegerValue(v)) => Some(FeatureAttrValType::Int(v as i64)),
                Ok(FieldValue::RealValue(v)) => Some(FeatureAttrValType::Double(v)),
                Err(err) => {
                    warn!("Layer '{}' - skipping field '{}': {}",
                          self.layer.name,
                          field.name(),
                          err);
                    None
                }
            };
            // match field.field_type {
            //    OGRFieldType::OFTString => {
            if let Some(val) = val {
                let fattr = FeatureAttr {
                    key: field.name(),
                    value: val,
                };
                attrs.push(fattr);
            };
        }
        attrs
    }
    fn geometry(&self) -> Result<GeometryType, String> {
        let _ogrgeom = self.feature.geometry();
        Ok(GeometryType::Point(geom::Point::new(960000.0, 6002729.0, Some(3857)))) //TODO
    }
}

impl DatasourceInput for GdalDatasource {
    fn retrieve_features<F>(&self,
                            layer: &Layer,
                            _extent: &Extent,
                            _zoom: u8,
                            _grid: &Grid,
                            mut read: F)
        where F: FnMut(&Feature)
    {
        let mut dataset = Dataset::open(Path::new(&self.path)).unwrap();
        let ogr_layer = dataset
            .layer_by_name(layer.table_name.as_ref().unwrap())
            .unwrap();
        let fields_defn = ogr_layer.defn().fields().collect::<Vec<_>>();
        for feature in ogr_layer.features() {
            let feat = VectorFeature {
                layer: layer,
                fields_defn: &fields_defn,
                feature: &feature,
            };
            read(&feat);
        }
    }
}

#[test]
fn test_gdal_api() {
    use std::path::Path;
    use gdal::vector::Dataset;

    let mut dataset = Dataset::open(Path::new("natural_earth.gpkg")).unwrap();
    let layer = dataset.layer_by_name("ne_10m_populated_places").unwrap();
    let feature = layer.features().next().unwrap();
    let name_field = feature.field("NAME").unwrap();
    let geometry = feature.geometry();
    assert_eq!(name_field.to_string(),
               Some("Colonia del Sacramento".to_string()));
    assert_eq!(geometry.wkt().unwrap(),
               "POINT (-6438719.62282072 -4093437.71441017)".to_string());
}

#[test]
fn test_gdal_retrieve() {
    let mut layer = Layer::new("points");
    layer.table_name = Some(String::from("ne_10m_populated_places"));
    layer.geometry_field = Some(String::from("wkb_geometry"));
    layer.geometry_type = Some(String::from("POINT"));
    let grid = Grid::web_mercator();
    let extent = Extent {
        minx: 821850.9,
        miny: 5909499.5,
        maxx: 860986.7,
        maxy: 5948635.3,
    };

    let ds = GdalDatasource::new("natural_earth.gpkg");
    let mut reccnt = 0;
    ds.retrieve_features(&layer, &extent, 10, &grid, |feat| {
        assert_eq!("Ok(Point(Point { x: 960000, y: 6002729, srid: Some(3857) }))",
                   &*format!("{:?}", feat.geometry()));
        assert_eq!(3, feat.attributes().len());
        assert_eq!(feat.attributes()[0].key, "SCALERANK");
        assert_eq!(feat.attributes()[1].key, "NAME");
        assert_eq!(feat.attributes()[2].key, "POP_MAX");
        if reccnt == 0 {
            assert_eq!(feat.attributes()[0].value, FeatureAttrValType::Int(10));
            assert_eq!(feat.attributes()[1].value,
                       FeatureAttrValType::String("Colonia del Sacramento".to_string()));
            assert_eq!(feat.attributes()[2].value, FeatureAttrValType::Int(21714));
        }
        assert_eq!(None, feat.fid());
        reccnt += 1;
    });
    assert_eq!(14644, reccnt);
}
<commit_msg>Implement fid() for VectorFeature<commit_after>//
// Copyright (c) Pirmin Kalberer. All rights reserved.
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//

use datasource::DatasourceInput;
use gdal;
use gdal::vector::{Dataset, FieldValue};
use core::feature::{Feature, FeatureAttr, FeatureAttrValType};
use core::geom::{self, GeometryType};
use core::grid::Extent;
use core::grid::Grid;
use core::layer::Layer;
use std::path::Path;

pub struct GdalDatasource {
    pub path: String,
}

impl GdalDatasource {
    pub fn new(path: &str) -> GdalDatasource {
        GdalDatasource { path: path.to_string() }
    }
}

struct VectorFeature<'a> {
    layer: &'a Layer,
    fields_defn: &'a Vec<gdal::vector::Field<'a>>,
    feature: &'a gdal::vector::Feature<'a>,
}

impl<'a> Feature for VectorFeature<'a> {
    fn fid(&self) -> Option<u64> {
        self.layer
            .fid_field
            .as_ref()
            .and_then(|fid| {
                          let field_value = self.feature.field(&fid);
                          match field_value {
                              Ok(FieldValue::IntegerValue(v)) => Some(v as u64),
                              _ => None,
                          }
                      })
    }
    fn attributes(&self) -> Vec<FeatureAttr> {
        let mut attrs = Vec::new();
        for (_i, field) in self.fields_defn.into_iter().enumerate() {
            let field_value = self.feature.field(&field.name()); //TODO: get by index
            let val = match field_value {
                Ok(FieldValue::StringValue(v)) => Some(FeatureAttrValType::String(v)),
                Ok(FieldValue::IntegerValue(v)) => Some(FeatureAttrValType::Int(v as i64)),
                Ok(FieldValue::RealValue(v)) => Some(FeatureAttrValType::Double(v)),
                Err(err) => {
                    warn!("Layer '{}' - skipping field '{}': {}",
                          self.layer.name,
                          field.name(),
                          err);
                    None
                }
            };
            // match field.field_type {
            //    OGRFieldType::OFTString => {
            if let Some(val) = val {
                let fattr = FeatureAttr {
                    key: field.name(),
                    value: val,
                };
                attrs.push(fattr);
            };
        }
        attrs
    }
    fn geometry(&self) -> Result<GeometryType, String> {
        let _ogrgeom = self.feature.geometry();
        Ok(GeometryType::Point(geom::Point::new(960000.0, 6002729.0, Some(3857)))) //TODO
    }
}

impl DatasourceInput for GdalDatasource {
    fn retrieve_features<F>(&self,
                            layer: &Layer,
                            _extent: &Extent,
                            _zoom: u8,
                            _grid: &Grid,
                            mut read: F)
        where F: FnMut(&Feature)
    {
        let mut dataset = Dataset::open(Path::new(&self.path)).unwrap();
        let ogr_layer = dataset
            .layer_by_name(layer.table_name.as_ref().unwrap())
            .unwrap();
        let fields_defn = ogr_layer.defn().fields().collect::<Vec<_>>();
        for feature in ogr_layer.features() {
            let feat = VectorFeature {
                layer: layer,
                fields_defn: &fields_defn,
                feature: &feature,
            };
            read(&feat);
        }
    }
}

#[test]
fn test_gdal_api() {
    use std::path::Path;
    use gdal::vector::Dataset;

    let mut dataset = Dataset::open(Path::new("natural_earth.gpkg")).unwrap();
    let layer = dataset.layer_by_name("ne_10m_populated_places").unwrap();
    let feature = layer.features().next().unwrap();
    let name_field = feature.field("NAME").unwrap();
    let geometry = feature.geometry();
    assert_eq!(name_field.to_string(),
               Some("Colonia del Sacramento".to_string()));
    assert_eq!(geometry.wkt().unwrap(),
               "POINT (-6438719.62282072 -4093437.71441017)".to_string());
}

#[test]
fn test_gdal_retrieve() {
    let mut layer = Layer::new("points");
    layer.table_name = Some(String::from("ne_10m_populated_places"));
    layer.geometry_field = Some(String::from("wkb_geometry"));
    layer.fid_field = Some(String::from("SCALERANK"));
    layer.geometry_type = Some(String::from("POINT"));
    let grid = Grid::web_mercator();
    let extent = Extent {
        minx: 821850.9,
        miny: 5909499.5,
        maxx: 860986.7,
        maxy: 5948635.3,
    };

    let ds = GdalDatasource::new("natural_earth.gpkg");
    let mut reccnt = 0;
    ds.retrieve_features(&layer, &extent, 10, &grid, |feat| {
        assert_eq!("Ok(Point(Point { x: 960000, y: 6002729, srid: Some(3857) }))",
                   &*format!("{:?}", feat.geometry()));
        assert_eq!(3, feat.attributes().len());
        assert_eq!(feat.attributes()[0].key, "SCALERANK");
        assert_eq!(feat.attributes()[1].key, "NAME");
        assert_eq!(feat.attributes()[2].key, "POP_MAX");
        if reccnt == 0 {
            assert_eq!(feat.attributes()[0].value, FeatureAttrValType::Int(10));
            assert_eq!(feat.attributes()[1].value,
                       FeatureAttrValType::String("Colonia del Sacramento".to_string()));
            assert_eq!(feat.attributes()[2].value, FeatureAttrValType::Int(21714));
            assert_eq!(Some(10), feat.fid());
        }
        reccnt += 1;
    });
    assert_eq!(14644, reccnt);
}
<|endoftext|>


<commit_before>
fn main() {
        // The statements here will be executed when the compiled binary is called

        // Print text to the console
        println!("Hello World!");
}

<commit_msg>Add userchannel module.<commit_after>
mod userchannel;

fn main() {
        // The statements here will be executed when the compiled binary is called

        // Print text to the console
        println!("Hello World!");
}

<|endoftext|>


<commit_before>use proc_macro2::Span;
use syn;

pub struct MetaItem {
    // Due to https://github.com/rust-lang/rust/issues/47941
    // we can only ever get the span of the #, which is better than nothing
    span: Span,
    meta: syn::Meta,
}

impl MetaItem {
    pub fn with_name<'a>(
        attrs: &[syn::Attribute],
        name: &'a str,
    ) -> Result<Self, MissingOption<'a>> {
        attrs
            .iter()
            .filter_map(|attr| attr.interpret_meta().map(|m| (attr.pound_token.0[0], m)))
            .find(|&(_, ref m)| m.name() == name)
            .map(|(span, meta)| Self { span, meta })
            .ok_or(MissingOption { name })
    }

    pub fn nested_item<'a>(&self, name: &'a str) -> Result<Self, MissingOption<'a>> {
        self.expect_nested().nth(0).ok_or(MissingOption { name })
    }

    pub fn expect_bool_value(&self) -> bool {
        match self.str_value().as_ref().map(|s| s.as_str()) {
            Some("true") => true,
            Some("false") => false,
            _ => panic!("`{0}` must be in the form `{0} = \"true\"`", self.name()),
        }
    }

    pub fn expect_ident_value(&self) -> syn::Ident {
        let maybe_attr = self.nested().and_then(|mut n| n.nth(0));
        let maybe_word = maybe_attr.as_ref().and_then(Self::word);
        match maybe_word {
            Some(x) => {
                println!(
                    "The form `{0}(value)` is deprecated. Use `{0} = \"value\"` instead",
                    self.name()
                );
                x
            }
            _ => syn::Ident::new(&self.expect_str_value(), self.span.resolved_at(Span::call_site())),
        }
    }

    pub fn expect_word(self) -> syn::Ident {
        self.word().unwrap_or_else(|| {
            let meta = &self.meta;
            panic!("Expected `{}` found `{}`", self.name(), quote!(#meta))
        })
    }

    pub fn word(&self) -> Option<syn::Ident> {
        use syn::Meta::*;

        match self.meta {
            Word(x) => Some(x),
            _ => None,
        }
    }

    pub fn expect_nested(&self) -> Nested {
        self.nested()
            .unwrap_or_else(|| panic!("`{0}` must be in the form `{0}(...)`", self.name()))
    }

    pub fn nested(&self) -> Option<Nested> {
        use syn::Meta::*;

        match self.meta {
            List(ref list) => Some(Nested(list.nested.iter(), self.span)),
            _ => None,
        }
    }

    fn expect_str_value(&self) -> String {
        self.str_value()
            .unwrap_or_else(|| panic!("`{0}` must be in the form `{0} = \"value\"`", self.name()))
    }

    fn name(&self) -> syn::Ident {
        self.meta.name()
    }

    fn str_value(&self) -> Option<String> {
        use syn::Meta::*;
        use syn::MetaNameValue;
        use syn::Lit::*;

        match self.meta {
            NameValue(MetaNameValue {
                lit: Str(ref s), ..
            }) => Some(s.value()),
            _ => None,
        }
    }
}

pub struct MissingOption<'a> {
    name: &'a str,
}

pub trait RequiredOption<T> {
    fn required(self) -> T;
}

impl<'a> RequiredOption<MetaItem> for Result<MetaItem, MissingOption<'a>> {
    fn required(self) -> MetaItem {
        self.unwrap_or_else(|e| panic!("Missing required option {}", e.name))
    }
}

#[cfg_attr(rustfmt, rustfmt_skip)] // https://github.com/rust-lang-nursery/rustfmt/issues/2392
pub struct Nested<'a>(syn::punctuated::Iter<'a, syn::NestedMeta, Token![,]>, Span);

impl<'a> Iterator for Nested<'a> {
    type Item = MetaItem;

    fn next(&mut self) -> Option<Self::Item> {
        use syn::NestedMeta::*;

        match self.0.next() {
            Some(&Meta(ref item)) => Some(MetaItem { span: self.1, meta: item.clone() }),
            Some(_) => self.next(),
            None => None,
        }
    }
}
<commit_msg>Rustfmt<commit_after>use proc_macro2::Span;
use syn;

pub struct MetaItem {
    // Due to https://github.com/rust-lang/rust/issues/47941
    // we can only ever get the span of the #, which is better than nothing
    span: Span,
    meta: syn::Meta,
}

impl MetaItem {
    pub fn with_name<'a>(
        attrs: &[syn::Attribute],
        name: &'a str,
    ) -> Result<Self, MissingOption<'a>> {
        attrs
            .iter()
            .filter_map(|attr| attr.interpret_meta().map(|m| (attr.pound_token.0[0], m)))
            .find(|&(_, ref m)| m.name() == name)
            .map(|(span, meta)| Self { span, meta })
            .ok_or(MissingOption { name })
    }

    pub fn nested_item<'a>(&self, name: &'a str) -> Result<Self, MissingOption<'a>> {
        self.expect_nested().nth(0).ok_or(MissingOption { name })
    }

    pub fn expect_bool_value(&self) -> bool {
        match self.str_value().as_ref().map(|s| s.as_str()) {
            Some("true") => true,
            Some("false") => false,
            _ => panic!("`{0}` must be in the form `{0} = \"true\"`", self.name()),
        }
    }

    pub fn expect_ident_value(&self) -> syn::Ident {
        let maybe_attr = self.nested().and_then(|mut n| n.nth(0));
        let maybe_word = maybe_attr.as_ref().and_then(Self::word);
        match maybe_word {
            Some(x) => {
                println!(
                    "The form `{0}(value)` is deprecated. Use `{0} = \"value\"` instead",
                    self.name()
                );
                x
            }
            _ => syn::Ident::new(
                &self.expect_str_value(),
                self.span.resolved_at(Span::call_site()),
            ),
        }
    }

    pub fn expect_word(self) -> syn::Ident {
        self.word().unwrap_or_else(|| {
            let meta = &self.meta;
            panic!("Expected `{}` found `{}`", self.name(), quote!(#meta))
        })
    }

    pub fn word(&self) -> Option<syn::Ident> {
        use syn::Meta::*;

        match self.meta {
            Word(x) => Some(x),
            _ => None,
        }
    }

    pub fn expect_nested(&self) -> Nested {
        self.nested()
            .unwrap_or_else(|| panic!("`{0}` must be in the form `{0}(...)`", self.name()))
    }

    pub fn nested(&self) -> Option<Nested> {
        use syn::Meta::*;

        match self.meta {
            List(ref list) => Some(Nested(list.nested.iter(), self.span)),
            _ => None,
        }
    }

    fn expect_str_value(&self) -> String {
        self.str_value()
            .unwrap_or_else(|| panic!("`{0}` must be in the form `{0} = \"value\"`", self.name()))
    }

    fn name(&self) -> syn::Ident {
        self.meta.name()
    }

    fn str_value(&self) -> Option<String> {
        use syn::Meta::*;
        use syn::MetaNameValue;
        use syn::Lit::*;

        match self.meta {
            NameValue(MetaNameValue {
                lit: Str(ref s), ..
            }) => Some(s.value()),
            _ => None,
        }
    }
}

pub struct MissingOption<'a> {
    name: &'a str,
}

pub trait RequiredOption<T> {
    fn required(self) -> T;
}

impl<'a> RequiredOption<MetaItem> for Result<MetaItem, MissingOption<'a>> {
    fn required(self) -> MetaItem {
        self.unwrap_or_else(|e| panic!("Missing required option {}", e.name))
    }
}

#[cfg_attr(rustfmt, rustfmt_skip)] // https://github.com/rust-lang-nursery/rustfmt/issues/2392
pub struct Nested<'a>(syn::punctuated::Iter<'a, syn::NestedMeta, Token![,]>, Span);

impl<'a> Iterator for Nested<'a> {
    type Item = MetaItem;

    fn next(&mut self) -> Option<Self::Item> {
        use syn::NestedMeta::*;

        match self.0.next() {
            Some(&Meta(ref item)) => Some(MetaItem {
                span: self.1,
                meta: item.clone(),
            }),
            Some(_) => self.next(),
            None => None,
        }
    }
}
<|endoftext|>


<commit_before>use super::VulkanoRenderer;

use game_state::winit;
use game_state::input::events::{
    InputEvent,
    MouseButton,
};

use game_state::input::screen::{
    ScreenPoint,
    ScreenRect,
    DeltaVector,
};

use std::collections::VecDeque;
use game_state::input::InputSource;

// TODO: probably extract this to game_state

impl InputSource for VulkanoRenderer {
    fn get_input_events(&mut self) -> VecDeque<InputEvent> {

        //println!("get_input_events");
        let mut events = VecDeque::new();
        {
            let event_loop = &mut self.events_loop.lock().unwrap();
            event_loop.poll_events(|e| events.push_back(e.clone()));
        }

        let this_window_id = self.id as u64;
        //test chg

        let mut converted_events = VecDeque::with_capacity(events.len());

        for e in events {

            match e {
                winit::Event::DeviceEvent{device_id, ref event} => {
                    match event {
                        &winit::DeviceEvent::Added => {
                            println!("device added");
                        },
                        &winit::DeviceEvent::Removed => {
                            println!("device removed")
                        },
                        &winit::DeviceEvent::MouseMotion { delta } => { },
                        &winit::DeviceEvent::MouseWheel {delta} => {},
                        &winit::DeviceEvent::Motion { axis, value } => {
                        },
                        &winit::DeviceEvent::Button { button, state } => {},
                        &winit::DeviceEvent::Key(input) => {},
                        &winit::DeviceEvent::Text{codepoint} => {}
                    }
                },
                winit::Event::WindowEvent{ window_id, ref event } => {
                    let maybe_converted_event = match event {
                        // Keyboard Events
                        &winit::WindowEvent::KeyboardInput{device_id, input} => {
                            let e = match input.state {
                                winit::ElementState::Pressed => InputEvent::KeyDown(self.id, input.scancode),
                                winit::ElementState::Released => InputEvent::KeyUp(self.id, input.scancode)
                            };

                            // within the renderer itself we want to listen for input events
                            // directly, so we read what's been copied
                            if let &InputEvent::KeyDown(ref id, ref scan) = &e {
                                let c = *scan as u8;
                                match c {
                                    33 => {
                                        self.fullscreen = !self.fullscreen;
                                        if self.fullscreen {
                                            println!("going into fullscreen");
                                            self.window.set_fullscreen(Some(self.window.get_current_monitor()));
                                            self.fullscreen = true;
                                            self.window.hide_cursor(true);
                                            self.cursor_hidden = true;
                                            match self.window.grab_cursor(true) {
                                               Ok(_) => {
                                                   println!("grabbed cursor");
                                                   self.cursor_grabbed = true;
                                               },
                                               Err(e) => println!("unable to grab cursor {:?}", e)
                                            }
                                        } else {
                                            println!("leaving fullscreen");
                                            self.window.set_fullscreen(None);
                                            self.fullscreen = false;
                                            self.window.hide_cursor(false);
                                            self.cursor_hidden = false;
                                            match self.window.grab_cursor(false) {
                                                Ok(_) => {
                                                    println!("grabbed cursor");
                                                    self.cursor_grabbed = false;
                                                },
                                                Err(e) => println!("unable to grab cursor {:?}", e)
                                            }
                                        }
                                    }
                                    _ => {}
                                }
                            }

                            Some(e)
                        }

                        // Mouse Events
                        &winit::WindowEvent::CursorMoved{device_id, position, modifiers} => {
                            let winit::dpi::LogicalPosition{x,y} = position;
                            let old_pos: ScreenPoint = self.get_mouse_pos().clone();
                            // TODO: resolve f64 truncation to i32 here
                            let new_pos = ScreenPoint::new(x as i32, y as i32);
                            let moved =
                                InputEvent::MouseMove(self.id, new_pos.clone(), DeltaVector::from_points(&old_pos, &new_pos));
                            self.set_mouse_pos(new_pos);
                            Some(moved)
                        },
                        &winit::WindowEvent::MouseInput{device_id, state, button, modifiers} => {
                            let b = match button {
                                winit::MouseButton::Left => MouseButton::Left,
                                winit::MouseButton::Right => MouseButton::Right,
                                winit::MouseButton::Middle => MouseButton::Middle,
                                winit::MouseButton::Other(n) => MouseButton::Other(n)
                            };
                            let e = match state {
                                winit::ElementState::Pressed => InputEvent::MouseDown(self.id, b, self.get_mouse_pos().clone()),
                                winit::ElementState::Released => InputEvent::MouseUp(self.id, b, self.get_mouse_pos().clone())
                            };
                            Some(e)
                        },

                        &winit::WindowEvent::MouseWheel{device_id, delta, phase, modifiers} => {
                            let e = match delta {
                                winit::MouseScrollDelta::LineDelta(x,y) => {
                                    InputEvent::MouseWheel(
                                        self.id, self.get_mouse_pos().clone(),
                                        DeltaVector::new(x as i32, y as i32)
                                    )
                                },
                                winit::MouseScrollDelta::PixelDelta(winit::dpi::LogicalPosition{x,y}) => {
                                    InputEvent::MouseWheel(
                                        self.id, self.get_mouse_pos().clone(),
                                        DeltaVector::new(x as i32, y as i32)
                                    )
                                }
                            };

                            Some(e)
                        },

                        // Window Manager events
                        &winit::WindowEvent::CloseRequested => Some(InputEvent::CloseRequested(self.id)),
                        &winit::WindowEvent::Destroyed => Some(InputEvent::Destroyed(self.id)),
                        &winit::WindowEvent::Focused(f) => Some(if f { InputEvent::GainedFocus(self.id) } else { InputEvent::LostFocus(self.id) }),
                        &winit::WindowEvent::Moved(winit::dpi::LogicalPosition{x,y}) => {
                            let new_rect = ScreenRect::new(x as i32, y as i32, self.rect.w, self.rect.h);
                            let e = InputEvent::Moved(self.id, ScreenPoint::new(x as i32, y as i32));
                            self.set_rect(new_rect);
                            Some(e)
                        }
                        &winit::WindowEvent::Resized(winit::dpi::LogicalSize{width, height}) => {
                            let new_rect = ScreenRect::new(self.rect.x, self.rect.y, width as i32, height as i32);
                            let e = InputEvent::Resized(self.id, new_rect.clone());
                            self.set_rect(new_rect);
                            Some(e)
                        },
                        _ => None

                    };
                    if maybe_converted_event.is_some() {
                        converted_events.push_back(maybe_converted_event.unwrap());
                    }

                }
                _ => {}
            };
        }
        converted_events
    }
    // FIXME Ruby
}

<commit_msg>toggle_fullscreen<commit_after>use super::VulkanoRenderer;

use game_state::winit;
use game_state::input::events::{
    InputEvent,
    MouseButton,
};

use game_state::input::screen::{
    ScreenPoint,
    ScreenRect,
    DeltaVector,
};

use std::collections::VecDeque;
use game_state::input::InputSource;

// TODO: probably extract this to game_state

impl VulkanoRenderer {
    fn toggle_fullscreen(&mut self) {
        let is_fullscreen = !self.fullscreen;
        println!("toggle_fullscreen {} -> {}", self.fullscreen, is_fullscreen);
        if is_fullscreen {
            let current = self.window.get_current_monitor();
            println!("current monitor {:?}", current);
            self.window.set_fullscreen( Some(current) );
        } else {
            self.window.set_fullscreen(None);
        }
        self.fullscreen = is_fullscreen;
        self.window.hide_cursor(is_fullscreen);
        self.cursor_hidden = is_fullscreen;
        match self.window.grab_cursor(is_fullscreen) {
            Ok(_) => {
                println!("{}", if is_fullscreen {"grabbed cursor"} else {"released cursor"});
                self.cursor_grabbed = is_fullscreen;
            },
            Err(e) => println!("unable to grab or release cursor {:?}", e)
        }

    }

}

impl InputSource for VulkanoRenderer {

    fn get_input_events(&mut self) -> VecDeque<InputEvent> {

        //println!("get_input_events");
        let mut events = VecDeque::new();
        {
            let event_loop = &mut self.events_loop.lock().unwrap();
            event_loop.poll_events(|e| events.push_back(e.clone()));
        }

        let this_window_id = self.id as u64;
        //test chg

        let mut converted_events = VecDeque::with_capacity(events.len());

        for e in events {

            match e {
                winit::Event::DeviceEvent{device_id, ref event} => {
                    match event {
                        &winit::DeviceEvent::Added => {
                            println!("device added");
                        },
                        &winit::DeviceEvent::Removed => {
                            println!("device removed")
                        },
                        &winit::DeviceEvent::MouseMotion { delta } => { },
                        &winit::DeviceEvent::MouseWheel {delta} => {},
                        &winit::DeviceEvent::Motion { axis, value } => {
                        },
                        &winit::DeviceEvent::Button { button, state } => {},
                        &winit::DeviceEvent::Key(input) => {},
                        &winit::DeviceEvent::Text{codepoint} => {}
                    }
                },
                winit::Event::WindowEvent{ window_id, ref event } => {
                    let maybe_converted_event = match event {
                        // Keyboard Events
                        &winit::WindowEvent::KeyboardInput{device_id, input} => {
                            let e = match input.state {
                                winit::ElementState::Pressed => InputEvent::KeyDown(self.id, input.scancode),
                                winit::ElementState::Released => InputEvent::KeyUp(self.id, input.scancode)
                            };

                            // within the renderer itself we want to listen for input events
                            // directly, so we read what's been copied
                            if let &InputEvent::KeyDown(ref id, ref scan) = &e {
                                let c = *scan as u8;
                                match c {
                                    33 => {
                                        self.toggle_fullscreen();
                                    }
                                    _ => {}
                                }
                            }

                            Some(e)
                        }

                        // Mouse Events
                        &winit::WindowEvent::CursorMoved{device_id, position, modifiers} => {
                            let winit::dpi::LogicalPosition{x,y} = position;
                            let old_pos: ScreenPoint = self.get_mouse_pos().clone();
                            // TODO: resolve f64 truncation to i32 here
                            let new_pos = ScreenPoint::new(x as i32, y as i32);
                            let moved =
                                InputEvent::MouseMove(self.id, new_pos.clone(), DeltaVector::from_points(&old_pos, &new_pos));
                            self.set_mouse_pos(new_pos);
                            Some(moved)
                        },
                        &winit::WindowEvent::MouseInput{device_id, state, button, modifiers} => {
                            let b = match button {
                                winit::MouseButton::Left => MouseButton::Left,
                                winit::MouseButton::Right => MouseButton::Right,
                                winit::MouseButton::Middle => MouseButton::Middle,
                                winit::MouseButton::Other(n) => MouseButton::Other(n)
                            };
                            let e = match state {
                                winit::ElementState::Pressed => InputEvent::MouseDown(self.id, b, self.get_mouse_pos().clone()),
                                winit::ElementState::Released => InputEvent::MouseUp(self.id, b, self.get_mouse_pos().clone())
                            };
                            Some(e)
                        },

                        &winit::WindowEvent::MouseWheel{device_id, delta, phase, modifiers} => {
                            let e = match delta {
                                winit::MouseScrollDelta::LineDelta(x,y) => {
                                    InputEvent::MouseWheel(
                                        self.id, self.get_mouse_pos().clone(),
                                        DeltaVector::new(x as i32, y as i32)
                                    )
                                },
                                winit::MouseScrollDelta::PixelDelta(winit::dpi::LogicalPosition{x,y}) => {
                                    InputEvent::MouseWheel(
                                        self.id, self.get_mouse_pos().clone(),
                                        DeltaVector::new(x as i32, y as i32)
                                    )
                                }
                            };

                            Some(e)
                        },

                        // Window Manager events
                        &winit::WindowEvent::CloseRequested => Some(InputEvent::CloseRequested(self.id)),
                        &winit::WindowEvent::Destroyed => Some(InputEvent::Destroyed(self.id)),
                        &winit::WindowEvent::Focused(f) => Some(if f { InputEvent::GainedFocus(self.id) } else { InputEvent::LostFocus(self.id) }),
                        &winit::WindowEvent::Moved(winit::dpi::LogicalPosition{x,y}) => {
                            let new_rect = ScreenRect::new(x as i32, y as i32, self.rect.w, self.rect.h);
                            let e = InputEvent::Moved(self.id, ScreenPoint::new(x as i32, y as i32));
                            self.set_rect(new_rect);
                            Some(e)
                        }
                        &winit::WindowEvent::Resized(winit::dpi::LogicalSize{width, height}) => {
                            let new_rect = ScreenRect::new(self.rect.x, self.rect.y, width as i32, height as i32);
                            let e = InputEvent::Resized(self.id, new_rect.clone());
                            self.set_rect(new_rect);
                            Some(e)
                        },
                        _ => None

                    };
                    if maybe_converted_event.is_some() {
                        converted_events.push_back(maybe_converted_event.unwrap());
                    }

                }
                _ => {}
            };
        }
        converted_events
    }
    // FIXME Ruby
}

<|endoftext|>


<commit_before>//! # Diesel
//!
//! Diesel is an ORM and query builder designed to reduce the boilerplate for database interactions.
//! If this is your first time reading this documentation,
//! we recommend you start with the [getting started guide].
//! We also have [many other long form guides].
//!
//! [getting started guide]: https://diesel.rs/guides/getting-started/
//! [many other long form guides]: https://diesel.rs/guides
//!
//! # Where to find things
//!
//! ## Declaring your schema
//!
//! So Diesel is able to validate your queries at compile time,
//! it requires you to specify your schema in your code,
//! which you can do with [the `table!` macro][`table!`].
//! `diesel print-schema` or `infer_schema!` can be used
//! to automatically generate these macro calls
//! (by connecting to your database and querying its schema).
//!
//! [`table!`]: macro.table.html
//!
//! ## Getting started
//!
//! Queries usually start from either a table, or a function like [`update`].
//! Those functions can be found [here](#functions).
//!
//! Diesel provides a [`prelude` module](prelude),
//! which exports most of the typically used traits and types.
//! We are conservative about what goes in this module,
//! and avoid anything which has a generic name.
//! Files which use Diesel are expected to have `use diesel::prelude::*;`.
//!
//! [`update`]: fn.update.html
//!
//! ## Constructing a query
//!
//! The tools the query builder gives you can be put into these three categories:
//!
//! - "Query builder methods" are things that map to portions of a whole query
//!   (such as `ORDER` and `WHERE`). These methods usually have the same name
//!   as the SQL they map to, except for `WHERE` which is called `filter` in Diesel
//!   (To not conflict with the Rust keyword).
//!   These methods live in [the `query_dsl` module](query_dsl).
//! - "Expression methods" are things you would call on columns
//!   or other individual values.
//!   These methods live in [the `expression_methods` module](expression_methods)
//!   You can often find these by thinking "what would this be called"
//!   if it were a method
//!   and typing that into the search bar
//!   (e.g. `LIKE` is called `like` in Diesel).
//!   Most operators are named based on the Rust function which maps to that
//!   operator in [`std::ops`]
//!   (For example `==` is called `.eq`, and `!=` is called `.ne`).
//! - "Bare functions" are normal SQL functions
//!   such as `sum`.
//!   They live in [the `dsl` module](dsl).
//!   Diesel only supports a very small number of these functions.
//!   You can declare additional functions you want to use
//!   with [the `sql_function!` macro][`sql_function!`].
//!
//! [`std::ops`]: //doc.rust-lang.org/stable/std/ops/index.html
//! [`sql_function!`]: macro.sql_function.html
//!
//! ## Serializing and Deserializing
//!
//! Types which represent the result of a SQL query implement
//! a trait called [`Queryable`].
//!
//! Diesel maps "Rust types" (e.g. `i32`) to and from "SQL types"
//! (e.g. [`diesel::types::Integer`]).
//! You can find all the types supported by Diesel in [the `types` module](types).
//! These types are only used to represent a SQL type.
//! You should never put them on your `Queryable` structs.
//!
//! To find all the Rust types which can be used with a given SQL type,
//! see the documentation for that SQL type.
//!
//! To find all the SQL types which can be used with a Rust type,
//! go to the docs for either [`ToSql`] or [`FromSql`],
//! go to the "Implementors" section,
//! and find the Rust type you want to use.
//!
//! [`Queryable`]: query_source/trait.Queryable.html
//! [`diesel::types::Integer`]: types/struct.Integer.html
//! [`ToSql`]: types/trait.ToSql.html
//! [`FromSql`]: types/trait.FromSql.html
//!
//! ## Getting help
//!
//! If you run into problems, Diesel has a very active Gitter room.
//! You can come ask for help at
//! [gitter.im/diesel-rs/diesel](https://gitter.im/diesel-rs/diesel)

#![cfg_attr(feature = "unstable", feature(specialization))]
// Built-in Lints
#![deny(warnings, missing_debug_implementations, missing_copy_implementations)]
// Clippy lints
#![cfg_attr(feature = "clippy", allow(unstable_features))]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
#![cfg_attr(feature = "clippy",
            allow(option_map_unwrap_or_else, option_map_unwrap_or, match_same_arms,
                  type_complexity))]
#![cfg_attr(feature = "clippy",
            warn(option_unwrap_used, result_unwrap_used, print_stdout,
                 wrong_pub_self_convention, mut_mut, non_ascii_literal, similar_names,
                 unicode_not_nfc, enum_glob_use, if_not_else, items_after_statements,
                 used_underscore_binding))]
#![cfg_attr(all(test, feature = "clippy"), allow(option_unwrap_used, result_unwrap_used))]

#[cfg(feature = "postgres")]
#[macro_use]
extern crate bitflags;
extern crate byteorder;
// This is required to make `diesel_derives` re-export, but clippy thinks its unused
#[cfg_attr(feature = "clippy", allow(useless_attribute))]
#[allow(unused_imports)]
#[macro_use]
extern crate diesel_derives;
#[doc(hidden)]
pub use diesel_derives::*;

#[macro_use]
mod macros;

#[cfg(test)]
#[macro_use]
extern crate cfg_if;

#[cfg(test)]
pub mod test_helpers;

#[deny(missing_docs)]
pub mod associations;
#[deny(missing_docs)]
pub mod backend;
#[doc(hidden)]
pub mod connection;
#[macro_use]
#[deny(missing_docs)]
pub mod expression;
#[deny(missing_docs)]
pub mod expression_methods;
#[doc(hidden)]
pub mod insertable;
#[deny(missing_docs)]
pub mod query_builder;
#[deny(missing_docs)]
#[macro_use]
pub mod types;

#[cfg(feature = "mysql")]
#[deny(missing_docs)]
pub mod mysql;
#[cfg(feature = "postgres")]
#[deny(missing_docs)]
pub mod pg;
#[cfg(feature = "sqlite")]
#[deny(missing_docs)]
pub mod sqlite;

#[deny(missing_docs)]
pub mod query_dsl;
#[deny(missing_docs)]
pub mod query_source;
#[deny(missing_docs)]
pub mod result;
#[deny(missing_docs)]
pub mod row;
mod util;

pub mod dsl {
    //! Includes various helper types and bare functions which are named too
    //! generically to be included in prelude, but are often used when using Diesel.

    #[doc(inline)]
    pub use helper_types::*;

    #[doc(inline)]
    pub use expression::dsl::*;
}

pub mod helper_types {
    //! Provide helper types for concisely writing the return type of functions.
    //! As with iterators, it is unfortunately difficult to return a partially
    //! constructed query without exposing the exact implementation of the
    //! function. Without higher kinded types, these various DSLs can't be
    //! combined into a single trait for boxing purposes.
    //!
    //! All types here are in the form `<FirstType as
    //! DslName<OtherTypes>>::Output`. So the return type of
    //! `users.filter(first_name.eq("John")).order(last_name.asc()).limit(10)` would
    //! be `Limit<Order<FindBy<users, first_name, &str>, Asc<last_name>>>`
    use super::query_dsl::*;
    use super::query_dsl::methods::*;
    use super::query_source::joins;

    #[doc(inline)]
    pub use expression::helper_types::*;

    /// Represents the return type of `.select(selection)`
    pub type Select<Source, Selection> = <Source as SelectDsl<Selection>>::Output;

    /// Represents the return type of `.filter(predicate)`
    pub type Filter<Source, Predicate> = <Source as FilterDsl<Predicate>>::Output;

    /// Represents the return type of `.filter(lhs.eq(rhs))`
    pub type FindBy<Source, Column, Value> = Filter<Source, Eq<Column, Value>>;

    /// Represents the return type of `.for_update()`
    pub type ForUpdate<Source> = <Source as ForUpdateDsl>::Output;

    /// Represents the return type of `.find(pk)`
    pub type Find<Source, PK> = <Source as FindDsl<PK>>::Output;

    /// Represents the return type of `.order(ordering)`
    pub type Order<Source, Ordering> = <Source as OrderDsl<Ordering>>::Output;

    /// Represents the return type of `.limit()`
    pub type Limit<Source> = <Source as LimitDsl>::Output;

    /// Represents the return type of `.offset()`
    pub type Offset<Source> = <Source as OffsetDsl>::Output;

    /// Represents the return type of `.inner_join(rhs)`
    pub type InnerJoin<Source, Rhs> =
        <Source as JoinWithImplicitOnClause<Rhs, joins::Inner>>::Output;

    /// Represents the return type of `.left_join(rhs)`
    pub type LeftJoin<Source, Rhs> =
        <Source as JoinWithImplicitOnClause<Rhs, joins::LeftOuter>>::Output;

    use super::associations::HasTable;
    use super::query_builder::{AsChangeset, IntoUpdateTarget, UpdateStatement};
    /// Represents the return type of `update(lhs).set(rhs)`
    pub type Update<Target, Changes> = UpdateStatement<
        <Target as HasTable>::Table,
        <Target as IntoUpdateTarget>::WhereClause,
        <Changes as AsChangeset>::Changeset,
    >;

    /// Represents the return type of `.into_boxed::<'a, DB>()`
    pub type IntoBoxed<'a, Source, DB> = <Source as BoxedDsl<'a, DB>>::Output;

    /// Represents the return type of `.distinct()`
    pub type Distinct<Source> = <Source as DistinctDsl>::Output;

    /// Represents the return type of `.distinct_on(expr)`
    #[cfg(feature = "postgres")]
    pub type DistinctOn<Source, Expr> = <Source as DistinctOnDsl<Expr>>::Output;
}

pub mod prelude {
    //! Re-exports important traits and types. Meant to be glob imported when using Diesel.
    pub use associations::{GroupedBy, Identifiable};
    pub use connection::Connection;
    pub use expression::{AppearsOnTable, BoxableExpression, Expression, IntoSql,
                         SelectableExpression};
    pub use expression_methods::*;
    #[doc(inline)]
    pub use insertable::Insertable;
    #[doc(hidden)]
    pub use query_dsl::GroupByDsl;
    pub use query_dsl::{BelongingToDsl, JoinOnDsl, QueryDsl, RunQueryDsl, SaveChangesDsl};

    pub use query_source::{Column, JoinTo, QuerySource, Queryable, Table};
    pub use result::{ConnectionError, ConnectionResult, OptionalExtension, QueryResult};

    #[cfg(feature = "postgres")]
    pub use pg::PgConnection;
    #[cfg(feature = "sqlite")]
    pub use sqlite::SqliteConnection;
    #[cfg(feature = "mysql")]
    pub use mysql::MysqlConnection;
}

pub use prelude::*;
#[doc(inline)]
pub use query_builder::debug_query;
#[doc(inline)]
pub use query_builder::functions::{delete, insert_into, replace_into, select, sql_query, update};
pub use result::Error::NotFound;
#[doc(inline)]
pub use types::structs::data_types;
<commit_msg>Make ambiguous markdown not ambiguous.<commit_after>//! # Diesel
//!
//! Diesel is an ORM and query builder designed to reduce the boilerplate for database interactions.
//! If this is your first time reading this documentation,
//! we recommend you start with the [getting started guide].
//! We also have [many other long form guides].
//!
//! [getting started guide]: https://diesel.rs/guides/getting-started/
//! [many other long form guides]: https://diesel.rs/guides
//!
//! # Where to find things
//!
//! ## Declaring your schema
//!
//! So Diesel is able to validate your queries at compile time,
//! it requires you to specify your schema in your code,
//! which you can do with [the `table!` macro][`table!`].
//! `diesel print-schema` or `infer_schema!` can be used
//! to automatically generate these macro calls
//! (by connecting to your database and querying its schema).
//!
//! [`table!`]: macro.table.html
//!
//! ## Getting started
//!
//! Queries usually start from either a table, or a function like [`update`].
//! Those functions can be found [here](#functions).
//!
//! Diesel provides a [`prelude` module](prelude),
//! which exports most of the typically used traits and types.
//! We are conservative about what goes in this module,
//! and avoid anything which has a generic name.
//! Files which use Diesel are expected to have `use diesel::prelude::*;`.
//!
//! [`update`]: fn.update.html
//!
//! ## Constructing a query
//!
//! The tools the query builder gives you can be put into these three categories:
//!
//! - "Query builder methods" are things that map to portions of a whole query
//!   (such as `ORDER` and `WHERE`). These methods usually have the same name
//!   as the SQL they map to, except for `WHERE` which is called `filter` in Diesel
//!   (To not conflict with the Rust keyword).
//!   These methods live in [the `query_dsl` module](query_dsl).
//! - "Expression methods" are things you would call on columns
//!   or other individual values.
//!   These methods live in [the `expression_methods` module](expression_methods)
//!   You can often find these by thinking "what would this be called"
//!   if it were a method
//!   and typing that into the search bar
//!   (e.g. `LIKE` is called `like` in Diesel).
//!   Most operators are named based on the Rust function which maps to that
//!   operator in [`std::ops`][]
//!   (For example `==` is called `.eq`, and `!=` is called `.ne`).
//! - "Bare functions" are normal SQL functions
//!   such as `sum`.
//!   They live in [the `dsl` module](dsl).
//!   Diesel only supports a very small number of these functions.
//!   You can declare additional functions you want to use
//!   with [the `sql_function!` macro][`sql_function!`].
//!
//! [`std::ops`]: //doc.rust-lang.org/stable/std/ops/index.html
//! [`sql_function!`]: macro.sql_function.html
//!
//! ## Serializing and Deserializing
//!
//! Types which represent the result of a SQL query implement
//! a trait called [`Queryable`].
//!
//! Diesel maps "Rust types" (e.g. `i32`) to and from "SQL types"
//! (e.g. [`diesel::types::Integer`]).
//! You can find all the types supported by Diesel in [the `types` module](types).
//! These types are only used to represent a SQL type.
//! You should never put them on your `Queryable` structs.
//!
//! To find all the Rust types which can be used with a given SQL type,
//! see the documentation for that SQL type.
//!
//! To find all the SQL types which can be used with a Rust type,
//! go to the docs for either [`ToSql`] or [`FromSql`],
//! go to the "Implementors" section,
//! and find the Rust type you want to use.
//!
//! [`Queryable`]: query_source/trait.Queryable.html
//! [`diesel::types::Integer`]: types/struct.Integer.html
//! [`ToSql`]: types/trait.ToSql.html
//! [`FromSql`]: types/trait.FromSql.html
//!
//! ## Getting help
//!
//! If you run into problems, Diesel has a very active Gitter room.
//! You can come ask for help at
//! [gitter.im/diesel-rs/diesel](https://gitter.im/diesel-rs/diesel)

#![cfg_attr(feature = "unstable", feature(specialization))]
// Built-in Lints
#![deny(warnings, missing_debug_implementations, missing_copy_implementations)]
// Clippy lints
#![cfg_attr(feature = "clippy", allow(unstable_features))]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
#![cfg_attr(feature = "clippy",
            allow(option_map_unwrap_or_else, option_map_unwrap_or, match_same_arms,
                  type_complexity))]
#![cfg_attr(feature = "clippy",
            warn(option_unwrap_used, result_unwrap_used, print_stdout,
                 wrong_pub_self_convention, mut_mut, non_ascii_literal, similar_names,
                 unicode_not_nfc, enum_glob_use, if_not_else, items_after_statements,
                 used_underscore_binding))]
#![cfg_attr(all(test, feature = "clippy"), allow(option_unwrap_used, result_unwrap_used))]

#[cfg(feature = "postgres")]
#[macro_use]
extern crate bitflags;
extern crate byteorder;
// This is required to make `diesel_derives` re-export, but clippy thinks its unused
#[cfg_attr(feature = "clippy", allow(useless_attribute))]
#[allow(unused_imports)]
#[macro_use]
extern crate diesel_derives;
#[doc(hidden)]
pub use diesel_derives::*;

#[macro_use]
mod macros;

#[cfg(test)]
#[macro_use]
extern crate cfg_if;

#[cfg(test)]
pub mod test_helpers;

#[deny(missing_docs)]
pub mod associations;
#[deny(missing_docs)]
pub mod backend;
#[doc(hidden)]
pub mod connection;
#[macro_use]
#[deny(missing_docs)]
pub mod expression;
#[deny(missing_docs)]
pub mod expression_methods;
#[doc(hidden)]
pub mod insertable;
#[deny(missing_docs)]
pub mod query_builder;
#[deny(missing_docs)]
#[macro_use]
pub mod types;

#[cfg(feature = "mysql")]
#[deny(missing_docs)]
pub mod mysql;
#[cfg(feature = "postgres")]
#[deny(missing_docs)]
pub mod pg;
#[cfg(feature = "sqlite")]
#[deny(missing_docs)]
pub mod sqlite;

#[deny(missing_docs)]
pub mod query_dsl;
#[deny(missing_docs)]
pub mod query_source;
#[deny(missing_docs)]
pub mod result;
#[deny(missing_docs)]
pub mod row;
mod util;

pub mod dsl {
    //! Includes various helper types and bare functions which are named too
    //! generically to be included in prelude, but are often used when using Diesel.

    #[doc(inline)]
    pub use helper_types::*;

    #[doc(inline)]
    pub use expression::dsl::*;
}

pub mod helper_types {
    //! Provide helper types for concisely writing the return type of functions.
    //! As with iterators, it is unfortunately difficult to return a partially
    //! constructed query without exposing the exact implementation of the
    //! function. Without higher kinded types, these various DSLs can't be
    //! combined into a single trait for boxing purposes.
    //!
    //! All types here are in the form `<FirstType as
    //! DslName<OtherTypes>>::Output`. So the return type of
    //! `users.filter(first_name.eq("John")).order(last_name.asc()).limit(10)` would
    //! be `Limit<Order<FindBy<users, first_name, &str>, Asc<last_name>>>`
    use super::query_dsl::*;
    use super::query_dsl::methods::*;
    use super::query_source::joins;

    #[doc(inline)]
    pub use expression::helper_types::*;

    /// Represents the return type of `.select(selection)`
    pub type Select<Source, Selection> = <Source as SelectDsl<Selection>>::Output;

    /// Represents the return type of `.filter(predicate)`
    pub type Filter<Source, Predicate> = <Source as FilterDsl<Predicate>>::Output;

    /// Represents the return type of `.filter(lhs.eq(rhs))`
    pub type FindBy<Source, Column, Value> = Filter<Source, Eq<Column, Value>>;

    /// Represents the return type of `.for_update()`
    pub type ForUpdate<Source> = <Source as ForUpdateDsl>::Output;

    /// Represents the return type of `.find(pk)`
    pub type Find<Source, PK> = <Source as FindDsl<PK>>::Output;

    /// Represents the return type of `.order(ordering)`
    pub type Order<Source, Ordering> = <Source as OrderDsl<Ordering>>::Output;

    /// Represents the return type of `.limit()`
    pub type Limit<Source> = <Source as LimitDsl>::Output;

    /// Represents the return type of `.offset()`
    pub type Offset<Source> = <Source as OffsetDsl>::Output;

    /// Represents the return type of `.inner_join(rhs)`
    pub type InnerJoin<Source, Rhs> =
        <Source as JoinWithImplicitOnClause<Rhs, joins::Inner>>::Output;

    /// Represents the return type of `.left_join(rhs)`
    pub type LeftJoin<Source, Rhs> =
        <Source as JoinWithImplicitOnClause<Rhs, joins::LeftOuter>>::Output;

    use super::associations::HasTable;
    use super::query_builder::{AsChangeset, IntoUpdateTarget, UpdateStatement};
    /// Represents the return type of `update(lhs).set(rhs)`
    pub type Update<Target, Changes> = UpdateStatement<
        <Target as HasTable>::Table,
        <Target as IntoUpdateTarget>::WhereClause,
        <Changes as AsChangeset>::Changeset,
    >;

    /// Represents the return type of `.into_boxed::<'a, DB>()`
    pub type IntoBoxed<'a, Source, DB> = <Source as BoxedDsl<'a, DB>>::Output;

    /// Represents the return type of `.distinct()`
    pub type Distinct<Source> = <Source as DistinctDsl>::Output;

    /// Represents the return type of `.distinct_on(expr)`
    #[cfg(feature = "postgres")]
    pub type DistinctOn<Source, Expr> = <Source as DistinctOnDsl<Expr>>::Output;
}

pub mod prelude {
    //! Re-exports important traits and types. Meant to be glob imported when using Diesel.
    pub use associations::{GroupedBy, Identifiable};
    pub use connection::Connection;
    pub use expression::{AppearsOnTable, BoxableExpression, Expression, IntoSql,
                         SelectableExpression};
    pub use expression_methods::*;
    #[doc(inline)]
    pub use insertable::Insertable;
    #[doc(hidden)]
    pub use query_dsl::GroupByDsl;
    pub use query_dsl::{BelongingToDsl, JoinOnDsl, QueryDsl, RunQueryDsl, SaveChangesDsl};

    pub use query_source::{Column, JoinTo, QuerySource, Queryable, Table};
    pub use result::{ConnectionError, ConnectionResult, OptionalExtension, QueryResult};

    #[cfg(feature = "postgres")]
    pub use pg::PgConnection;
    #[cfg(feature = "sqlite")]
    pub use sqlite::SqliteConnection;
    #[cfg(feature = "mysql")]
    pub use mysql::MysqlConnection;
}

pub use prelude::*;
#[doc(inline)]
pub use query_builder::debug_query;
#[doc(inline)]
pub use query_builder::functions::{delete, insert_into, replace_into, select, sql_query, update};
pub use result::Error::NotFound;
#[doc(inline)]
pub use types::structs::data_types;
<|endoftext|>


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

<%namespace name="helpers" file="/helpers.mako.rs" />

<% data.new_style_struct("Table", inherited=False) %>

${helpers.single_keyword("table-layout", "auto fixed",
                         gecko_ffi_name="mLayoutStrategy", animatable=False)}
<commit_msg>Add spec links for table properties<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

<% data.new_style_struct("Table", inherited=False) %>

${helpers.single_keyword("table-layout", "auto fixed",
                         gecko_ffi_name="mLayoutStrategy", animatable=False,
                         spec="https://drafts.csswg.org/css-tables/#propdef-table-layout")}
<|endoftext|>


<commit_before>use typedef::*;

/// A preamble to identify bakervm images
pub const PREAMBLE: &str = "BAKER1";

/// Stops the program and shuts down the vm
///
/// # Example
///
/// ```
/// halt
/// ```
pub const HALT: Byte = 0x01;

/// Adds the two top most values and pushes the result back to the data stack.
/// This also removes the processed values from the data stack.
///
/// # Example
///
/// ```
/// add
/// ```
pub const ADD: Byte = 0x02;

/// Subtracts the first value on the data stack from the second and pushes the
/// result back to the data stack. This also removes the processed values from
/// the data stack.
///
/// # Example
///
/// ```
/// sub
/// ```
pub const SUB: Byte = 0x03;

/// Adds the two top most values and pushes the result back to the data stack.
/// This also removes the processed values from the data stack.
///
/// # Example
///
/// ```
/// mul
/// ```
pub const MUL: Byte = 0x04;

/// Divides the second value on the data stack throuh the first one and pushes
/// the result back to the top of the data stack. This also removes the
/// processed values from the data stack.
///
/// # Example
///
/// ```
/// div
/// ```
pub const DIV: Byte = 0x05;

/// Prints out the top most value on the data stack
#[deprecated(since="0.1.0", note="will be replaced soon")]
pub const PRINT: Byte = 0x06;

/// Pushes a value (Word) to the data stack
///
/// # Example
///
/// ```
/// push WORD
/// ```
pub const PUSH: Byte = 0x07;

/// An unconditional jump to the specified address
///
/// # Example
///
/// ```
/// jmp ADDRESS
/// ```
pub const JMP: Byte = 0x08;

/// Jumps to the specified address if the top most value on the data stack
/// equals 0
///
/// # Example
///
/// ```
/// jz ADDRESS
/// ```
pub const JZ: Byte = 0x09;

/// Jumps to the specified address if the top most value on the data stack is
/// not equal to 0
///
/// # Example
///
/// ```
/// jnz ADDRESS
/// ```
pub const JNZ: Byte = 0x0A;

/// Moves the specified value (Word) to the specified register (Address)
///
/// # Example
///
/// ```
/// movw WORD, ADDRESS
/// ```
pub const MOVW: Byte = 0x0B;

/// Moves the specified value (SmallWord) to the specified register (Address)
///
/// # Example
///
/// ```
/// movs SMALLWORD, ADDRESS
/// ```
pub const MOVS: Byte = 0x0C;

/// Moves the specified value (TinyWord) to the specified register (Address)
///
/// # Example
///
/// ```
/// movt TINYWORD, ADDRESS
/// ```
pub const MOVT: Byte = 0x0D;

/// Moves the specified value (Byte) to the specified register (Address)
///
/// # Example
///
/// ```
/// movb BYTE, ADDRESS
/// ```
pub const MOVB: Byte = 0x0E;

/// Moves the value in the specified buffer register (Address) to the otherwise
/// specified buffer register (Address)
///
/// # Example
///
/// ```
/// mov ADDRESS, ADDRESS
/// ```
pub const MOV: Byte = 0x0F;

/// Moves the top most value of the data stack to the specified register
/// (Address)
///
/// # Example
///
/// ```
/// smov ADDRESS
/// ```
pub const SMOV: Byte = 0x10;

/// Registers an interrupt callback by mapping the specified signal_id to the
/// given function call address
///
/// # Example
///
/// ```
/// regi WORD, ADDRESS
/// ```
pub const REGI: Byte = 0x11;

/// Calls a function while pushing the return address to the return stack
///
/// # Example
///
/// ```
/// call ADDRESS
/// ```
pub const CALL: Byte = 0x12;

/// Returns from a function. The return value is pushed to the data stack
///
/// # Example
///
/// ```
/// ret
/// ```
pub const RET: Byte = 0x13;

/// Pushes a value from the data stack as a return value to the return value
/// stack. This also tracks the number of return values yielded when `ret` is
/// called
///
/// # Examples
///
/// ```
/// yld
/// ```
pub const YLD: Byte = 0x14;
<commit_msg>ignore doc tests<commit_after>use typedef::*;

/// A preamble to identify bakervm images
pub const PREAMBLE: &str = "BAKER1";

/// Stops the program and shuts down the vm
///
/// # Example
///
/// ```ignore
/// halt
/// ```
pub const HALT: Byte = 0x01;

/// Adds the two top most values and pushes the result back to the data stack.
/// This also removes the processed values from the data stack.
///
/// # Example
///
/// ```ignore
/// add
/// ```
pub const ADD: Byte = 0x02;

/// Subtracts the first value on the data stack from the second and pushes the
/// result back to the data stack. This also removes the processed values from
/// the data stack.
///
/// # Example
///
/// ```ignore
/// sub
/// ```
pub const SUB: Byte = 0x03;

/// Adds the two top most values and pushes the result back to the data stack.
/// This also removes the processed values from the data stack.
///
/// # Example
///
/// ```ignore
/// mul
/// ```
pub const MUL: Byte = 0x04;

/// Divides the second value on the data stack throuh the first one and pushes
/// the result back to the top of the data stack. This also removes the
/// processed values from the data stack.
///
/// # Example
///
/// ```ignore
/// div
/// ```
pub const DIV: Byte = 0x05;

/// Prints out the top most value on the data stack
#[deprecated(since="0.1.0", note="will be replaced soon")]
pub const PRINT: Byte = 0x06;

/// Pushes a value (Word) to the data stack
///
/// # Example
///
/// ```ignore
/// push WORD
/// ```
pub const PUSH: Byte = 0x07;

/// An unconditional jump to the specified address
///
/// # Example
///
/// ```ignore
/// jmp ADDRESS
/// ```
pub const JMP: Byte = 0x08;

/// Jumps to the specified address if the top most value on the data stack
/// equals 0
///
/// # Example
///
/// ```ignore
/// jz ADDRESS
/// ```
pub const JZ: Byte = 0x09;

/// Jumps to the specified address if the top most value on the data stack is
/// not equal to 0
///
/// # Example
///
/// ```ignore
/// jnz ADDRESS
/// ```
pub const JNZ: Byte = 0x0A;

/// Moves the specified value (Word) to the specified register (Address)
///
/// # Example
///
/// ```ignore
/// movw WORD, ADDRESS
/// ```
pub const MOVW: Byte = 0x0B;

/// Moves the specified value (SmallWord) to the specified register (Address)
///
/// # Example
///
/// ```ignore
/// movs SMALLWORD, ADDRESS
/// ```
pub const MOVS: Byte = 0x0C;

/// Moves the specified value (TinyWord) to the specified register (Address)
///
/// # Example
///
/// ```ignore
/// movt TINYWORD, ADDRESS
/// ```
pub const MOVT: Byte = 0x0D;

/// Moves the specified value (Byte) to the specified register (Address)
///
/// # Example
///
/// ```ignore
/// movb BYTE, ADDRESS
/// ```
pub const MOVB: Byte = 0x0E;

/// Moves the value in the specified buffer register (Address) to the otherwise
/// specified buffer register (Address)
///
/// # Example
///
/// ```ignore
/// mov ADDRESS, ADDRESS
/// ```
pub const MOV: Byte = 0x0F;

/// Moves the top most value of the data stack to the specified register
/// (Address)
///
/// # Example
///
/// ```ignore
/// smov ADDRESS
/// ```
pub const SMOV: Byte = 0x10;

/// Registers an interrupt callback by mapping the specified signal_id to the
/// given function call address
///
/// # Example
///
/// ```ignore
/// regi WORD, ADDRESS
/// ```
pub const REGI: Byte = 0x11;

/// Calls a function while pushing the return address to the return stack
///
/// # Example
///
/// ```ignore
/// call ADDRESS
/// ```
pub const CALL: Byte = 0x12;

/// Returns from a function. The return value is pushed to the data stack
///
/// # Example
///
/// ```ignore
/// ret
/// ```
pub const RET: Byte = 0x13;

/// Pushes a value from the data stack as a return value to the return value
/// stack. This also tracks the number of return values yielded when `ret` is
/// called
///
/// # Examples
///
/// ```ignore
/// yld
/// ```
pub const YLD: Byte = 0x14;
<|endoftext|>