<commit_before>use control_updates as cu;
use serde_json::Value;
use std::collections::BTreeMap;
use std::fmt::Debug;

// --------------------------------------------------------
// root obj.  contains controls.
// --------------------------------------------------------

// root is not itself a Control!  although maybe it should be?
#[derive(Debug)]
pub struct Root {
  pub title: String,
  pub root_control: Box<dyn Control>,
}

// --------------------------------------------------------
// controls.
// --------------------------------------------------------

pub trait Control: Debug + Send {
  fn control_type(&self) -> &'static str;
  fn control_id(&self) -> &Vec<i32>;
  fn clone_trol(&self) -> Box<dyn Control>;
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>>;
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>>;
  fn add_control(&mut self, Box<dyn Control>);
  fn update(&mut self, _: &cu::UpdateMsg);
  fn empty_update(&self) -> Option<cu::UpdateMsg>;
  // build full update message of current state.
  fn to_update(&self) -> Option<cu::UpdateMsg>;
  fn name(&self) -> &str;
  fn as_json(&self) -> Value;
}

#[derive(Debug, Copy, Clone)]
pub enum Orientation {
  Vertical,
  Horizontal,
}

#[derive(Debug)]
pub struct Slider {
  pub control_id: Vec<i32>,
  pub name: String,
  pub label: Option<String>,
  pub pressed: bool,
  pub location: f32,
  pub orientation: Orientation,
}

impl Control for Slider {
  fn as_json(&self) -> Value {
    let mut btv = BTreeMap::new();
    btv.insert(String::from("type"), Value::String("slider".to_string()));
    btv.insert(
      String::from("orientation"),
      Value::String("vertical".to_string()),
    );
    btv.insert(String::from("name"), Value::String(self.name.to_string()));
    if let Some(lb) = &self.label {
      btv.insert(String::from("label"), Value::String(lb.to_string()));
    };
    match self.orientation {
      Orientation::Vertical => btv.insert(
        String::from("orientation"),
        Value::String("vertical".to_string()),
      ),
      Orientation::Horizontal => btv.insert(
        String::from("orientation"),
        Value::String("horizontal".to_string()),
      ),
    };
    Value::Object(btv)
  }
  fn control_type(&self) -> &'static str {
    "slider"
  }
  fn control_id(&self) -> &Vec<i32> {
    &self.control_id
  }
  fn clone_trol(&self) -> Box<dyn Control> {
    Box::new(Slider {
      control_id: self.control_id.clone(),
      name: self.name.clone(),
      label: self.label.clone(),
      pressed: self.pressed.clone(),
      location: self.location.clone(),
      orientation: self.orientation,
    })
  }
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>> {
    None
  }
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>> {
    None
  }
  fn add_control(&mut self, _control: Box<dyn Control>) {}

  fn update(&mut self, um: &cu::UpdateMsg) {
    match um {
      &cu::UpdateMsg::Slider {
        control_id: _,
        state: ref opt_state,
        location: ref opt_loc,
        label: ref opt_label,
      } => {
        if let &Some(ref st) = opt_state {
          self.pressed = match st {
            &cu::SliderState::Pressed => true,
            &cu::SliderState::Unpressed => false,
          };
        };
        if let &Some(ref loc) = opt_loc {
          self.location = *loc as f32;
        };
        if let &Some(ref t) = opt_label {
          self.label = Some(t.clone());
        };
        ()
      }
      _ => (),
    }
  }
  fn empty_update(&self) -> Option<cu::UpdateMsg> {
    Some(cu::UpdateMsg::Slider {
      control_id: self.control_id.clone(),
      state: None,
      location: None,
      label: None,
    })
  }
  fn to_update(&self) -> Option<cu::UpdateMsg> {
    let state = if self.pressed {
      cu::SliderState::Pressed
    } else {
      cu::SliderState::Unpressed
    };
    Some(cu::UpdateMsg::Slider {
      control_id: self.control_id.clone(),
      state: Some(state),
      location: Some(self.location as f64),
      label: self.label.clone(),
    })
  }
  fn name(&self) -> &str {
    &self.name[..]
  }
}

#[derive(Debug)]
pub struct Button {
  pub control_id: Vec<i32>,
  pub name: String,
  pub label: Option<String>,
  pub pressed: bool,
}

impl Control for Button {
  fn as_json(&self) -> Value {
    let mut btv = BTreeMap::new();
    btv.insert(
      String::from("type"),
      Value::String(self.control_type().to_string()),
    );
    btv.insert(String::from("name"), Value::String(self.name.to_string()));
    if let Some(lb) = &self.label {
      btv.insert(String::from("label"), Value::String(lb.to_string()));
    };
    Value::Object(btv)
  }
  fn control_type(&self) -> &'static str {
    "button"
  }
  fn control_id(&self) -> &Vec<i32> {
    &self.control_id
  }
  fn clone_trol(&self) -> Box<dyn Control> {
    Box::new(Button {
      control_id: self.control_id.clone(),
      name: self.name.clone(),
      label: self.label.clone(),
      pressed: self.pressed.clone(),
    })
  }
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>> {
    None
  }
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>> {
    None
  }
  fn add_control(&mut self, _control: Box<dyn Control>) {}
  fn update(&mut self, um: &cu::UpdateMsg) {
    match um {
      &cu::UpdateMsg::Button {
        control_id: _,
        state: ref opt_state,
        label: ref opt_label,
      } => {
        if let &Some(ref st) = opt_state {
          self.pressed = match st {
            &cu::ButtonState::Pressed => true,
            &cu::ButtonState::Unpressed => false,
          };
        };
        if let &Some(ref t) = opt_label {
          self.label = Some(t.clone());
        };
        ()
      }
      _ => (),
    }
  }
  fn empty_update(&self) -> Option<cu::UpdateMsg> {
    Some(cu::UpdateMsg::Button {
      control_id: self.control_id.clone(),
      state: None,
      label: None,
    })
  }
  fn to_update(&self) -> Option<cu::UpdateMsg> {
    let ut = if self.pressed {
      cu::ButtonState::Pressed
    } else {
      cu::ButtonState::Unpressed
    };
    Some(cu::UpdateMsg::Button {
      control_id: self.control_id.clone(),
      state: Some(ut),
      label: self.label.clone(),
    })
  }
  fn name(&self) -> &str {
    &self.name[..]
  }
}

#[derive(Debug)]
pub struct Label {
  pub control_id: Vec<i32>,
  pub name: String,
  pub label: String,
}

impl Control for Label {
  fn as_json(&self) -> Value {
    let mut btv = BTreeMap::new();
    btv.insert(
      String::from("type"),
      Value::String(self.control_type().to_string()),
    );
    btv.insert(String::from("name"), Value::String(self.name.to_string()));
    btv.insert(String::from("label"), Value::String(self.label.to_string()));
    Value::Object(btv)
  }
  fn control_type(&self) -> &'static str {
    "label"
  }
  fn control_id(&self) -> &Vec<i32> {
    &self.control_id
  }
  fn clone_trol(&self) -> Box<dyn Control> {
    Box::new(Label {
      control_id: self.control_id.clone(),
      name: self.name.clone(),
      label: self.label.clone(),
    })
  }
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>> {
    None
  }
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>> {
    None
  }
  fn add_control(&mut self, _control: Box<dyn Control>) {}
  fn update(&mut self, um: &cu::UpdateMsg) {
    match um {
      &cu::UpdateMsg::Label {
        control_id: _,
        label: ref l,
      } => {
        self.label = l.clone();
        ()
      }
      _ => (),
    }
  }
  fn empty_update(&self) -> Option<cu::UpdateMsg> {
    Some(cu::UpdateMsg::Label {
      control_id: self.control_id.clone(),
      label: String::from(""),
    })
  }
  fn to_update(&self) -> Option<cu::UpdateMsg> {
    Some(cu::UpdateMsg::Label {
      control_id: self.control_id.clone(),
      label: self.label.clone(),
    })
  }
  fn name(&self) -> &str {
    &self.name[..]
  }
}

//#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct Sizer {
  pub control_id: Vec<i32>,
  pub controls: Vec<Box<dyn Control>>,
  pub orientation: Orientation,
}

impl Control for Sizer {
  fn as_json(&self) -> Value {
    let ctrlvals = self.controls.iter().map(|c| c.as_json()).collect();
    let mut btv = BTreeMap::new();
    btv.insert(
      String::from("type"),
      Value::String(self.control_type().to_string()),
    );
    match self.orientation {
      Orientation::Vertical => btv.insert(
        String::from("orientation"),
        Value::String("vertical".to_string()),
      ),
      Orientation::Horizontal => btv.insert(
        String::from("orientation"),
        Value::String("horizontal".to_string()),
      ),
    };
    btv.insert(String::from("controls"), Value::Array(ctrlvals));
    Value::Object(btv)
  }
  fn control_type(&self) -> &'static str {
    "sizer"
  }
  fn control_id(&self) -> &Vec<i32> {
    &self.control_id
  }
  fn clone_trol(&self) -> Box<dyn Control> {
    Box::new(Sizer {
      control_id: self.control_id.clone(),
      controls: Vec::new(),
      orientation: self.orientation,
    })
  }
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>> {
    Some(&self.controls)
  }
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>> {
    Some(&mut self.controls)
  }
  fn add_control(&mut self, control: Box<dyn Control>) {
    self.controls.push(control);
  }
  fn update(&mut self, _: &cu::UpdateMsg) {}
  fn empty_update(&self) -> Option<cu::UpdateMsg> {
    None
  }
  fn to_update(&self) -> Option<cu::UpdateMsg> {
    None
  }
  fn name(&self) -> &str {
    ""
  }
}

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

pub fn get_um_id(um: &cu::UpdateMsg) -> &Vec<i32> {
  match um {
    &cu::UpdateMsg::Button {
      control_id: ref cid,
      state: _,
      label: _,
    } => &cid,
    &cu::UpdateMsg::Slider {
      control_id: ref cid,
      state: _,
      label: _,
      location: _,
    } => &cid,
    &cu::UpdateMsg::Label {
      control_id: ref cid,
      label: _,
    } => &cid,
  }
}

// --------------------------------------------------------
// control state map.  copies all the controls.
// --------------------------------------------------------

pub type ControlMap = BTreeMap<Vec<i32>, Box<dyn Control>>;

pub fn make_control_map(control: &dyn Control) -> ControlMap {
  let btm = BTreeMap::new();

  make_control_map_impl(control, btm)
}

fn make_control_map_impl(control: &dyn Control, mut map: ControlMap) -> ControlMap {
  map.insert(control.control_id().clone(), control.clone_trol());

  match control.sub_controls() {
    Some(trols) => {
      let mut item = trols.into_iter();

      loop {
        match item.next() {
          Some(x) => map = make_control_map_impl(&**x, map),
          None => break,
        }
      }
    }
    None => {}
  }

  map
}

pub type ControlNameMap = BTreeMap<String, Vec<i32>>;

pub fn control_map_to_name_map(cmap: &ControlMap) -> ControlNameMap {
  let mut iter = cmap.iter();
  let mut cnm = BTreeMap::new();

  loop {
    match iter.next() {
      Some((key, val)) => {
        let s = String::from(&*val.name());
        cnm.insert(s, key.clone());
        ()
      }
      None => break,
    }
  }

  cnm
}

