<commit_before>extern crate polydraw;

use std::cmp::{Ordering, min, max};
use std::i64;

use polydraw::geom::point::Point;
use polydraw::{Application, Renderer, Frame};
use polydraw::raster::{Scene, Rasterizer, EdgeType, Poly, create_default_vec};

#[derive(Debug, Clone, Copy)]
pub struct Edge {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
}

impl Edge {
   #[inline]
   pub fn new(edge_type: EdgeType, x1: i64, y1: i64, x2: i64, y2: i64) -> Self {
      Edge {
         edge_type: edge_type,
         p1: Point::new(x1, y1),
         p2: Point::new(x2, y2),
      }
   }

   #[inline]
   pub fn vert_top(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVT, x1, y1, x2, y2)
   }

   #[inline]
   pub fn vert_bottom(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVB, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBL, x1, y1, x2, y2)
   }
}

#[derive(Debug, Clone, Copy, Default)]
pub struct Section {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
   pub edge: usize,
   pub poly: usize,
}

impl Section {
   fn set_bottom(&mut self, point: &Point) {
      if self.edge_type.reversed() {
         self.p2 = *point;
      } else {
         self.p1 = *point;
      }
   }

   fn set_top(&mut self, point: &Point) {
      if self.edge_type.reversed() {
         self.p1 = *point;
      } else {
         self.p2 = *point;
      }
   }
}

struct ClipRenderer {
   rasterizer: Rasterizer,
   div_per_pixel: i64,

   edges: Vec<Edge>,
   polys: Vec<Poly>,

   sections: Vec<Section>,
   sections_end: usize,

   sections_min_y: Vec<i64>,
   sections_max_y: Vec<i64>,
   sections_order: Vec<usize>,

   active: Vec<Section>,
   active_source: Vec<usize>,
   active_end: usize,
}

impl ClipRenderer {
   fn new() -> Self {
      let div_per_pixel = 1000;

      let mut edges = vec![
         Edge::top_left(5, 1, 1, 6),       // 0
         Edge::top_right(1, 6, 8, 9),      // 1
         Edge::bottom_right(8, 9, 9, 6),   // 2
         Edge::bottom_left(9, 6, 5, 1),    // 3
         Edge::top_right(1, 1, 3, 8),      // 4
         Edge::bottom_right(3, 8, 10, 4),  // 5
         Edge::bottom_left(10, 4, 1, 1),   // 6
      ];

      for edge in edges.iter_mut() {
         edge.p1.x *= div_per_pixel;
         edge.p1.y *= div_per_pixel;
         edge.p2.x *= div_per_pixel;
         edge.p2.y *= div_per_pixel;
      }

      let polys = vec![
         Poly::new(0, 4, 0),    // 0
         Poly::new(4, 7, 1),    // 1
      ];

      let sections = create_default_vec(65536);

      let sections_min_y = create_default_vec(65536);
      let sections_max_y = create_default_vec(65536);
      let sections_order = create_default_vec(65536);

      let active = create_default_vec(65536);
      let active_source = create_default_vec(65536);

      ClipRenderer {
         rasterizer: Rasterizer::new(),
         div_per_pixel: div_per_pixel,

         edges: edges,
         polys: polys,

         sections: sections,
         sections_end: 0,

         sections_min_y: sections_min_y,
         sections_max_y: sections_max_y,
         sections_order: sections_order,

         active: active,
         active_source: active_source,
         active_end: 0,
      }
   }

   fn create_scene(&self) -> Scene {
      let points = vec![];

      let segments = vec![];

      let circles = vec![];

      let edges = vec![];

      let polys = vec![];

      let colors = vec![];

      Scene {
         points: points,
         segments: segments,
         circles: circles,
         edges: edges,
         polys: polys,
         colors: colors,
      }
   }

   fn eval_sections_min_max_y(&mut self) {
      for section_index in 0..self.sections_end {
         let ref section = self.sections[section_index];

         let mut min_y = i64::MAX;
         let mut max_y = i64::MIN;

         let (section_min_y, section_max_y) = if section.edge_type.reversed() {
            (section.p2.y, section.p1.y)
         } else {
            (section.p1.y, section.p2.y)
         };

         if section_min_y < min_y  {
            min_y = section_min_y;
         }

         if section_max_y > max_y {
            max_y = section_max_y;
         }

         self.sections_min_y[section_index] = min_y;
         self.sections_max_y[section_index] = max_y;
         self.sections_order[section_index] = section_index;
      }

      self.sort_sections_order();

      println!("MIN Y {:?}", &self.sections_min_y[..self.sections_end]);
      println!("MAX Y {:?}", &self.sections_max_y[..self.sections_end]);
      println!("ORDER {:?}", &self.sections_order[..self.sections_end]);

      self.iterate_sections();
   }

   fn sort_sections_order(&mut self) {
      let sections_order = &mut self.sections_order[..self.sections_end];
      let sections_min_y = &self.sections_min_y;
      let sections_max_y = &self.sections_max_y;

      sections_order.sort_by(|a, b| {
         match sections_min_y[*a].cmp(&sections_min_y[*b]) {
            Ordering::Less => Ordering::Less,
            Ordering::Greater => Ordering::Greater,
            Ordering::Equal => sections_max_y[*a].cmp(&sections_max_y[*b])
         }
      });
   }

   fn iterate_sections(&self) {
      let mut prev_y = i64::MIN;
      for order_index in 0..self.sections_end {
         let section_index = self.sections_order[order_index];
         let min_y = self.sections_min_y[section_index];

         println!("I MIN Y {:?} {:?}", section_index, min_y);

         if min_y != prev_y {
            println!("HOR {:?}", min_y);
            prev_y = min_y;
         }
      }
   }

   fn transfer_sections(&mut self) {
      self.sections_end = 0;

      for poly_index in 0..self.polys.len() {
         let ref poly = self.polys[poly_index];

         for edge_index in poly.start..poly.end {
            let ref edge = self.edges[edge_index];

            self.sections[self.sections_end] = Section {
               edge_type: edge.edge_type,
               p1: edge.p1,
               p2: edge.p2,
               edge: edge_index,
               poly: poly_index,
            };

            self.sections_end += 1;
         }
      }

      println!("SECTIONS {:?}", &self.sections[..self.sections_end]);
   }

   fn clip_sections(&mut self) {
      let sections_target = self.sections_order[0];
      let sections_clipper = self.sections_order[1];

      let active_target = self.copy_to_active(sections_target);
      let active_clipper = self.copy_to_active(sections_clipper);

      println!("TARGET {:?}", self.active[active_target]);
      println!("CLIPPER {:?}", self.active[active_clipper]);

      let intersection = self.intersect_sections(
         &self.active[active_target],
         &self.active[active_clipper]
      );
      println!("INTERSECTION {:?}", intersection);

      match intersection {
         Some(pt) => {
            self.sections[sections_target].set_bottom(&pt);
            self.sections[sections_clipper].set_bottom(&pt);

            self.active[active_target].set_top(&pt);
            self.active[active_clipper].set_top(&pt);
         },
         None => {}
      }

      for index in 0..self.sections_end {
         println!("SECTIONS [{}] - {:?}", index, self.sections[index]);
      }

      for index in 0..self.active_end {
         println!("ACTIVE   [{}] - {:?}", index, self.active[index]);
      }
   }

   fn copy_to_active(&mut self, sections_index: usize) -> usize {
      let active_index = self.active_end;

      self.active_source[active_index] = sections_index;
      self.active[active_index] = self.sections[sections_index];

      self.active_end += 1;

      active_index
   }

   fn intersect_sections(&self, s1: &Section, s2: &Section) -> Option<Point> {
      let s1_a = (s1.p2.y - s1.p1.y) as f64;
      let s1_b = (s1.p1.x - s1.p2.x) as f64;
      let s1_c = (s1.p2.x * s1.p1.y - s1.p1.x * s1.p2.y) as f64;

      let s2_a = (s2.p2.y - s2.p1.y) as f64;
      let s2_b = (s2.p1.x - s2.p2.x) as f64;
      let s2_c = (s2.p2.x * s2.p1.y - s2.p1.x * s2.p2.y) as f64;

      let denominator = s1_a * s2_b - s2_a * s1_b;

      if denominator == 0. {
         return None;
      }

      let x = (s2_c * s1_b - s1_c * s2_b) / denominator;
      let y = (s2_a * s1_c - s1_a * s2_c) / denominator;

      let x = x.round() as i64;
      let y = y.round() as i64;

      let x1 = max(min(s1.p1.x, s1.p2.x), min(s2.p1.x, s2.p2.x));
      let x2 = min(max(s1.p1.x, s1.p2.x), max(s2.p1.x, s2.p2.x));
      let y1 = max(min(s1.p1.y, s1.p2.y), min(s2.p1.y, s2.p2.y));
      let y2 = min(max(s1.p1.y, s1.p2.y), max(s2.p1.y, s2.p2.y));

      if x < x1 || x > x2 || y < y1 || y > y2 {
         return None;
      }

      return Some(Point::new(x, y));
   }
}

impl Renderer for ClipRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.transfer_sections();

      self.eval_sections_min_max_y();

      self.clip_sections();

      let scene = self.create_scene();

      self.rasterizer.render(&scene, frame, self.div_per_pixel);

      panic!("END");
   }
}

fn main() {
   let mut renderer = ClipRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Clip")
      .run();
}
<commit_msg>Section min y resorting method<commit_after>extern crate polydraw;

use std::cmp::{Ordering, min, max};
use std::i64;

use polydraw::geom::point::Point;
use polydraw::{Application, Renderer, Frame};
use polydraw::raster::{Scene, Rasterizer, EdgeType, Poly, create_default_vec};

#[derive(Debug, Clone, Copy)]
pub struct Edge {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
}

impl Edge {
   #[inline]
   pub fn new(edge_type: EdgeType, x1: i64, y1: i64, x2: i64, y2: i64) -> Self {
      Edge {
         edge_type: edge_type,
         p1: Point::new(x1, y1),
         p2: Point::new(x2, y2),
      }
   }

   #[inline]
   pub fn vert_top(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVT, x1, y1, x2, y2)
   }

   #[inline]
   pub fn vert_bottom(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVB, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBL, x1, y1, x2, y2)
   }
}

#[derive(Debug, Clone, Copy, Default)]
pub struct Section {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
   pub edge: usize,
   pub poly: usize,
}

impl Section {
   fn set_bottom(&mut self, point: &Point) {
      if self.edge_type.reversed() {
         self.p2 = *point;
      } else {
         self.p1 = *point;
      }
   }

