<commit_before>use super::TreeNode;
use exprs::MacroType;
use types::{AttrsAndVisType, AttrsAndBlockType, ReturnType, AttrType};

#[derive(Debug, Clone)]
pub struct CrateType {
  pub inner_attrs: Vec<AttrType>,
  pub mod_items: Vec<ModItemType>,
}

impl CrateType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    let mod_items = value.get_nodes().into_iter().next().map(|items|
      items.get_nodes().into_iter().map(|item| ModItemType::from_tree(&item)).collect()).unwrap_or(Vec::new());
    let mut krate = CrateType {
      inner_attrs: vec![],
      mod_items: mod_items,
    };
    krate.identify_types();
    krate
  }

  pub fn unknown_type_count(&self) -> u32 {
    self.mod_items.iter().fold(0, |acc, item| acc + item.unknown_type_count())
  }

  pub fn identify_types(&mut self) {
    loop {
      let before = self.unknown_type_count();
      for mod_item in self.mod_items.iter_mut() {
        mod_item.identify_types();
      }
      let after = self.unknown_type_count();
      if after == 0 {
        break;
      }
      if before == after {
        panic!("Cannot identify {} types in {:?}", after, self);
      }
    }
  }
}

#[derive(Debug, Clone)]
pub struct ModItemType {
  pub attrs_and_vis: AttrsAndVisType,
  pub item: ItemType,
}

impl ModItemType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    assert_eq!(value.get_name(), "Item");
    let nodes = value.get_nodes();
    assert_eq!(nodes.len(), 2);
    ModItemType {
      attrs_and_vis: AttrsAndVisType::from_tree(&nodes[0]),
      item: ItemType::from_tree(&nodes[1]),
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    self.item.unknown_type_count()
  }

  fn identify_types(&mut self) {
    self.item.identify_types();
  }
}

#[derive(Debug, Clone)]
pub struct ImplMethodType {
  pub attrs_and_vis: AttrsAndVisType,
  pub is_static: bool,
  pub is_unsafe: bool,
  pub name: String,
  pub generic_params: (Vec<String>, Vec<String>),
  pub fn_decl: (Vec<ParameterType>, Option<Vec<String>>),
  pub where_clause: Vec<String>,
  pub inner_attrs_and_block: AttrsAndBlockType,
}

impl ImplMethodType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    let fn_decl_node = value.get_node_by_name("FnDecl").unwrap();
    let is_static = fn_decl_node.get_node_by_name("SelfStatic").is_some();
    let fn_decl: (Vec<ParameterType>, Option<Vec<String>>) = {
      (fn_decl_node.get_nodes()[0].get_nodes()[0].get_nodes().iter().map(|arg| {
         let name = arg
           .get_node_by_name("PatLit").unwrap()
           .get_components_ident_joined();
         let parameter_type = arg
           .get_node_by_name("TySum").unwrap()
           .get_node_by_name("TyPath").unwrap()
           .get_components_ident();
         ParameterType { name: name, parameter_type: parameter_type }
         }).collect(),
       fn_decl_node.get_node_by_name("ret-ty")
         .and_then(|node| node.get_node_by_name("TyPath"))
         .map(|node| node.get_components_ident())
       )
    };

    let return_type = match fn_decl.1 {
      Some(ref v) => ReturnType::Some(v.clone()),
      None => ReturnType::None,
    };

    ImplMethodType {
      attrs_and_vis: AttrsAndVisType::from_tree(value.get_node_by_name("AttrsAndVis").unwrap()),
      is_static: is_static,
      is_unsafe: !value.get_nodes()[1].is_null(),
      name: value.get_node_by_name("ident").unwrap()
        .get_string_nodes().into_iter().next().unwrap(),
      generic_params: (vec![], vec![]),
      where_clause: vec![],
      fn_decl: fn_decl,
      inner_attrs_and_block: AttrsAndBlockType::from_tree(value, return_type),
    }
  }
}

#[derive(Debug, Clone)]
pub enum ImplItemType {
  ImplMethod(ImplMethodType)
}

impl ImplItemType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    match &*value.get_name() {
      "Method" => ImplItemType::ImplMethod(ImplMethodType::from_tree(value)),
      _ => panic!("{:?}", value),
    }
  }

  pub fn get_name(&self) -> String {
    match *self {
      ImplItemType::ImplMethod(ref t) => t.name.clone(),
    }
  }

  pub fn is_static(&self) -> bool {
    match *self {
      ImplItemType::ImplMethod(ref t) => t.is_static,
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    match *self {
      ImplItemType::ImplMethod(ref t) => t.inner_attrs_and_block.block.unknown_type_count(),
    }
  }

  fn identify_types(&mut self) {
    match *self {
      ImplItemType::ImplMethod(ref mut t) => t.inner_attrs_and_block.block.identify_types(),
    }
  }
}

#[derive(Debug, Clone)]
pub struct ImplType {
  pub is_unsafe: bool,
  pub name: String,
  pub generic_params: (Vec<String>, Vec<String>),
  pub attr: AttrType,
  pub items: Vec<ImplItemType>
}

impl ImplType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    let nodes = value.get_nodes();
    ImplType {
      is_unsafe: !nodes[0].is_null(),
      name: value
        .get_node_by_name("TySum").unwrap()
        .get_node_by_name("TyPath").unwrap()
        .get_components_ident_joined(),
      generic_params: (vec![], vec![]),
      attr: AttrType { doc_comment: None },
      items: value.get_node_by_name("ImplItems")
        .map(|items| items.get_nodes().iter().map(|item| ImplItemType::from_tree(item)).collect())
        .unwrap_or(vec![])
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    self.items.iter().fold(0, |acc, item| acc + item.unknown_type_count())
  }

  pub fn identify_types(&mut self) {
    for item in self.items.iter_mut() {
      item.identify_types();
    }
  }
}

#[derive(Debug, Clone)]
pub struct StructType {
  pub name: String,
  pub generic_params: (Vec<String>, Vec<String>),
  pub where_clause: Vec<String>,
  pub fields: Vec<StructFieldType>,
}

#[derive(Debug, Clone)]
pub struct StructFieldType {
  pub attrs_and_vis: AttrsAndVisType,
  pub name: String,
  pub parameter_type: Vec<String>,
}

impl StructType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    assert_eq!(value.get_name(), "ItemStruct");
    assert_eq!(value.get_nodes().len(), 4);
    let name = value.get_node_by_name("ident").unwrap()
      .get_string_nodes().into_iter().next().unwrap();
    StructType {
      name: name,
      generic_params: (vec![], vec![]),
      where_clause: vec![],
      fields: value.get_node_by_name("StructFields")
        .map(|fields| fields.get_nodes())
        .unwrap_or(vec![])
        .iter()
        .map(|node| {
          StructFieldType {
            attrs_and_vis: AttrsAndVisType::from_tree(node.get_node_by_name("AttrsAndVis").unwrap()),
            name: node
              .get_node_by_name("ident").unwrap()
              .get_string_nodes().join(""),
            parameter_type: node
              .get_node_by_name("TySum").unwrap()
              .get_node_by_name("TyPath").unwrap()
              .get_components_ident(),
          }
        })
        .collect(),
    }
  }
}

#[derive(Debug, Clone)]
pub enum ItemType {
  ItemFn(ItemFnType),
  ItemStruct(StructType),
  ItemMacro(MacroType),
  ItemImpl(ImplType),
  ViewItemExternCrate(ViewItemExternCrateType),
  ItemMod(ModType),
}

impl ItemType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    match &*value.get_name() {
      "ItemFn" => ItemType::ItemFn(ItemFnType::from_tree(value)),
      "ItemMacro" => ItemType::ItemMacro(MacroType::from_tree(value, ReturnType::None)),
      "ItemStruct" => ItemType::ItemStruct(StructType::from_tree(value)),
      "ItemImpl" => ItemType::ItemImpl(ImplType::from_tree(value)),
      "ViewItemExternCrate" => ItemType::ViewItemExternCrate(ViewItemExternCrateType::from_tree(value)),
      "ItemMod" => ItemType::ItemMod(ModType::from_tree(value)),
      _ => panic!("{:?}", value),
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    match *self {
      ItemType::ItemFn(ref i) => i.unknown_type_count(),
      ItemType::ItemStruct(_) => 0,
      ItemType::ItemMacro(_) => 0,
      ItemType::ItemImpl(ref i) => i.unknown_type_count(),
      ItemType::ViewItemExternCrate(_) => 0,
      ItemType::ItemMod(_) => 0,
    }
  }

  pub fn identify_types(&mut self) {
    match *self {
      ItemType::ItemFn(ref mut i) => i.identify_types(),
      ItemType::ItemStruct(_) => (),
      ItemType::ItemMacro(_) => (),
      ItemType::ItemImpl(ref mut i) => i.identify_types(),
      ItemType::ViewItemExternCrate(_) => (),
      ItemType::ItemMod(_) => (),
    }
  }
}

#[derive(Debug, Clone)]
pub struct ParameterType {
  pub name: String,
  pub parameter_type: Vec<String>,
}

#[derive(Debug, Clone)]
pub struct ItemFnType {
  pub name: String,
  pub generic_params: (Vec<String>, Vec<String>),
  pub fn_decl: (Vec<ParameterType>, Option<Vec<String>>),
  pub inner_attrs_and_block: AttrsAndBlockType,
}

impl ItemFnType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    assert_eq!(value.get_name(), "ItemFn");
    let name = value.get_node_by_name("ident").unwrap()
      .get_string_nodes().into_iter().next().unwrap();
    let fn_decl: (Vec<ParameterType>, Option<Vec<String>>) = value.
      get_node_by_name("FnDecl").map(|node| {
          (node.get_node_by_name("Args")
           .map(|args|
             args.get_nodes().iter().map(|arg| {
               let name = arg
                 .get_node_by_name("PatLit").unwrap()
                 .get_components_ident_joined();
               let parameter_type = arg
                 .get_node_by_name("TySum").unwrap()
                 .get_node_by_name("TyPath").unwrap()
                 .get_components_ident();
               ParameterType { name: name, parameter_type: parameter_type }
               }).collect()
             ).unwrap_or(vec![]),
           node.get_node_by_name("ret-ty")
             .and_then(|node| node.get_node_by_name("TyPath"))
             .map(|node| node.get_components_ident())
           )
        }).unwrap_or((vec![], None));

    let return_type = match fn_decl.1 {
      Some(ref v) => ReturnType::Some(v.clone()),
      None => ReturnType::None,
    };
    ItemFnType {
      name: name,
      generic_params: (Vec::new(), Vec::new()),
      fn_decl: fn_decl,
      inner_attrs_and_block: AttrsAndBlockType::from_tree(value, return_type),
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    self.inner_attrs_and_block.block.unknown_type_count()
  }

  pub fn identify_types(&mut self) {
    self.inner_attrs_and_block.block.identify_types();
  }
}

#[derive(Debug, Clone)]
pub struct ViewItemExternCrateType {
  pub name: String,
  pub local_name: Option<String>,
}

impl ViewItemExternCrateType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    let nodes = value.get_nodes();
    assert!(nodes.len() == 1 || nodes.len() == 2);
    ViewItemExternCrateType {
      name: nodes[0].get_string_nodes().join(""),
      local_name: nodes.get(1).map(|node| node.get_string_nodes().join("")),
    }
  }
}

#[derive(Debug, Clone)]
pub struct ModType {
  pub name: String,
}

impl ModType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    assert_eq!(value.get_name(), "ItemMod");
    ModType {
      name: value
        .get_nodes().iter()
        .map(|node|
          node.get_string_nodes().join("")
        )
        .collect::<Vec<_>>()
        .join("")
    }
  }
}
<commit_msg>Expose items by name<commit_after>use super::TreeNode;
use exprs::MacroType;
use types::{AttrsAndVisType, AttrsAndBlockType, ReturnType, AttrType};

#[derive(Debug, Clone)]
pub struct CrateType {
  pub inner_attrs: Vec<AttrType>,
  pub mod_items: Vec<ModItemType>,
}