pub fn cm_to_update_array(cm: &ControlMap) -> Vec<cu::UpdateMsg> {
  let mut iter = cm.iter();
  let mut result = Vec::new();

  loop {
    match iter.next() {
      Some((_, val)) => match val.to_update() {
        Some(updmsg) => result.push(updmsg),
        None => (),
      },
      None => return result,
    }
  }
}
<commit_msg>rust xy control<commit_after>use control_updates as cu;
use serde_json::Value;
use std::collections::BTreeMap;
use std::fmt::Debug;

// --------------------------------------------------------
// root obj.  contains controls.
// --------------------------------------------------------

// root is not itself a Control!  although maybe it should be?
#[derive(Debug)]
pub struct Root {
  pub title: String,
  pub root_control: Box<dyn Control>,
}

// --------------------------------------------------------
// controls.
// --------------------------------------------------------

pub trait Control: Debug + Send {
  fn control_type(&self) -> &'static str;
  fn control_id(&self) -> &Vec<i32>;
  fn clone_trol(&self) -> Box<dyn Control>;
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>>;
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>>;
  fn add_control(&mut self, Box<dyn Control>);
  fn update(&mut self, _: &cu::UpdateMsg);
  fn empty_update(&self) -> Option<cu::UpdateMsg>;
  // build full update message of current state.
  fn to_update(&self) -> Option<cu::UpdateMsg>;
  fn name(&self) -> &str;
  fn as_json(&self) -> Value;
}

#[derive(Debug, Copy, Clone)]
pub enum Orientation {
  Vertical,
  Horizontal,
}

#[derive(Debug)]
pub struct Slider {
  pub control_id: Vec<i32>,
  pub name: String,
  pub label: Option<String>,
  pub pressed: bool,
  pub location: f32,
  pub orientation: Orientation,
}

impl Control for Slider {
  fn as_json(&self) -> Value {
    let mut btv = BTreeMap::new();
    btv.insert(String::from("type"), Value::String("slider".to_string()));
    btv.insert(
      String::from("orientation"),
      Value::String("vertical".to_string()),
    );
    btv.insert(String::from("name"), Value::String(self.name.to_string()));
    if let Some(lb) = &self.label {
      btv.insert(String::from("label"), Value::String(lb.to_string()));
    };
    match self.orientation {
      Orientation::Vertical => btv.insert(
        String::from("orientation"),
        Value::String("vertical".to_string()),
      ),
      Orientation::Horizontal => btv.insert(
        String::from("orientation"),
        Value::String("horizontal".to_string()),
      ),
    };
    Value::Object(btv)
  }
  fn control_type(&self) -> &'static str {
    "slider"
  }
  fn control_id(&self) -> &Vec<i32> {
    &self.control_id
  }
  fn clone_trol(&self) -> Box<dyn Control> {
    Box::new(Slider {
      control_id: self.control_id.clone(),
      name: self.name.clone(),
      label: self.label.clone(),
      pressed: self.pressed.clone(),
      location: self.location.clone(),
      orientation: self.orientation,
    })
  }
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>> {
    None
  }
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>> {
    None
  }
  fn add_control(&mut self, _control: Box<dyn Control>) {}

  fn update(&mut self, um: &cu::UpdateMsg) {
    match um {
      &cu::UpdateMsg::Slider {
        control_id: _,
        state: ref opt_state,
        location: ref opt_loc,
        label: ref opt_label,
      } => {
        if let &Some(ref st) = opt_state {
          self.pressed = match st {
            &cu::SliderState::Pressed => true,
            &cu::SliderState::Unpressed => false,
          };
        };
        if let &Some(ref loc) = opt_loc {
          self.location = *loc as f32;
        };
        if let &Some(ref t) = opt_label {
          self.label = Some(t.clone());
        };
        ()
      }
      _ => (),
    }
  }
  fn empty_update(&self) -> Option<cu::UpdateMsg> {
    Some(cu::UpdateMsg::Slider {
      control_id: self.control_id.clone(),
      state: None,
      location: None,
      label: None,
    })
  }
  fn to_update(&self) -> Option<cu::UpdateMsg> {
    let state = if self.pressed {
      cu::SliderState::Pressed
    } else {
      cu::SliderState::Unpressed
    };
    Some(cu::UpdateMsg::Slider {
      control_id: self.control_id.clone(),
      state: Some(state),
      location: Some(self.location as f64),
      label: self.label.clone(),
    })
  }
  fn name(&self) -> &str {
    &self.name[..]
  }
}

#[derive(Debug)]
pub struct XY {
  pub control_id: Vec<i32>,
  pub name: String,
  pub label: Option<String>,
  pub pressed: bool,
  pub location: (f32,f32),
}

impl Control for XY {
  fn as_json(&self) -> Value {
    let mut btv = BTreeMap::new();
    btv.insert(String::from("type"), Value::String("slider".to_string()));
    btv.insert(String::from("name"), Value::String(self.name.to_string()));
    if let Some(lb) = &self.label {
      btv.insert(String::from("label"), Value::String(lb.to_string()));
    };
    Value::Object(btv)
  }
  fn control_type(&self) -> &'static str {
    "slider"
  }
  fn control_id(&self) -> &Vec<i32> {
    &self.control_id
  }
  fn clone_trol(&self) -> Box<dyn Control> {
    Box::new(XY {
      control_id: self.control_id.clone(),
      name: self.name.clone(),
      label: self.label.clone(),
      pressed: self.pressed.clone(),
      location: self.location.clone(),
    })
  }
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>> {
    None
  }
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>> {
    None
  }
  fn add_control(&mut self, _control: Box<dyn Control>) {}

  fn update(&mut self, um: &cu::UpdateMsg) {
    match um {
      &cu::UpdateMsg::XY {
        control_id: _,
        state: ref opt_state,
        location: ref opt_loc,
        label: ref opt_label,
      } => {
        if let &Some(ref st) = opt_state {
          self.pressed = match st {
            &cu::XYState::Pressed => true,
            &cu::XYState::Unpressed => false,
          };
        };
        if let &Some(ref loc) = opt_loc {
          self.location = *loc as f32;
        };
        if let &Some(ref t) = opt_label {
          self.label = Some(t.clone());
        };
        ()
      }
      _ => (),
    }
  }
  fn empty_update(&self) -> Option<cu::UpdateMsg> {
    Some(cu::UpdateMsg::XY {
      control_id: self.control_id.clone(),
      state: None,
      location: None,
      label: None,
    })
  }
  fn to_update(&self) -> Option<cu::UpdateMsg> {
    let state = if self.pressed {
      cu::XYState::Pressed
    } else {
      cu::XYState::Unpressed
    };
    Some(cu::UpdateMsg::XY {
      control_id: self.control_id.clone(),
      state: Some(state),
      location: Some(self.location as f64),
      label: self.label.clone(),
    })
  }
  fn name(&self) -> &str {
    &self.name[..]
  }
}

#[derive(Debug)]
pub struct Button {
  pub control_id: Vec<i32>,
  pub name: String,
  pub label: Option<String>,
  pub pressed: bool,
}

impl Control for Button {
  fn as_json(&self) -> Value {
    let mut btv = BTreeMap::new();
    btv.insert(
      String::from("type"),
      Value::String(self.control_type().to_string()),
    );
    btv.insert(String::from("name"), Value::String(self.name.to_string()));
    if let Some(lb) = &self.label {
      btv.insert(String::from("label"), Value::String(lb.to_string()));
    };
    Value::Object(btv)
  }
  fn control_type(&self) -> &'static str {
    "button"
  }
  fn control_id(&self) -> &Vec<i32> {
    &self.control_id
  }
  fn clone_trol(&self) -> Box<dyn Control> {
    Box::new(Button {
      control_id: self.control_id.clone(),
      name: self.name.clone(),
      label: self.label.clone(),
      pressed: self.pressed.clone(),
    })
  }
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>> {
    None
  }
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>> {
    None
  }
  fn add_control(&mut self, _control: Box<dyn Control>) {}
  fn update(&mut self, um: &cu::UpdateMsg) {
    match um {
      &cu::UpdateMsg::Button {
        control_id: _,
        state: ref opt_state,
        label: ref opt_label,
      } => {
        if let &Some(ref st) = opt_state {
          self.pressed = match st {
            &cu::ButtonState::Pressed => true,
            &cu::ButtonState::Unpressed => false,
          };
        };
        if let &Some(ref t) = opt_label {
          self.label = Some(t.clone());
        };
        ()
      }
      _ => (),
    }
  }
  fn empty_update(&self) -> Option<cu::UpdateMsg> {
    Some(cu::UpdateMsg::Button {
      control_id: self.control_id.clone(),
      state: None,
      label: None,
    })
  }
  fn to_update(&self) -> Option<cu::UpdateMsg> {
    let ut = if self.pressed {
      cu::ButtonState::Pressed
    } else {
      cu::ButtonState::Unpressed
    };
    Some(cu::UpdateMsg::Button {
      control_id: self.control_id.clone(),
      state: Some(ut),
      label: self.label.clone(),
    })
  }
  fn name(&self) -> &str {
    &self.name[..]
  }
}

#[derive(Debug)]
pub struct Label {
  pub control_id: Vec<i32>,
  pub name: String,
  pub label: String,
}

impl Control for Label {
  fn as_json(&self) -> Value {
    let mut btv = BTreeMap::new();
    btv.insert(
      String::from("type"),
      Value::String(self.control_type().to_string()),
    );
    btv.insert(String::from("name"), Value::String(self.name.to_string()));
    btv.insert(String::from("label"), Value::String(self.label.to_string()));
    Value::Object(btv)
  }
  fn control_type(&self) -> &'static str {
    "label"
  }
  fn control_id(&self) -> &Vec<i32> {
    &self.control_id
  }
  fn clone_trol(&self) -> Box<dyn Control> {
    Box::new(Label {
      control_id: self.control_id.clone(),
      name: self.name.clone(),
      label: self.label.clone(),
    })
  }
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>> {
    None
  }
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>> {
    None
  }
  fn add_control(&mut self, _control: Box<dyn Control>) {}
  fn update(&mut self, um: &cu::UpdateMsg) {
    match um {
      &cu::UpdateMsg::Label {
        control_id: _,
        label: ref l,
      } => {
        self.label = l.clone();
        ()
      }
      _ => (),
    }
  }
  fn empty_update(&self) -> Option<cu::UpdateMsg> {
    Some(cu::UpdateMsg::Label {
      control_id: self.control_id.clone(),
      label: String::from(""),
    })
  }
  fn to_update(&self) -> Option<cu::UpdateMsg> {
    Some(cu::UpdateMsg::Label {
      control_id: self.control_id.clone(),
      label: self.label.clone(),
    })
  }
  fn name(&self) -> &str {
    &self.name[..]
  }
}

//#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct Sizer {
  pub control_id: Vec<i32>,
  pub controls: Vec<Box<dyn Control>>,
  pub orientation: Orientation,
}