   fn set_top(&mut self, point: &Point) {
      if self.edge_type.reversed() {
         self.p1 = *point;
      } else {
         self.p2 = *point;
      }
   }
}

struct ClipRenderer {
   rasterizer: Rasterizer,
   div_per_pixel: i64,

   edges: Vec<Edge>,
   polys: Vec<Poly>,

   sections: Vec<Section>,
   sections_end: usize,

   sections_min_y: Vec<i64>,
   sections_max_y: Vec<i64>,
   sections_order: Vec<usize>,

   active: Vec<Section>,
   active_source: Vec<usize>,
   active_end: usize,
}

impl ClipRenderer {
   fn new() -> Self {
      let div_per_pixel = 1000;

      let mut edges = vec![
         Edge::top_left(5, 1, 1, 6),       // 0
         Edge::top_right(1, 6, 8, 9),      // 1
         Edge::bottom_right(8, 9, 9, 6),   // 2
         Edge::bottom_left(9, 6, 5, 1),    // 3
         Edge::top_right(1, 1, 3, 8),      // 4
         Edge::bottom_right(3, 8, 10, 4),  // 5
         Edge::bottom_left(10, 4, 1, 1),   // 6
      ];

      for edge in edges.iter_mut() {
         edge.p1.x *= div_per_pixel;
         edge.p1.y *= div_per_pixel;
         edge.p2.x *= div_per_pixel;
         edge.p2.y *= div_per_pixel;
      }

      let polys = vec![
         Poly::new(0, 4, 0),    // 0
         Poly::new(4, 7, 1),    // 1
      ];

      let sections = create_default_vec(65536);

      let sections_min_y = create_default_vec(65536);
      let sections_max_y = create_default_vec(65536);
      let sections_order = create_default_vec(65536);

      let active = create_default_vec(65536);
      let active_source = create_default_vec(65536);

      ClipRenderer {
         rasterizer: Rasterizer::new(),
         div_per_pixel: div_per_pixel,

         edges: edges,
         polys: polys,

         sections: sections,
         sections_end: 0,

         sections_min_y: sections_min_y,
         sections_max_y: sections_max_y,
         sections_order: sections_order,

         active: active,
         active_source: active_source,
         active_end: 0,
      }
   }

   fn create_scene(&self) -> Scene {
      let points = vec![];

      let segments = vec![];

      let circles = vec![];

      let edges = vec![];

      let polys = vec![];

      let colors = vec![];

      Scene {
         points: points,
         segments: segments,
         circles: circles,
         edges: edges,
         polys: polys,
         colors: colors,
      }
   }

   fn eval_sections_min_max_y(&mut self) {
      for section_index in 0..self.sections_end {
         let ref section = self.sections[section_index];

         let mut min_y = i64::MAX;
         let mut max_y = i64::MIN;

         let (section_min_y, section_max_y) = if section.edge_type.reversed() {
            (section.p2.y, section.p1.y)
         } else {
            (section.p1.y, section.p2.y)
         };

         if section_min_y < min_y  {
            min_y = section_min_y;
         }

         if section_max_y > max_y {
            max_y = section_max_y;
         }

         self.sections_min_y[section_index] = min_y;
         self.sections_max_y[section_index] = max_y;
         self.sections_order[section_index] = section_index;
      }

      self.sort_sections_order();

      println!("MIN Y {:?}", &self.sections_min_y[..self.sections_end]);
      println!("MAX Y {:?}", &self.sections_max_y[..self.sections_end]);
      println!("ORDER {:?}", &self.sections_order[..self.sections_end]);

      self.iterate_sections();
   }

   fn sort_sections_order(&mut self) {
      let sections_order = &mut self.sections_order[..self.sections_end];
      let sections_min_y = &self.sections_min_y;
      let sections_max_y = &self.sections_max_y;

      sections_order.sort_by(|a, b| {
         match sections_min_y[*a].cmp(&sections_min_y[*b]) {
            Ordering::Less => Ordering::Less,
            Ordering::Greater => Ordering::Greater,
            Ordering::Equal => sections_max_y[*a].cmp(&sections_max_y[*b])
         }
      });
   }

   fn iterate_sections(&self) {
      let mut prev_y = i64::MIN;
      for order_index in 0..self.sections_end {
         let section_index = self.sections_order[order_index];
         let min_y = self.sections_min_y[section_index];

         println!("I MIN Y {:?} {:?}", section_index, min_y);

         if min_y != prev_y {
            println!("HOR {:?}", min_y);
            prev_y = min_y;
         }
      }
   }

   fn transfer_sections(&mut self) {
      self.sections_end = 0;

      for poly_index in 0..self.polys.len() {
         let ref poly = self.polys[poly_index];

         for edge_index in poly.start..poly.end {
            let ref edge = self.edges[edge_index];

            self.sections[self.sections_end] = Section {
               edge_type: edge.edge_type,
               p1: edge.p1,
               p2: edge.p2,
               edge: edge_index,
               poly: poly_index,
            };

            self.sections_end += 1;
         }
      }

      println!("SECTIONS {:?}", &self.sections[..self.sections_end]);
   }

   fn clip_sections(&mut self) {
      let sections_target = self.sections_order[0];
      let sections_clipper = self.sections_order[1];

      let active_target = self.copy_to_active(sections_target);
      let active_clipper = self.copy_to_active(sections_clipper);

      println!("TARGET {:?}", self.active[active_target]);
      println!("CLIPPER {:?}", self.active[active_clipper]);

      let intersection = self.intersect_sections(
         &self.active[active_target],
         &self.active[active_clipper]
      );
      println!("INTERSECTION {:?}", intersection);

      match intersection {
         Some(pt) => {
            self.sections[sections_clipper].set_bottom(&pt);
            self.change_section_order(1, pt.y);

            self.sections[sections_target].set_bottom(&pt);
            self.change_section_order(0, pt.y);

            self.active[active_target].set_top(&pt);
            self.active[active_clipper].set_top(&pt);
         },
         None => {}
      }

      for index in 0..self.sections_end {
         println!("SECTIONS [{}] - {:?}", index, self.sections[index]);
      }

      for index in 0..self.active_end {
         println!("ACTIVE   [{}] - {:?}", index, self.active[index]);
      }
   }

   fn copy_to_active(&mut self, sections_index: usize) -> usize {
      let active_index = self.active_end;

      self.active_source[active_index] = sections_index;
      self.active[active_index] = self.sections[sections_index];

      self.active_end += 1;

      active_index
   }

   fn change_section_order(&mut self, order_index: usize, new_min_y: i64) {
      println!("NEW MIN Y {:?}", new_min_y);

      let sections_index = self.sections_order[order_index];
      self.sections_min_y[sections_index] = new_min_y;

      let mut current_order_index = order_index;
      let mut next_order_index = order_index + 1;

      while next_order_index < self.sections_end {
         let next_index = self.sections_order[next_order_index];

         if new_min_y > self.sections_min_y[next_index] {
            self.sections_order[current_order_index] = next_index;
            println!("Passing {:?} / {:?}", next_index, self.sections_min_y[next_index]);
         } else {
            break;
         }

         current_order_index = next_order_index;
         next_order_index += 1;
      }

      if current_order_index != order_index {
         self.sections_order[current_order_index] = sections_index;
         println!("Setting {:?}", sections_index);
      }

      for i in 0..self.sections_end {
         let si = self.sections_order[i];
         let min_y = self.sections_min_y[si];
         println!("[I] {:?} {:?} {:?}", i, si, min_y);
      }
   }

   fn intersect_sections(&self, s1: &Section, s2: &Section) -> Option<Point> {
      let s1_a = (s1.p2.y - s1.p1.y) as f64;
      let s1_b = (s1.p1.x - s1.p2.x) as f64;
      let s1_c = (s1.p2.x * s1.p1.y - s1.p1.x * s1.p2.y) as f64;

      let s2_a = (s2.p2.y - s2.p1.y) as f64;
      let s2_b = (s2.p1.x - s2.p2.x) as f64;
      let s2_c = (s2.p2.x * s2.p1.y - s2.p1.x * s2.p2.y) as f64;

      let denominator = s1_a * s2_b - s2_a * s1_b;

      if denominator == 0. {
         return None;
      }

      let x = (s2_c * s1_b - s1_c * s2_b) / denominator;
      let y = (s2_a * s1_c - s1_a * s2_c) / denominator;

      let x = x.round() as i64;
      let y = y.round() as i64;

      let x1 = max(min(s1.p1.x, s1.p2.x), min(s2.p1.x, s2.p2.x));
      let x2 = min(max(s1.p1.x, s1.p2.x), max(s2.p1.x, s2.p2.x));
      let y1 = max(min(s1.p1.y, s1.p2.y), min(s2.p1.y, s2.p2.y));
      let y2 = min(max(s1.p1.y, s1.p2.y), max(s2.p1.y, s2.p2.y));

      if x < x1 || x > x2 || y < y1 || y > y2 {
         return None;
      }

      return Some(Point::new(x, y));
   }
}

impl Renderer for ClipRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.transfer_sections();

      self.eval_sections_min_max_y();

      self.clip_sections();

      let scene = self.create_scene();

      self.rasterizer.render(&scene, frame, self.div_per_pixel);

      panic!("END");
   }
}

fn main() {
   let mut renderer = ClipRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Clip")
      .run();
}
<|endoftext|>


<commit_before>extern crate piston_window;
extern crate vecmath;
extern crate camera_controllers;
#[macro_use]
extern crate gfx;
extern crate gfx_device_gl;
extern crate sdl2_window;

use sdl2_window::Sdl2Window;
use piston_window::*;
use camera_controllers::{
    FirstPersonSettings,
    FirstPerson,
    CameraPerspective,
    model_view_projection
};
use gfx::attrib::Floater;
use gfx::traits::*;

//----------------------------------------
// Cube associated data

gfx_vertex!( Vertex {
    a_pos@ a_pos: [Floater<i8>; 3],
    a_tex_coord@ a_tex_coord: [Floater<u8>; 2],
});

impl Vertex {
    fn new(pos: [i8; 3], tc: [u8; 2]) -> Vertex {
        Vertex {
            a_pos: Floater::cast3(pos),
            a_tex_coord: Floater::cast2(tc),
        }
    }
}

gfx_parameters!( Params {
    u_model_view_proj@ u_model_view_proj: [[f32; 4]; 4],
    t_color@ t_color: gfx::shade::TextureParam<R>,
});

//----------------------------------------