impl CrateType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    let mod_items = value.get_nodes().into_iter().next().map(|items|
      items.get_nodes().into_iter().map(|item| ModItemType::from_tree(&item)).collect()).unwrap_or(Vec::new());
    let mut krate = CrateType {
      inner_attrs: vec![],
      mod_items: mod_items,
    };
    krate.identify_types();
    krate
  }

  pub fn unknown_type_count(&self) -> u32 {
    self.mod_items.iter().fold(0, |acc, item| acc + item.unknown_type_count())
  }

  pub fn identify_types(&mut self) {
    loop {
      let before = self.unknown_type_count();
      for mod_item in self.mod_items.iter_mut() {
        mod_item.identify_types();
      }
      let after = self.unknown_type_count();
      if after == 0 {
        break;
      }
      if before == after {
        panic!("Cannot identify {} types in {:?}", after, self);
      }
    }
  }

  fn get_by_name(&self, name: &str) -> Option<&ModItemType> {
    for item in self.mod_items.iter() {
      if item.get_name() == Some(name) {
        return Some(item)
      }
    }
    None
  }
}

#[derive(Debug, Clone)]
pub struct ModItemType {
  pub attrs_and_vis: AttrsAndVisType,
  pub item: ItemType,
}

impl ModItemType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    assert_eq!(value.get_name(), "Item");
    let nodes = value.get_nodes();
    assert_eq!(nodes.len(), 2);
    ModItemType {
      attrs_and_vis: AttrsAndVisType::from_tree(&nodes[0]),
      item: ItemType::from_tree(&nodes[1]),
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    self.item.unknown_type_count()
  }

  fn identify_types(&mut self) {
    self.item.identify_types();
  }

  fn get_name(&self) -> Option<&str> {
    self.item.get_name()
  }
}

#[derive(Debug, Clone)]
pub struct ImplMethodType {
  pub attrs_and_vis: AttrsAndVisType,
  pub is_static: bool,
  pub is_unsafe: bool,
  pub name: String,
  pub generic_params: (Vec<String>, Vec<String>),
  pub fn_decl: (Vec<ParameterType>, Option<Vec<String>>),
  pub where_clause: Vec<String>,
  pub inner_attrs_and_block: AttrsAndBlockType,
}

impl ImplMethodType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    let fn_decl_node = value.get_node_by_name("FnDecl").unwrap();
    let is_static = fn_decl_node.get_node_by_name("SelfStatic").is_some();
    let fn_decl: (Vec<ParameterType>, Option<Vec<String>>) = {
      (fn_decl_node.get_nodes()[0].get_nodes()[0].get_nodes().iter().map(|arg| {
         let name = arg
           .get_node_by_name("PatLit").unwrap()
           .get_components_ident_joined();
         let parameter_type = arg
           .get_node_by_name("TySum").unwrap()
           .get_node_by_name("TyPath").unwrap()
           .get_components_ident();
         ParameterType { name: name, parameter_type: parameter_type }
         }).collect(),
       fn_decl_node.get_node_by_name("ret-ty")
         .and_then(|node| node.get_node_by_name("TyPath"))
         .map(|node| node.get_components_ident())
       )
    };

    let return_type = match fn_decl.1 {
      Some(ref v) => ReturnType::Some(v.clone()),
      None => ReturnType::None,
    };

    ImplMethodType {
      attrs_and_vis: AttrsAndVisType::from_tree(value.get_node_by_name("AttrsAndVis").unwrap()),
      is_static: is_static,
      is_unsafe: !value.get_nodes()[1].is_null(),
      name: value.get_node_by_name("ident").unwrap()
        .get_string_nodes().into_iter().next().unwrap(),
      generic_params: (vec![], vec![]),
      where_clause: vec![],
      fn_decl: fn_decl,
      inner_attrs_and_block: AttrsAndBlockType::from_tree(value, return_type),
    }
  }
}

#[derive(Debug, Clone)]
pub enum ImplItemType {
  ImplMethod(ImplMethodType)
}

impl ImplItemType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    match &*value.get_name() {
      "Method" => ImplItemType::ImplMethod(ImplMethodType::from_tree(value)),
      _ => panic!("{:?}", value),
    }
  }

  pub fn get_name(&self) -> String {
    match *self {
      ImplItemType::ImplMethod(ref t) => t.name.clone(),
    }
  }

  pub fn is_static(&self) -> bool {
    match *self {
      ImplItemType::ImplMethod(ref t) => t.is_static,
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    match *self {
      ImplItemType::ImplMethod(ref t) => t.inner_attrs_and_block.block.unknown_type_count(),
    }
  }

  fn identify_types(&mut self) {
    match *self {
      ImplItemType::ImplMethod(ref mut t) => t.inner_attrs_and_block.block.identify_types(),
    }
  }
}

#[derive(Debug, Clone)]
pub struct ImplType {
  pub is_unsafe: bool,
  pub name: String,
  pub generic_params: (Vec<String>, Vec<String>),
  pub attr: AttrType,
  pub items: Vec<ImplItemType>
}

impl ImplType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    let nodes = value.get_nodes();
    ImplType {
      is_unsafe: !nodes[0].is_null(),
      name: value
        .get_node_by_name("TySum").unwrap()
        .get_node_by_name("TyPath").unwrap()
        .get_components_ident_joined(),
      generic_params: (vec![], vec![]),
      attr: AttrType { doc_comment: None },
      items: value.get_node_by_name("ImplItems")
        .map(|items| items.get_nodes().iter().map(|item| ImplItemType::from_tree(item)).collect())
        .unwrap_or(vec![])
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    self.items.iter().fold(0, |acc, item| acc + item.unknown_type_count())
  }

  pub fn identify_types(&mut self) {
    for item in self.items.iter_mut() {
      item.identify_types();
    }
  }
}

#[derive(Debug, Clone)]
pub struct StructType {
  pub name: String,
  pub generic_params: (Vec<String>, Vec<String>),
  pub where_clause: Vec<String>,
  pub fields: Vec<StructFieldType>,
}

#[derive(Debug, Clone)]
pub struct StructFieldType {
  pub attrs_and_vis: AttrsAndVisType,
  pub name: String,
  pub parameter_type: Vec<String>,
}

impl StructType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    assert_eq!(value.get_name(), "ItemStruct");
    assert_eq!(value.get_nodes().len(), 4);
    let name = value.get_node_by_name("ident").unwrap()
      .get_string_nodes().into_iter().next().unwrap();
    StructType {
      name: name,
      generic_params: (vec![], vec![]),
      where_clause: vec![],
      fields: value.get_node_by_name("StructFields")
        .map(|fields| fields.get_nodes())
        .unwrap_or(vec![])
        .iter()
        .map(|node| {
          StructFieldType {
            attrs_and_vis: AttrsAndVisType::from_tree(node.get_node_by_name("AttrsAndVis").unwrap()),
            name: node
              .get_node_by_name("ident").unwrap()
              .get_string_nodes().join(""),
            parameter_type: node
              .get_node_by_name("TySum").unwrap()
              .get_node_by_name("TyPath").unwrap()
              .get_components_ident(),
          }
        })
        .collect(),
    }
  }
}

#[derive(Debug, Clone)]
pub enum ItemType {
  ItemFn(ItemFnType),
  ItemStruct(StructType),
  ItemMacro(MacroType),
  ItemImpl(ImplType),
  ViewItemExternCrate(ViewItemExternCrateType),
  ItemMod(ModType),
}

impl ItemType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    match &*value.get_name() {
      "ItemFn" => ItemType::ItemFn(ItemFnType::from_tree(value)),
      "ItemMacro" => ItemType::ItemMacro(MacroType::from_tree(value, ReturnType::None)),
      "ItemStruct" => ItemType::ItemStruct(StructType::from_tree(value)),
      "ItemImpl" => ItemType::ItemImpl(ImplType::from_tree(value)),
      "ViewItemExternCrate" => ItemType::ViewItemExternCrate(ViewItemExternCrateType::from_tree(value)),
      "ItemMod" => ItemType::ItemMod(ModType::from_tree(value)),
      _ => panic!("{:?}", value),
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    match *self {
      ItemType::ItemFn(ref i) => i.unknown_type_count(),
      ItemType::ItemStruct(_) => 0,
      ItemType::ItemMacro(_) => 0,
      ItemType::ItemImpl(ref i) => i.unknown_type_count(),
      ItemType::ViewItemExternCrate(_) => 0,
      ItemType::ItemMod(_) => 0,
    }
  }

  pub fn identify_types(&mut self) {
    match *self {
      ItemType::ItemFn(ref mut i) => i.identify_types(),
      ItemType::ItemStruct(_) => (),
      ItemType::ItemMacro(_) => (),
      ItemType::ItemImpl(ref mut i) => i.identify_types(),
      ItemType::ViewItemExternCrate(_) => (),
      ItemType::ItemMod(_) => (),
    }
  }

  pub fn get_name(&self) -> Option<&str> {
    match *self {
      ItemType::ItemFn(ref i) => Some(&*i.name),
      _ => None,
    }
  }
}

#[derive(Debug, Clone)]
pub struct ParameterType {
  pub name: String,
  pub parameter_type: Vec<String>,
}

#[derive(Debug, Clone)]
pub struct ItemFnType {
  pub name: String,
  pub generic_params: (Vec<String>, Vec<String>),
  pub fn_decl: (Vec<ParameterType>, Option<Vec<String>>),
  pub inner_attrs_and_block: AttrsAndBlockType,
}

impl ItemFnType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    assert_eq!(value.get_name(), "ItemFn");
    let name = value.get_node_by_name("ident").unwrap()
      .get_string_nodes().into_iter().next().unwrap();
    let fn_decl: (Vec<ParameterType>, Option<Vec<String>>) = value.
      get_node_by_name("FnDecl").map(|node| {
          (node.get_node_by_name("Args")
           .map(|args|
             args.get_nodes().iter().map(|arg| {
               let name = arg
                 .get_node_by_name("PatLit").unwrap()
                 .get_components_ident_joined();
               let parameter_type = arg
                 .get_node_by_name("TySum").unwrap()
                 .get_node_by_name("TyPath").unwrap()
                 .get_components_ident();
               ParameterType { name: name, parameter_type: parameter_type }
               }).collect()
             ).unwrap_or(vec![]),
           node.get_node_by_name("ret-ty")
             .and_then(|node| node.get_node_by_name("TyPath"))
             .map(|node| node.get_components_ident())
           )
        }).unwrap_or((vec![], None));

    let return_type = match fn_decl.1 {
      Some(ref v) => ReturnType::Some(v.clone()),
      None => ReturnType::None,
    };
    ItemFnType {
      name: name,
      generic_params: (Vec::new(), Vec::new()),
      fn_decl: fn_decl,
      inner_attrs_and_block: AttrsAndBlockType::from_tree(value, return_type),
    }
  }

  pub fn unknown_type_count(&self) -> u32 {
    self.inner_attrs_and_block.block.unknown_type_count()
  }

  pub fn identify_types(&mut self) {
    self.inner_attrs_and_block.block.identify_types();
  }
}

#[derive(Debug, Clone)]
pub struct ViewItemExternCrateType {
  pub name: String,
  pub local_name: Option<String>,
}

impl ViewItemExternCrateType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    let nodes = value.get_nodes();
    assert!(nodes.len() == 1 || nodes.len() == 2);
    ViewItemExternCrateType {
      name: nodes[0].get_string_nodes().join(""),
      local_name: nodes.get(1).map(|node| node.get_string_nodes().join("")),
    }
  }
}

#[derive(Debug, Clone)]
pub struct ModType {
  pub name: String,
}

impl ModType {
  pub fn from_tree<T: TreeNode>(value: &T) -> Self {
    assert_eq!(value.get_name(), "ItemMod");
    ModType {
      name: value
        .get_nodes().iter()
        .map(|node|
          node.get_string_nodes().join("")
        )
        .collect::<Vec<_>>()
        .join("")
    }
  }
}
<|endoftext|>


<commit_before>use var::Var;
use parse::IR;
use eval::{Eval,Evaluator};
use def::Def;

use std::collections::HashMap;

/// Expect Types for Composites
#[derive(Debug,PartialEq, Clone, Copy)]
pub enum Expect {
    All,
    Any,
    None,
}

impl Expect {
    pub fn parse(s: String) -> Expect {
        match &s[..] {
            "all" => Expect::All,
            "any" => Expect::Any,
            "none" => Expect::None,
            _ => Expect::None,
        }
    }
}