impl Control for Sizer {
  fn as_json(&self) -> Value {
    let ctrlvals = self.controls.iter().map(|c| c.as_json()).collect();
    let mut btv = BTreeMap::new();
    btv.insert(
      String::from("type"),
      Value::String(self.control_type().to_string()),
    );
    match self.orientation {
      Orientation::Vertical => btv.insert(
        String::from("orientation"),
        Value::String("vertical".to_string()),
      ),
      Orientation::Horizontal => btv.insert(
        String::from("orientation"),
        Value::String("horizontal".to_string()),
      ),
    };
    btv.insert(String::from("controls"), Value::Array(ctrlvals));
    Value::Object(btv)
  }
  fn control_type(&self) -> &'static str {
    "sizer"
  }
  fn control_id(&self) -> &Vec<i32> {
    &self.control_id
  }
  fn clone_trol(&self) -> Box<dyn Control> {
    Box::new(Sizer {
      control_id: self.control_id.clone(),
      controls: Vec::new(),
      orientation: self.orientation,
    })
  }
  fn sub_controls(&self) -> Option<&Vec<Box<dyn Control>>> {
    Some(&self.controls)
  }
  fn mut_sub_controls(&mut self) -> Option<&mut Vec<Box<dyn Control>>> {
    Some(&mut self.controls)
  }
  fn add_control(&mut self, control: Box<dyn Control>) {
    self.controls.push(control);
  }
  fn update(&mut self, _: &cu::UpdateMsg) {}
  fn empty_update(&self) -> Option<cu::UpdateMsg> {
    None
  }
  fn to_update(&self) -> Option<cu::UpdateMsg> {
    None
  }
  fn name(&self) -> &str {
    ""
  }
}

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

pub fn get_um_id(um: &cu::UpdateMsg) -> &Vec<i32> {
  match um {
    &cu::UpdateMsg::Button {
      control_id: ref cid,
      state: _,
      label: _,
    } => &cid,
    &cu::UpdateMsg::Slider {
      control_id: ref cid,
      state: _,
      label: _,
      location: _,
    } => &cid,
    &cu::UpdateMsg::Label {
      control_id: ref cid,
      label: _,
    } => &cid,
  }
}

// --------------------------------------------------------
// control state map.  copies all the controls.
// --------------------------------------------------------

pub type ControlMap = BTreeMap<Vec<i32>, Box<dyn Control>>;

pub fn make_control_map(control: &dyn Control) -> ControlMap {
  let btm = BTreeMap::new();

  make_control_map_impl(control, btm)
}

fn make_control_map_impl(control: &dyn Control, mut map: ControlMap) -> ControlMap {
  map.insert(control.control_id().clone(), control.clone_trol());

  match control.sub_controls() {
    Some(trols) => {
      let mut item = trols.into_iter();

      loop {
        match item.next() {
          Some(x) => map = make_control_map_impl(&**x, map),
          None => break,
        }
      }
    }
    None => {}
  }

  map
}

pub type ControlNameMap = BTreeMap<String, Vec<i32>>;

pub fn control_map_to_name_map(cmap: &ControlMap) -> ControlNameMap {
  let mut iter = cmap.iter();
  let mut cnm = BTreeMap::new();

  loop {
    match iter.next() {
      Some((key, val)) => {
        let s = String::from(&*val.name());
        cnm.insert(s, key.clone());
        ()
      }
      None => break,
    }
  }

  cnm
}

pub fn cm_to_update_array(cm: &ControlMap) -> Vec<cu::UpdateMsg> {
  let mut iter = cm.iter();
  let mut result = Vec::new();

  loop {
    match iter.next() {
      Some((_, val)) => match val.to_update() {
        Some(updmsg) => result.push(updmsg),
        None => (),
      },
      None => return result,
    }
  }
}
<|endoftext|>


<commit_before>//
pub mod editor;
pub mod config;
pub mod screen;
pub mod codepointinfo;
pub mod document;
pub mod buffer;
pub mod bufferlog;
pub mod mapped_file;
pub mod event;
pub mod view;
pub mod mark;
pub mod codec;
pub mod server;

/// This function starts the core thread.

/// This thread will be the "❤" of unlimited.
pub fn start() {
    server::start()
}

/// This function stops the core thread.
// TODO: return a status , ex waiting for job to finsh etc
pub fn stop() {
    server::stop()
}
<commit_msg>update docs<commit_after>//
pub mod editor;
pub mod config;
pub mod screen;
pub mod codepointinfo;
pub mod document;
pub mod buffer;
pub mod bufferlog;
pub mod mapped_file;
pub mod event;
pub mod view;
pub mod mark;
pub mod codec;
pub mod server;

/// not implemented : This function starts the core thread.

/// This thread will be the "❤" of unlimited.
pub fn start() {
    server::start()
}

/// not implemented : This function stops the core thread.
// not implemented : TODO: return a status , ex waiting for job to finsh etc
pub fn stop() {
    server::stop()
}
<|endoftext|>


<commit_before>use std::io::{File, BufferedReader};
use std::io::SeekStyle::SeekSet;
use error::{CTResult, CTDatabaseError, CTSyntaxError};
use error::CTError::{DatabaseError, SyntaxError};
use token::Token;
use token::TokenKind::Elem;

#[derive(Show, PartialEq)]
pub struct ElemData {
    short_name: String,
    long_name: String,
    mass: f64,
    atomic_num: u16,
}

pub struct ElemDatabase {
    db: BufferedReader<File>,
}

impl ElemDatabase {
    pub fn open(path: &str) -> CTResult<ElemDatabase> {
        match File::open(&Path::new(path)) {
            Ok(db_file) => Ok(ElemDatabase { db: BufferedReader::new(db_file) }),
            Err(_) => Err(DatabaseError(CTDatabaseError {
                desc: format!("Could not open database file. Expected at: {:?}", path)
            })),
        }
    }

    pub fn get_single_data(&mut self, elem: &Token) -> CTResult<ElemData> {
        // we return to the beginning of the underlying file, since the data
        // might lie on a line we have previously read past
        self.db.get_mut().seek(0, SeekSet).ok().expect("Internal error reading database");
        let mut line_iter = self.db.lines();
        let short_name = match elem.tok {
            Elem(ref name) => name.as_slice(),
            _ => unreachable!(),
        };
        // TODO: Make this cleaner, and avoid returns
        loop {
            match line_iter.next() {
                Some(Ok(ref line)) if line.starts_with(short_name) => return decode_line(line),
                Some(Err(_)) => return Err(DatabaseError(CTDatabaseError {
                    desc: "Error reading the database".to_string()
                })),
                None => return Err(SyntaxError(CTSyntaxError {
                    desc: format!("Could not find element: {:?}", short_name),
                    pos: elem.pos,
                    len: elem.len,
                })),
                _ => (),
            }
        }
    }
}