fn main() {
    let mut events: PistonWindow<Sdl2Window> =
        WindowSettings::new("piston: cube", [640, 480])
        .exit_on_esc(true)
        .samples(4)
        .into();
    events.set_capture_cursor(true);

    let ref mut factory = events.factory.borrow().clone();

    let vertex_data = vec![
        //top (0, 0, 1)
        Vertex::new([-1, -1,  1], [0, 0]),
        Vertex::new([ 1, -1,  1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //bottom (0, 0, -1)
        Vertex::new([ 1,  1, -1], [0, 0]),
        Vertex::new([-1,  1, -1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
        //right (1, 0, 0)
        Vertex::new([ 1, -1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([ 1, -1,  1], [0, 1]),
        //left (-1, 0, 0)
        Vertex::new([-1,  1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([-1,  1, -1], [0, 1]),
        //front (0, 1, 0)
        Vertex::new([-1,  1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //back (0, -1, 0)
        Vertex::new([ 1, -1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
    ];

    let mesh = factory.create_mesh(&vertex_data);

    let index_data: &[u8] = &[
         0,  1,  2,  2,  3,  0, // top
         4,  6,  5,  6,  4,  7, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 14, 13, 14, 12, 16, // left
        16, 18, 17, 18, 16, 19, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = index_data.to_slice(factory, gfx::PrimitiveType::TriangleList);

    let texture = factory.create_texture_rgba8_static(1, 1, &[0x00_C0_A0_20]).unwrap();

    let sampler = factory.create_sampler(
        gfx::tex::SamplerInfo::new(gfx::tex::FilterMethod::Bilinear,
                                   gfx::tex::WrapMode::Clamp)
    );

    let program = {
        let vertex = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("../assets/cube_120.glslv")),
            glsl_150: Some(include_bytes!("../assets/cube_150.glslv")),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("../assets/cube_120.glslf")),
            glsl_150: Some(include_bytes!("../assets/cube_150.glslf")),
            .. gfx::ShaderSource::empty()
        };
        factory.link_program_source(vertex, fragment).unwrap()
    };

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
        _r: std::marker::PhantomData,
    };

    let get_projection = |w: &PistonWindow<Sdl2Window>| {
        let draw_size = w.window.borrow().draw_size();
        CameraPerspective {
            fov: 90.0, near_clip: 0.1, far_clip: 1000.0,
            aspect_ratio: (draw_size.width as f32) / (draw_size.height as f32)
        }.projection()
    };

    let model = vecmath::mat4_id();
    let mut projection = get_projection(&events);
    let mut first_person = FirstPerson::new(
        [0.5, 0.5, 4.0],
        FirstPersonSettings::keyboard_wasd()
    );
    let state = gfx::DrawState::new().depth(gfx::state::Comparison::LessEqual, true);

    for e in events {
        first_person.event(&e);

        e.draw_3d(|stream| {
            let args = e.render_args().unwrap();
            stream.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                }
            );
            data.u_model_view_proj = model_view_projection(
                model,
                first_person.camera(args.ext_dt).orthogonal(),
                projection
            );
            stream.draw(&(&mesh, slice.clone(), &program, &data, &state)).unwrap();
        });

        if let Some(_) = e.resize_args() {
            projection = get_projection(&e);
        }
    }
}
<commit_msg>Reading vertices from cube.ogex<commit_after>extern crate piston_window;
extern crate vecmath;
extern crate camera_controllers;
#[macro_use]
extern crate gfx;
extern crate gfx_device_gl;
extern crate sdl2_window;
extern crate piston_meta;

use std::fs::File;
use std::io::Read;
use sdl2_window::Sdl2Window;
use piston_window::*;
use camera_controllers::{
    FirstPersonSettings,
    FirstPerson,
    CameraPerspective,
    model_view_projection
};
use gfx::traits::*;
use piston_meta::*;

//----------------------------------------
// Cube associated data

gfx_vertex!( Vertex {
    a_pos@ a_pos: [f32; 3],
    a_tex_coord@ a_tex_coord: [f32; 2],
});

impl Vertex {
    fn new(pos: [f32; 3], tc: [f32; 2]) -> Vertex {
        Vertex {
            a_pos: pos,
            a_tex_coord: tc,
        }
    }
}

gfx_parameters!( Params {
    u_model_view_proj@ u_model_view_proj: [[f32; 4]; 4],
    t_color@ t_color: gfx::shade::TextureParam<R>,
});

//----------------------------------------

fn main() {
    let mut events: PistonWindow<Sdl2Window> =
        WindowSettings::new("piston: cube", [640, 480])
        .exit_on_esc(true)
        .samples(4)
        .into();
    events.set_capture_cursor(true);

    let ref mut factory = events.factory.borrow().clone();

    // Read OpenGEX meta rules.
    let mut file_h = File::open("assets/opengex-syntax.txt").unwrap();
    let mut source = String::new();
    file_h.read_to_string(&mut source).unwrap();
    let rules = stderr_unwrap(&source, syntax(&source));

    // Read cube.ogex.
    let mut file_h = File::open("assets/cube.ogex").unwrap();
    let mut source = String::new();
    file_h.read_to_string(&mut source).unwrap();
    let data = stderr_unwrap(&source, parse(&rules, &source));

    let v3 = |mut s: &mut Search| Ok([
        try!(s.f64("x")) as f32,
        try!(s.f64("y")) as f32,
        try!(s.f64("z")) as f32
    ]);

    let s = Search::new(&data);
    let vertex_data: Vec<Vertex> = stderr_unwrap(&source, s.for_bool("position", true,
        |ref mut s| {
        Ok(vec![
            Vertex::new(try!(v3(s)), [0.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 1.0]),
            Vertex::new(try!(v3(s)), [0.0, 1.0]),
            //bottom (0, 0, -1)
            Vertex::new(try!(v3(s)), [0.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 1.0]),
            Vertex::new(try!(v3(s)), [0.0, 1.0]),
            //right (1, 0, 0)
            Vertex::new(try!(v3(s)), [0.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 1.0]),
            Vertex::new(try!(v3(s)), [0.0, 1.0]),
            //left (-1, 0, 0)
            Vertex::new(try!(v3(s)), [0.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 1.0]),
            Vertex::new(try!(v3(s)), [0.0, 1.0]),
            //front (0, 1, 0)
            Vertex::new(try!(v3(s)), [0.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 1.0]),
            Vertex::new(try!(v3(s)), [0.0, 1.0]),
            //back (0, -1, 0)
            Vertex::new(try!(v3(s)), [0.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 0.0]),
            Vertex::new(try!(v3(s)), [1.0, 1.0]),
            Vertex::new(try!(v3(s)), [0.0, 1.0]),
        ])
    }));

    let mesh = factory.create_mesh(&vertex_data);

    let index_data: &[u8] = &[
         0,  1,  2,  2,  3,  0, // top
         4,  6,  5,  6,  4,  7, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 14, 13, 14, 12, 16, // left
        16, 18, 17, 18, 16, 19, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = index_data.to_slice(factory, gfx::PrimitiveType::TriangleList);

    let texture = factory.create_texture_rgba8_static(1, 1, &[0x00_C0_A0_20]).unwrap();

    let sampler = factory.create_sampler(
        gfx::tex::SamplerInfo::new(gfx::tex::FilterMethod::Bilinear,
                                   gfx::tex::WrapMode::Clamp)
    );

    let program = {
        let vertex = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("../assets/cube_120.glslv")),
            glsl_150: Some(include_bytes!("../assets/cube_150.glslv")),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("../assets/cube_120.glslf")),
            glsl_150: Some(include_bytes!("../assets/cube_150.glslf")),
            .. gfx::ShaderSource::empty()
        };
        factory.link_program_source(vertex, fragment).unwrap()
    };

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
        _r: std::marker::PhantomData,
    };

    let get_projection = |w: &PistonWindow<Sdl2Window>| {
        let draw_size = w.window.borrow().draw_size();
        CameraPerspective {
            fov: 90.0, near_clip: 0.1, far_clip: 1000.0,
            aspect_ratio: (draw_size.width as f32) / (draw_size.height as f32)
        }.projection()
    };

    let model = vecmath::mat4_id();
    let mut projection = get_projection(&events);
    let mut first_person = FirstPerson::new(
        [0.5, 0.5, 4.0],
        FirstPersonSettings::keyboard_wasd()
    );
    let state = gfx::DrawState::new().depth(gfx::state::Comparison::LessEqual, true);

    for e in events {
        first_person.event(&e);

        e.draw_3d(|stream| {
            let args = e.render_args().unwrap();
            stream.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                }
            );
            data.u_model_view_proj = model_view_projection(
                model,
                first_person.camera(args.ext_dt).orthogonal(),
                projection
            );
            stream.draw(&(&mesh, slice.clone(), &program, &data, &state)).unwrap();
        });

        if let Some(_) = e.resize_args() {
            projection = get_projection(&e);
        }
    }
}
<|endoftext|>


<commit_before>#![feature(core)]

extern crate portaudio;

use portaudio::*;
use std::error::Error;

const SAMPLE_RATE: f64 = 44_100.0;
const FRAMES: u32 = 256;

fn main() {

    println!("PortAudio version : {}", pa::get_version());
    println!("PortAudio version text : {}", pa::get_version_text());

    match pa::initialize() {
        Ok(()) => println!("Successfully initialized PortAudio"),
        Err(err) => println!("An error occurred while initializing PortAudio: {}", err.description()),
    }

    println!("PortAudio host count : {}", pa::host::get_api_count() as isize);

    let default_host = pa::host::get_default_api();
    println!("PortAudio default host : {}", default_host as isize);

    match pa::host::get_api_info(default_host) {
        None => println!("Couldn't retrieve api info for the default host."),
        Some(info) => println!("PortAudio host name : {}", info.name),
    }

    let type_id = pa::host::api_type_id_to_host_api_index(pa::HostApiTypeId::CoreAudio) as isize;
    println!("PortAudio type id : {}", type_id);

    let def_input = pa::device::get_default_input();
    let input_info = match pa::device::get_info(def_input) {
        Ok(info) => info,
        Err(err) => panic!("An error occurred while retrieving input info: {}", err.description()),
    };
    println!("Default input device info :");
    println!("\tversion : {}", input_info.struct_version);
    println!("\tname : {}", input_info.name);
    println!("\tmax input channels : {}", input_info.max_input_channels);
    println!("\tmax output channels : {}", input_info.max_output_channels);
    println!("\tdefault sample rate : {}", input_info.default_sample_rate);

    // Construct the input stream parameters.
    let input_stream_params = pa::StreamParameters {
        device : def_input,
        channel_count : 2,
        sample_format : pa::SampleFormat::Float32,
        suggested_latency : input_info.default_low_input_latency
    };

    let def_output = pa::device::get_default_output();
    let output_info = match pa::device::get_info(def_output) {
        Ok(info) => info,
        Err(err) => panic!("An error occurred while retrieving output info: {}", err.description()),
    };

    println!("Default output device name : {}", output_info.name);

    // Construct the output stream parameters.
    let output_stream_params = pa::StreamParameters {
        device : def_output,
        channel_count : 2,
        sample_format : pa::SampleFormat::Float32,
        suggested_latency : output_info.default_low_output_latency
    };

    let mut stream : pa::Stream<f32, f32> = pa::Stream::new();

    match stream.open(Some(&input_stream_params),
                      Some(&output_stream_params),
                      SAMPLE_RATE,
                      FRAMES,
                      pa::StreamFlags::ClipOff) {
        Ok(()) => println!("Successfully opened the stream."),
        Err(err) => println!("An error occurred while opening the stream: {}", err.description()),
    }

    match stream.start() {
        Ok(()) => println!("Successfully started the stream."),
        Err(err) => println!("An error occurred while starting the stream: {}", err.description()),
    }

    // We'll use this function to wait for read/write availability.
    fn wait_for_stream<F: Fn() -> Result<Option<i64>, pa::error::Error>>(f: F, name: &str) {
        'waiting_for_stream: loop {
            match f() {
                Ok(None) => (),
                Ok(Some(frames)) => {
                    println!("{} stream available with {} frames.", name, frames);
                    break 'waiting_for_stream
                },
                Err(err) => panic!("An error occurred while waiting for the {} stream: {}", name, err.description()),
            }
        }
    };

    // Now start the main read/write loop! In this example, we pass the input buffer directly to
    // the output buffer, so watch out for feedback.
    'stream: loop {
        wait_for_stream(|&:| stream.get_stream_read_available(), "Read");
        match stream.read(FRAMES) {
            Ok(input_samples)  => {
                wait_for_stream(|&:| stream.get_stream_write_available(), "Write");
                match stream.write(input_samples, FRAMES) {
                    Ok(()) => (),
                    Err(err) => {
                        println!("An error occurred while writing to the output stream: {}", err.description());
                        break 'stream
                    },
                }
            },
            Err(err) => {
                println!("An error occurred while reading from the input stream: {}", err.description());
                break 'stream
            }
        };
    }

    match stream.close() {
        Ok(()) => println!("Successfully closed the stream."),
        Err(err) => println!("An error occurred while closing the stream: {}", err.description()),
    }

    println!("");

    match pa::terminate() {
        Ok(()) => println!("Successfully terminated PortAudio."),
        Err(err) => println!("An error occurred while terminating PortAudio: {}", err.description()),
    }

}
<commit_msg>Removed obsolete closure syntax<commit_after>#![feature(core)]