/// Logic Variants
///
/// These are each to be delimited by a new line
/// Always should resolve to boolean
#[derive(Debug,PartialEq)]
pub enum Logic {
    /// Greater Than, eg: weight > 1
    GT(Var,Var),
    /// Lesser Than
    LT(Var,Var),

    /// Boolean: True
    Is(String),
    /// Boolean: False
    IsNot(String),

    /// A composite logic type to group logic statements together
    Composite(Expect, Vec<String>),
}

pub type Logics = HashMap<String,LogicFn>;
pub struct LogicFn(Box<Fn(&Def,&Logics) -> Option<bool>>);
impl LogicFn {
    pub fn run(&self, def: &Def, logic: &Logics) -> Option<bool> {
        self.0(def, logic)
    }
}

// NOTE: we don't actually impl this, but satisfy checker
impl PartialEq for LogicFn {
    fn eq(&self, _other: &LogicFn) -> bool {
        false
    }
}

use std::fmt;
// NOTE: we don't actually impl this, but satisfy checker
impl fmt::Debug for LogicFn {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,"")
    }
}

impl Logic {
    pub fn parse_comp(mut keys: Vec<&str>,
                      mut exp: Vec<IR>) -> Result<Logic,&'static str> {
        // NOTE: we may want to inspect what happened if the kind was not found
        let kind = Expect::parse(keys.pop().unwrap().to_owned());

        let exp = exp.drain(..).map(|n| n.into()).collect();
        Ok(Logic::Composite(kind,
                            exp))
    }

    pub fn parse(mut exp: Vec<IR>) -> Result<Logic,&'static str> {
        let len = exp.len();

        if len == 1 {
            let mut exp: String = exp.pop().unwrap().into();
            let inv = exp.remove(0);
            if inv == '!' {
                Ok(Logic::IsNot(exp))
            }
            else {
                exp.insert(0,inv);
                Ok(Logic::Is(exp))
            }
        }
        else if len == 3 {
            let var = exp.pop().unwrap();
            let var = try!(Var::parse(var));

            let sym: String = exp.pop().unwrap().into();
            let key = exp.pop().unwrap();
            let key = try!(Var::parse(key));

            if sym == ">" {
                Ok(Logic::GT(key,var))
            }
            else if sym == "<" {
                Ok(Logic::LT(key,var))
            }
            else { Err("Invalid Logic Syntax") }
        }
        else { Err("Unbalanced Logic Syntax") }
    }

    /// Evaluate Logic into Functions
    pub fn eval (&self) -> LogicFn {
        match self {
            &Logic::Is(ref lookup) => {
                let lookup = lookup.clone();
                let lfn = Box::new(move |data: &Def, logic: &Logics| {
                    if let Some(r) = Evaluator::resolve(&lookup, logic, data) {
                        match r {
                            Var::Bool(v) => {
                                 Some(v)
                            },
                            _ => { //if exists?
                                Some(true)
                            },
                        }
                    }
                    else { Some(false) }
                });

                LogicFn(lfn)
            },
            &Logic::IsNot(ref lookup) => { //inverse state
                let lookup = lookup.clone();
                let lfn = Box::new(move |data: &Def, logic: &Logics| {
                    if let Some(r) = Evaluator::resolve(&lookup, logic, data) {
                        match r {
                            Var::Bool(v) => {
                                Some(!v)
                            },
                            _ => {
                                Some(false)
                            },
                        }
                    }
                    else {  Some(true) } // missing identity turns into true on inv bool
                });

                LogicFn(lfn)
            },

            &Logic::GT(ref left, ref right) => {
                let left = left.clone();
                let right = right.clone();
                let lfn = Box::new(move |data: &Def, _logic: &Logics| {
                    let right = Var::get_num(&right,data);
                    let left = Var::get_num(&left,data);

                    if left.is_ok() && right.is_ok() {
                        Some(left.unwrap() > right.unwrap())
                    }
                    else { None }
                });

                LogicFn(lfn)
            },
            &Logic::LT(ref left, ref right) => {
                let left = left.clone();
                let right = right.clone();
                let lfn = Box::new(move |data: &Def, _logic: &Logics| {
                    let right = Var::get_num(&right,data);
                    let left = Var::get_num(&left,data);

                    if left.is_ok() && right.is_ok() {
                        Some(left.unwrap() < right.unwrap())
                    }
                    else { None }
                });

                LogicFn(lfn)
            },
            &Logic::Composite(x, ref lookups) => {
                let lookups = lookups.clone();
                let lfn = Box::new(move |data: &Def, logic: &Logics| {
                    // track if any lookups are false or true
                    let mut comp_true = false;
                    let mut comp_false = false;

                    for lookup in lookups.iter() {
                        if let Some(val) = Evaluator::resolve(lookup, logic, data) {
                            match val {
                                Var::Bool(v) => {
                                    if v { comp_true = true; }
                                    else { comp_false = true; }
                                },
                                _ => { comp_true = lookup != &val.to_string(); }
                            }
                        }
                        else { comp_false = true }
                    }

                    match x {
                        Expect::All => { // all must pass as true
                            Some(comp_true && !comp_false)
                        },
                        Expect::Any => { // first truth passes for set
                            Some(comp_true)
                        },
                        Expect::None => { // inverse of any, none must be true
                            Some(!comp_true && comp_false)
                        },
                    }
                });

                LogicFn(lfn)
            }
        }

    }
}
<commit_msg>remove unused<commit_after>use var::Var;
use parse::IR;
use eval::Evaluator;
use def::Def;

use std::collections::HashMap;

/// Expect Types for Composites
#[derive(Debug,PartialEq, Clone, Copy)]
pub enum Expect {
    All,
    Any,
    None,
}

impl Expect {
    pub fn parse(s: String) -> Expect {
        match &s[..] {
            "all" => Expect::All,
            "any" => Expect::Any,
            "none" => Expect::None,
            _ => Expect::None,
        }
    }
}

/// Logic Variants
///
/// These are each to be delimited by a new line
/// Always should resolve to boolean
#[derive(Debug,PartialEq)]
pub enum Logic {
    /// Greater Than, eg: weight > 1
    GT(Var,Var),
    /// Lesser Than
    LT(Var,Var),

    /// Boolean: True
    Is(String),
    /// Boolean: False
    IsNot(String),

    /// A composite logic type to group logic statements together
    Composite(Expect, Vec<String>),
}

pub type Logics = HashMap<String,LogicFn>;
pub struct LogicFn(Box<Fn(&Def,&Logics) -> Option<bool>>);
impl LogicFn {
    pub fn run(&self, def: &Def, logic: &Logics) -> Option<bool> {
        self.0(def, logic)
    }
}

// NOTE: we don't actually impl this, but satisfy checker
impl PartialEq for LogicFn {
    fn eq(&self, _other: &LogicFn) -> bool {
        false
    }
}

use std::fmt;
// NOTE: we don't actually impl this, but satisfy checker
impl fmt::Debug for LogicFn {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,"")
    }
}

impl Logic {
    pub fn parse_comp(mut keys: Vec<&str>,
                      mut exp: Vec<IR>) -> Result<Logic,&'static str> {
        // NOTE: we may want to inspect what happened if the kind was not found
        let kind = Expect::parse(keys.pop().unwrap().to_owned());

        let exp = exp.drain(..).map(|n| n.into()).collect();
        Ok(Logic::Composite(kind,
                            exp))
    }

    pub fn parse(mut exp: Vec<IR>) -> Result<Logic,&'static str> {
        let len = exp.len();

        if len == 1 {
            let mut exp: String = exp.pop().unwrap().into();
            let inv = exp.remove(0);
            if inv == '!' {
                Ok(Logic::IsNot(exp))
            }
            else {
                exp.insert(0,inv);
                Ok(Logic::Is(exp))
            }
        }
        else if len == 3 {
            let var = exp.pop().unwrap();
            let var = try!(Var::parse(var));

            let sym: String = exp.pop().unwrap().into();
            let key = exp.pop().unwrap();
            let key = try!(Var::parse(key));

            if sym == ">" {
                Ok(Logic::GT(key,var))
            }
            else if sym == "<" {
                Ok(Logic::LT(key,var))
            }
            else { Err("Invalid Logic Syntax") }
        }
        else { Err("Unbalanced Logic Syntax") }
    }

    /// Evaluate Logic into Functions
    pub fn eval (&self) -> LogicFn {
        match self {
            &Logic::Is(ref lookup) => {
                let lookup = lookup.clone();
                let lfn = Box::new(move |data: &Def, logic: &Logics| {
                    if let Some(r) = Evaluator::resolve(&lookup, logic, data) {
                        match r {
                            Var::Bool(v) => {
                                 Some(v)
                            },
                            _ => { //if exists?
                                Some(true)
                            },
                        }
                    }
                    else { Some(false) }
                });

                LogicFn(lfn)
            },
            &Logic::IsNot(ref lookup) => { //inverse state
                let lookup = lookup.clone();
                let lfn = Box::new(move |data: &Def, logic: &Logics| {
                    if let Some(r) = Evaluator::resolve(&lookup, logic, data) {
                        match r {
                            Var::Bool(v) => {
                                Some(!v)
                            },
                            _ => {
                                Some(false)
                            },
                        }
                    }
                    else {  Some(true) } // missing identity turns into true on inv bool
                });

                LogicFn(lfn)
            },

            &Logic::GT(ref left, ref right) => {
                let left = left.clone();
                let right = right.clone();
                let lfn = Box::new(move |data: &Def, _logic: &Logics| {
                    let right = Var::get_num(&right,data);
                    let left = Var::get_num(&left,data);

                    if left.is_ok() && right.is_ok() {
                        Some(left.unwrap() > right.unwrap())
                    }
                    else { None }
                });

                LogicFn(lfn)
            },
            &Logic::LT(ref left, ref right) => {
                let left = left.clone();
                let right = right.clone();
                let lfn = Box::new(move |data: &Def, _logic: &Logics| {
                    let right = Var::get_num(&right,data);
                    let left = Var::get_num(&left,data);

                    if left.is_ok() && right.is_ok() {
                        Some(left.unwrap() < right.unwrap())
                    }
                    else { None }
                });

                LogicFn(lfn)
            },
            &Logic::Composite(x, ref lookups) => {
                let lookups = lookups.clone();
                let lfn = Box::new(move |data: &Def, logic: &Logics| {
                    // track if any lookups are false or true
                    let mut comp_true = false;
                    let mut comp_false = false;

                    for lookup in lookups.iter() {
                        if let Some(val) = Evaluator::resolve(lookup, logic, data) {
                            match val {
                                Var::Bool(v) => {
                                    if v { comp_true = true; }
                                    else { comp_false = true; }
                                },
                                _ => { comp_true = lookup != &val.to_string(); }
                            }
                        }
                        else { comp_false = true }
                    }

                    match x {
                        Expect::All => { // all must pass as true
                            Some(comp_true && !comp_false)
                        },
                        Expect::Any => { // first truth passes for set
                            Some(comp_true)
                        },
                        Expect::None => { // inverse of any, none must be true
                            Some(!comp_true && comp_false)
                        },
                    }
                });

                LogicFn(lfn)
            }
        }

    }
}
<|endoftext|>


<commit_before>use decoders::*;
use decoders::tiff::*;
use decoders::basics::*;
use std::f32::NAN;
use itertools::Itertools;
use std::cmp;

#[derive(Debug, Clone)]
pub struct DcrDecoder<'a> {
  buffer: &'a [u8],
  rawloader: &'a RawLoader,
  tiff: TiffIFD<'a>,
}