fn decode_line(line: &String) -> CTResult<ElemData> {
    let data: Vec<&str> = line.trim().split(';').collect();
    if data.len() < 4 {
        Err(DatabaseError(CTDatabaseError {
            desc: "Missing field in database".to_string()
        }))
    } else {
        let mass = data[1].parse::<f64>();
        let atomic_num = data[3].parse::<u16>();
        if let (Some(m), Some(an)) = (mass, atomic_num) {
            Ok(ElemData {
                short_name: data[0].to_string(),
                long_name: data[2].to_string(),
                mass: m,
                atomic_num: an,
            })
        } else {
            Err(DatabaseError(CTDatabaseError {
                desc: "Field in database corrupted".to_string()
            }))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io::File;
    use std::io::fs;
    use token::Token;
    use token::TokenKind::Elem;

    fn make_dummy_db(name: &str, contents: &str) -> ElemDatabase {
        if let Err(e) = File::create(&Path::new(name)).and_then(|mut f| f.write_str(contents)) {
            // if we can't make the database we can't test, so just abort here
            panic!("Could not create dummy database: {:?}", e.desc);
        }
        ElemDatabase::open(name).unwrap()
    }

    fn remove_dummy_db(name: &str) {
        if let Err(e) = fs::unlink(&Path::new(name)) {
            // if we can't remove the database something is wrong, and we abort the test
            panic!("Could not remove dummy database: {:?}", e.desc);
        }
    }

    #[test]
    fn decode() {
        let db_name = "decode_test_db";
        let mut db = make_dummy_db(db_name, "A;123.456789;Abba;12");
        let raw_result = db.get_single_data(&Token { tok: Elem("A".to_string()), pos: 0, len: 2 });
        let expected = ElemData {
            short_name: "A".to_string(),
            long_name: "Abba".to_string(),
            mass: 123.456789,
            atomic_num: 12,
        };
        remove_dummy_db(db_name);
        assert_eq!(Ok(expected), raw_result);
    }

    #[test]
    fn missing_field() {
        let db_name = "missing_field_db";
        let mut db = make_dummy_db(db_name, "A;");
        let result = db.get_single_data(&Token { tok: Elem("A".to_string()), pos: 0, len: 2 });
        remove_dummy_db(db_name);
        assert!(result.is_err());
    }

    #[test]
    fn field_corrupted() {
        let db_name = "field_corrupted_db";
        let mut db = make_dummy_db(db_name, "A;not a number;Abba;12");
        let result = db.get_single_data(&Token { tok: Elem("A".to_string()), pos: 0, len: 2 });
        remove_dummy_db(db_name);
        assert!(result.is_err());
    }
}<commit_msg>Rework get_single_data's search method<commit_after>use std::io::{File, BufferedReader};
use std::io::SeekStyle::SeekSet;
use error::{CTResult, CTDatabaseError, CTSyntaxError};
use error::CTError::{DatabaseError, SyntaxError};
use token::Token;
use token::TokenKind::Elem;

#[derive(Show, PartialEq)]
pub struct ElemData {
    short_name: String,
    long_name: String,
    mass: f64,
    atomic_num: u16,
}

pub struct ElemDatabase {
    db: BufferedReader<File>,
}

impl ElemDatabase {
    pub fn open(path: &str) -> CTResult<ElemDatabase> {
        match File::open(&Path::new(path)) {
            Ok(db_file) => Ok(ElemDatabase { db: BufferedReader::new(db_file) }),
            Err(_) => Err(DatabaseError(CTDatabaseError {
                desc: format!("Could not open database file. Expected at: {:?}", path)
            })),
        }
    }

    pub fn get_single_data(&mut self, elem: &Token) -> CTResult<ElemData> {
        // we return to the beginning of the underlying file, since the data
        // might lie on a line we have previously read past
        self.db.get_mut().seek(0, SeekSet).ok().expect("Internal error reading database");
        let mut line_iter = self.db.lines();
        let short_name = match elem.tok {
            Elem(ref name) => name.as_slice(),
            _ => unreachable!(),
        };
        match line_iter.find(|l| l.is_err() || l.as_ref().ok().unwrap().starts_with(short_name)) {
            Some(Ok(ref line)) => decode_line(line),
            Some(Err(_)) => Err(DatabaseError(CTDatabaseError {
                desc: "Error reading the database".to_string()
            })),
            None => Err(SyntaxError(CTSyntaxError {
                desc: format!("Could not find element: {:?}", short_name),
                pos: elem.pos,
                len: elem.len,
            })),
        }
    }
}

fn decode_line(line: &String) -> CTResult<ElemData> {
    let data: Vec<&str> = line.trim().split(';').collect();
    if data.len() < 4 {
        Err(DatabaseError(CTDatabaseError {
            desc: "Missing field in database".to_string()
        }))
    } else {
        let mass = data[1].parse::<f64>();
        let atomic_num = data[3].parse::<u16>();
        if let (Some(m), Some(an)) = (mass, atomic_num) {
            Ok(ElemData {
                short_name: data[0].to_string(),
                long_name: data[2].to_string(),
                mass: m,
                atomic_num: an,
            })
        } else {
            Err(DatabaseError(CTDatabaseError {
                desc: "Field in database corrupted".to_string()
            }))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io::File;
    use std::io::fs;
    use token::Token;
    use token::TokenKind::Elem;

    fn make_dummy_db(name: &str, contents: &str) -> ElemDatabase {
        if let Err(e) = File::create(&Path::new(name)).and_then(|mut f| f.write_str(contents)) {
            // if we can't make the database we can't test, so just abort here
            panic!("Could not create dummy database: {:?}", e.desc);
        }
        ElemDatabase::open(name).unwrap()
    }

    fn remove_dummy_db(name: &str) {
        if let Err(e) = fs::unlink(&Path::new(name)) {
            // if we can't remove the database something is wrong, and we abort the test
            panic!("Could not remove dummy database: {:?}", e.desc);
        }
    }

    #[test]
    fn decode() {
        let db_name = "decode_test_db";
        let mut db = make_dummy_db(db_name, "A;123.456789;Abba;12");
        let raw_result = db.get_single_data(&Token { tok: Elem("A".to_string()), pos: 0, len: 2 });
        let expected = ElemData {
            short_name: "A".to_string(),
            long_name: "Abba".to_string(),
            mass: 123.456789,
            atomic_num: 12,
        };
        remove_dummy_db(db_name);
        assert_eq!(Ok(expected), raw_result);
    }

    #[test]
    fn missing_field() {
        let db_name = "missing_field_db";
        let mut db = make_dummy_db(db_name, "A;");
        let result = db.get_single_data(&Token { tok: Elem("A".to_string()), pos: 0, len: 2 });
        remove_dummy_db(db_name);
        assert!(result.is_err());
    }

    #[test]
    fn field_corrupted() {
        let db_name = "field_corrupted_db";
        let mut db = make_dummy_db(db_name, "A;not a number;Abba;12");
        let result = db.get_single_data(&Token { tok: Elem("A".to_string()), pos: 0, len: 2 });
        remove_dummy_db(db_name);
        assert!(result.is_err());
    }
}<|endoftext|>


<commit_before>use crate::convert::{Convert};
use std::hash::{BuildHasherDefault, Hasher, BuildHasher};
use const_random::const_random;

//This value is pulled from a 64 bit LCG.
const MULTIPLE: u64 = 6364136223846793005;

const DEFAULT_KEYS: [u64; 2] = [const_random!(u64), const_random!(u64)];

#[derive(Debug, Clone)]
pub struct FallbackHasher {
    buffer: u64,
    key: u64,
}

impl FallbackHasher {
    #[inline(always)]
    fn hash(&self, data: u64) -> u64 {
        return (data.wrapping_mul(MULTIPLE)).swap_bytes();
    }

    #[inline]
    pub fn new_with_keys(key0: u64, key1: u64) -> FallbackHasher {
        FallbackHasher { buffer: key0, key: key1 }
    }
}
impl Default for FallbackHasher {
    #[inline]
    fn default() -> FallbackHasher {
        FallbackHasher {buffer: DEFAULT_KEYS[0], key: DEFAULT_KEYS[1]}
    }
}

/// Provides methods to hash all of the primitive types.
impl Hasher for FallbackHasher {

    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.buffer = self.hash(self.buffer ^ i as u64);
    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.buffer = self.hash(self.buffer ^ i as u64);
    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.buffer = self.hash(self.buffer ^ i as u64);
    }

    #[inline]
    fn write_u64(&mut self, i: u64) {
        self.buffer = self.hash(self.buffer ^ i);
    }

    #[inline]
    fn write_u128(&mut self, i: u128) {
        let data: [u64;2] = i.convert();
        self.buffer = self.hash(self.buffer ^ data[0]);
        self.buffer = self.hash(self.buffer ^ data[1]);
    }

    #[inline]
    fn write_usize(&mut self, i: usize) {
        self.write_u64(i as u64);
    }

    #[inline]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        while data.len() >= 8 {
            let (block, rest) = data.split_at(8);
            let val: u64 = as_array!(block, 8).convert();
            self.buffer = self.hash(self.buffer ^ val);
            data = rest;
        }
        if data.len() >= 4 {
            let (block, rest) = data.split_at(4);
            let val: u32 = as_array!(block, 4).convert();
            self.buffer ^= val as u64;
            self.buffer = self.buffer.rotate_left(32);
            data = rest;
        }
        if data.len() >= 2 {
            let (block, rest) = data.split_at(2);
            let val: u16 = as_array!(block, 2).convert();
            self.buffer ^= val as u64;
            self.buffer = self.buffer.rotate_left(16);
            data = rest;
        }
        if data.len() >= 1 {
            self.buffer ^= data[0] as u64;
            self.buffer = self.buffer.rotate_left(8);
        }
        self.buffer = self.hash(self.buffer ^ self.key);
    }
    #[inline]
    fn finish(&self) -> u64 {
        (self.buffer ^ self.key).wrapping_mul(MULTIPLE)
    }
}
<commit_msg>Improve speed of fallback<commit_after>use crate::convert::{Convert};
use std::hash::{BuildHasherDefault, Hasher, BuildHasher};
use const_random::const_random;

//This value is pulled from a 64 bit LCG.
const MULTIPLE: u64 = 6364136223846793005;

const DEFAULT_KEYS: [u64; 2] = [const_random!(u64), const_random!(u64)];

#[derive(Debug, Clone)]
pub struct FallbackHasher {
    buffer: u64,
    key: u64,
}

impl FallbackHasher {
    #[inline(always)]
    fn hash(&self, data: u64) -> u64 {
        return (data.wrapping_mul(MULTIPLE)).rotate_left(17);
        //Valid rotations here are 10, 12 and 17.
        //Of these 17 is selected because it is largest and relatively prime to 64.
    }

    #[inline]
    pub fn new_with_keys(key0: u64, key1: u64) -> FallbackHasher {
        FallbackHasher { buffer: key0, key: key1 }
    }
}
impl Default for FallbackHasher {
    #[inline]
    fn default() -> FallbackHasher {
        FallbackHasher {buffer: DEFAULT_KEYS[0], key: DEFAULT_KEYS[1]}
    }
}

/// Provides methods to hash all of the primitive types.
impl Hasher for FallbackHasher {

    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.buffer = self.hash(self.buffer ^ i as u64);
    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.buffer = self.hash(self.buffer ^ i as u64);
    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.buffer = self.hash(self.buffer ^ i as u64);
    }

    #[inline]
    fn write_u64(&mut self, i: u64) {
        self.buffer = self.hash(self.buffer ^ i);
    }

    #[inline]
    fn write_u128(&mut self, i: u128) {
        let data: [u64;2] = i.convert();
        self.buffer = self.hash(self.buffer ^ data[0]);
        self.buffer = self.hash(self.buffer ^ data[1]);
    }

    #[inline]
    fn write_usize(&mut self, i: usize) {
        self.write_u64(i as u64);
    }

    #[inline]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        while data.len() >= 8 {
            let (block, rest) = data.split_at(8);
            let val: u64 = as_array!(block, 8).convert();
            self.buffer = self.hash(self.buffer ^ val);
            data = rest;
        }
        if data.len() >= 4 {
            let (block, rest) = data.split_at(4);
            let val: u32 = as_array!(block, 4).convert();
            self.buffer ^= val as u64;
            self.buffer = self.buffer.rotate_left(32);
            data = rest;
        }
        if data.len() >= 2 {
            let (block, rest) = data.split_at(2);
            let val: u16 = as_array!(block, 2).convert();
            self.buffer ^= val as u64;
            self.buffer = self.buffer.rotate_left(16);
            data = rest;
        }
        if data.len() >= 1 {
            self.buffer ^= data[0] as u64;
            self.buffer = self.buffer.rotate_left(8);
        }
        self.buffer = self.hash(self.buffer ^ self.key);
    }
    #[inline]
    fn finish(&self) -> u64 {
        (self.buffer ^ self.key).wrapping_mul(MULTIPLE)
    }
}
<|endoftext|>


<commit_before>s! {
    pub struct lconv {
        pub decimal_point: *mut ::c_char,
        pub thousands_sep: *mut ::c_char,
        pub grouping: *mut ::c_char,
        pub int_curr_symbol: *mut ::c_char,
        pub currency_symbol: *mut ::c_char,
        pub mon_decimal_point: *mut ::c_char,
        pub mon_thousands_sep: *mut ::c_char,
        pub mon_grouping: *mut ::c_char,
        pub positive_sign: *mut ::c_char,
        pub negative_sign: *mut ::c_char,
        pub int_frac_digits: ::c_char,
        pub frac_digits: ::c_char,
        pub p_cs_precedes: ::c_char,
        pub p_sep_by_space: ::c_char,
        pub n_cs_precedes: ::c_char,
        pub n_sep_by_space: ::c_char,
        pub p_sign_posn: ::c_char,
        pub n_sign_posn: ::c_char,
        pub int_p_cs_precedes: ::c_char,
        pub int_p_sep_by_space: ::c_char,
        pub int_n_cs_precedes: ::c_char,
        pub int_n_sep_by_space: ::c_char,
        pub int_p_sign_posn: ::c_char,
        pub int_n_sign_posn: ::c_char,
    }
}

// https://github.com/openbsd/src/blob/master/sys/net/if.h#L187
pub const IFF_UP: ::c_int = 0x1; // interface is up
pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid
pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging
pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net
pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link
pub const IFF_STATICARP: ::c_int = 0x20; // only static ARP
pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated
pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol
pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets
pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets
pub const IFF_OACTIVE: ::c_int = 0x400; // transmission in progress
pub const IFF_SIMPLEX: ::c_int = 0x800; // can't hear own transmissions
pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit
pub const IFF_LINK1: ::c_int = 0x2000; // per link layer defined bit
pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit
pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast

extern {
    pub fn accept4(s: ::c_int, addr: *mut ::sockaddr,
                   addrlen: *mut ::socklen_t, flags: ::c_int) -> ::c_int;
    pub fn execvpe(file: *const ::c_char, argv: *const *const ::c_char,
                   envp: *const *const ::c_char) -> ::c_int;
    pub fn pledge(promises: *const ::c_char,
                  execpromises: *const ::c_char) -> ::c_int;
}

cfg_if! {
    if #[cfg(target_arch = "x86")] {
        mod x86;
        pub use self::x86::*;
    } else if #[cfg(target_arch = "x86_64")] {
        mod x86_64;
        pub use self::x86_64::*;
    } else if #[cfg(target_arch = "aarch64")] {
        mod aarch64;
        pub use self::aarch64::*;
    } else {
        // Unknown target_arch
    }
}
<commit_msg>Auto merge of #954 - cphrn:master, r=alexcrichton<commit_after>s! {
    pub struct lconv {
        pub decimal_point: *mut ::c_char,
        pub thousands_sep: *mut ::c_char,
        pub grouping: *mut ::c_char,
        pub int_curr_symbol: *mut ::c_char,
        pub currency_symbol: *mut ::c_char,
        pub mon_decimal_point: *mut ::c_char,
        pub mon_thousands_sep: *mut ::c_char,
        pub mon_grouping: *mut ::c_char,
        pub positive_sign: *mut ::c_char,
        pub negative_sign: *mut ::c_char,
        pub int_frac_digits: ::c_char,
        pub frac_digits: ::c_char,
        pub p_cs_precedes: ::c_char,
        pub p_sep_by_space: ::c_char,
        pub n_cs_precedes: ::c_char,
        pub n_sep_by_space: ::c_char,
        pub p_sign_posn: ::c_char,
        pub n_sign_posn: ::c_char,
        pub int_p_cs_precedes: ::c_char,
        pub int_p_sep_by_space: ::c_char,
        pub int_n_cs_precedes: ::c_char,
        pub int_n_sep_by_space: ::c_char,
        pub int_p_sign_posn: ::c_char,
        pub int_n_sign_posn: ::c_char,
    }
}