extern crate portaudio;

use portaudio::*;
use std::error::Error;

const SAMPLE_RATE: f64 = 44_100.0;
const FRAMES: u32 = 256;

fn main() {

    println!("PortAudio version : {}", pa::get_version());
    println!("PortAudio version text : {}", pa::get_version_text());

    match pa::initialize() {
        Ok(()) => println!("Successfully initialized PortAudio"),
        Err(err) => println!("An error occurred while initializing PortAudio: {}", err.description()),
    }

    println!("PortAudio host count : {}", pa::host::get_api_count() as isize);

    let default_host = pa::host::get_default_api();
    println!("PortAudio default host : {}", default_host as isize);

    match pa::host::get_api_info(default_host) {
        None => println!("Couldn't retrieve api info for the default host."),
        Some(info) => println!("PortAudio host name : {}", info.name),
    }

    let type_id = pa::host::api_type_id_to_host_api_index(pa::HostApiTypeId::CoreAudio) as isize;
    println!("PortAudio type id : {}", type_id);

    let def_input = pa::device::get_default_input();
    let input_info = match pa::device::get_info(def_input) {
        Ok(info) => info,
        Err(err) => panic!("An error occurred while retrieving input info: {}", err.description()),
    };
    println!("Default input device info :");
    println!("\tversion : {}", input_info.struct_version);
    println!("\tname : {}", input_info.name);
    println!("\tmax input channels : {}", input_info.max_input_channels);
    println!("\tmax output channels : {}", input_info.max_output_channels);
    println!("\tdefault sample rate : {}", input_info.default_sample_rate);

    // Construct the input stream parameters.
    let input_stream_params = pa::StreamParameters {
        device : def_input,
        channel_count : 2,
        sample_format : pa::SampleFormat::Float32,
        suggested_latency : input_info.default_low_input_latency
    };

    let def_output = pa::device::get_default_output();
    let output_info = match pa::device::get_info(def_output) {
        Ok(info) => info,
        Err(err) => panic!("An error occurred while retrieving output info: {}", err.description()),
    };

    println!("Default output device name : {}", output_info.name);

    // Construct the output stream parameters.
    let output_stream_params = pa::StreamParameters {
        device : def_output,
        channel_count : 2,
        sample_format : pa::SampleFormat::Float32,
        suggested_latency : output_info.default_low_output_latency
    };

    let mut stream : pa::Stream<f32, f32> = pa::Stream::new();

    match stream.open(Some(&input_stream_params),
                      Some(&output_stream_params),
                      SAMPLE_RATE,
                      FRAMES,
                      pa::StreamFlags::ClipOff) {
        Ok(()) => println!("Successfully opened the stream."),
        Err(err) => println!("An error occurred while opening the stream: {}", err.description()),
    }

    match stream.start() {
        Ok(()) => println!("Successfully started the stream."),
        Err(err) => println!("An error occurred while starting the stream: {}", err.description()),
    }

    // We'll use this function to wait for read/write availability.
    fn wait_for_stream<F: Fn() -> Result<Option<i64>, pa::error::Error>>(f: F, name: &str) {
        'waiting_for_stream: loop {
            match f() {
                Ok(None) => (),
                Ok(Some(frames)) => {
                    println!("{} stream available with {} frames.", name, frames);
                    break 'waiting_for_stream
                },
                Err(err) => panic!("An error occurred while waiting for the {} stream: {}", name, err.description()),
            }
        }
    };

    // Now start the main read/write loop! In this example, we pass the input buffer directly to
    // the output buffer, so watch out for feedback.
    'stream: loop {
        wait_for_stream(|| stream.get_stream_read_available(), "Read");
        match stream.read(FRAMES) {
            Ok(input_samples)  => {
                wait_for_stream(|| stream.get_stream_write_available(), "Write");
                match stream.write(input_samples, FRAMES) {
                    Ok(()) => (),
                    Err(err) => {
                        println!("An error occurred while writing to the output stream: {}", err.description());
                        break 'stream
                    },
                }
            },
            Err(err) => {
                println!("An error occurred while reading from the input stream: {}", err.description());
                break 'stream
            }
        };
    }

    match stream.close() {
        Ok(()) => println!("Successfully closed the stream."),
        Err(err) => println!("An error occurred while closing the stream: {}", err.description()),
    }

    println!("");

    match pa::terminate() {
        Ok(()) => println!("Successfully terminated PortAudio."),
        Err(err) => println!("An error occurred while terminating PortAudio: {}", err.description()),
    }

}
<|endoftext|>


<commit_before>extern crate ruroonga_client;

use ruroonga_client as groonga;

fn main() {
    let mut command = groonga::CommandQuery::new("select");
    command.set_argument(vec![("table", "Entry")]);
    let mut request = groonga::HTTPRequest::new();
    let url = format!("http://localhost:10041{}", command.encode());
    println!("url: {}", url);
    let res = request.get(url);
    let result = request.receive(&mut res.unwrap());
    println!("result: {}", result);
}
<commit_msg>Update example<commit_after>extern crate ruroonga_client;
extern crate json_flex;

use json_flex::Unwrap;

use ruroonga_client as groonga;