impl<'a> DcrDecoder<'a> {
  pub fn new(buf: &'a [u8], tiff: TiffIFD<'a>, rawloader: &'a RawLoader) -> DcrDecoder<'a> {
    DcrDecoder {
      buffer: buf,
      tiff: tiff,
      rawloader: rawloader,
    }
  }
}

impl<'a> Decoder for DcrDecoder<'a> {
  fn image(&self) -> Result<RawImage,String> {
    let camera = try!(self.rawloader.check_supported(&self.tiff));
    let raw = fetch_ifd!(&self.tiff, Tag::CFAPattern);
    let width = fetch_tag!(raw, Tag::ImageWidth).get_usize(0);
    let height = fetch_tag!(raw, Tag::ImageLength).get_usize(0);
    let offset = fetch_tag!(raw, Tag::StripOffsets).get_usize(0);
    let src = &self.buffer[offset..];

    let linearization = fetch_tag!(self.tiff, Tag::DcrLinearization);
    let curve = {
      let mut points = Vec::new();
      for i in 0..linearization.count() {
        points.push(linearization.get_u32(i) as u16);
      }
      LookupTable::new(&points)
    };

    let image = DcrDecoder::decode_kodak65000(src, &curve, width, height);

    ok_image(camera, width, height, try!(self.get_wb()), image)
  }
}

impl<'a> DcrDecoder<'a> {
  fn get_wb(&self) -> Result<[f32;4], String> {
    let dcrwb = fetch_tag!(self.tiff, Tag::DcrWB);
    if dcrwb.count() >= 46 {
      let levels = dcrwb.get_data();
      Ok([2048.0 / BEu16(levels,40) as f32,
          2048.0 / BEu16(levels,42) as f32,
          2048.0 / BEu16(levels,44) as f32,
          NAN])
    } else {
      Ok([NAN,NAN,NAN,NAN])
    }
  }

  pub(crate) fn decode_kodak65000(buf: &[u8], curve: &LookupTable, width: usize, height: usize) -> Vec<u16> {
    let mut out: Vec<u16> = alloc_image!(width, height);
    let mut input = ByteStream::new(buf, LITTLE_ENDIAN);

    let mut random: u32 = 0;
    for row in 0..height {
      for col in (0..width).step(256) {
        let mut pred: [i32;2] = [0;2];
        let buf = DcrDecoder::decode_segment(&mut input, cmp::min(256, width-col));
        for (i,val) in buf.iter().enumerate() {
          pred[i & 1] += *val;
          if pred[i & 1] < 0 {
            println!("Found a negative pixel!");
          }
          out[row*width+col+i] = curve.dither(pred[i & 1] as u16, &mut random);
        }
      }
    }

    out
  }

  fn decode_segment(input: &mut ByteStream, size: usize) -> Vec<i32> {
    let mut out: Vec<i32> = vec![0; size];

    let mut lens: [usize;256] = [0;256];
    for i in (0..size).step(2) {
      lens[i] = (input.peek_u8() & 15) as usize;
      lens[i+1] = (input.get_u8() >> 4) as usize;
    }

    let mut bitbuf: u64 = 0;
    let mut bits: usize = 0;
    if (size & 7) == 4 {
      bitbuf  = (input.get_u8() as u64) << 8 | (input.get_u8() as u64);
      bits = 16;
    }

    for i in 0..size {
      let len = lens[i];
      if bits < len {
        for j in (0..32).step(8) {
          bitbuf += (input.get_u8() as u64) << (bits+(j^8));
        }
        bits += 32;
      }
      out[i] = (bitbuf & (0xffff >> (16-len))) as i32;
      bitbuf >>= len;
      bits -= len;
      if len != 0 && (out[i] & (1 << (len-1))) == 0 {
        out[i] -= (1 << len) - 1;
      }
    }

    out
  }
}
<commit_msg>DCR: bail out on negative pixels<commit_after>use decoders::*;
use decoders::tiff::*;
use decoders::basics::*;
use std::f32::NAN;
use itertools::Itertools;
use std::cmp;

#[derive(Debug, Clone)]
pub struct DcrDecoder<'a> {
  buffer: &'a [u8],
  rawloader: &'a RawLoader,
  tiff: TiffIFD<'a>,
}

impl<'a> DcrDecoder<'a> {
  pub fn new(buf: &'a [u8], tiff: TiffIFD<'a>, rawloader: &'a RawLoader) -> DcrDecoder<'a> {
    DcrDecoder {
      buffer: buf,
      tiff: tiff,
      rawloader: rawloader,
    }
  }
}

impl<'a> Decoder for DcrDecoder<'a> {
  fn image(&self) -> Result<RawImage,String> {
    let camera = try!(self.rawloader.check_supported(&self.tiff));
    let raw = fetch_ifd!(&self.tiff, Tag::CFAPattern);
    let width = fetch_tag!(raw, Tag::ImageWidth).get_usize(0);
    let height = fetch_tag!(raw, Tag::ImageLength).get_usize(0);
    let offset = fetch_tag!(raw, Tag::StripOffsets).get_usize(0);
    let src = &self.buffer[offset..];

    let linearization = fetch_tag!(self.tiff, Tag::DcrLinearization);
    let curve = {
      let mut points = Vec::new();
      for i in 0..linearization.count() {
        points.push(linearization.get_u32(i) as u16);
      }
      LookupTable::new(&points)
    };

    let image = DcrDecoder::decode_kodak65000(src, &curve, width, height);

    ok_image(camera, width, height, try!(self.get_wb()), image)
  }
}

impl<'a> DcrDecoder<'a> {
  fn get_wb(&self) -> Result<[f32;4], String> {
    let dcrwb = fetch_tag!(self.tiff, Tag::DcrWB);
    if dcrwb.count() >= 46 {
      let levels = dcrwb.get_data();
      Ok([2048.0 / BEu16(levels,40) as f32,
          2048.0 / BEu16(levels,42) as f32,
          2048.0 / BEu16(levels,44) as f32,
          NAN])
    } else {
      Ok([NAN,NAN,NAN,NAN])
    }
  }

  pub(crate) fn decode_kodak65000(buf: &[u8], curve: &LookupTable, width: usize, height: usize) -> Vec<u16> {
    let mut out: Vec<u16> = alloc_image!(width, height);
    let mut input = ByteStream::new(buf, LITTLE_ENDIAN);

    let mut random: u32 = 0;
    for row in 0..height {
      for col in (0..width).step(256) {
        let mut pred: [i32;2] = [0;2];
        let buf = DcrDecoder::decode_segment(&mut input, cmp::min(256, width-col));
        for (i,val) in buf.iter().enumerate() {
          pred[i & 1] += *val;
          if pred[i & 1] < 0 {
            panic!("Found a negative pixel!");
          }
          out[row*width+col+i] = curve.dither(pred[i & 1] as u16, &mut random);
        }
      }
    }

    out
  }

  fn decode_segment(input: &mut ByteStream, size: usize) -> Vec<i32> {
    let mut out: Vec<i32> = vec![0; size];

    let mut lens: [usize;256] = [0;256];
    for i in (0..size).step(2) {
      lens[i] = (input.peek_u8() & 15) as usize;
      lens[i+1] = (input.get_u8() >> 4) as usize;
    }

    let mut bitbuf: u64 = 0;
    let mut bits: usize = 0;
    if (size & 7) == 4 {
      bitbuf  = (input.get_u8() as u64) << 8 | (input.get_u8() as u64);
      bits = 16;
    }

    for i in 0..size {
      let len = lens[i];
      if bits < len {
        for j in (0..32).step(8) {
          bitbuf += (input.get_u8() as u64) << (bits+(j^8));
        }
        bits += 32;
      }
      out[i] = (bitbuf & (0xffff >> (16-len))) as i32;
      bitbuf >>= len;
      bits -= len;
      if len != 0 && (out[i] & (1 << (len-1))) == 0 {
        out[i] -= (1 << len) - 1;
      }
    }

    out
  }
}
<|endoftext|>


<commit_before>use std::{convert};
use std::io::{Cursor, Read};

use byteorder::{self, ReadBytesExt};

#[derive(Debug, PartialEq, Eq)]
pub enum DeserializationError {
    UnexpectedTag,
    ShortData,
    ExtraData,
    IntegerOverflow,
    InvalidValue,
}

impl convert::From<byteorder::Error> for DeserializationError {
    fn from(e: byteorder::Error) -> DeserializationError {
        return match e {
            byteorder::Error::UnexpectedEOF => DeserializationError::ShortData,
            _ => panic!("Unexpected error!"),
        }
    }
}

pub type DeserializationResult<T> = Result<T, DeserializationError>;

pub struct Deserializer {
    reader: Cursor<Vec<u8>>,
}

impl Deserializer {
    pub fn new(data: Vec<u8>) -> Deserializer {
        return Deserializer{
            reader: Cursor::new(data),
        }
    }

    fn _read_length(&mut self) -> DeserializationResult<usize> {
        let b = try!(self.reader.read_u8());
        // TODO: handle lengths greater than 128
        assert!(b & 0x80 == 0);
        return Ok((b & 0x7f) as usize);
    }

    fn _read_with_tag<T, F>(&mut self, expected_tag: u8, body: F) -> DeserializationResult<T>
            where F: Fn(Vec<u8>) -> DeserializationResult<T> {
        let tag = try!(self.reader.read_u8());
        // TODO: only some of the bits in the first byte are for the tag
        if tag != expected_tag {
            return Err(DeserializationError::UnexpectedTag);
        }
        let length = try!(self._read_length());
        let mut data = vec![0; length];
        let n = self.reader.read(&mut data).unwrap();
        if n != length {
            return Err(DeserializationError::ShortData);
        }
        return body(data);
    }

    pub fn finish(self) -> DeserializationResult<()> {
        if self.reader.position() as usize != self.reader.get_ref().len() {
            return Err(DeserializationError::ExtraData);
        }
        return Ok(());
    }

    pub fn read_bool(&mut self) -> DeserializationResult<bool> {
        return self._read_with_tag(1, |data| {
            if data == b"\x00" {
                return Ok(false);
            } else if data == b"\xff" {
                return Ok(true)
            } else {
                return Err(DeserializationError::InvalidValue);
            }
        });
    }

    pub fn read_int(&mut self) -> DeserializationResult<i64> {
        return self._read_with_tag(2, |data| {
            if data.len() > 8 {
                return Err(DeserializationError::IntegerOverflow);
            }
            if data.len() > 1 {
                match (data[0], data[1] & 0x80) {
                    (0xff, 0x80) | (0x00, 0x00) => return Err(DeserializationError::InvalidValue),
                    _ => {},
                }
            }
            let mut ret = 0;
            for b in data.iter() {
                ret <<= 8;
                ret |= *b as i64;
            }
            // Shift up and down in order to sign extend the result.
            ret <<= 64 - data.len() * 8;
            ret >>= 64 - data.len() * 8;
            return Ok(ret);
        });
    }

    pub fn read_octet_string(&mut self) -> DeserializationResult<Vec<u8>> {
        return self._read_with_tag(4, |data| {
            return Ok(data);
        });
    }
}

pub fn from_vec<F, T>(data: Vec<u8>, f: F) -> DeserializationResult<T>
        where F: Fn(&mut Deserializer) -> DeserializationResult<T> {
    let mut deserializer = Deserializer::new(data);
    let result = try!(f(&mut deserializer));
    try!(deserializer.finish());
    return Ok(result);
}

#[cfg(test)]
mod tests {
    use std;
    use std::{fmt};

    use super::{Deserializer, DeserializationError, DeserializationResult, from_vec};

    fn assert_deserializes<T, F>(values: Vec<(DeserializationResult<T>, Vec<u8>)>, f: F)
            where T: Eq + fmt::Debug, F: Fn(&mut Deserializer) -> DeserializationResult<T> {
        for (expected, value) in values {
            let result = from_vec(value, &f);
            assert_eq!(result, expected);
        }
    }
    #[test]
    fn test_read_extra_data() {
        assert_deserializes(vec![
            (Err(DeserializationError::ExtraData), b"\x00".to_vec()),
        ], |_| {
            return Ok(());
        });
    }

    #[test]
    fn test_read_bool() {
        assert_deserializes(vec![
            (Ok(true), b"\x01\x01\xff".to_vec()),
            (Ok(false), b"\x01\x01\x00".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x01\x00".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x01\x01\x01".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x01\x02\x00\x00".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x01\x02\xff\x01".to_vec()),
        ], |deserializer| {
            return deserializer.read_bool();
        });
    }