// https://github.com/openbsd/src/blob/master/sys/net/if.h#L187
pub const IFF_UP: ::c_int = 0x1; // interface is up
pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid
pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging
pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net
pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link
pub const IFF_STATICARP: ::c_int = 0x20; // only static ARP
pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated
pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol
pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets
pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets
pub const IFF_OACTIVE: ::c_int = 0x400; // transmission in progress
pub const IFF_SIMPLEX: ::c_int = 0x800; // can't hear own transmissions
pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit
pub const IFF_LINK1: ::c_int = 0x2000; // per link layer defined bit
pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit
pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast

extern {
    pub fn accept4(s: ::c_int, addr: *mut ::sockaddr,
                   addrlen: *mut ::socklen_t, flags: ::c_int) -> ::c_int;
    pub fn execvpe(file: *const ::c_char, argv: *const *const ::c_char,
                   envp: *const *const ::c_char) -> ::c_int;
    pub fn pledge(promises: *const ::c_char,
                  execpromises: *const ::c_char) -> ::c_int;
    pub fn strtonum(nptr: *const ::c_char, minval: ::c_longlong,
                    maxval: ::c_longlong,
                    errstr: *mut *const ::c_char) -> ::c_longlong;
}

cfg_if! {
    if #[cfg(target_arch = "x86")] {
        mod x86;
        pub use self::x86::*;
    } else if #[cfg(target_arch = "x86_64")] {
        mod x86_64;
        pub use self::x86_64::*;
    } else if #[cfg(target_arch = "aarch64")] {
        mod aarch64;
        pub use self::aarch64::*;
    } else {
        // Unknown target_arch
    }
}
<|endoftext|>


<commit_before>use piston;
use piston::input::*;
use piston::window::{AdvancedWindow, Window};
use piston_window::{Context, G2d};

use std::cmp::{max, min};
use std::fmt::{self, Debug, Formatter};
use std::rc::Rc;

use {GameState, Resources, StateTransition};
use sprites::{Sprite, SpriteSheet};
use utils::one_rest_split_iter;
use vecmath::*;
use world::{Entity, EntityLogic, EntityPhysics, MapFactory, Spawnable, World, WorldView};

mod pausemenu;

const CAMERA_MARGIN_X: f32 = 5.0;
const CAMERA_MARGIN_Y: f32 = 5.0;

struct Character {
    player: usize,
    dir: f32,
    jump: bool,
    sprite_sheet: Rc<SpriteSheet>,
}

impl fmt::Debug for Character {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Character for player={:?}", self.player)
    }
}

impl Character {
    fn new(player: usize, resources: &mut Resources) -> Character {
        Character {
            player: player,
            dir: 0.0,
            jump: false,
            sprite_sheet: resources.load_spritesheet(
                "alien/green__0000_idle_1.png"),
        }
    }
}

const CHAR_W: f32 = 0.63;
const CHAR_H: f32 = 1.29;
const MARGIN: f32 = 0.05;

impl EntityLogic for Character {
    fn update(&mut self, entity: &mut EntityPhysics, dt: f64,
              world: &mut WorldView, resources: &Resources, sprite: &mut Option<Sprite>) -> bool {
        // Characters should be in focus
        world.focus(&entity.pos);

        // Read input
        if let Some(i) = resources.input_manager.player_input(0) {
            self.dir = i.x();
            self.jump = i.jump();
        };

        // Movements
        let mut on_ground = false;
        if entity.speed.y() <= 0.05 {
            if let Some(tile) = world.map.tilef(entity.pos.x(),
                                                entity.pos.y() - CHAR_H / 2. - MARGIN) {
                if tile.collide {
                    on_ground = true;
                    entity.speed[1] = 0.0;
                    entity.pos[1] = (entity.pos.y() - CHAR_H / 2. - MARGIN).floor() +
                                    1. + CHAR_H / 2.;
                }
            }
        }
        if on_ground {
            entity.speed[0] = self.dir * 5.0;
            if self.jump {
                entity.speed[1] = 5.0;
            }
        } else {
            entity.speed[1] += -10.0 * dt as f32;
        }

        let dir = entity.speed.x().signum();
        for height in [-1.0f32, 1.0].iter() {
            if let Some(tile) = world.map.tilef(entity.pos.x() + (CHAR_W / 2. + MARGIN) * dir,
                                                entity.pos.y() - (CHAR_H / 2. - MARGIN) * height) {
                if tile.collide {
                    entity.pos[0] = (entity.pos.x() + (CHAR_W / 2. + MARGIN) * dir).floor() +
                        -dir * (CHAR_W / 2. + 0.5) + 0.5;
                    entity.speed[0] = 0.0;
                    break;
                }
            }
        }

        entity.pos = vec2_add(entity.pos, vec2_scale(entity.speed, dt as f32));

        // Set sprite
        // TODO: Animation
        *sprite = Some(Sprite {
            sheet: self.sprite_sheet.clone(),
            coords: [0, 0, 213, 428],
            size: [CHAR_W, CHAR_H],
        });

        true
    }
}

struct SimpleSpawn {
    entity_logic: Option<Box<EntityLogic>>,
}

impl SimpleSpawn {
    fn new(entity_logic: Box<EntityLogic>) -> SimpleSpawn {
        SimpleSpawn {
            entity_logic: Some(entity_logic),
        }
    }
}

impl fmt::Debug for SimpleSpawn {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(entity_logic) = self.entity_logic.as_ref() {
            write!(f, "SimpleSpawn({:?})", entity_logic)
        } else {
            write!(f, "SimpleSpawn(empty)")
        }
    }
}

impl Spawnable for SimpleSpawn {
    fn spawn(&mut self, pos: &Vector2) -> (bool, Option<Entity>) {
        (false, self.entity_logic.take().map(|entity_logic| {
            Some(Entity {
                physics: EntityPhysics {
                    pos: pos.clone(),
                    speed: [0.0, 0.0],
                },
                logic: entity_logic,
                sprite: None,
            })
        }).unwrap_or(None))
    }
}

struct Camera {
    aspect_ratio: f32,
    pos: Vector2,
    size: f32,
    update_rate: f32,
}

pub struct Game {
    pub world: World,
    camera: Camera,
}

impl Game {
    pub fn new(map_factory: MapFactory, resources: &mut Resources) -> Game {
        info!("Creating game...");

        if map_factory.nb_players < 1 {
            panic!("Can't play on map meant for 0 players");
        }

        info!("Creating map");
        let mut world = map_factory.create(resources, 42);

        info!("Creating {} characters", 1);
        let character = Character::new(0, resources);
        world.spawnables.push(Box::new(SimpleSpawn::new(Box::new(character))));

        let window_size = resources.window.size();
        let mut game = Game {
            world: world,
            camera: Camera {
                aspect_ratio: window_size.height as f32 / window_size.width as f32,
                pos: [0.0, 0.0],
                size: 10.0,
                update_rate: 1.0,
            }
        };

        // Initial update: spawns characters, set camera, ...
        game.update(0.0, resources);

        game.camera.update_rate = 0.1;
        info!("Camera: aspect_ratio = {:?}", game.camera.aspect_ratio);
        info!("Camera: Initial position: {:?}, {:?}", game.camera.pos, game.camera.size);

        game
    }
}

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

impl GameState for Game {
    fn handle_event(&mut self, event: &piston::input::Event<piston::input::Input>,
                    resources: &mut Resources) -> StateTransition
    {
        if let Some(Button::Keyboard(key)) = event.press_args() {
            if key == Key::Escape {
                return StateTransition::Push(Box::new(pausemenu::PauseMenu::new(resources)));
            }
        }

        resources.input_manager.handle_event(event);

        StateTransition::Continue
    }

    fn update(&mut self, dt: f64, resources: &mut Resources) -> StateTransition {
        resources.input_manager.update(dt);

        let map = &mut self.world.map;
        let spawnables = &mut self.world.spawnables;
        let mut focus = None;
        one_rest_split_iter(&mut self.world.entities, |mut entity, other_entities| {
            let mut world_view = WorldView {
                map: map,
                entities: other_entities,
                spawnables: spawnables,
                focus: &mut focus,
            };
            entity.logic.update(&mut entity.physics, dt,
                                &mut world_view, resources, &mut entity.sprite);
        });
        if let Some((a, b)) = focus {
            let a = [a.x() - CAMERA_MARGIN_X, a.y() - CAMERA_MARGIN_Y];
            let b = [b.x() + CAMERA_MARGIN_X, b.y() + CAMERA_MARGIN_Y];

            let mut camera = &mut self.camera;

            // Compute desired camera position
            let ratio = camera.aspect_ratio;
            let size = (b.x() - a.x()).max((b.y() - a.y())/ratio as f32);
            let pos = [(a.x() + b.x() - size)/2.0,
                       (a.y() + b.y() - size * ratio)/2.0];

            // Update current camera position according to update rate
            camera.pos = vec2_add(vec2_scale(camera.pos, 1.0 - camera.update_rate),
                                  vec2_scale(pos, camera.update_rate));
            camera.size = camera.size * (1.0 - camera.update_rate) + size * camera.update_rate;
        }

        StateTransition::Continue
    }

    fn draw(&mut self, c: Context, g: &mut G2d) {
        use graphics::*;

        let (width, height) = if let Some(v) = c.viewport {
            (v.rect[2], v.rect[3])
        } else {
            warn!("Got Context with no attached Viewport");
            return;
        };

        // Clear the screen.
        clear([0.0, 0.0, 0.5, 1.0], g);

        // Compute transformation from camera
        let zoom = width as f64 / self.camera.size as f64;
        let transform = c.transform
            .trans(0.0, height as f64)
            .scale(1.0, -1.0)
            .scale(zoom, zoom)
            .trans(-self.camera.pos.x() as f64, -self.camera.pos.y() as f64);

        let x1 = max(self.camera.pos.x() as i32 - 1, 0);
        let y1 = max(self.camera.pos.y() as i32 - 1, 0);
        let x2 = min((self.camera.pos.x() + self.camera.size + 1.0) as i32,
                     self.world.map.width as i32);
        let y2 = min((self.camera.pos.y() + self.camera.size * self.camera.aspect_ratio + 1.0) as i32,
                            self.world.map.height as i32);

        // Draw map
        for y in y1..y2 {
            for x in x1..x2 {
                if let Some(ref sprite) = self.world.map.tile(x, y).unwrap().sprite {
                    let image = Image::new()
                        .src_rect(sprite.coords)
                        .rect([(x as f32 + 0.5 - sprite.size[0] / 2.0) as f64,
                               (y as f32 + 0.5 + sprite.size[1] / 2.0) as f64,
                               sprite.size[0] as f64,
                               -sprite.size[1] as f64]);
                    image.draw(&sprite.sheet.texture, &DrawState::default(),
                               transform, g);
                }
            }
        }

        // Debug: draw grid
        for x in x1..x2 {
            rectangle([1.0, 1.0, 1.0, 1.0],
                      rectangle::centered([x as f64, (y1 + y2) as f64 * 0.5,
                                           0.5 / zoom as f64, (y2 - y1) as f64 * 0.5]),
                      transform, g);
        }
        for y in y1..y2 {
            rectangle([1.0, 1.0, 1.0, 1.0],
                      rectangle::centered([(x1 + x2) as f64 * 0.5, y as f64,
                                           (x2 - x1) as f64 * 0.5, 0.5 / zoom as f64]),
                      transform, g);
        }

        // Draw entities
        for entity in self.world.entities.iter() {
            if let Some(ref sprite) = entity.sprite {
                let image = Image::new()
                    .src_rect(sprite.coords)
                    .rect([(entity.physics.pos.x() - sprite.size[0] / 2.0) as f64,
                           (entity.physics.pos.y() + sprite.size[1] / 2.0) as f64,
                           sprite.size[0] as f64,
                           -sprite.size[1] as f64]);
                image.draw(&sprite.sheet.texture, &DrawState::default(),
                           transform, g);
            } else {
                // Debug: circle invisible entities
                let circle = CircleArc::new(
                    [1.0, 0.0, 0.0, 1.0],
                    0.05, 0.0, 2.0 * ::std::f64::consts::PI);
                circle.draw(
                    rectangle::centered([entity.physics.pos.x() as f64, entity.physics.pos.y() as f64, 0.5, 0.5]),
                    &DrawState::default(), transform, g);
            }
        }
    }