fn main() {
    let mut command = groonga::CommandQuery::new("select");
    command.set_argument(vec![("table", "Site")]);
    let mut request = groonga::HTTPRequest::new();
    let url = format!("http://localhost:10041{}", command.encode());
    println!("url: {}", url);
    let res = request.get(url);
    let result = request.receive(&mut res.unwrap());
    println!("result: {}", result);
    let mut decode = groonga::ResultParser::new(result);
    println!("status: {:?}", decode.status().unwrap());
    println!("start: {:?}", decode.start_time().unwrap());
    println!("elapsed: {:?}", decode.elapsed_time().unwrap());
    println!("matched columns: {:?}", decode.matched_columns().unwrap());
    // Read got response
    for v in decode.result().unwrap().pop().unwrap().unwrap_vec().iter() {
        println!("{:?}", v);
        for vv in v.unwrap_vec().iter() {
            if vv.is_integer() {
                println!("{:?}", vv.unwrap_i64())
            } else if vv.is_string() {
                println!("{:?}", vv.unwrap_string())
            } else {
                println!("{:?}", vv)
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate rustylifx;

use rustylifx::{colour, messages, response};
use rustylifx::network::Device;

use std::time::Duration;
use std::thread;

fn main() {
    println!("Available named colours: {:?}", colour::named_colours());

    let device = find_device();

    let device = get_device_state(device);

    parse_hsvk(&device);

    change_colour(device);

    println!("\nFinished.");
}

fn find_device() -> Device {
    let device = messages::get_service().unwrap();

    match device.response {
        Some(ref resp) => display_response("State service", &resp),
        None => panic!("no response"),
    };

    thread::sleep(Duration::from_millis(1000));
    device
}

fn get_device_state(device: Device) -> Device {
    let device = messages::get_device_state(&device).unwrap();
    match device.response {
        Some(ref resp) => display_response("State", resp),
        None => panic!("no response"),
    };

    thread::sleep(Duration::from_millis(1000));
    device
}

fn parse_hsvk(device: &Device) {
    println!("\nCurrent state received:");
    let resp = match device.response {
        Some(ref v) => v,
        None => panic!("no response"),
    };

    let payload = match resp.payload {
        response::Payload::State(ref v) => Some(v),
        _ => None,
    };

    match payload {
        Some(v) => {
            println!("current payload body: {:?}", v.body);
            println!("current hue: {:?}", v.hsbk.hue);
            println!("current hue degrees: {:?}º",
                     colour::hue_word_to_degrees(v.hsbk.hue));
            println!("current sat: {:?}", v.hsbk.saturation);
            println!("current sat percent: {:?}%",
                     colour::saturation_word_to_percent(v.hsbk.saturation as u16));
            println!("current bri: {:?}", v.hsbk.brightness);
            println!("current bri percent: {:?}%",
                     colour::brightness_word_to_percent(v.hsbk.brightness as u16));
            println!("current kel: {:?}", v.hsbk.kelvin);
        }
        None => (),
    };
    println!("\n");
}

fn change_colour(device: Device) {
    // Use constants.
    let cols: Vec<colour::HSB> =
        vec![colour::get_colour("red"), colour::get_colour("green"), colour::get_colour("blue")];

    for c in cols {
        let _ = messages::set_device_state(&device, &c, 1000, 0);
        thread::sleep(Duration::from_millis(1000));
    }

    // Use RGB.
    let rgb_orange = colour::rgb_to_hsv(colour::RGB {
        red: 255,
        green: 165,
        blue: 0,
    });
    let _ = messages::set_device_state(&device, &rgb_orange, 1000, 0);
    thread::sleep(Duration::from_millis(1000));

    // More constants.
    let cols: Vec<colour::HSB> = vec![
        colour::get_colour("beige"),
        colour::get_colour("chartreuse"),
        colour::get_colour("coral"),
        colour::get_colour("cornflower"),
        colour::get_colour("crimson"),
        colour::get_colour("deep_sky_blue"),
        colour::get_colour("slate_gray"),
    ];

    for c in cols {
        let _ = messages::set_device_state(&device, &c, 1000, 0);
        thread::sleep(Duration::from_millis(1000));
    }

    let device = messages::set_device_state(&device, &colour::get_colour("beige"), 1000, 0);
    display_response("Set state", &device.unwrap().response.unwrap());

}

fn display_response(title: &str, resp: &response::Response) {
    println!("\n{} :", title);
    println!("Response:");
    println!("Size: {}", resp.size);
    println!("Source: {:?}", resp.source);
    println!("Mac addr: {:?}", resp.mac_address);
    println!("Firmware: {:?}", resp.firmware);

    // packed byte
    println!("Sequence num: {:?}", resp.sequence_number);
    println!("Reserved_1 (timestamp?): {:?}", resp.reserved_1);
    println!("Message type: {:?}", resp.message_type);
    println!("Reserved_2: {:?}", resp.reserved_2);

    // println!("Service: {:?}", resp.service);
    // println!("Port: {:?}", resp.port);
    // println!("Unknown: {:?}", resp.unknown);

    println!("==========");
}
<commit_msg>Tidy, extend example.<commit_after>extern crate rustylifx;

use rustylifx::{colour, messages, response};
use rustylifx::network::Device;

use std::process;
use std::time::Duration;
use std::thread;

fn main() {
    println!("Available named colours: {:?}", colour::named_colours());

    let device = find_device();

    let device = get_device_state(device);

    let device = match messages::get_device_power_state(&device) {
        Ok(v) => v,
        Err(e) => {
            println!("failed getting device power state: {:?}", e);
            process::exit(1);
        },
    };

    parse_hsvk(&device);

    change_colour(device);

    println!("\nFinished.");
}

fn find_device() -> Device {
    let device = match messages::get_service() {
        Ok(v) => v,
        Err(e) => {
            println!("failed getting device power state: {:?}", e);
            process::exit(1);
        },
    };

    match device.response {
        Some(ref resp) => display_response("State service", &resp),
        None => panic!("no response"),
    };

    thread::sleep(Duration::from_millis(1000));
    device
}

fn get_device_state(device: Device) -> Device {
    let device = messages::get_device_state(&device).unwrap();
    match device.response {
        Some(ref resp) => display_response("State", resp),
        None => panic!("no response"),
    };

    thread::sleep(Duration::from_millis(1000));
    device
}

fn parse_hsvk(device: &Device) {
    println!("\nCurrent state received:");
    let resp = match device.response {
        Some(ref v) => v,
        None => panic!("no response"),
    };

    let payload = match resp.payload {
        response::Payload::State(ref v) => Some(v),
        _ => None,
    };

    match payload {
        Some(v) => {
            println!("current payload body: {:?}", v.body);
            println!("current hue: {:?}", v.hsbk.hue);
            println!("current hue degrees: {:?}º",
                     colour::hue_word_to_degrees(v.hsbk.hue));
            println!("current sat: {:?}", v.hsbk.saturation);
            println!("current sat percent: {:?}%",
                     colour::saturation_word_to_percent(v.hsbk.saturation as u16));
            println!("current bri: {:?}", v.hsbk.brightness);
            println!("current bri percent: {:?}%",
                     colour::brightness_word_to_percent(v.hsbk.brightness as u16));
            println!("current kel: {:?}", v.hsbk.kelvin);
        }
        None => (),
    };
    println!("\n");
}

fn change_colour(device: Device) {
    // Use constants.
    let cols: Vec<colour::HSB> =
        vec![colour::get_colour("red"), colour::get_colour("green"), colour::get_colour("blue")];

    for c in cols {
        let _ = messages::set_device_state(&device, &c, 1000, 0);
        thread::sleep(Duration::from_millis(1000));
    }

    // Use RGB.
    let rgb_orange = colour::rgb_to_hsv(colour::RGB {
        red: 255,
        green: 165,
        blue: 0,
    });
    let _ = messages::set_device_state(&device, &rgb_orange, 1000, 0);
    thread::sleep(Duration::from_millis(1000));

    // More constants.
    let cols: Vec<colour::HSB> = vec![
        colour::get_colour("beige"),
        colour::get_colour("chartreuse"),
        colour::get_colour("coral"),
        colour::get_colour("cornflower"),
        colour::get_colour("crimson"),
        colour::get_colour("deep_sky_blue"),
        colour::get_colour("slate_gray"),
    ];

    for c in cols {
        let _ = messages::set_device_state(&device, &c, 1000, 0);
        thread::sleep(Duration::from_millis(1000));
    }

    let device = messages::set_device_state(&device, &colour::get_colour("beige"), 1000, 0);
    display_response("Set state", &device.unwrap().response.unwrap());

}

fn display_response(title: &str, resp: &response::Response) {
    println!("\n{} :", title);
    println!("Response:");
    println!("Size: {}", resp.size);
    println!("Source: {:?}", resp.source);
    println!("Mac addr: {:?}", resp.mac_address);
    println!("Firmware: {:?}", resp.firmware);

    // packed byte
    println!("Sequence num: {:?}", resp.sequence_number);
    println!("Reserved_1 (timestamp?): {:?}", resp.reserved_1);
    println!("Message type: {:?}", resp.message_type);
    println!("Reserved_2: {:?}", resp.reserved_2);

    // println!("Service: {:?}", resp.service);
    // println!("Port: {:?}", resp.port);
    // println!("Unknown: {:?}", resp.unknown);

    println!("==========");
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    account_resource::SimplifiedAccountResource,
    command::{Command, CommandName},
    validator_config::DecryptedValidatorConfig,
    validator_set::DecryptedValidatorInfo,
    TransactionContext,
};
use libra_config::config;
use libra_crypto::{ed25519::Ed25519PublicKey, x25519};
use libra_management::{error::Error, secure_backend::DISK};
use libra_network_address::NetworkAddress;
use libra_secure_json_rpc::VMStatusView;
use libra_types::{account_address::AccountAddress, chain_id::ChainId};
use structopt::StructOpt;

const TOOL_NAME: &str = "libra-operational-tool";

/// A helper to test the operational tool in tests
pub struct OperationalTool {
    host: String,
    chain_id: ChainId,
}

impl OperationalTool {
    pub fn new(host: String, chain_id: ChainId) -> OperationalTool {
        OperationalTool { host, chain_id }
    }

    pub fn account_resource(
        &self,
        account_address: AccountAddress,
    ) -> Result<SimplifiedAccountResource, Error> {
        let args = format!(
            "
                {command}
                --json-server {json_server}
                --account-address {account_address}
            ",
            command = command(TOOL_NAME, CommandName::AccountResource),
            json_server = self.host,
            account_address = account_address,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.account_resource()
    }

    pub fn check_endpoint(&self, network_address: NetworkAddress) -> Result<String, Error> {
        let args = format!(
            "
            {command}
            --address {network_address}
            ",
            command = command(TOOL_NAME, CommandName::CheckEndpoint),
            network_address = network_address,
        );
        let command = Command::from_iter(args.split_whitespace());
        command.check_endpoint()
    }

    pub fn create_account(
        &self,
        name: &str,
        path_to_key: &str,
        backend: &config::SecureBackend,
        command_name: CommandName,
        execute: fn(Command) -> Result<(TransactionContext, AccountAddress), Error>,
    ) -> Result<(TransactionContext, AccountAddress), Error> {
        let args = format!(
            "
                {command}
                --name {name}
                --path-to-key {path_to_key}
                --json-server {host}
                --chain-id {chain_id}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, command_name),
            name = name,
            path_to_key = path_to_key,
            host = self.host,
            chain_id = self.chain_id.id(),
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        execute(command)
    }

    pub fn create_validator(
        &self,
        name: &str,
        path_to_key: &str,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, AccountAddress), Error> {
        self.create_account(
            name,
            path_to_key,
            backend,
            CommandName::CreateValidator,
            |cmd| cmd.create_validator(),
        )
    }

    pub fn create_validator_operator(
        &self,
        name: &str,
        path_to_key: &str,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, AccountAddress), Error> {
        self.create_account(
            name,
            path_to_key,
            backend,
            CommandName::CreateValidatorOperator,
            |cmd| cmd.create_validator_operator(),
        )
    }

    fn extract_key(
        &self,
        key_name: &str,
        key_file: &str,
        backend: &config::SecureBackend,
        command_name: CommandName,
        execute: fn(Command) -> Result<(), Error>,
    ) -> Result<(), Error> {
        let args = format!(
            "
                {command}
                --key-name {key_name}
                --key-file {key_file}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, command_name),
            key_name = key_name,
            key_file = key_file,
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        execute(command)
    }

    pub fn extract_public_key(
        &self,
        key_name: &str,
        key_file: &str,
        backend: &config::SecureBackend,
    ) -> Result<(), Error> {
        self.extract_key(
            key_name,
            key_file,
            backend,
            CommandName::ExtractPublicKey,
            |cmd| cmd.extract_public_key(),
        )
    }

    pub fn extract_private_key(
        &self,
        key_name: &str,
        key_file: &str,
        backend: &config::SecureBackend,
    ) -> Result<(), Error> {
        self.extract_key(
            key_name,
            key_file,
            backend,
            CommandName::ExtractPrivateKey,
            |cmd| cmd.extract_private_key(),
        )
    }

    pub fn print_account(
        &self,
        account_name: &str,
        backend: &config::SecureBackend,
    ) -> Result<AccountAddress, Error> {
        let args = format!(
            "
            {command}
            --account-name {account_name}
            --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::PrintAccount),
            account_name = account_name,
            backend_args = backend_args(backend)?,
        );
        let command = Command::from_iter(args.split_whitespace());
        command.print_account()
    }

    pub fn set_validator_config(
        &self,
        validator_address: Option<NetworkAddress>,
        fullnode_address: Option<NetworkAddress>,
        backend: &config::SecureBackend,
    ) -> Result<TransactionContext, Error> {
        let args = format!(
            "
                {command}
                {fullnode_address}
                {validator_address}
                --chain-id {chain_id}
                --json-server {host}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::SetValidatorConfig),
            host = self.host,
            chain_id = self.chain_id.id(),
            fullnode_address = optional_arg("fullnode-address", fullnode_address),
            validator_address = optional_arg("validator-address", validator_address),
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.set_validator_config()
    }

    fn rotate_key<T>(
        &self,
        backend: &config::SecureBackend,
        name: CommandName,
        execute: fn(Command) -> Result<T, Error>,
    ) -> Result<T, Error> {
        let args = format!(
            "
                {command}
                --chain-id {chain_id}
                --json-server {host}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, name),
            host = self.host,
            chain_id = self.chain_id.id(),
            backend_args = backend_args(backend)?,
        );
        let command = Command::from_iter(args.split_whitespace());
        execute(command)
    }

    pub fn rotate_consensus_key(
        &self,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, Ed25519PublicKey), Error> {
        self.rotate_key(backend, CommandName::RotateConsensusKey, |cmd| {
            cmd.rotate_consensus_key()
        })
    }

    pub fn rotate_operator_key(
        &self,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, Ed25519PublicKey), Error> {
        self.rotate_key(backend, CommandName::RotateOperatorKey, |cmd| {
            cmd.rotate_operator_key()
        })
    }

    pub fn rotate_validator_network_key(
        &self,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, x25519::PublicKey), Error> {
        self.rotate_key(backend, CommandName::RotateValidatorNetworkKey, |cmd| {
            cmd.rotate_validator_network_key()
        })
    }

    pub fn rotate_fullnode_network_key(
        &self,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, x25519::PublicKey), Error> {
        self.rotate_key(backend, CommandName::RotateFullNodeNetworkKey, |cmd| {
            cmd.rotate_fullnode_network_key()
        })
    }

    pub fn validate_transaction(
        &self,
        account_address: AccountAddress,
        sequence_number: u64,
    ) -> Result<Option<VMStatusView>, Error> {
        let args = format!(
            "
                {command}
                --json-server {host}
                --account-address {account_address}
                --sequence-number {sequence_number}
        ",
            command = command(TOOL_NAME, CommandName::ValidateTransaction),
            host = self.host,
            account_address = account_address,
            sequence_number = sequence_number,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.validate_transaction()
    }

    pub fn set_validator_operator(
        &self,
        name: &str,
        account_address: AccountAddress,
        backend: &config::SecureBackend,
    ) -> Result<TransactionContext, Error> {
        let args = format!(
            "
                {command}
                --json-server {json_server}
                --chain-id {chain_id}
                --name {name}
                --account-address {account_address}
                --validator-backend {backend_args}
        ",
            command = command(TOOL_NAME, CommandName::SetValidatorOperator),
            json_server = self.host,
            name = name,
            chain_id = self.chain_id.id(),
            account_address = account_address,
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.set_validator_operator()
    }

    pub fn validator_config(
        &self,
        account_address: AccountAddress,
        backend: &config::SecureBackend,
    ) -> Result<DecryptedValidatorConfig, Error> {
        let args = format!(
            "
                {command}
                --json-server {json_server}
                --account-address {account_address}
                --validator-backend {backend_args}
        ",
            command = command(TOOL_NAME, CommandName::ValidatorConfig),
            json_server = self.host,
            account_address = account_address,
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.validator_config()
    }

    pub fn validator_set(
        &self,
        account_address: Option<AccountAddress>,
        backend: &config::SecureBackend,
    ) -> Result<Vec<DecryptedValidatorInfo>, Error> {
        let args = format!(
            "
                {command}
                {account_address}
                --json-server {json_server}
                --validator-backend {backend_args}
        ",
            command = command(TOOL_NAME, CommandName::ValidatorSet),
            json_server = self.host,
            account_address = optional_arg("account-address", account_address),
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.validator_set()
    }

    pub fn add_validator(
        &self,
        account_address: AccountAddress,
        backend: &config::SecureBackend,
    ) -> Result<TransactionContext, Error> {
        let args = format!(
            "
            {command}
            --json-server {host}
            --chain-id {chain_id}
            --account-address {account_address}
            --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::AddValidator),
            host = self.host,
            chain_id = self.chain_id.id(),
            account_address = account_address,
            backend_args = backend_args(backend)?,
        );
        let command = Command::from_iter(args.split_whitespace());
        command.add_validator()
    }

    pub fn remove_validator(
        &self,
        account_address: AccountAddress,
        backend: &config::SecureBackend,
    ) -> Result<TransactionContext, Error> {
        let args = format!(
            "
            {command}
            --json-server {host}
            --chain-id {chain_id}
            --account-address {account_address}
            --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::RemoveValidator),
            host = self.host,
            chain_id = self.chain_id.id(),
            account_address = account_address,
            backend_args = backend_args(backend)?,
        );
        let command = Command::from_iter(args.split_whitespace());
        command.remove_validator()
    }
}

fn command(tool_name: &'static str, command: CommandName) -> String {
    format!("{tool} {command}", tool = tool_name, command = command)
}

/// Allow arguments to be optional
fn optional_arg<T: std::fmt::Display>(name: &'static str, maybe_value: Option<T>) -> String {
    if let Some(value) = maybe_value {
        format!("--{name} {value}", name = name, value = value)
    } else {
        String::new()
    }
}

/// Extract on disk storage args
/// TODO: Support other types of storage
fn backend_args(backend: &config::SecureBackend) -> Result<String, Error> {
    match backend {
        config::SecureBackend::OnDiskStorage(config) => Ok(format!(
            "backend={backend};\
            path={path};\
            namespace={namespace}",
            backend = DISK,
            namespace = config.namespace.clone().unwrap(),
            path = config.path.to_str().unwrap(),
        )),
        _ => Err(Error::UnexpectedError("Storage isn't on disk".to_string())),
    }
}
<commit_msg>[Operational Tools] Format string commands in test helper<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    account_resource::SimplifiedAccountResource,
    command::{Command, CommandName},
    validator_config::DecryptedValidatorConfig,
    validator_set::DecryptedValidatorInfo,
    TransactionContext,
};
use libra_config::config;
use libra_crypto::{ed25519::Ed25519PublicKey, x25519};
use libra_management::{error::Error, secure_backend::DISK};
use libra_network_address::NetworkAddress;
use libra_secure_json_rpc::VMStatusView;
use libra_types::{account_address::AccountAddress, chain_id::ChainId};
use structopt::StructOpt;

const TOOL_NAME: &str = "libra-operational-tool";

/// A helper to test the operational tool in tests
pub struct OperationalTool {
    host: String,
    chain_id: ChainId,
}

impl OperationalTool {
    pub fn new(host: String, chain_id: ChainId) -> OperationalTool {
        OperationalTool { host, chain_id }
    }

    pub fn account_resource(
        &self,
        account_address: AccountAddress,
    ) -> Result<SimplifiedAccountResource, Error> {
        let args = format!(
            "
                {command}
                --json-server {json_server}
                --account-address {account_address}
            ",
            command = command(TOOL_NAME, CommandName::AccountResource),
            json_server = self.host,
            account_address = account_address,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.account_resource()
    }

    pub fn check_endpoint(&self, network_address: NetworkAddress) -> Result<String, Error> {
        let args = format!(
            "
                {command}
                --address {network_address}
            ",
            command = command(TOOL_NAME, CommandName::CheckEndpoint),
            network_address = network_address,
        );
        let command = Command::from_iter(args.split_whitespace());
        command.check_endpoint()
    }

    pub fn create_account(
        &self,
        name: &str,
        path_to_key: &str,
        backend: &config::SecureBackend,
        command_name: CommandName,
        execute: fn(Command) -> Result<(TransactionContext, AccountAddress), Error>,
    ) -> Result<(TransactionContext, AccountAddress), Error> {
        let args = format!(
            "
                {command}
                --name {name}
                --path-to-key {path_to_key}
                --json-server {host}
                --chain-id {chain_id}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, command_name),
            name = name,
            path_to_key = path_to_key,
            host = self.host,
            chain_id = self.chain_id.id(),
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        execute(command)
    }

    pub fn create_validator(
        &self,
        name: &str,
        path_to_key: &str,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, AccountAddress), Error> {
        self.create_account(
            name,
            path_to_key,
            backend,
            CommandName::CreateValidator,
            |cmd| cmd.create_validator(),
        )
    }

    pub fn create_validator_operator(
        &self,
        name: &str,
        path_to_key: &str,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, AccountAddress), Error> {
        self.create_account(
            name,
            path_to_key,
            backend,
            CommandName::CreateValidatorOperator,
            |cmd| cmd.create_validator_operator(),
        )
    }

    fn extract_key(
        &self,
        key_name: &str,
        key_file: &str,
        backend: &config::SecureBackend,
        command_name: CommandName,
        execute: fn(Command) -> Result<(), Error>,
    ) -> Result<(), Error> {
        let args = format!(
            "
                {command}
                --key-name {key_name}
                --key-file {key_file}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, command_name),
            key_name = key_name,
            key_file = key_file,
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        execute(command)
    }

    pub fn extract_public_key(
        &self,
        key_name: &str,
        key_file: &str,
        backend: &config::SecureBackend,
    ) -> Result<(), Error> {
        self.extract_key(
            key_name,
            key_file,
            backend,
            CommandName::ExtractPublicKey,
            |cmd| cmd.extract_public_key(),
        )
    }

    pub fn extract_private_key(
        &self,
        key_name: &str,
        key_file: &str,
        backend: &config::SecureBackend,
    ) -> Result<(), Error> {
        self.extract_key(
            key_name,
            key_file,
            backend,
            CommandName::ExtractPrivateKey,
            |cmd| cmd.extract_private_key(),
        )
    }

    pub fn print_account(
        &self,
        account_name: &str,
        backend: &config::SecureBackend,
    ) -> Result<AccountAddress, Error> {
        let args = format!(
            "
                {command}
                --account-name {account_name}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::PrintAccount),
            account_name = account_name,
            backend_args = backend_args(backend)?,
        );
        let command = Command::from_iter(args.split_whitespace());
        command.print_account()
    }

    pub fn set_validator_config(
        &self,
        validator_address: Option<NetworkAddress>,
        fullnode_address: Option<NetworkAddress>,
        backend: &config::SecureBackend,
    ) -> Result<TransactionContext, Error> {
        let args = format!(
            "
                {command}
                {fullnode_address}
                {validator_address}
                --chain-id {chain_id}
                --json-server {host}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::SetValidatorConfig),
            host = self.host,
            chain_id = self.chain_id.id(),
            fullnode_address = optional_arg("fullnode-address", fullnode_address),
            validator_address = optional_arg("validator-address", validator_address),
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.set_validator_config()
    }

    fn rotate_key<T>(
        &self,
        backend: &config::SecureBackend,
        name: CommandName,
        execute: fn(Command) -> Result<T, Error>,
    ) -> Result<T, Error> {
        let args = format!(
            "
                {command}
                --chain-id {chain_id}
                --json-server {host}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, name),
            host = self.host,
            chain_id = self.chain_id.id(),
            backend_args = backend_args(backend)?,
        );
        let command = Command::from_iter(args.split_whitespace());
        execute(command)
    }

    pub fn rotate_consensus_key(
        &self,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, Ed25519PublicKey), Error> {
        self.rotate_key(backend, CommandName::RotateConsensusKey, |cmd| {
            cmd.rotate_consensus_key()
        })
    }

    pub fn rotate_operator_key(
        &self,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, Ed25519PublicKey), Error> {
        self.rotate_key(backend, CommandName::RotateOperatorKey, |cmd| {
            cmd.rotate_operator_key()
        })
    }

    pub fn rotate_validator_network_key(
        &self,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, x25519::PublicKey), Error> {
        self.rotate_key(backend, CommandName::RotateValidatorNetworkKey, |cmd| {
            cmd.rotate_validator_network_key()
        })
    }

    pub fn rotate_fullnode_network_key(
        &self,
        backend: &config::SecureBackend,
    ) -> Result<(TransactionContext, x25519::PublicKey), Error> {
        self.rotate_key(backend, CommandName::RotateFullNodeNetworkKey, |cmd| {
            cmd.rotate_fullnode_network_key()
        })
    }

    pub fn validate_transaction(
        &self,
        account_address: AccountAddress,
        sequence_number: u64,
    ) -> Result<Option<VMStatusView>, Error> {
        let args = format!(
            "
                {command}
                --json-server {host}
                --account-address {account_address}
                --sequence-number {sequence_number}
            ",
            command = command(TOOL_NAME, CommandName::ValidateTransaction),
            host = self.host,
            account_address = account_address,
            sequence_number = sequence_number,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.validate_transaction()
    }

    pub fn set_validator_operator(
        &self,
        name: &str,
        account_address: AccountAddress,
        backend: &config::SecureBackend,
    ) -> Result<TransactionContext, Error> {
        let args = format!(
            "
                {command}
                --json-server {json_server}
                --chain-id {chain_id}
                --name {name}
                --account-address {account_address}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::SetValidatorOperator),
            json_server = self.host,
            name = name,
            chain_id = self.chain_id.id(),
            account_address = account_address,
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.set_validator_operator()
    }

    pub fn validator_config(
        &self,
        account_address: AccountAddress,
        backend: &config::SecureBackend,
    ) -> Result<DecryptedValidatorConfig, Error> {
        let args = format!(
            "
                {command}
                --json-server {json_server}
                --account-address {account_address}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::ValidatorConfig),
            json_server = self.host,
            account_address = account_address,
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.validator_config()
    }

    pub fn validator_set(
        &self,
        account_address: Option<AccountAddress>,
        backend: &config::SecureBackend,
    ) -> Result<Vec<DecryptedValidatorInfo>, Error> {
        let args = format!(
            "
                {command}
                {account_address}
                --json-server {json_server}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::ValidatorSet),
            json_server = self.host,
            account_address = optional_arg("account-address", account_address),
            backend_args = backend_args(backend)?,
        );

        let command = Command::from_iter(args.split_whitespace());
        command.validator_set()
    }

    pub fn add_validator(
        &self,
        account_address: AccountAddress,
        backend: &config::SecureBackend,
    ) -> Result<TransactionContext, Error> {
        let args = format!(
            "
                {command}
                --json-server {host}
                --chain-id {chain_id}
                --account-address {account_address}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::AddValidator),
            host = self.host,
            chain_id = self.chain_id.id(),
            account_address = account_address,
            backend_args = backend_args(backend)?,
        );
        let command = Command::from_iter(args.split_whitespace());
        command.add_validator()
    }

    pub fn remove_validator(
        &self,
        account_address: AccountAddress,
        backend: &config::SecureBackend,
    ) -> Result<TransactionContext, Error> {
        let args = format!(
            "
                {command}
                --json-server {host}
                --chain-id {chain_id}
                --account-address {account_address}
                --validator-backend {backend_args}
            ",
            command = command(TOOL_NAME, CommandName::RemoveValidator),
            host = self.host,
            chain_id = self.chain_id.id(),
            account_address = account_address,
            backend_args = backend_args(backend)?,
        );
        let command = Command::from_iter(args.split_whitespace());
        command.remove_validator()
    }
}

fn command(tool_name: &'static str, command: CommandName) -> String {
    format!("{tool} {command}", tool = tool_name, command = command)
}

/// Allow arguments to be optional
fn optional_arg<T: std::fmt::Display>(name: &'static str, maybe_value: Option<T>) -> String {
    if let Some(value) = maybe_value {
        format!("--{name} {value}", name = name, value = value)
    } else {
        String::new()
    }
}

/// Extract on disk storage args
/// TODO: Support other types of storage
fn backend_args(backend: &config::SecureBackend) -> Result<String, Error> {
    match backend {
        config::SecureBackend::OnDiskStorage(config) => Ok(format!(
            "backend={backend};\
            path={path};\
            namespace={namespace}",
            backend = DISK,
            namespace = config.namespace.clone().unwrap(),
            path = config.path.to_str().unwrap(),
        )),
        _ => Err(Error::UnexpectedError("Storage isn't on disk".to_string())),
    }
}
<|endoftext|>


<commit_before>use svm::svm::cell::SVMCell;
use svm::slist::List;

/// Trait for AST nodes.
pub trait ASTNode {
    /// Compile this node to a list of SVM expressions
    fn compile(self)                        -> Result<SVMCell, &'static str>;

    /// Pretty-print this node
    fn prettyprint(&self)                   -> String {
        prettyprint_level(&self, 0usize)
    }

    /// Pretty-print this node at the desired indent level
    fn print_level(&self, level: usize)     -> String;
}

/// Expression
///
/// All Seax Scheme expressions are one of the following
///  + Nested S-Expressions
///  + Identifiers
///  + Lists
///  + Numbers
///     - signed int
///     - unsigned int
///     - floating-point
///  + Characters
///  + Strings
///  TODO: implement the entire Scheme 'numeric tower'
///  TODO: macros should happen
#[derive(Clone, PartialEq)]
pub enum ExprNode {
    Root(RootNode),
    SExpr(SExprNode),
    Name(NameNode),
    List(ListNode),
    IntConst(IntNode),
    UIntConst(UIntNode),
    FloatConst(FloatNode),
    BoolConst(BoolNode),
    StringConst(StringNode),
    CharConst(CharNode),
}

/// AST node for the root of a program's AST
#[derive(Clone, PartialEq)]
pub struct RootNode { pub exprs: Vec<ExprNode> }

/// AST node for an S-expression.
///
/// This includes function application, assignment,
/// function definition, et cetera...Scheme is not a complexl anguage.
#[derive(Clone, PartialEq)]
pub struct SExprNode {
    pub operator: NameNode,
    pub operands: Vec<ExprNode>,
}

/// AST node for a list literal
#[derive(Clone, PartialEq)]
pub struct ListNode { pub elements: Vec<ExprNode> }

/// AST node for an identifier
#[derive(Clone, PartialEq)]
pub struct NameNode { pub name: String }

/// AST node for an integer constant
#[derive(Clone, PartialEq)]
pub struct IntNode { pub value: isize }

/// AST node for an unsigned integer constant
#[derive(Clone, PartialEq)]
pub struct UIntNode { pub value: usize }

/// AST node for a floating-point constant
#[derive(Clone, PartialEq)]
pub struct FloatNode { pub value: f64 }

/// AST node for a boolean constant
#[derive(Clone, PartialEq)]
pub struct BoolNode { pub value: bool }

/// AST node for a character constant
#[derive(Clone, PartialEq)]
pub struct CharNode { pub value: char }

<commit_msg>Misc AST bugfixes<commit_after>use svm::cell::SVMCell;
use svm::slist::List;

/// Trait for AST nodes.
pub trait ASTNode {
    /// Compile this node to a list of SVM expressions
    fn compile(self)                    -> Result<SVMCell, &'static str>;

    /// Pretty-print this node
    fn prettyprint(&self)               -> String { self.print_level(0usize) }

    /// Pretty-print this node at the desired indent level
    fn print_level(&self, level: usize) -> String;
}

/// Expression
///
/// All Seax Scheme expressions are one of the following
///  + Nested S-Expressions
///  + Identifiers
///  + Lists
///  + Numbers
///     - signed int
///     - unsigned int
///     - floating-point
///  + Characters
///  + Strings
///  TODO: implement the entire Scheme 'numeric tower'
///  TODO: macros should happen
#[derive(Clone, PartialEq)]
pub enum ExprNode {
    Root(RootNode),
    SExpr(SExprNode),
    Name(NameNode),
    List(ListNode),
    IntConst(IntNode),
    UIntConst(UIntNode),
    FloatConst(FloatNode),
    BoolConst(BoolNode),
    StringConst(StringNode),
    CharConst(CharNode),
}

/// AST node for the root of a program's AST
#[derive(Clone, PartialEq)]
pub struct RootNode { pub exprs: Vec<ExprNode> }

/// AST node for an S-expression.
///
/// This includes function application, assignment,
/// function definition, et cetera...Scheme is not a complexl anguage.
#[derive(Clone, PartialEq)]
pub struct SExprNode {
    pub operator: NameNode,
    pub operands: Vec<ExprNode>,
}

/// AST node for a list literal
#[derive(Clone, PartialEq)]
pub struct ListNode { pub elements: Vec<ExprNode> }

/// AST node for an identifier
#[derive(Clone, PartialEq)]
pub struct NameNode { pub name: String }

/// AST node for an integer constant
#[derive(Clone, PartialEq)]
pub struct IntNode { pub value: isize }

/// AST node for an unsigned integer constant
#[derive(Clone, PartialEq)]
pub struct UIntNode { pub value: usize }

/// AST node for a floating-point constant
#[derive(Clone, PartialEq)]
pub struct FloatNode { pub value: f64 }

/// AST node for a boolean constant
#[derive(Clone, PartialEq)]
pub struct BoolNode { pub value: bool }

/// AST node for a character constant
#[derive(Clone, PartialEq)]
pub struct CharNode { pub value: char }

<|endoftext|>


<commit_before>use absorb::commands::*;
use std::process::Command;
use git2::{Repository};

fn git_revparse() -> String {
  let output = Command::new("git")
                       .arg("rev-parse")
                       .arg("--abbrev-ref")
                       .arg("HEAD")
                       .output()
                       .unwrap_or_else(|e| {
                          panic!("failed to execute process: {}", e) });

  String::from_utf8_lossy(&output.stdout).to_string()
}

#[test]
fn test_branch() {
    let path = ".";
    let repo = Repository::open(&path).unwrap();
    let branchname = branch(&repo).unwrap();
    let contrast = git_revparse();

    assert_eq!(contrast.trim_right(), branchname);
}
<commit_msg>Refactor git_revparse() test helper<commit_after>use absorb::commands::*;
use std::process::Command;
use git2::{Repository};

fn git_revparse() -> String {
  let output = Command::new("git")
                       .arg("rev-parse")
                       .arg("--abbrev-ref")
                       .arg("HEAD")
                       .output()
                       .unwrap_or_else(|e| {
                          panic!("failed to execute process: {}", e) });

  String::from_utf8_lossy(&output.stdout).trim_right().to_string()
}

#[test]
fn test_branch() {
    let path = ".";
    let repo = Repository::open(&path).unwrap();
    let branchname = branch(&repo).unwrap();
    let contrast = git_revparse();

    assert_eq!(contrast, branchname);
}
<|endoftext|>


<commit_before>// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]
#![feature(unwind_attributes)]

extern {
// CHECK: Function Attrs: nounwind
// CHECK-NEXT: declare void @extern_fn
    fn extern_fn();
// CHECK-NOT: Function Attrs: nounwind
// CHECK: declare void @unwinding_extern_fn
    #[unwind(allowed)]
    fn unwinding_extern_fn();
// CHECK-NOT: nounwind
// CHECK: declare void @aborting_extern_fn
    #[unwind(aborts)]
    fn aborting_extern_fn(); // FIXME: we want to have the attribute here
}

extern "Rust" {
// CHECK-NOT: nounwind
// CHECK: declare void @rust_extern_fn
    fn rust_extern_fn();
// CHECK-NOT: nounwind
// CHECK: declare void @rust_unwinding_extern_fn
    #[unwind(allowed)]
    fn rust_unwinding_extern_fn();
// CHECK-NOT: nounwind
// CHECK: declare void @rust_aborting_extern_fn
    #[unwind(aborts)]
    fn rust_aborting_extern_fn(); // FIXME: we want to have the attribute here
}

pub unsafe fn force_declare() {
    extern_fn();
    unwinding_extern_fn();
    aborting_extern_fn();
    rust_extern_fn();
    rust_unwinding_extern_fn();
    rust_aborting_extern_fn();
}
<commit_msg>make tests more robust<commit_after>// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]
#![feature(unwind_attributes)]

extern {
// CHECK: Function Attrs:{{.*}}nounwind
// CHECK-NEXT: declare void @extern_fn
    fn extern_fn();
// CHECK-NOT: Function Attrs:{{.*}}nounwind
// CHECK: declare void @unwinding_extern_fn
    #[unwind(allowed)]
    fn unwinding_extern_fn();
// CHECK-NOT: nounwind
// CHECK: declare void @aborting_extern_fn
    #[unwind(aborts)]
    fn aborting_extern_fn(); // FIXME: we want to have the attribute here
}

extern "Rust" {
// CHECK-NOT: nounwind
// CHECK: declare void @rust_extern_fn
    fn rust_extern_fn();
// CHECK-NOT: nounwind
// CHECK: declare void @rust_unwinding_extern_fn
    #[unwind(allowed)]
    fn rust_unwinding_extern_fn();
// CHECK-NOT: nounwind
// CHECK: declare void @rust_aborting_extern_fn
    #[unwind(aborts)]
    fn rust_aborting_extern_fn(); // FIXME: we want to have the attribute here
}

pub unsafe fn force_declare() {
    extern_fn();
    unwinding_extern_fn();
    aborting_extern_fn();
    rust_extern_fn();
    rust_unwinding_extern_fn();
    rust_aborting_extern_fn();
}
<|endoftext|>


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

use std::ops::{Deref, DerefMut};
use std::{ptr, slice, str};

pub use std::io::{Result, SeekFrom};
pub use std::syscall::*;

/// Helper function for handling C strings, please do not copy it or make it pub or change it
fn c_string_to_str<'a>(ptr: *const u8) -> &'a str {
    if ptr > 0 as *const u8 {
        let mut len = 0;
        while unsafe { ptr::read(ptr.offset(len as isize)) } > 0 {
            len += 1;
        }

        unsafe { str::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) }
    } else {
        ""
    }
}

#[derive(Copy, Clone, Debug, Default)]
#[repr(packed)]
pub struct Packet {
    pub id: usize,
    pub a: usize,
    pub b: usize,
    pub c: usize,
    pub d: usize
}

impl Deref for Packet {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe {
            std::slice::from_raw_parts(self as *const Packet as *const u8, std::mem::size_of::<Packet>()) as &[u8]
        }
    }
}