    #[test]
    fn test_read_int() {
        assert_deserializes(vec![
            (Ok(0), b"\x02\x01\x00".to_vec()),
            (Ok(127), b"\x02\x01\x7f".to_vec()),
            (Ok(128), b"\x02\x02\x00\x80".to_vec()),
            (Ok(256), b"\x02\x02\x01\x00".to_vec()),
            (Ok(-128), b"\x02\x01\x80".to_vec()),
            (Ok(-129), b"\x02\x02\xff\x7f".to_vec()),
            (Ok(-256), b"\x02\x02\xff\x00".to_vec()),
            (Ok(std::i64::MAX), b"\x02\x08\x7f\xff\xff\xff\xff\xff\xff\xff".to_vec()),
            (Err(DeserializationError::UnexpectedTag), b"\x03".to_vec()),
            (Err(DeserializationError::ShortData), b"\x02\x02\x00".to_vec()),
            (Err(DeserializationError::ShortData), b"".to_vec()),
            (Err(DeserializationError::ShortData), b"\x02".to_vec()),
            (
                Err(DeserializationError::IntegerOverflow),
                b"\x02\x09\x02\x00\x00\x00\x00\x00\x00\x00\x00".to_vec()
            ),
            (Err(DeserializationError::InvalidValue), b"\x02\x05\x00\x00\x00\x00\x01".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x02\x02\xff\x80".to_vec()),
        ], |deserializer| {
            return deserializer.read_int();
        });
    }

    #[test]
    fn test_read_octet_string() {
        assert_deserializes(vec![
            (Ok(b"\x01\x02\x03".to_vec()), b"\x04\x03\x01\x02\x03".to_vec()),
            (Err(DeserializationError::ShortData), b"\x04\x03\x01\x02".to_vec()),
        ], |deserializer| {
            return deserializer.read_octet_string();
        });
    }
}
<commit_msg>test the empty vec<commit_after>use std::{convert};
use std::io::{Cursor, Read};

use byteorder::{self, ReadBytesExt};

#[derive(Debug, PartialEq, Eq)]
pub enum DeserializationError {
    UnexpectedTag,
    ShortData,
    ExtraData,
    IntegerOverflow,
    InvalidValue,
}

impl convert::From<byteorder::Error> for DeserializationError {
    fn from(e: byteorder::Error) -> DeserializationError {
        return match e {
            byteorder::Error::UnexpectedEOF => DeserializationError::ShortData,
            _ => panic!("Unexpected error!"),
        }
    }
}

pub type DeserializationResult<T> = Result<T, DeserializationError>;

pub struct Deserializer {
    reader: Cursor<Vec<u8>>,
}

impl Deserializer {
    pub fn new(data: Vec<u8>) -> Deserializer {
        return Deserializer{
            reader: Cursor::new(data),
        }
    }

    fn _read_length(&mut self) -> DeserializationResult<usize> {
        let b = try!(self.reader.read_u8());
        // TODO: handle lengths greater than 128
        assert!(b & 0x80 == 0);
        return Ok((b & 0x7f) as usize);
    }

    fn _read_with_tag<T, F>(&mut self, expected_tag: u8, body: F) -> DeserializationResult<T>
            where F: Fn(Vec<u8>) -> DeserializationResult<T> {
        let tag = try!(self.reader.read_u8());
        // TODO: only some of the bits in the first byte are for the tag
        if tag != expected_tag {
            return Err(DeserializationError::UnexpectedTag);
        }
        let length = try!(self._read_length());
        let mut data = vec![0; length];
        let n = self.reader.read(&mut data).unwrap();
        if n != length {
            return Err(DeserializationError::ShortData);
        }
        return body(data);
    }

    pub fn finish(self) -> DeserializationResult<()> {
        if self.reader.position() as usize != self.reader.get_ref().len() {
            return Err(DeserializationError::ExtraData);
        }
        return Ok(());
    }

    pub fn read_bool(&mut self) -> DeserializationResult<bool> {
        return self._read_with_tag(1, |data| {
            if data == b"\x00" {
                return Ok(false);
            } else if data == b"\xff" {
                return Ok(true)
            } else {
                return Err(DeserializationError::InvalidValue);
            }
        });
    }

    pub fn read_int(&mut self) -> DeserializationResult<i64> {
        return self._read_with_tag(2, |data| {
            if data.len() > 8 {
                return Err(DeserializationError::IntegerOverflow);
            }
            if data.len() > 1 {
                match (data[0], data[1] & 0x80) {
                    (0xff, 0x80) | (0x00, 0x00) => return Err(DeserializationError::InvalidValue),
                    _ => {},
                }
            }
            let mut ret = 0;
            for b in data.iter() {
                ret <<= 8;
                ret |= *b as i64;
            }
            // Shift up and down in order to sign extend the result.
            ret <<= 64 - data.len() * 8;
            ret >>= 64 - data.len() * 8;
            return Ok(ret);
        });
    }

    pub fn read_octet_string(&mut self) -> DeserializationResult<Vec<u8>> {
        return self._read_with_tag(4, |data| {
            return Ok(data);
        });
    }
}

pub fn from_vec<F, T>(data: Vec<u8>, f: F) -> DeserializationResult<T>
        where F: Fn(&mut Deserializer) -> DeserializationResult<T> {
    let mut deserializer = Deserializer::new(data);
    let result = try!(f(&mut deserializer));
    try!(deserializer.finish());
    return Ok(result);
}

#[cfg(test)]
mod tests {
    use std;
    use std::{fmt};

    use super::{Deserializer, DeserializationError, DeserializationResult, from_vec};

    fn assert_deserializes<T, F>(values: Vec<(DeserializationResult<T>, Vec<u8>)>, f: F)
            where T: Eq + fmt::Debug, F: Fn(&mut Deserializer) -> DeserializationResult<T> {
        for (expected, value) in values {
            let result = from_vec(value, &f);
            assert_eq!(result, expected);
        }
    }
    #[test]
    fn test_read_extra_data() {
        assert_deserializes(vec![
            (Err(DeserializationError::ExtraData), b"\x00".to_vec()),
        ], |_| {
            return Ok(());
        });
    }

    #[test]
    fn test_read_bool() {
        assert_deserializes(vec![
            (Ok(true), b"\x01\x01\xff".to_vec()),
            (Ok(false), b"\x01\x01\x00".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x01\x00".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x01\x01\x01".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x01\x02\x00\x00".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x01\x02\xff\x01".to_vec()),
        ], |deserializer| {
            return deserializer.read_bool();
        });
    }

    #[test]
    fn test_read_int() {
        assert_deserializes(vec![
            (Ok(0), b"\x02\x01\x00".to_vec()),
            (Ok(127), b"\x02\x01\x7f".to_vec()),
            (Ok(128), b"\x02\x02\x00\x80".to_vec()),
            (Ok(256), b"\x02\x02\x01\x00".to_vec()),
            (Ok(-128), b"\x02\x01\x80".to_vec()),
            (Ok(-129), b"\x02\x02\xff\x7f".to_vec()),
            (Ok(-256), b"\x02\x02\xff\x00".to_vec()),
            (Ok(std::i64::MAX), b"\x02\x08\x7f\xff\xff\xff\xff\xff\xff\xff".to_vec()),
            (Err(DeserializationError::UnexpectedTag), b"\x03".to_vec()),
            (Err(DeserializationError::ShortData), b"\x02\x02\x00".to_vec()),
            (Err(DeserializationError::ShortData), b"".to_vec()),
            (Err(DeserializationError::ShortData), b"\x02".to_vec()),
            (
                Err(DeserializationError::IntegerOverflow),
                b"\x02\x09\x02\x00\x00\x00\x00\x00\x00\x00\x00".to_vec()
            ),
            (Err(DeserializationError::InvalidValue), b"\x02\x05\x00\x00\x00\x00\x01".to_vec()),
            (Err(DeserializationError::InvalidValue), b"\x02\x02\xff\x80".to_vec()),
        ], |deserializer| {
            return deserializer.read_int();
        });
    }