    fn pause(&mut self, resources: &mut Resources) {
        resources.window.set_capture_cursor(false);
    }

    fn resume(&mut self, resources: &mut Resources) {
        resources.window.set_capture_cursor(true);
    }
}
<commit_msg>Allows air control<commit_after>use piston;
use piston::input::*;
use piston::window::{AdvancedWindow, Window};
use piston_window::{Context, G2d};

use std::cmp::{max, min};
use std::fmt::{self, Debug, Formatter};
use std::rc::Rc;

use {GameState, Resources, StateTransition};
use sprites::{Sprite, SpriteSheet};
use utils::one_rest_split_iter;
use vecmath::*;
use world::{Entity, EntityLogic, EntityPhysics, MapFactory, Spawnable, World, WorldView};

mod pausemenu;

const CAMERA_MARGIN_X: f32 = 5.0;
const CAMERA_MARGIN_Y: f32 = 5.0;

struct Character {
    player: usize,
    dir: f32,
    jump: bool,
    sprite_sheet: Rc<SpriteSheet>,
}

impl fmt::Debug for Character {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Character for player={:?}", self.player)
    }
}

impl Character {
    fn new(player: usize, resources: &mut Resources) -> Character {
        Character {
            player: player,
            dir: 0.0,
            jump: false,
            sprite_sheet: resources.load_spritesheet(
                "alien/green__0000_idle_1.png"),
        }
    }
}

const CHAR_W: f32 = 0.63;
const CHAR_H: f32 = 1.29;
const MARGIN: f32 = 0.05;

impl EntityLogic for Character {
    fn update(&mut self, entity: &mut EntityPhysics, dt: f64,
              world: &mut WorldView, resources: &Resources, sprite: &mut Option<Sprite>) -> bool {
        // Characters should be in focus
        world.focus(&entity.pos);

        // Read input
        if let Some(i) = resources.input_manager.player_input(0) {
            self.dir = i.x();
            self.jump = i.jump();
        };

        // Movements
        let mut on_ground = false;
        if entity.speed.y() <= 0.05 {
            if let Some(tile) = world.map.tilef(entity.pos.x(),
                                                entity.pos.y() - CHAR_H / 2. - MARGIN) {
                if tile.collide {
                    on_ground = true;
                    entity.speed[1] = 0.0;
                    entity.pos[1] = (entity.pos.y() - CHAR_H / 2. - MARGIN).floor() +
                                    1. + CHAR_H / 2.;
                }
            }
        }
        if on_ground {
            entity.speed[0] = self.dir * 5.0;
            if self.jump {
                entity.speed[1] = 5.0;
            }
        } else {
            if entity.speed.x() * self.dir.signum() < self.dir.abs() * 5.0 {
                entity.speed[0] += self.dir * 20.0 * dt as f32;
            }
            entity.speed[1] += -10.0 * dt as f32;
        }

        let dir = entity.speed.x().signum();
        for height in [-1.0f32, 1.0].iter() {
            if let Some(tile) = world.map.tilef(entity.pos.x() + (CHAR_W / 2. + MARGIN) * dir,
                                                entity.pos.y() - (CHAR_H / 2. - MARGIN) * height) {
                if tile.collide {
                    entity.pos[0] = (entity.pos.x() + (CHAR_W / 2. + MARGIN) * dir).floor() +
                        -dir * (CHAR_W / 2. + 0.5) + 0.5;
                    entity.speed[0] = 0.0;
                    break;
                }
            }
        }

        entity.pos = vec2_add(entity.pos, vec2_scale(entity.speed, dt as f32));

        // Set sprite
        // TODO: Animation
        *sprite = Some(Sprite {
            sheet: self.sprite_sheet.clone(),
            coords: [0, 0, 213, 428],
            size: [CHAR_W, CHAR_H],
        });

        true
    }
}

struct SimpleSpawn {
    entity_logic: Option<Box<EntityLogic>>,
}

impl SimpleSpawn {
    fn new(entity_logic: Box<EntityLogic>) -> SimpleSpawn {
        SimpleSpawn {
            entity_logic: Some(entity_logic),
        }
    }
}

impl fmt::Debug for SimpleSpawn {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(entity_logic) = self.entity_logic.as_ref() {
            write!(f, "SimpleSpawn({:?})", entity_logic)
        } else {
            write!(f, "SimpleSpawn(empty)")
        }
    }
}

impl Spawnable for SimpleSpawn {
    fn spawn(&mut self, pos: &Vector2) -> (bool, Option<Entity>) {
        (false, self.entity_logic.take().map(|entity_logic| {
            Some(Entity {
                physics: EntityPhysics {
                    pos: pos.clone(),
                    speed: [0.0, 0.0],
                },
                logic: entity_logic,
                sprite: None,
            })
        }).unwrap_or(None))
    }
}

struct Camera {
    aspect_ratio: f32,
    pos: Vector2,
    size: f32,
    update_rate: f32,
}

pub struct Game {
    pub world: World,
    camera: Camera,
}

impl Game {
    pub fn new(map_factory: MapFactory, resources: &mut Resources) -> Game {
        info!("Creating game...");

        if map_factory.nb_players < 1 {
            panic!("Can't play on map meant for 0 players");
        }

        info!("Creating map");
        let mut world = map_factory.create(resources, 42);

        info!("Creating {} characters", 1);
        let character = Character::new(0, resources);
        world.spawnables.push(Box::new(SimpleSpawn::new(Box::new(character))));

        let window_size = resources.window.size();
        let mut game = Game {
            world: world,
            camera: Camera {
                aspect_ratio: window_size.height as f32 / window_size.width as f32,
                pos: [0.0, 0.0],
                size: 10.0,
                update_rate: 1.0,
            }
        };

        // Initial update: spawns characters, set camera, ...
        game.update(0.0, resources);

        game.camera.update_rate = 0.1;
        info!("Camera: aspect_ratio = {:?}", game.camera.aspect_ratio);
        info!("Camera: Initial position: {:?}, {:?}", game.camera.pos, game.camera.size);

        game
    }
}

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

impl GameState for Game {
    fn handle_event(&mut self, event: &piston::input::Event<piston::input::Input>,
                    resources: &mut Resources) -> StateTransition
    {
        if let Some(Button::Keyboard(key)) = event.press_args() {
            if key == Key::Escape {
                return StateTransition::Push(Box::new(pausemenu::PauseMenu::new(resources)));
            }
        }

        resources.input_manager.handle_event(event);

        StateTransition::Continue
    }

    fn update(&mut self, dt: f64, resources: &mut Resources) -> StateTransition {
        resources.input_manager.update(dt);

        let map = &mut self.world.map;
        let spawnables = &mut self.world.spawnables;
        let mut focus = None;
        one_rest_split_iter(&mut self.world.entities, |mut entity, other_entities| {
            let mut world_view = WorldView {
                map: map,
                entities: other_entities,
                spawnables: spawnables,
                focus: &mut focus,
            };
            entity.logic.update(&mut entity.physics, dt,
                                &mut world_view, resources, &mut entity.sprite);
        });
        if let Some((a, b)) = focus {
            let a = [a.x() - CAMERA_MARGIN_X, a.y() - CAMERA_MARGIN_Y];
            let b = [b.x() + CAMERA_MARGIN_X, b.y() + CAMERA_MARGIN_Y];

            let mut camera = &mut self.camera;

            // Compute desired camera position
            let ratio = camera.aspect_ratio;
            let size = (b.x() - a.x()).max((b.y() - a.y())/ratio as f32);
            let pos = [(a.x() + b.x() - size)/2.0,
                       (a.y() + b.y() - size * ratio)/2.0];

            // Update current camera position according to update rate
            camera.pos = vec2_add(vec2_scale(camera.pos, 1.0 - camera.update_rate),
                                  vec2_scale(pos, camera.update_rate));
            camera.size = camera.size * (1.0 - camera.update_rate) + size * camera.update_rate;
        }

        StateTransition::Continue
    }

    fn draw(&mut self, c: Context, g: &mut G2d) {
        use graphics::*;

        let (width, height) = if let Some(v) = c.viewport {
            (v.rect[2], v.rect[3])
        } else {
            warn!("Got Context with no attached Viewport");
            return;
        };

        // Clear the screen.
        clear([0.0, 0.0, 0.5, 1.0], g);

        // Compute transformation from camera
        let zoom = width as f64 / self.camera.size as f64;
        let transform = c.transform
            .trans(0.0, height as f64)
            .scale(1.0, -1.0)
            .scale(zoom, zoom)
            .trans(-self.camera.pos.x() as f64, -self.camera.pos.y() as f64);

        let x1 = max(self.camera.pos.x() as i32 - 1, 0);
        let y1 = max(self.camera.pos.y() as i32 - 1, 0);
        let x2 = min((self.camera.pos.x() + self.camera.size + 1.0) as i32,
                     self.world.map.width as i32);
        let y2 = min((self.camera.pos.y() + self.camera.size * self.camera.aspect_ratio + 1.0) as i32,
                            self.world.map.height as i32);

        // Draw map
        for y in y1..y2 {
            for x in x1..x2 {
                if let Some(ref sprite) = self.world.map.tile(x, y).unwrap().sprite {
                    let image = Image::new()
                        .src_rect(sprite.coords)
                        .rect([(x as f32 + 0.5 - sprite.size[0] / 2.0) as f64,
                               (y as f32 + 0.5 + sprite.size[1] / 2.0) as f64,
                               sprite.size[0] as f64,
                               -sprite.size[1] as f64]);
                    image.draw(&sprite.sheet.texture, &DrawState::default(),
                               transform, g);
                }
            }
        }

        // Debug: draw grid
        for x in x1..x2 {
            rectangle([1.0, 1.0, 1.0, 1.0],
                      rectangle::centered([x as f64, (y1 + y2) as f64 * 0.5,
                                           0.5 / zoom as f64, (y2 - y1) as f64 * 0.5]),
                      transform, g);
        }
        for y in y1..y2 {
            rectangle([1.0, 1.0, 1.0, 1.0],
                      rectangle::centered([(x1 + x2) as f64 * 0.5, y as f64,
                                           (x2 - x1) as f64 * 0.5, 0.5 / zoom as f64]),
                      transform, g);
        }

        // Draw entities
        for entity in self.world.entities.iter() {
            if let Some(ref sprite) = entity.sprite {
                let image = Image::new()
                    .src_rect(sprite.coords)
                    .rect([(entity.physics.pos.x() - sprite.size[0] / 2.0) as f64,
                           (entity.physics.pos.y() + sprite.size[1] / 2.0) as f64,
                           sprite.size[0] as f64,
                           -sprite.size[1] as f64]);
                image.draw(&sprite.sheet.texture, &DrawState::default(),
                           transform, g);
            } else {
                // Debug: circle invisible entities
                let circle = CircleArc::new(
                    [1.0, 0.0, 0.0, 1.0],
                    0.05, 0.0, 2.0 * ::std::f64::consts::PI);
                circle.draw(
                    rectangle::centered([entity.physics.pos.x() as f64, entity.physics.pos.y() as f64, 0.5, 0.5]),
                    &DrawState::default(), transform, g);
            }
        }
    }