impl DerefMut for Packet {
    fn deref_mut(&mut self) -> &mut [u8] {
        unsafe {
            std::slice::from_raw_parts_mut(self as *mut Packet as *mut u8, std::mem::size_of::<Packet>()) as &mut [u8]
        }
    }
}

pub trait Resource {
    #[allow(unused_variables)]
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        Err(SysError::new(EBADF))
    }

    #[allow(unused_variables)]
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        Err(SysError::new(EBADF))
    }

    #[allow(unused_variables)]
    fn seek(&mut self, pos: SeekFrom) -> Result<usize> {
        Err(SysError::new(EBADF))
    }
}

pub trait Scheme {
    fn handle(&mut self, packet: &mut Packet) {
        packet.a = SysError::mux(match packet.a {
            SYS_OPEN => self.open(c_string_to_str(packet.b as *const u8), packet.c, packet.d),
            SYS_UNLINK => self.unlink(c_string_to_str(packet.b as *const u8)),
            _ => Err(SysError::new(ENOSYS))
        });
    }

    #[allow(unused_variables)]
    fn open(&mut self, path: &str, flags: usize, mode: usize) -> Result<usize> {
        Err(SysError::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn unlink(&mut self, path: &str) -> Result<usize> {
        Err(SysError::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn mkdir(&mut self, path: &str, mode: usize) -> Result<usize> {
        Err(SysError::new(ENOENT))
    }
}
<commit_msg>Add file operations to scheme trait<commit_after>#![crate_type="lib"]

use std::ops::{Deref, DerefMut};
use std::{ptr, slice, str};

pub use std::io::{Result, SeekFrom};
pub use std::syscall::*;

/// Helper function for handling C strings, please do not copy it or make it pub or change it
fn c_string_to_str<'a>(ptr: *const u8) -> &'a str {
    if ptr > 0 as *const u8 {
        let mut len = 0;
        while unsafe { ptr::read(ptr.offset(len as isize)) } > 0 {
            len += 1;
        }

        unsafe { str::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) }
    } else {
        ""
    }
}

#[derive(Copy, Clone, Debug, Default)]
#[repr(packed)]
pub struct Packet {
    pub id: usize,
    pub a: usize,
    pub b: usize,
    pub c: usize,
    pub d: usize
}

impl Deref for Packet {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe {
            std::slice::from_raw_parts(self as *const Packet as *const u8, std::mem::size_of::<Packet>()) as &[u8]
        }
    }
}

impl DerefMut for Packet {
    fn deref_mut(&mut self) -> &mut [u8] {
        unsafe {
            std::slice::from_raw_parts_mut(self as *mut Packet as *mut u8, std::mem::size_of::<Packet>()) as &mut [u8]
        }
    }
}

pub trait Scheme {
    fn handle(&mut self, packet: &mut Packet) {
        packet.a = SysError::mux(match packet.a {
            SYS_OPEN => self.open(c_string_to_str(packet.b as *const u8), packet.c, packet.d),
            SYS_UNLINK => self.unlink(c_string_to_str(packet.b as *const u8)).and(Ok(0)),
            SYS_MKDIR => self.mkdir(c_string_to_str(packet.b as *const u8), packet.c).and(Ok(0)),

            SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
            SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
            SYS_LSEEK => match packet.d {
                SEEK_SET => self.seek(packet.b, SeekFrom::Start(packet.c as u64)),
                SEEK_CUR => self.seek(packet.b, SeekFrom::Current(packet.c as i64)),
                SEEK_END => self.seek(packet.b, SeekFrom::End(packet.c as i64)),
                _ => Err(SysError::new(EINVAL))
            },
            SYS_FSYNC => self.sync(packet.b).and(Ok(0)),
            SYS_FTRUNCATE => self.truncate(packet.b, packet.c).and(Ok(0)),

            _ => Err(SysError::new(ENOSYS))
        });
    }

    /* Scheme operations */

    #[allow(unused_variables)]
    fn open(&mut self, path: &str, flags: usize, mode: usize) -> Result<usize> {
        Err(SysError::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn unlink(&mut self, path: &str) -> Result<()> {
        Err(SysError::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn mkdir(&mut self, path: &str, mode: usize) -> Result<()> {
        Err(SysError::new(ENOENT))
    }

    /* Resource operations */

    #[allow(unused_variables)]
    fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
        Err(SysError::new(EBADF))
    }

    #[allow(unused_variables)]
    fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
        Err(SysError::new(EBADF))
    }

    #[allow(unused_variables)]
    fn seek(&mut self, id: usize, pos: SeekFrom) -> Result<usize> {
        Err(SysError::new(EBADF))
    }

    #[allow(unused_variables)]
    fn sync(&mut self, id: usize) -> Result<()> {
        Err(SysError::new(EBADF))
    }

    #[allow(unused_variables)]
    fn truncate(&mut self, id: usize, len: usize) -> Result<()> {
        Err(SysError::new(EBADF))
    }
}
<|endoftext|>