    #[test]
    fn test_read_octet_string() {
        assert_deserializes(vec![
            (Ok(b"".to_vec()), b"\x04\x00".to_vec()),
            (Ok(b"\x01\x02\x03".to_vec()), b"\x04\x03\x01\x02\x03".to_vec()),
            (Err(DeserializationError::ShortData), b"\x04\x03\x01\x02".to_vec()),
        ], |deserializer| {
            return deserializer.read_octet_string();
        });
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

extern crate num;

use self::num::complex::{Complex32, Complex64};
use pointer::CPtr;
use scalar::Scalar;
use matrix;
use matrix::BlasMatrix;
use vector::BlasVector;

pub trait Gemm {
    fn gemm(alpha: Self, a: &BlasMatrix<Self>, b: &BlasMatrix<Self>, beta: Self, c: &mut BlasMatrix<Self>);
}

macro_rules! gemm_impl(
    ($t: ty, $gemm_fn: ident) => (
        impl Gemm for $t {
            fn gemm(alpha: $t, a: &BlasMatrix<$t>, b: &BlasMatrix<$t>, beta: $t, c: &mut BlasMatrix<$t>) {
                unsafe {
                    matrix::ll::$gemm_fn(a.order(),
                        a.transpose(), b.transpose(),
                        a.rows(), b.cols(), a.cols(),
                        (&alpha).as_const(),
                        a.as_ptr().as_c_ptr(), a.lead_dim(),
                        b.as_ptr().as_c_ptr(), b.lead_dim(),
                        (&beta).as_const(),
                        c.as_mut_ptr().as_c_ptr(), c.lead_dim());
                }
            }
        }
    );
)

gemm_impl!(f32,       cblas_sgemm)
gemm_impl!(f64,       cblas_dgemm)
gemm_impl!(Complex32, cblas_cgemm)
gemm_impl!(Complex64, cblas_zgemm)
<commit_msg>Add Symm and Hemm traits<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

extern crate num;

use self::num::complex::{Complex32, Complex64};
use attribute::{Side, Symmetry};
use pointer::CPtr;
use scalar::Scalar;
use matrix;
use matrix::BlasMatrix;
use vector::BlasVector;

pub trait Gemm {
    fn gemm(alpha: Self, a: &BlasMatrix<Self>, b: &BlasMatrix<Self>, beta: Self, c: &mut BlasMatrix<Self>);
}

macro_rules! gemm_impl(
    ($t: ty, $gemm_fn: ident) => (
        impl Gemm for $t {
            fn gemm(alpha: $t, a: &BlasMatrix<$t>, b: &BlasMatrix<$t>, beta: $t, c: &mut BlasMatrix<$t>) {
                unsafe {
                    matrix::ll::$gemm_fn(a.order(),
                        a.transpose(), b.transpose(),
                        a.rows(), b.cols(), a.cols(),
                        (&alpha).as_const(),
                        a.as_ptr().as_c_ptr(), a.lead_dim(),
                        b.as_ptr().as_c_ptr(), b.lead_dim(),
                        (&beta).as_const(),
                        c.as_mut_ptr().as_c_ptr(), c.lead_dim());
                }
            }
        }
    );
)

gemm_impl!(f32,       cblas_sgemm)
gemm_impl!(f64,       cblas_dgemm)
gemm_impl!(Complex32, cblas_cgemm)
gemm_impl!(Complex64, cblas_zgemm)

pub trait Symm {
    fn symm(side: Side, symmetry: Symmetry, alpha: Self, a: &BlasMatrix<Self>, b: &BlasMatrix<Self>, beta: Self, c: &mut BlasMatrix<Self>);
}

pub trait Hemm {
    fn hemm(side: Side, symmetry: Symmetry, alpha: Self, a: &BlasMatrix<Self>, b: &BlasMatrix<Self>, beta: Self, c: &mut BlasMatrix<Self>);
}

macro_rules! symm_impl(
    ($trait_name: ident, $fn_name: ident, $t: ty, $symm_fn: ident) => (
        impl $trait_name for $t {
            fn $fn_name(side: Side, symmetry: Symmetry, alpha: $t, a: &BlasMatrix<$t>, b: &BlasMatrix<$t>, beta: $t, c: &mut BlasMatrix<$t>) {
                unsafe {
                    matrix::ll::$symm_fn(a.order(),
                        side, symmetry,
                        a.rows(), b.cols(),
                        (&alpha).as_const(),
                        a.as_ptr().as_c_ptr(), a.lead_dim(),
                        b.as_ptr().as_c_ptr(), b.lead_dim(),
                        (&beta).as_const(),
                        c.as_mut_ptr().as_c_ptr(), c.lead_dim());
                }
            }
        }
    );
)

symm_impl!(Symm, symm, f32,       cblas_ssymm)
symm_impl!(Symm, symm, f64,       cblas_dsymm)
symm_impl!(Symm, symm, Complex32, cblas_csymm)
symm_impl!(Symm, symm, Complex64, cblas_zsymm)

symm_impl!(Hemm, hemm, Complex32, cblas_chemm)
symm_impl!(Hemm, hemm, Complex64, cblas_zhemm)
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::collections::btree_map::Entry;

use errors::*;

/// Position relative in file where the declaration is present.
pub type Pos = (usize, usize);

#[derive(Debug, PartialEq, Clone)]
pub struct TupleElement {
    pub name: Option<String>,
    pub ty: Type,
}

impl TupleElement {
    pub fn new(name: Option<String>, ty: Type) -> TupleElement {
        TupleElement {
            name: name,
            ty: ty,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum OptionValue {
    String(String),
}

#[derive(Debug, PartialEq, Clone)]
pub struct OptionDecl {
    pub name: String,
    pub values: Vec<OptionValue>,
}

impl OptionDecl {
    pub fn new(name: String, values: Vec<OptionValue>) -> OptionDecl {
        OptionDecl {
            name: name,
            values: values,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub struct Options {
    options: Vec<OptionDecl>,
}

impl Options {
    pub fn new(options: Vec<OptionDecl>) -> Options {
        Options { options: options }
    }

    pub fn lookup(&self, name: &str) -> Vec<&OptionValue> {
        self.options
            .iter()
            .filter(|o| o.name.as_str() == name)
            .flat_map(|o| o.values.iter())
            .collect()
    }

    pub fn lookup_nth(&self, name: &str, n: usize) -> Option<&OptionValue> {
        self.options
            .iter()
            .filter(|o| o.name.as_str() == name)
            .flat_map(|o| o.values.iter())
            .nth(n)
    }

    pub fn lookup_string(&self, name: &str) -> Vec<&String> {
        self.options
            .iter()
            .filter(|o| o.name.as_str() == name)
            .flat_map(|o| o.values.iter())
            .flat_map(|v| match *v {
                OptionValue::String(ref s) => Some(s).into_iter(),
            })
            .collect()
    }

    pub fn lookup_string_nth(&self, name: &str, n: usize) -> Option<&String> {
        self.options
            .iter()
            .filter(|o| o.name.as_str() == name)
            .flat_map(|o| o.values.iter())
            .flat_map(|v| match *v {
                OptionValue::String(ref s) => Some(s).into_iter(),
            })
            .nth(n)
    }

    pub fn merge(&mut self, other: &Options) {
        self.options.extend(other.options.clone());
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum Modifier {
    Required,
    Optional,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Type {
    Double,
    Float,
    I32,
    I64,
    U32,
    U64,
    Bool,
    String,
    Bytes,
    Any,
    UsedType(String, String),
    Custom(String),
    Array(Box<Type>),
    Tuple(Vec<TupleElement>),
    Map(Box<Type>, Box<Type>),
}

#[derive(Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
pub struct Package {
    pub parts: Vec<String>,
}

impl Package {
    pub fn new(parts: Vec<String>) -> Package {
        Package { parts: parts }
    }

    pub fn join(&self, other: &Package) -> Package {
        let mut parts = self.parts.clone();
        parts.extend(other.parts.clone());
        Package::new(parts)
    }
}

impl ::std::fmt::Display for Package {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "{}", self.parts.join("."))
    }
}

#[derive(Debug, PartialEq, Clone)]
pub struct Field {
    pub modifier: Modifier,
    pub name: String,
    pub ty: Type,
    pub id: u32,
}

impl Field {
    pub fn new(modifier: Modifier, name: String, ty: Type, id: u32) -> Field {
        Field {
            modifier: modifier,
            name: name,
            ty: ty,
            id: id,
        }
    }

    pub fn is_optional(&self) -> bool {
        match self.modifier {
            Modifier::Optional => true,
            _ => false,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub struct OneOf {
    pub name: String,
    pub fields: Vec<Field>,
}

impl OneOf {
    pub fn new(name: String, fields: Vec<Field>) -> OneOf {
        OneOf {
            name: name,
            fields: fields,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum MessageMember {
    Field(Field, Pos),
    Code(String, Vec<String>, Pos),
    OneOf(OneOf, Pos),
}

/// message <name> { <members>* }
#[derive(Debug, PartialEq, Clone)]
pub struct MessageDecl {
    pub name: String,
    pub options: Options,
    pub members: Vec<MessageMember>,
    pub pos: Pos,
}

impl MessageDecl {
    pub fn new(name: String,
               options: Options,
               members: Vec<MessageMember>,
               pos: Pos)
               -> MessageDecl {
        MessageDecl {
            name: name,
            options: options,
            members: members,
            pos: pos,
        }
    }

    pub fn merge(&mut self, other: &Decl) -> Result<()> {
        if let Decl::Message(ref other) = *other {
            self.options.merge(&other.options);
            self.members.extend(other.members.clone());
            return Ok(());
        }

        return Err(format!("Expected Decl::Message, but got {:?}", other).into());
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum SubTypeMember {
    Field(Field),
    Code(String, Vec<String>, Pos),
    OneOf(OneOf),
}

#[derive(Debug, PartialEq, Clone)]
pub struct SubType {
    pub name: String,
    pub options: Options,
    pub members: Vec<SubTypeMember>,
    pub pos: Pos,
}

impl SubType {
    pub fn new(name: String, options: Options, members: Vec<SubTypeMember>, pos: Pos) -> SubType {
        SubType {
            name: name,
            options: options,
            members: members,
            pos: pos,
        }
    }

    pub fn merge(&mut self, other: &SubType) -> Result<()> {
        self.options.merge(&other.options);
        self.members.extend(other.members.clone());
        Ok(())
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum InterfaceMember {
    Field(Field, Pos),
    Code(String, Vec<String>, Pos),
    OneOf(OneOf, Pos),
}

/// interface <name> { <members>* }
#[derive(Debug, PartialEq, Clone)]
pub struct InterfaceDecl {
    pub name: String,
    pub options: Options,
    pub members: Vec<InterfaceMember>,
    pub sub_types: BTreeMap<String, SubType>,
    pub pos: Pos,
}

impl InterfaceDecl {
    pub fn new(name: String,
               options: Options,
               members: Vec<InterfaceMember>,
               sub_types: BTreeMap<String, SubType>,
               pos: Pos)
               -> InterfaceDecl {
        InterfaceDecl {
            name: name,
            options: options,
            members: members,
            sub_types: sub_types,
            pos: pos,
        }
    }

    pub fn merge(&mut self, other: &Decl) -> Result<()> {
        if let Decl::Interface(ref other) = *other {
            self.options.merge(&other.options);
            self.members.extend(other.members.clone());

            for (key, sub_type) in &other.sub_types {
                match self.sub_types.entry(key.to_owned()) {
                    Entry::Vacant(entry) => {
                        entry.insert(sub_type.clone());
                    }
                    Entry::Occupied(entry) => {
                        entry.into_mut().merge(sub_type)?;
                    }
                }
            }

            return Ok(());
        }

        return Err("unexpected declaration".into());
    }
}

/// type <name> = <value>;
///
/// Example, simple type alias:
/// type Foo = Bar;
#[derive(Debug, PartialEq, Clone)]
pub struct TypeDecl {
    pub name: String,
    pub value: Type,
    pub pos: Pos,
}

impl TypeDecl {
    pub fn new(name: String, value: Type, pos: Pos) -> TypeDecl {
        TypeDecl {
            name: name,
            value: value,
            pos: pos,
        }
    }

    pub fn merge(&mut self, _: &Decl) -> Result<()> {
        return Err("cannot merge type declarations".into());
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum Decl {
    Message(MessageDecl),
    Interface(InterfaceDecl),
    Type(TypeDecl),
}

impl Decl {
    pub fn name(&self) -> String {
        match *self {
            Decl::Message(ref message) => message.name.clone(),
            Decl::Interface(ref interface) => interface.name.clone(),
            Decl::Type(ref ty) => ty.name.clone(),
        }
    }

    pub fn pos(&self) -> Pos {
        match *self {
            Decl::Message(ref message) => message.pos.clone(),
            Decl::Interface(ref interface) => interface.pos.clone(),
            Decl::Type(ref ty) => ty.pos.clone(),
        }
    }

    pub fn merge(&mut self, other: &Decl) -> Result<()> {
        match *self {
            Decl::Message(ref mut message) => message.merge(other),
            Decl::Interface(ref mut interface) => interface.merge(other),
            Decl::Type(ref mut ty) => ty.merge(other),
        }
    }
}

#[derive(Debug, PartialEq)]
pub struct UseDecl {
    pub package: Package,
    pub alias: Option<String>,
}

impl UseDecl {
    pub fn new(package: Package, alias: Option<String>) -> UseDecl {
        UseDecl {
            package: package,
            alias: alias,
        }
    }
}

#[derive(Debug, PartialEq)]
pub struct File {
    pub package: Package,
    pub uses: Vec<UseDecl>,
    pub decls: Vec<Decl>,
}

impl File {
    pub fn new(package: Package, uses: Vec<UseDecl>, decls: Vec<Decl>) -> File {
        File {
            package: package,
            uses: uses,
            decls: decls,
        }
    }
}
<commit_msg>remove OneOf<commit_after>use std::collections::BTreeMap;
use std::collections::btree_map::Entry;

use errors::*;

/// Position relative in file where the declaration is present.
pub type Pos = (usize, usize);

#[derive(Debug, PartialEq, Clone)]
pub struct TupleElement {
    pub name: Option<String>,
    pub ty: Type,
}

impl TupleElement {
    pub fn new(name: Option<String>, ty: Type) -> TupleElement {
        TupleElement {
            name: name,
            ty: ty,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum OptionValue {
    String(String),
}

#[derive(Debug, PartialEq, Clone)]
pub struct OptionDecl {
    pub name: String,
    pub values: Vec<OptionValue>,
}

impl OptionDecl {
    pub fn new(name: String, values: Vec<OptionValue>) -> OptionDecl {
        OptionDecl {
            name: name,
            values: values,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub struct Options {
    options: Vec<OptionDecl>,
}

impl Options {
    pub fn new(options: Vec<OptionDecl>) -> Options {
        Options { options: options }
    }

    pub fn lookup(&self, name: &str) -> Vec<&OptionValue> {
        self.options
            .iter()
            .filter(|o| o.name.as_str() == name)
            .flat_map(|o| o.values.iter())
            .collect()
    }

    pub fn lookup_nth(&self, name: &str, n: usize) -> Option<&OptionValue> {
        self.options
            .iter()
            .filter(|o| o.name.as_str() == name)
            .flat_map(|o| o.values.iter())
            .nth(n)
    }

    pub fn lookup_string(&self, name: &str) -> Vec<&String> {
        self.options
            .iter()
            .filter(|o| o.name.as_str() == name)
            .flat_map(|o| o.values.iter())
            .flat_map(|v| match *v {
                OptionValue::String(ref s) => Some(s).into_iter(),
            })
            .collect()
    }

    pub fn lookup_string_nth(&self, name: &str, n: usize) -> Option<&String> {
        self.options
            .iter()
            .filter(|o| o.name.as_str() == name)
            .flat_map(|o| o.values.iter())
            .flat_map(|v| match *v {
                OptionValue::String(ref s) => Some(s).into_iter(),
            })
            .nth(n)
    }

    pub fn merge(&mut self, other: &Options) {
        self.options.extend(other.options.clone());
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum Modifier {
    Required,
    Optional,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Type {
    Double,
    Float,
    I32,
    I64,
    U32,
    U64,
    Bool,
    String,
    Bytes,
    Any,
    UsedType(String, String),
    Custom(String),
    Array(Box<Type>),
    Tuple(Vec<TupleElement>),
    Map(Box<Type>, Box<Type>),
}

#[derive(Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
pub struct Package {
    pub parts: Vec<String>,
}

impl Package {
    pub fn new(parts: Vec<String>) -> Package {
        Package { parts: parts }
    }

    pub fn join(&self, other: &Package) -> Package {
        let mut parts = self.parts.clone();
        parts.extend(other.parts.clone());
        Package::new(parts)
    }
}

impl ::std::fmt::Display for Package {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "{}", self.parts.join("."))
    }
}

#[derive(Debug, PartialEq, Clone)]
pub struct Field {
    pub modifier: Modifier,
    pub name: String,
    pub ty: Type,
    pub id: u32,
}

impl Field {
    pub fn new(modifier: Modifier, name: String, ty: Type, id: u32) -> Field {
        Field {
            modifier: modifier,
            name: name,
            ty: ty,
            id: id,
        }
    }

    pub fn is_optional(&self) -> bool {
        match self.modifier {
            Modifier::Optional => true,
            _ => false,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum MessageMember {
    Field(Field, Pos),
    Code(String, Vec<String>, Pos),
}

/// message <name> { <members>* }
#[derive(Debug, PartialEq, Clone)]
pub struct MessageDecl {
    pub name: String,
    pub options: Options,
    pub members: Vec<MessageMember>,
    pub pos: Pos,
}

impl MessageDecl {
    pub fn new(name: String,
               options: Options,
               members: Vec<MessageMember>,
               pos: Pos)
               -> MessageDecl {
        MessageDecl {
            name: name,
            options: options,
            members: members,
            pos: pos,
        }
    }

    pub fn merge(&mut self, other: &Decl) -> Result<()> {
        if let Decl::Message(ref other) = *other {
            self.options.merge(&other.options);
            self.members.extend(other.members.clone());
            return Ok(());
        }

        return Err(format!("Expected Decl::Message, but got {:?}", other).into());
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum SubTypeMember {
    Field(Field),
    Code(String, Vec<String>, Pos),
}

#[derive(Debug, PartialEq, Clone)]
pub struct SubType {
    pub name: String,
    pub options: Options,
    pub members: Vec<SubTypeMember>,
    pub pos: Pos,
}

impl SubType {
    pub fn new(name: String, options: Options, members: Vec<SubTypeMember>, pos: Pos) -> SubType {
        SubType {
            name: name,
            options: options,
            members: members,
            pos: pos,
        }
    }

    pub fn merge(&mut self, other: &SubType) -> Result<()> {
        self.options.merge(&other.options);
        self.members.extend(other.members.clone());
        Ok(())
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum InterfaceMember {
    Field(Field, Pos),
    Code(String, Vec<String>, Pos),
}

/// interface <name> { <members>* }
#[derive(Debug, PartialEq, Clone)]
pub struct InterfaceDecl {
    pub name: String,
    pub options: Options,
    pub members: Vec<InterfaceMember>,
    pub sub_types: BTreeMap<String, SubType>,
    pub pos: Pos,
}

impl InterfaceDecl {
    pub fn new(name: String,
               options: Options,
               members: Vec<InterfaceMember>,
               sub_types: BTreeMap<String, SubType>,
               pos: Pos)
               -> InterfaceDecl {
        InterfaceDecl {
            name: name,
            options: options,
            members: members,
            sub_types: sub_types,
            pos: pos,
        }
    }

    pub fn merge(&mut self, other: &Decl) -> Result<()> {
        if let Decl::Interface(ref other) = *other {
            self.options.merge(&other.options);
            self.members.extend(other.members.clone());

            for (key, sub_type) in &other.sub_types {
                match self.sub_types.entry(key.to_owned()) {
                    Entry::Vacant(entry) => {
                        entry.insert(sub_type.clone());
                    }
                    Entry::Occupied(entry) => {
                        entry.into_mut().merge(sub_type)?;
                    }
                }
            }

            return Ok(());
        }

        return Err("unexpected declaration".into());
    }
}

/// type <name> = <value>;
///
/// Example, simple type alias:
/// type Foo = Bar;
#[derive(Debug, PartialEq, Clone)]
pub struct TypeDecl {
    pub name: String,
    pub value: Type,
    pub pos: Pos,
}

impl TypeDecl {
    pub fn new(name: String, value: Type, pos: Pos) -> TypeDecl {
        TypeDecl {
            name: name,
            value: value,
            pos: pos,
        }
    }

    pub fn merge(&mut self, _: &Decl) -> Result<()> {
        return Err("cannot merge type declarations".into());
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum Decl {
    Message(MessageDecl),
    Interface(InterfaceDecl),
    Type(TypeDecl),
}

impl Decl {
    pub fn name(&self) -> String {
        match *self {
            Decl::Message(ref message) => message.name.clone(),
            Decl::Interface(ref interface) => interface.name.clone(),
            Decl::Type(ref ty) => ty.name.clone(),
        }
    }

    pub fn pos(&self) -> Pos {
        match *self {
            Decl::Message(ref message) => message.pos.clone(),
            Decl::Interface(ref interface) => interface.pos.clone(),
            Decl::Type(ref ty) => ty.pos.clone(),
        }
    }

    pub fn merge(&mut self, other: &Decl) -> Result<()> {
        match *self {
            Decl::Message(ref mut message) => message.merge(other),
            Decl::Interface(ref mut interface) => interface.merge(other),
            Decl::Type(ref mut ty) => ty.merge(other),
        }
    }
}

#[derive(Debug, PartialEq)]
pub struct UseDecl {
    pub package: Package,
    pub alias: Option<String>,
}

impl UseDecl {
    pub fn new(package: Package, alias: Option<String>) -> UseDecl {
        UseDecl {
            package: package,
            alias: alias,
        }
    }
}

#[derive(Debug, PartialEq)]
pub struct File {
    pub package: Package,
    pub uses: Vec<UseDecl>,
    pub decls: Vec<Decl>,
}

impl File {
    pub fn new(package: Package, uses: Vec<UseDecl>, decls: Vec<Decl>) -> File {
        File {
            package: package,
            uses: uses,
            decls: decls,
        }
    }
}
<|endoftext|>


<commit_before>use super::Document;

use rustc_serialize::json::Json;

#[derive(Debug)]
enum Filter {
    Not(Box<Filter>),
    Or(Vec<Filter>),
    And(Vec<Filter>),
    Term(String, String),
}

impl Filter {
    fn matches(&self, doc: &Document) -> bool {
        match *self {
            Filter::Not(ref filter) => !filter.matches(doc),
            Filter::Or(ref filters) => {
                for filter in filters.iter() {
                    if (filter.matches(doc)) {
                        return true;
                    }
                }

                false
            }
            Filter::And(ref filters) => {
                for filter in filters.iter() {
                    if (!filter.matches(doc)) {
                        return false;
                    }
                }

                true
            }
            Filter::Term(ref field, ref value) => {
                let obj = doc.data.as_object().unwrap();

                if let Some(field_value) = obj.get(field) {
                    if let Json::String(ref field_value) = *field_value {
                        return field_value == value;
                    }
                }

                false
            }
        }
    }
}
<commit_msg>Removed unneeded brackets<commit_after>use super::Document;

use rustc_serialize::json::Json;

#[derive(Debug)]
enum Filter {
    Not(Box<Filter>),
    Or(Vec<Filter>),
    And(Vec<Filter>),
    Term(String, String),
}

impl Filter {
    fn matches(&self, doc: &Document) -> bool {
        match *self {
            Filter::Not(ref filter) => !filter.matches(doc),
            Filter::Or(ref filters) => {
                for filter in filters.iter() {
                    if filter.matches(doc) {
                        return true;
                    }
                }

                false
            }
            Filter::And(ref filters) => {
                for filter in filters.iter() {
                    if !filter.matches(doc) {
                        return false;
                    }
                }

                true
            }
            Filter::Term(ref field, ref value) => {
                let obj = doc.data.as_object().unwrap();

                if let Some(field_value) = obj.get(field) {
                    if let Json::String(ref field_value) = *field_value {
                        return field_value == value;
                    }
                }

                false
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Parallel iterator types for [ranges][std::range],
//! the type for values created by `a..b` expressions
//!
//! You will rarely need to interact with this module directly unless you have
//! need to name one of the iterator types.
//!
//! ```
//! use rayon::prelude::*;
//!
//! let r = (0..100u64).into_par_iter()
//!                    .sum();
//!
//! // compare result with sequential calculation
//! assert_eq!((0..100).sum::<u64>(), r);
//! ```
//!
//! [std::range]: https://doc.rust-lang.org/core/ops/struct.Range.html

use iter::*;
use iter::plumbing::*;
use std::ops::Range;
use std::usize;

/// Parallel iterator over a range, implemented for all integer types.
///
/// **Note:** The `zip` operation requires `IndexedParallelIterator`
/// which is not implemented for `u64`, `i64`, `u128`, or `i128`.
///
/// ```
/// use rayon::prelude::*;
///
/// let p = (0..25usize).into_par_iter()
///                   .zip(0..25usize)
///                   .filter(|&(x, y)| x % 5 == 0 || y % 5 == 0)
///                   .map(|(x, y)| x * y)
///                   .sum::<usize>();
///
/// let s = (0..25usize).zip(0..25)
///                   .filter(|&(x, y)| x % 5 == 0 || y % 5 == 0)
///                   .map(|(x, y)| x * y)
///                   .sum();
///
/// assert_eq!(p, s);
/// ```
#[derive(Debug, Clone)]
pub struct Iter<T> {
    range: Range<T>,
}

impl<T> IntoParallelIterator for Range<T>
    where Iter<T>: ParallelIterator
{
    type Item = <Iter<T> as ParallelIterator>::Item;
    type Iter = Iter<T>;

    fn into_par_iter(self) -> Self::Iter {
        Iter { range: self }
    }
}

struct IterProducer<T> {
    range: Range<T>,
}

impl<T> IntoIterator for IterProducer<T>
    where Range<T>: Iterator
{
    type Item = <Range<T> as Iterator>::Item;
    type IntoIter = Range<T>;

    fn into_iter(self) -> Self::IntoIter {
        self.range
    }
}

macro_rules! indexed_range_impl {
    ( $t:ty ) => {
        impl ParallelIterator for Iter<$t> {
            type Item = $t;

            fn drive_unindexed<C>(self, consumer: C) -> C::Result
                where C: UnindexedConsumer<Self::Item>
            {
                bridge(self, consumer)
            }

            fn opt_len(&self) -> Option<usize> {
                Some(self.len())
            }
        }

        impl IndexedParallelIterator for Iter<$t> {
            fn drive<C>(self, consumer: C) -> C::Result
                where C: Consumer<Self::Item>
            {
                bridge(self, consumer)
            }

            fn len(&self) -> usize {
                self.range.len()
            }

            fn with_producer<CB>(self, callback: CB) -> CB::Output
                where CB: ProducerCallback<Self::Item>
            {
                callback.callback(IterProducer { range: self.range })
            }
        }

        impl Producer for IterProducer<$t> {

            type Item = <Range<$t> as Iterator>::Item;
            type IntoIter = Range<$t>;
            fn into_iter(self) -> Self::IntoIter {
                self.range
            }

            fn split_at(self, index: usize) -> (Self, Self) {
                assert!(index <= self.range.len());
                // For signed $t, the length and requested index could be greater than $t::MAX, and
                // then `index as $t` could wrap to negative, so wrapping_add is necessary.
                let mid = self.range.start.wrapping_add(index as $t);
                let left = self.range.start .. mid;
                let right = mid .. self.range.end;
                (IterProducer { range: left }, IterProducer { range: right })
            }
        }
    }
}

trait UnindexedRangeLen<L> {
    fn len(&self) -> L;
}

macro_rules! unindexed_range_impl {
    ( $t:ty, $len_t:ty ) => {
        impl UnindexedRangeLen<$len_t> for Range<$t> {
            fn len(&self) -> $len_t {
                let &Range { start, end } = self;
                if end > start {
                    end.wrapping_sub(start) as $len_t
                } else {
                    0
                }
            }
        }

        impl ParallelIterator for Iter<$t> {
            type Item = $t;

            fn drive_unindexed<C>(self, consumer: C) -> C::Result
                where C: UnindexedConsumer<Self::Item>
            {
                if let Some(len) = self.opt_len() {
                    (0..len).into_par_iter()
                        .map(|i| self.range.start.wrapping_add(i as $t))
                        .drive_unindexed(consumer)
                } else {
                    bridge_unindexed(IterProducer { range: self.range }, consumer)
                }
            }

            fn opt_len(&self) -> Option<usize> {
                let len = self.range.len();
                if len <= usize::MAX as $len_t {
                    Some(len as usize)
                } else {
                    None
                }
            }
        }

        impl UnindexedProducer for IterProducer<$t> {
            type Item = $t;

            fn split(mut self) -> (Self, Option<Self>) {
                let index = self.range.len() / 2;
                if index > 0 {
                    let mid = self.range.start.wrapping_add(index as $t);
                    let right = mid .. self.range.end;
                    self.range.end = mid;
                    (self, Some(IterProducer { range: right }))
                } else {
                    (self, None)
                }
            }

            fn fold_with<F>(self, folder: F) -> F
                where F: Folder<Self::Item>
            {
                folder.consume_iter(self)
            }
        }
    }
}

// all Range<T> with ExactSizeIterator
indexed_range_impl!{u8}
indexed_range_impl!{u16}
indexed_range_impl!{u32}
indexed_range_impl!{usize}
indexed_range_impl!{i8}
indexed_range_impl!{i16}
indexed_range_impl!{i32}
indexed_range_impl!{isize}

// other Range<T> with just Iterator
unindexed_range_impl!{u64, u64}
unindexed_range_impl!{i64, u64}
#[cfg(has_i128)] unindexed_range_impl!{u128, u128}
#[cfg(has_i128)] unindexed_range_impl!{i128, u128}

#[test]
fn check_range_split_at_overflow() {
    // Note, this split index overflows i8!
    let producer = IterProducer { range: -100i8..100 };
    let (left, right) = producer.split_at(150);
    let r1: i32 = left.range.map(|i| i as i32).sum();
    let r2: i32 = right.range.map(|i| i as i32).sum();
    assert_eq!(r1 + r2, -100);
}

#[cfg(has_i128)]
#[test]
fn test_i128_len_doesnt_overflow() {
    use std::{i128, u128};

    // Using parse because some versions of rust don't allow long literals
    let octillion: i128 = "1000000000000000000000000000".parse().unwrap();
    let producer = IterProducer { range: 0..octillion };

    assert_eq!(octillion as u128, producer.range.len());
    assert_eq!(octillion as u128, (0..octillion).len());
    assert_eq!(2 * octillion as u128, (-octillion..octillion).len());

    assert_eq!(u128::MAX, (i128::MIN..i128::MAX).len());

}

#[test]
fn test_u64_opt_len() {
    use std::{u64, usize};
    assert_eq!(Some(100), (0..100u64).into_par_iter().opt_len());
    assert_eq!(Some(usize::MAX), (0..usize::MAX as u64).into_par_iter().opt_len());
    if (usize::MAX as u64) < u64::MAX {
        assert_eq!(None, (0..1 + usize::MAX as u64).into_par_iter().opt_len());
        assert_eq!(None, (0..u64::MAX).into_par_iter().opt_len());
    }
}

#[cfg(has_i128)]
#[test]
fn test_u128_opt_len() {
    use std::{u128, usize};
    assert_eq!(Some(100), (0..100u128).into_par_iter().opt_len());
    assert_eq!(Some(usize::MAX), (0..usize::MAX as u128).into_par_iter().opt_len());
    assert_eq!(None, (0..1 + usize::MAX as u128).into_par_iter().opt_len());
    assert_eq!(None, (0..u128::MAX).into_par_iter().opt_len());
}

// `usize as i64` can overflow, so make sure to wrap it appropriately
// when using the `opt_len` "indexed" mode.
#[test]
#[cfg(target_pointer_width = "64")]
fn test_usize_i64_overflow() {
    use std::i64;
    use ThreadPoolBuilder;

    let iter = (-2..i64::MAX).into_par_iter();
    assert_eq!(iter.opt_len(), Some(i64::MAX as usize + 2));

    // always run with multiple threads to split into, or this will take forever...
    let pool = ThreadPoolBuilder::new().num_threads(8).build().unwrap();
    pool.install(|| assert_eq!(iter.find_last(|_| true), Some(i64::MAX - 1)));
}
<commit_msg>Make it clearer that we're driving some ranges indexed<commit_after>//! Parallel iterator types for [ranges][std::range],
//! the type for values created by `a..b` expressions
//!
//! You will rarely need to interact with this module directly unless you have
//! need to name one of the iterator types.
//!
//! ```
//! use rayon::prelude::*;
//!
//! let r = (0..100u64).into_par_iter()
//!                    .sum();
//!
//! // compare result with sequential calculation
//! assert_eq!((0..100).sum::<u64>(), r);
//! ```
//!
//! [std::range]: https://doc.rust-lang.org/core/ops/struct.Range.html

use iter::*;
use iter::plumbing::*;
use std::ops::Range;
use std::usize;

/// Parallel iterator over a range, implemented for all integer types.
///
/// **Note:** The `zip` operation requires `IndexedParallelIterator`
/// which is not implemented for `u64`, `i64`, `u128`, or `i128`.
///
/// ```
/// use rayon::prelude::*;
///
/// let p = (0..25usize).into_par_iter()
///                   .zip(0..25usize)
///                   .filter(|&(x, y)| x % 5 == 0 || y % 5 == 0)
///                   .map(|(x, y)| x * y)
///                   .sum::<usize>();
///
/// let s = (0..25usize).zip(0..25)
///                   .filter(|&(x, y)| x % 5 == 0 || y % 5 == 0)
///                   .map(|(x, y)| x * y)
///                   .sum();
///
/// assert_eq!(p, s);
/// ```
#[derive(Debug, Clone)]
pub struct Iter<T> {
    range: Range<T>,
}

impl<T> IntoParallelIterator for Range<T>
    where Iter<T>: ParallelIterator
{
    type Item = <Iter<T> as ParallelIterator>::Item;
    type Iter = Iter<T>;

    fn into_par_iter(self) -> Self::Iter {
        Iter { range: self }
    }
}

struct IterProducer<T> {
    range: Range<T>,
}

impl<T> IntoIterator for IterProducer<T>
    where Range<T>: Iterator
{
    type Item = <Range<T> as Iterator>::Item;
    type IntoIter = Range<T>;

    fn into_iter(self) -> Self::IntoIter {
        self.range
    }
}

macro_rules! indexed_range_impl {
    ( $t:ty ) => {
        impl ParallelIterator for Iter<$t> {
            type Item = $t;

            fn drive_unindexed<C>(self, consumer: C) -> C::Result
                where C: UnindexedConsumer<Self::Item>
            {
                bridge(self, consumer)
            }

            fn opt_len(&self) -> Option<usize> {
                Some(self.len())
            }
        }

        impl IndexedParallelIterator for Iter<$t> {
            fn drive<C>(self, consumer: C) -> C::Result
                where C: Consumer<Self::Item>
            {
                bridge(self, consumer)
            }

            fn len(&self) -> usize {
                self.range.len()
            }

            fn with_producer<CB>(self, callback: CB) -> CB::Output
                where CB: ProducerCallback<Self::Item>
            {
                callback.callback(IterProducer { range: self.range })
            }
        }

        impl Producer for IterProducer<$t> {

            type Item = <Range<$t> as Iterator>::Item;
            type IntoIter = Range<$t>;
            fn into_iter(self) -> Self::IntoIter {
                self.range
            }

            fn split_at(self, index: usize) -> (Self, Self) {
                assert!(index <= self.range.len());
                // For signed $t, the length and requested index could be greater than $t::MAX, and
                // then `index as $t` could wrap to negative, so wrapping_add is necessary.
                let mid = self.range.start.wrapping_add(index as $t);
                let left = self.range.start .. mid;
                let right = mid .. self.range.end;
                (IterProducer { range: left }, IterProducer { range: right })
            }
        }
    }
}

trait UnindexedRangeLen<L> {
    fn len(&self) -> L;
}

macro_rules! unindexed_range_impl {
    ( $t:ty, $len_t:ty ) => {
        impl UnindexedRangeLen<$len_t> for Range<$t> {
            fn len(&self) -> $len_t {
                let &Range { start, end } = self;
                if end > start {
                    end.wrapping_sub(start) as $len_t
                } else {
                    0
                }
            }
        }

        impl ParallelIterator for Iter<$t> {
            type Item = $t;

            fn drive_unindexed<C>(self, consumer: C) -> C::Result
                where C: UnindexedConsumer<Self::Item>
            {
                if let Some(len) = self.opt_len() {
                    // Drive this in indexed mode for better `collect`.
                    (0..len).into_par_iter()
                        .map(|i| self.range.start.wrapping_add(i as $t))
                        .drive(consumer)
                } else {
                    bridge_unindexed(IterProducer { range: self.range }, consumer)
                }
            }

            fn opt_len(&self) -> Option<usize> {
                let len = self.range.len();
                if len <= usize::MAX as $len_t {
                    Some(len as usize)
                } else {
                    None
                }
            }
        }

        impl UnindexedProducer for IterProducer<$t> {
            type Item = $t;

            fn split(mut self) -> (Self, Option<Self>) {
                let index = self.range.len() / 2;
                if index > 0 {
                    let mid = self.range.start.wrapping_add(index as $t);
                    let right = mid .. self.range.end;
                    self.range.end = mid;
                    (self, Some(IterProducer { range: right }))
                } else {
                    (self, None)
                }
            }

            fn fold_with<F>(self, folder: F) -> F
                where F: Folder<Self::Item>
            {
                folder.consume_iter(self)
            }
        }
    }
}

// all Range<T> with ExactSizeIterator
indexed_range_impl!{u8}
indexed_range_impl!{u16}
indexed_range_impl!{u32}
indexed_range_impl!{usize}
indexed_range_impl!{i8}
indexed_range_impl!{i16}
indexed_range_impl!{i32}
indexed_range_impl!{isize}

// other Range<T> with just Iterator
unindexed_range_impl!{u64, u64}
unindexed_range_impl!{i64, u64}
#[cfg(has_i128)] unindexed_range_impl!{u128, u128}
#[cfg(has_i128)] unindexed_range_impl!{i128, u128}

#[test]
fn check_range_split_at_overflow() {
    // Note, this split index overflows i8!
    let producer = IterProducer { range: -100i8..100 };
    let (left, right) = producer.split_at(150);
    let r1: i32 = left.range.map(|i| i as i32).sum();
    let r2: i32 = right.range.map(|i| i as i32).sum();
    assert_eq!(r1 + r2, -100);
}

#[cfg(has_i128)]
#[test]
fn test_i128_len_doesnt_overflow() {
    use std::{i128, u128};

    // Using parse because some versions of rust don't allow long literals
    let octillion: i128 = "1000000000000000000000000000".parse().unwrap();
    let producer = IterProducer { range: 0..octillion };

    assert_eq!(octillion as u128, producer.range.len());
    assert_eq!(octillion as u128, (0..octillion).len());
    assert_eq!(2 * octillion as u128, (-octillion..octillion).len());

    assert_eq!(u128::MAX, (i128::MIN..i128::MAX).len());

}

#[test]
fn test_u64_opt_len() {
    use std::{u64, usize};
    assert_eq!(Some(100), (0..100u64).into_par_iter().opt_len());
    assert_eq!(Some(usize::MAX), (0..usize::MAX as u64).into_par_iter().opt_len());
    if (usize::MAX as u64) < u64::MAX {
        assert_eq!(None, (0..1 + usize::MAX as u64).into_par_iter().opt_len());
        assert_eq!(None, (0..u64::MAX).into_par_iter().opt_len());
    }
}

#[cfg(has_i128)]
#[test]
fn test_u128_opt_len() {
    use std::{u128, usize};
    assert_eq!(Some(100), (0..100u128).into_par_iter().opt_len());
    assert_eq!(Some(usize::MAX), (0..usize::MAX as u128).into_par_iter().opt_len());
    assert_eq!(None, (0..1 + usize::MAX as u128).into_par_iter().opt_len());
    assert_eq!(None, (0..u128::MAX).into_par_iter().opt_len());
}

// `usize as i64` can overflow, so make sure to wrap it appropriately
// when using the `opt_len` "indexed" mode.
#[test]
#[cfg(target_pointer_width = "64")]
fn test_usize_i64_overflow() {
    use std::i64;
    use ThreadPoolBuilder;

    let iter = (-2..i64::MAX).into_par_iter();
    assert_eq!(iter.opt_len(), Some(i64::MAX as usize + 2));

    // always run with multiple threads to split into, or this will take forever...
    let pool = ThreadPoolBuilder::new().num_threads(8).build().unwrap();
    pool.install(|| assert_eq!(iter.find_last(|_| true), Some(i64::MAX - 1)));
}
<|endoftext|>