    fn pause(&mut self, resources: &mut Resources) {
        resources.window.set_capture_cursor(false);
    }

    fn resume(&mut self, resources: &mut Resources) {
        resources.window.set_capture_cursor(true);
    }
}
<|endoftext|>


<commit_before>//! Hosting the CLR with Rust

pub mod windows;<commit_msg>OS-flagged windows hosting code<commit_after>//! Hosting the CLR with Rust

#[cfg(windows)]
pub mod windows;<|endoftext|>


<commit_before>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

mod msg_on_socket;

use std::io::Result;
use std::marker::PhantomData;
use std::os::unix::io::{AsRawFd, RawFd};
use std::pin::Pin;
use std::task::{Context, Poll};

use futures::Stream;
use libc::{EWOULDBLOCK, O_NONBLOCK};

use cros_async::add_read_waker;
use sys_util::{
    add_fd_flags, clear_fd_flags, error, handle_eintr, net::UnixSeqpacket, Error as SysError,
    ScmSocket,
};

pub use crate::msg_on_socket::*;
pub use msg_on_socket_derive::*;

/// Create a pair of socket. Request is send in one direction while response is in the other
/// direction.
pub fn pair<Request: MsgOnSocket, Response: MsgOnSocket>(
) -> Result<(MsgSocket<Request, Response>, MsgSocket<Response, Request>)> {
    let (sock1, sock2) = UnixSeqpacket::pair()?;
    let requester = MsgSocket::new(sock1);
    let responder = MsgSocket::new(sock2);
    Ok((requester, responder))
}

/// Bidirection sock that support both send and recv.
pub struct MsgSocket<I: MsgOnSocket, O: MsgOnSocket> {
    sock: UnixSeqpacket,
    _i: PhantomData<I>,
    _o: PhantomData<O>,
}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSocket<I, O> {
    // Create a new MsgSocket.
    pub fn new(s: UnixSeqpacket) -> MsgSocket<I, O> {
        MsgSocket {
            sock: s,
            _i: PhantomData,
            _o: PhantomData,
        }
    }

    // Creates an async receiver that implements `futures::Stream`.
    pub fn async_receiver(&mut self) -> MsgResult<AsyncReceiver<I, O>> {
        AsyncReceiver::new(self)
    }
}

/// One direction socket that only supports sending.
pub struct Sender<M: MsgOnSocket> {
    sock: UnixSeqpacket,
    _m: PhantomData<M>,
}

impl<M: MsgOnSocket> Sender<M> {
    /// Create a new sender sock.
    pub fn new(s: UnixSeqpacket) -> Sender<M> {
        Sender {
            sock: s,
            _m: PhantomData,
        }
    }
}

/// One direction socket that only supports receiving.
pub struct Receiver<M: MsgOnSocket> {
    sock: UnixSeqpacket,
    _m: PhantomData<M>,
}

impl<M: MsgOnSocket> Receiver<M> {
    /// Create a new receiver sock.
    pub fn new(s: UnixSeqpacket) -> Receiver<M> {
        Receiver {
            sock: s,
            _m: PhantomData,
        }
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixSeqpacket> for MsgSocket<I, O> {
    fn as_ref(&self) -> &UnixSeqpacket {
        &self.sock
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRawFd for MsgSocket<I, O> {
    fn as_raw_fd(&self) -> RawFd {
        self.sock.as_raw_fd()
    }
}

impl<M: MsgOnSocket> AsRef<UnixSeqpacket> for Sender<M> {
    fn as_ref(&self) -> &UnixSeqpacket {
        &self.sock
    }
}

impl<M: MsgOnSocket> AsRawFd for Sender<M> {
    fn as_raw_fd(&self) -> RawFd {
        self.sock.as_raw_fd()
    }
}

impl<M: MsgOnSocket> AsRef<UnixSeqpacket> for Receiver<M> {
    fn as_ref(&self) -> &UnixSeqpacket {
        &self.sock
    }
}

impl<M: MsgOnSocket> AsRawFd for Receiver<M> {
    fn as_raw_fd(&self) -> RawFd {
        self.sock.as_raw_fd()
    }
}

/// Types that could send a message.
pub trait MsgSender: AsRef<UnixSeqpacket> {
    type M: MsgOnSocket;
    fn send(&self, msg: &Self::M) -> MsgResult<()> {
        let msg_size = msg.msg_size();
        let fd_size = msg.fd_count();
        let mut msg_buffer: Vec<u8> = vec![0; msg_size];
        let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];

        let fd_size = msg.write_to_buffer(&mut msg_buffer, &mut fd_buffer)?;
        let sock: &UnixSeqpacket = self.as_ref();
        if fd_size == 0 {
            handle_eintr!(sock.send(&msg_buffer))
                .map_err(|e| MsgError::Send(SysError::new(e.raw_os_error().unwrap_or(0))))?;
        } else {
            sock.send_with_fds(&msg_buffer[..], &fd_buffer[0..fd_size])
                .map_err(MsgError::Send)?;
        }
        Ok(())
    }
}

/// Types that could receive a message.
pub trait MsgReceiver: AsRef<UnixSeqpacket> {
    type M: MsgOnSocket;
    fn recv(&self) -> MsgResult<Self::M> {
        let sock: &UnixSeqpacket = self.as_ref();

        let (msg_buffer, fd_buffer) = {
            if Self::M::uses_fd() {
                sock.recv_as_vec_with_fds()
                    .map_err(|e| MsgError::Recv(SysError::new(e.raw_os_error().unwrap_or(0))))?
            } else {
                (
                    sock.recv_as_vec().map_err(|e| {
                        MsgError::Recv(SysError::new(e.raw_os_error().unwrap_or(0)))
                    })?,
                    vec![],
                )
            }
        };

        if msg_buffer.len() == 0 && Self::M::fixed_size() != Some(0) {
            return Err(MsgError::RecvZero);
        }

        if let Some(fixed_size) = Self::M::fixed_size() {
            if fixed_size != msg_buffer.len() {
                return Err(MsgError::BadRecvSize {
                    expected: fixed_size,
                    actual: msg_buffer.len(),
                });
            }
        }

        // Safe because fd buffer is read from socket.
        let (v, read_fd_size) = unsafe { Self::M::read_from_buffer(&msg_buffer, &fd_buffer)? };
        if fd_buffer.len() != read_fd_size {
            return Err(MsgError::NotExpectFd);
        }
        Ok(v)
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSender for MsgSocket<I, O> {
    type M = I;
}
impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver for MsgSocket<I, O> {
    type M = O;
}

impl<I: MsgOnSocket> MsgSender for Sender<I> {
    type M = I;
}
impl<O: MsgOnSocket> MsgReceiver for Receiver<O> {
    type M = O;
}

/// Asynchronous adaptor for `MsgSocket`.
pub struct AsyncReceiver<'a, I: MsgOnSocket, O: MsgOnSocket> {
    inner: &'a MsgSocket<I, O>,
    done: bool, // Have hit an error and the Stream should return null when polled.
}

impl<'a, I: MsgOnSocket, O: MsgOnSocket> AsyncReceiver<'a, I, O> {
    fn new(msg_socket: &MsgSocket<I, O>) -> MsgResult<AsyncReceiver<I, O>> {
        add_fd_flags(msg_socket.as_raw_fd(), O_NONBLOCK).map_err(MsgError::SettingFdFlags)?;
        Ok(AsyncReceiver {
            inner: msg_socket,
            done: false,
        })
    }
}

impl<'a, I: MsgOnSocket, O: MsgOnSocket> Drop for AsyncReceiver<'a, I, O> {
    fn drop(&mut self) {
        if let Err(e) = clear_fd_flags(self.inner.as_raw_fd(), O_NONBLOCK) {
            error!(
                "Failed to restore non-blocking behavior to message socket: {}",
                e
            );
        }
    }
}

impl<'a, I: MsgOnSocket, O: MsgOnSocket> Stream for AsyncReceiver<'a, I, O> {
    type Item = MsgResult<O>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        if self.done {
            return Poll::Ready(None);
        }

        let ret = match self.inner.recv() {
            Ok(msg) => Ok(Poll::Ready(Some(Ok(msg)))),
            Err(MsgError::Recv(e)) => {
                if e.errno() == EWOULDBLOCK {
                    add_read_waker(self.inner.as_raw_fd(), cx.waker().clone())
                        .map(|_| Poll::Pending)
                        .map_err(MsgError::AddingWaker)
                } else {
                    Err(MsgError::Recv(e))
                }
            }
            Err(e) => Err(e),
        };

        match ret {
            Ok(p) => p,
            Err(e) => {
                // Indicate something went wrong and no more events will be provided.
                self.done = true;
                Poll::Ready(Some(Err(e)))
            }
        }
    }
}
<commit_msg>msg_socket: AsyncReceiver doesn't need a mut ref<commit_after>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

mod msg_on_socket;

use std::io::Result;
use std::marker::PhantomData;
use std::os::unix::io::{AsRawFd, RawFd};
use std::pin::Pin;
use std::task::{Context, Poll};

use futures::Stream;
use libc::{EWOULDBLOCK, O_NONBLOCK};

use cros_async::add_read_waker;
use sys_util::{
    add_fd_flags, clear_fd_flags, error, handle_eintr, net::UnixSeqpacket, Error as SysError,
    ScmSocket,
};

pub use crate::msg_on_socket::*;
pub use msg_on_socket_derive::*;

/// Create a pair of socket. Request is send in one direction while response is in the other
/// direction.
pub fn pair<Request: MsgOnSocket, Response: MsgOnSocket>(
) -> Result<(MsgSocket<Request, Response>, MsgSocket<Response, Request>)> {
    let (sock1, sock2) = UnixSeqpacket::pair()?;
    let requester = MsgSocket::new(sock1);
    let responder = MsgSocket::new(sock2);
    Ok((requester, responder))
}

/// Bidirection sock that support both send and recv.
pub struct MsgSocket<I: MsgOnSocket, O: MsgOnSocket> {
    sock: UnixSeqpacket,
    _i: PhantomData<I>,
    _o: PhantomData<O>,
}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSocket<I, O> {
    // Create a new MsgSocket.
    pub fn new(s: UnixSeqpacket) -> MsgSocket<I, O> {
        MsgSocket {
            sock: s,
            _i: PhantomData,
            _o: PhantomData,
        }
    }

    // Creates an async receiver that implements `futures::Stream`.
    pub fn async_receiver(&self) -> MsgResult<AsyncReceiver<I, O>> {
        AsyncReceiver::new(self)
    }
}

/// One direction socket that only supports sending.
pub struct Sender<M: MsgOnSocket> {
    sock: UnixSeqpacket,
    _m: PhantomData<M>,
}

impl<M: MsgOnSocket> Sender<M> {
    /// Create a new sender sock.
    pub fn new(s: UnixSeqpacket) -> Sender<M> {
        Sender {
            sock: s,
            _m: PhantomData,
        }
    }
}

/// One direction socket that only supports receiving.
pub struct Receiver<M: MsgOnSocket> {
    sock: UnixSeqpacket,
    _m: PhantomData<M>,
}

impl<M: MsgOnSocket> Receiver<M> {
    /// Create a new receiver sock.
    pub fn new(s: UnixSeqpacket) -> Receiver<M> {
        Receiver {
            sock: s,
            _m: PhantomData,
        }
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixSeqpacket> for MsgSocket<I, O> {
    fn as_ref(&self) -> &UnixSeqpacket {
        &self.sock
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRawFd for MsgSocket<I, O> {
    fn as_raw_fd(&self) -> RawFd {
        self.sock.as_raw_fd()
    }
}

impl<M: MsgOnSocket> AsRef<UnixSeqpacket> for Sender<M> {
    fn as_ref(&self) -> &UnixSeqpacket {
        &self.sock
    }
}

impl<M: MsgOnSocket> AsRawFd for Sender<M> {
    fn as_raw_fd(&self) -> RawFd {
        self.sock.as_raw_fd()
    }
}

impl<M: MsgOnSocket> AsRef<UnixSeqpacket> for Receiver<M> {
    fn as_ref(&self) -> &UnixSeqpacket {
        &self.sock
    }
}

impl<M: MsgOnSocket> AsRawFd for Receiver<M> {
    fn as_raw_fd(&self) -> RawFd {
        self.sock.as_raw_fd()
    }
}

/// Types that could send a message.
pub trait MsgSender: AsRef<UnixSeqpacket> {
    type M: MsgOnSocket;
    fn send(&self, msg: &Self::M) -> MsgResult<()> {
        let msg_size = msg.msg_size();
        let fd_size = msg.fd_count();
        let mut msg_buffer: Vec<u8> = vec![0; msg_size];
        let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];

        let fd_size = msg.write_to_buffer(&mut msg_buffer, &mut fd_buffer)?;
        let sock: &UnixSeqpacket = self.as_ref();
        if fd_size == 0 {
            handle_eintr!(sock.send(&msg_buffer))
                .map_err(|e| MsgError::Send(SysError::new(e.raw_os_error().unwrap_or(0))))?;
        } else {
            sock.send_with_fds(&msg_buffer[..], &fd_buffer[0..fd_size])
                .map_err(MsgError::Send)?;
        }
        Ok(())
    }
}

/// Types that could receive a message.
pub trait MsgReceiver: AsRef<UnixSeqpacket> {
    type M: MsgOnSocket;
    fn recv(&self) -> MsgResult<Self::M> {
        let sock: &UnixSeqpacket = self.as_ref();

        let (msg_buffer, fd_buffer) = {
            if Self::M::uses_fd() {
                sock.recv_as_vec_with_fds()
                    .map_err(|e| MsgError::Recv(SysError::new(e.raw_os_error().unwrap_or(0))))?
            } else {
                (
                    sock.recv_as_vec().map_err(|e| {
                        MsgError::Recv(SysError::new(e.raw_os_error().unwrap_or(0)))
                    })?,
                    vec![],
                )
            }
        };

        if msg_buffer.len() == 0 && Self::M::fixed_size() != Some(0) {
            return Err(MsgError::RecvZero);
        }

        if let Some(fixed_size) = Self::M::fixed_size() {
            if fixed_size != msg_buffer.len() {
                return Err(MsgError::BadRecvSize {
                    expected: fixed_size,
                    actual: msg_buffer.len(),
                });
            }
        }

        // Safe because fd buffer is read from socket.
        let (v, read_fd_size) = unsafe { Self::M::read_from_buffer(&msg_buffer, &fd_buffer)? };
        if fd_buffer.len() != read_fd_size {
            return Err(MsgError::NotExpectFd);
        }
        Ok(v)
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSender for MsgSocket<I, O> {
    type M = I;
}
impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver for MsgSocket<I, O> {
    type M = O;
}

impl<I: MsgOnSocket> MsgSender for Sender<I> {
    type M = I;
}
impl<O: MsgOnSocket> MsgReceiver for Receiver<O> {
    type M = O;
}

/// Asynchronous adaptor for `MsgSocket`.
pub struct AsyncReceiver<'a, I: MsgOnSocket, O: MsgOnSocket> {
    inner: &'a MsgSocket<I, O>,
    done: bool, // Have hit an error and the Stream should return null when polled.
}

impl<'a, I: MsgOnSocket, O: MsgOnSocket> AsyncReceiver<'a, I, O> {
    fn new(msg_socket: &MsgSocket<I, O>) -> MsgResult<AsyncReceiver<I, O>> {
        add_fd_flags(msg_socket.as_raw_fd(), O_NONBLOCK).map_err(MsgError::SettingFdFlags)?;
        Ok(AsyncReceiver {
            inner: msg_socket,
            done: false,
        })
    }
}

impl<'a, I: MsgOnSocket, O: MsgOnSocket> Drop for AsyncReceiver<'a, I, O> {
    fn drop(&mut self) {
        if let Err(e) = clear_fd_flags(self.inner.as_raw_fd(), O_NONBLOCK) {
            error!(
                "Failed to restore non-blocking behavior to message socket: {}",
                e
            );
        }
    }
}

impl<'a, I: MsgOnSocket, O: MsgOnSocket> Stream for AsyncReceiver<'a, I, O> {
    type Item = MsgResult<O>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        if self.done {
            return Poll::Ready(None);
        }

        let ret = match self.inner.recv() {
            Ok(msg) => Ok(Poll::Ready(Some(Ok(msg)))),
            Err(MsgError::Recv(e)) => {
                if e.errno() == EWOULDBLOCK {
                    add_read_waker(self.inner.as_raw_fd(), cx.waker().clone())
                        .map(|_| Poll::Pending)
                        .map_err(MsgError::AddingWaker)
                } else {
                    Err(MsgError::Recv(e))
                }
            }
            Err(e) => Err(e),
        };

        match ret {
            Ok(p) => p,
            Err(e) => {
                // Indicate something went wrong and no more events will be provided.
                self.done = true;
                Poll::Ready(Some(Err(e)))
            }
        }
    }
}
<|endoftext|>


<commit_before>extern mod extra;

use std::from_str::from_str;
use std::io::net::ip::SocketAddr;
use std::io::net::tcp::{TcpListener,TcpStream};
use std::io::{Acceptor,Listener};
use std::run::{Process,ProcessOptions};

use extra::url::Url;

// Note: Error handling should be improved
fn main() {
        let browserCommand = "firefox";
        let address = "127.0.0.1:7777";

        // Prepare a socket listening on localhost:7777
        let addr: SocketAddr = from_str(address).expect(format!("Invalid address: {}", address));
        let listener = TcpListener::bind(addr).expect(format!("Failed to bind to: {}", address));
        let mut acceptor = listener.listen().expect("Could not listen");

        // Infinite loop to keep handling new connections.
        loop {
                let tcpStream = acceptor.accept().expect("Could not accept connection");
                debug!("Accepted new connection");
                do spawn {
                        handleClient(tcpStream, browserCommand)
                }
        }
}

// Accept a new connection and listen for URLs
fn handleClient(tcpStream: TcpStream, browserCommand: &'static str) {
        debug!("Spawned new task");

        let mut tcpStream = tcpStream;

        // Note that as soon as read_to_str() returns, everything sent
        // to the socket after this point will be discarded as once
        // we're done working with the content we've just read, the
        // tcpStream will be freed.
        let message = tcpStream.read_to_str();

        // Iterate over the lines in the received message
        for line in message.lines() {
                debug!("Current line is: {}", line);

                // This tries to convert the line to a Url struct
                let url: Option<Url> = from_str(line);

                // If this fails, it returns None, else we got a valid
                // URL
                match url {
                        None     => { info!("No Url found") }
                        Some(u)  => {
                                debug!("Found Url in: {}", line);
                                if checkUrl(&u) {
                                        spawnProcess(&u, browserCommand)
                                }
                        }
                }
        }
}

// Check that the URL is actually usable
fn checkUrl(u: &Url) -> bool {
        (u.scheme == ~"http" || u.scheme == ~"https" ) && u.host != ~""
}

// Spawn a browser to access the URL
fn spawnProcess(u: &Url, command: &'static str) {
        debug!("Spawning process {} {}", command, u.to_str());
        let pOptions = ProcessOptions::new();
        let mut child = Process::new(command, [u.to_str()], pOptions).expect("Could not fork process");
        child.finish();
}<commit_msg>Minor cleanup<commit_after>extern mod extra;

use std::from_str::from_str;
use std::io::net::tcp::{TcpListener,TcpStream};
use std::io::{Acceptor,Listener};
use std::run::{Process,ProcessOptions};

use extra::url::Url;

// Note: Error handling should be improved
fn main() {
        let browserCommand = "firefox";
        let address = "127.0.0.1:7777";

        // Prepare a socket listening on localhost:7777
        let addr = from_str(address).expect(format!("Invalid address: {}", address));
        let listener = TcpListener::bind(addr).expect(format!("Failed to bind to: {}", address));
        let mut acceptor = listener.listen().expect("Could not listen");

        // Infinite loop to keep handling new connections.
        loop {
                let tcpStream = acceptor.accept().expect("Could not accept connection");
                debug!("Accepted new connection");
                do spawn {
                        handleClient(tcpStream, browserCommand)
                }
        }
}

// Accept a new connection and listen for URLs
fn handleClient(tcpStream: TcpStream, browserCommand: &'static str) {
        debug!("Spawned new task");

        let mut tcpStream = tcpStream;

        // Note that as soon as read_to_str() returns, everything sent
        // to the socket after this point will be discarded as once
        // we're done working with the content we've just read, the
        // tcpStream will be freed.
        let message = tcpStream.read_to_str();

        // Iterate over the lines in the received message
        for line in message.lines() {
                debug!("Current line is: {}", line);

                // This tries to convert the line to a Url struct
                let url = from_str(line);

                // On failure it returns None; on success a valid URL
                match url {
                        None     => { info!("No Url found") }
                        Some(u)  => {
                                debug!("Found Url in: {}", line);
                                if checkUrl(&u) {
                                        spawnProcess(&u, browserCommand)
                                }
                        }
                }
        }
}

// Check that the URL is actually usable
fn checkUrl(u: &Url) -> bool {
        (u.scheme == ~"http" || u.scheme == ~"https" ) && u.host != ~""
}

// Spawn a browser to access the URL
fn spawnProcess(u: &Url, command: &'static str) {
        debug!("Spawning process {} {}", command, u.to_str());
        let pOptions = ProcessOptions::new();
        let mut child = Process::new(command, [u.to_str()], pOptions).expect("Could not fork process");
        child.finish();
}<|endoftext|>