<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::hashmap::HashMap;
use std::gc::Gc;
use syntax::ast::TokenTree;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base::ExtCtxt;
use syntax::parse::{token, ParseSess, lexer};

use node;

#[allow(dead_code)]
pub struct Parser<'a> {
  pub sess: &'a ParseSess,
  reader: Box<lexer::Reader:>,
  token: token::Token,
  span: Span,

  last_token: Option<Box<token::Token>>,
  last_span: Span,
}

impl<'a> Parser<'a> {
  #[allow(dead_code)]
  pub fn new<'a>(cx: &'a ExtCtxt, tts: &[TokenTree]) -> Parser<'a> {
    let sess = cx.parse_sess();
    let ttsvec = tts.iter().map(|x| (*x).clone()).collect();
    let mut reader = box lexer::new_tt_reader(
        &sess.span_diagnostic, None, ttsvec) as Box<lexer::Reader>;

    let tok0 = reader.next_token();
    let token = tok0.tok;
    let span = tok0.sp;

    Parser {
      sess: sess,
      reader: reader,

      token: token,
      span: span,

      last_token: None,
      last_span: span,
    }
  }

  /// Parse the platform tree from passed in tokens.
  pub fn parse_platformtree(&mut self) -> Option<node::PlatformTree> {
    let mut nodes: Vec<Gc<node::Node>> = Vec::new();
    let mut failed = false;
    loop {
      if self.token == token::EOF {
        break
      }

      let node = match self.parse_node() {
        Some(node) => box(GC) node,
        None => {
          failed = true;
          self.bump();
          continue
        }
      };

      nodes.push(node);
    }

    if failed {
      None
    } else {
      let some_named = self.collect_node_names(&HashMap::new(), &nodes);

      if some_named.is_none() {
        None
      } else {
        Some(node::PlatformTree::new(nodes, some_named.unwrap()))
      }
    }
  }

  fn collect_node_names(&self, map: &HashMap<String, Gc<node::Node>>,
      nodes: &Vec<Gc<node::Node>>) -> Option<HashMap<String, Gc<node::Node>>> {
    let mut local_map: HashMap<String, Gc<node::Node>> = HashMap::new();
    for (k,v) in map.iter() {
      local_map.insert(k.clone(), *v);
    }
    for n in nodes.iter() {
      let collected_sub = self.collect_node_names(&local_map, &n.subnodes);
      if collected_sub.is_none() {
        return None;
      } else {
        for (k,v) in collected_sub.unwrap().iter() {
          local_map.insert(k.clone(), *v);
        }
      }
      match n.name {
        Some(ref name) => {
          if local_map.contains_key(name) {
            self.sess.span_diagnostic.span_err(n.name_span, format!(
                "duplicate `{}` definition", name).as_slice());

            self.sess.span_diagnostic.span_warn(
                local_map.get(name).name_span,
                "previously defined here");
            return None;
          } else {
            local_map.insert(name.clone(), *n);
          }
        },
        None => (),
      }
    }
    Some(local_map)
  }

  fn parse_node(&mut self) -> Option<node::Node> {
    let name_span: Option<Span>;
    let node_name: Option<String>;

    //  we're here
    // /
    // v
    // NAME @ PATH { ... }
    //      ^-- peeking here
    if self.reader.peek().tok == token::AT {
      name_span = Some(self.span);
      node_name = match self.expect_ident() {
        Some(name) => Some(name),
        None => return None,
      };
      if !self.expect(&token::AT) {
        return None;
      }
    } else {
      node_name = None;
      name_span = None;
    }

    let node_span: Span;
    let node_path_span: Span;
    let attributes: HashMap<String, node::Attribute>;
    let subnodes: Vec<Gc<node::Node>>;

    // NAME is resolved, if it was there anyway.
    //    we're here
    //          |
    //          v
    //   NAME @ PATH { ... }
    node_path_span = self.span;
    if node_name == None {
      node_span = self.span;
    } else {
      node_span = mk_sp(name_span.unwrap().lo, self.span.hi);
    }

    let node_path = match self.token {
      token::IDENT(_, _) => {
        token::to_str(&self.bump())
      },
      token::LIT_INT_UNSUFFIXED(u) => {
        self.bump();
        u.to_str()
      }
      ref other => {
        self.error(format!("expected node path but found `{}`",
            token::to_str(other)));
        return None;
      }
    };

    //    we're here
    //             |
    //             v
    // NAME @ PATH { ... }
    // it's either a body, or a semicolon (no body)
    match self.bump() {
      token::LBRACE => {
        let (a, s) = match self.parse_node_body() {
          Some((attrs, subnodes)) => (attrs, subnodes),
          // TODO(farcaller): eat everything up to '}' and continue if failed
          // we can still parse further nodes.
          None => return None,
        };
        attributes = a;
        subnodes = s;

        if !self.expect(&token::RBRACE) {
          return None;
        }
      },
      token::SEMI => {
        attributes = HashMap::new();
        subnodes = Vec::new();
      },
      ref other => {
        self.error(format!("expected `\\{` or `;` but found `{}`",
            token::to_str(other)));
        return None;
      }
    }

    let mut node = node::Node::new(node_name, node_span, node_path, node_path_span);
    node.attributes = attributes;
    node.subnodes = subnodes;
    Some(node)
  }

  fn parse_node_body(&mut self)
      -> Option<(HashMap<String, node::Attribute>, Vec<Gc<node::Node>>)> {
    let mut attrs = HashMap::new();
    let mut subnodes = Vec::new();

    loop {
      // break early if at brace
      if self.token == token::RBRACE {
        break;
      }

      // we're here
      // |
      // v
      // ATTR = VAL ;
      // NAME @ PATH
      // PATH { ... }
      // PATH ;
      //      ^-- peeking here
      if self.reader.peek().tok == token::EQ {
        // we're here
        // |
        // v
        // ATTR = VAL ;
        let name_span = self.span;
        let some_name = match self.expect_ident() {
          Some(name) => name,
          None => return None,
        };

        if attrs.contains_key(&some_name) {
          self.error(format!("key `{}` is already defined", some_name));
          return None;
        }

        self.bump(); // bump token::EQ

        // we're here
        //        |
        //        v
        // ATTR = VAL ;
        let attr_value_span = self.span;
        let attr_value = match self.parse_attribute_value() {
          Some(value) => value,
          None => return None,
        };

        //   we're here
        //            |
        //            v
        // ATTR = VAL ;
        if !self.expect(&token::SEMI) {
          return None;
        }

        attrs.insert(some_name, node::Attribute::new(
            attr_value, name_span, attr_value_span));
      } else {
        // this should be a subnode
        let oldsp = self.span;
        let oldtok = self.token.clone();
        let node = match self.parse_node() {
          Some(node) => node,
          None => {
            self.span = oldsp;
            self.error(format!("expected `=` or node but found `{}`",
                token::to_str(&oldtok)));
            return None;
          },
        };

        subnodes.push(box(GC) node);
      }
    }

    Some((attrs, subnodes))
  }

  fn parse_attribute_value(&mut self) -> Option<node::AttributeValue> {
    match self.token {
      token::LIT_STR(string_val) => {
        self.bump();
        let string = token::get_ident(string_val).get().to_str();
        Some(node::StrValue(string))
      },
      token::LIT_INT_UNSUFFIXED(intval) => {
        self.bump();
        Some(node::UIntValue(intval as uint))
      },
      token::BINOP(token::AND) => {
        self.bump();
        let name = match self.expect_ident() {
          Some(name) => name,
          None => return None,
        };
        Some(node::RefValue(name))
      },
      ref other => {
        self.error(format!("expected string but found `{}`",
            token::to_str(other)));
        None
      }
    }
  }

  fn error(&self, m: String) {
    self.sess.span_diagnostic.span_err(self.span, m.as_slice());
  }

  /// Bumps a token.
  ///
  /// This moves current token to last token, pops a new token from backlog or
  /// reader and returns the last token (i.e. the 'current' token at the time of
  /// method call).
  fn bump(&mut self) -> token::Token {
    let tok = self.token.clone();
    self.last_span = self.span;
    self.last_token = Some(box tok.clone());

    let next = self.reader.next_token();

    self.span = next.sp;
    self.token = next.tok;

    tok
  }

  /// Expects that the current token is t. Bumps on success.
  fn expect(&mut self, t: &token::Token) -> bool {
    if self.token == *t {
      self.bump();
      true
    } else {
      let token_str = token::to_str(t);
      let this_token_str = token::to_str(&self.token);
      self.error(format!("expected `{}` but found `{}`", token_str,
          this_token_str));
      false
    }
  }

  /// Expects that the current token is IDENT, returns its string value. Bumps
  /// on success.
  fn expect_ident(&mut self) -> Option<String> {
    let tok_str = token::to_str(&self.token);
    match self.token {
      token::IDENT(_, _) => {
        self.bump();
        Some(tok_str)
      },
      _ => {
        self.error(format!("expected identifier but found `{}`", tok_str));
        None
      },
    }
  }
}
<commit_msg>Code cleanup.<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::hashmap::HashMap;
use std::gc::Gc;
use syntax::ast::TokenTree;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base::ExtCtxt;
use syntax::parse::{token, ParseSess, lexer};

use node;

pub struct Parser<'a> {
  pub sess: &'a ParseSess,
  reader: Box<lexer::Reader:>,
  token: token::Token,
  span: Span,

  last_token: Option<Box<token::Token>>,
  last_span: Span,
}

impl<'a> Parser<'a> {
  pub fn new<'a>(cx: &'a ExtCtxt, tts: &[TokenTree]) -> Parser<'a> {
    let sess = cx.parse_sess();
    let ttsvec = tts.iter().map(|x| (*x).clone()).collect();
    let mut reader = box lexer::new_tt_reader(
        &sess.span_diagnostic, None, ttsvec) as Box<lexer::Reader>;

    let tok0 = reader.next_token();
    let token = tok0.tok;
    let span = tok0.sp;

    Parser {
      sess: sess,
      reader: reader,

      token: token,
      span: span,

      last_token: None,
      last_span: span,
    }
  }

  /// Parse the platform tree from passed in tokens.
  pub fn parse_platformtree(&mut self) -> Option<node::PlatformTree> {
    let mut nodes: Vec<Gc<node::Node>> = Vec::new();
    let mut failed = false;
    loop {
      if self.token == token::EOF {
        break
      }

      let node = match self.parse_node() {
        Some(node) => box(GC) node,
        None => {
          failed = true;
          self.bump();
          continue
        }
      };

      nodes.push(node);
    }

    if failed {
      None
    } else {
      let some_named = self.collect_node_names(&HashMap::new(), &nodes);

      if some_named.is_none() {
        None
      } else {
        Some(node::PlatformTree::new(nodes, some_named.unwrap()))
      }
    }
  }

  fn collect_node_names(&self, map: &HashMap<String, Gc<node::Node>>,
      nodes: &Vec<Gc<node::Node>>) -> Option<HashMap<String, Gc<node::Node>>> {
    let mut local_map: HashMap<String, Gc<node::Node>> = HashMap::new();
    for (k,v) in map.iter() {
      local_map.insert(k.clone(), *v);
    }
    for n in nodes.iter() {
      let collected_sub = self.collect_node_names(&local_map, &n.subnodes);
      if collected_sub.is_none() {
        return None;
      } else {
        for (k,v) in collected_sub.unwrap().iter() {
          local_map.insert(k.clone(), *v);
        }
      }
      match n.name {
        Some(ref name) => {
          if local_map.contains_key(name) {
            self.sess.span_diagnostic.span_err(n.name_span, format!(
                "duplicate `{}` definition", name).as_slice());

            self.sess.span_diagnostic.span_warn(
                local_map.get(name).name_span,
                "previously defined here");
            return None;
          } else {
            local_map.insert(name.clone(), *n);
          }
        },
        None => (),
      }
    }
    Some(local_map)
  }

  fn parse_node(&mut self) -> Option<node::Node> {
    let name_span: Option<Span>;
    let node_name: Option<String>;

    //  we're here
    // /
    // v
    // NAME @ PATH { ... }
    //      ^-- peeking here
    if self.reader.peek().tok == token::AT {
      name_span = Some(self.span);
      node_name = match self.expect_ident() {
        Some(name) => Some(name),
        None => return None,
      };
      if !self.expect(&token::AT) {
        return None;
      }
    } else {
      node_name = None;
      name_span = None;
    }

    let node_span: Span;
    let node_path_span: Span;
    let attributes: HashMap<String, node::Attribute>;
    let subnodes: Vec<Gc<node::Node>>;

    // NAME is resolved, if it was there anyway.
    //    we're here
    //          |
    //          v
    //   NAME @ PATH { ... }
    node_path_span = self.span;
    if node_name == None {
      node_span = self.span;
    } else {
      node_span = mk_sp(name_span.unwrap().lo, self.span.hi);
    }

    let node_path = match self.token {
      token::IDENT(_, _) => {
        token::to_str(&self.bump())
      },
      token::LIT_INT_UNSUFFIXED(u) => {
        self.bump();
        u.to_str()
      }
      ref other => {
        self.error(format!("expected node path but found `{}`",
            token::to_str(other)));
        return None;
      }
    };

    //    we're here
    //             |
    //             v
    // NAME @ PATH { ... }
    // it's either a body, or a semicolon (no body)
    match self.bump() {
      token::LBRACE => {
        let (a, s) = match self.parse_node_body() {
          Some((attrs, subnodes)) => (attrs, subnodes),
          // TODO(farcaller): eat everything up to '}' and continue if failed
          // we can still parse further nodes.
          None => return None,
        };
        attributes = a;
        subnodes = s;

        if !self.expect(&token::RBRACE) {
          return None;
        }
      },
      token::SEMI => {
        attributes = HashMap::new();
        subnodes = Vec::new();
      },
      ref other => {
        self.error(format!("expected `\\{` or `;` but found `{}`",
            token::to_str(other)));
        return None;
      }
    }

    let mut node = node::Node::new(node_name, node_span, node_path, node_path_span);
    node.attributes = attributes;
    node.subnodes = subnodes;
    Some(node)
  }

  fn parse_node_body(&mut self)
      -> Option<(HashMap<String, node::Attribute>, Vec<Gc<node::Node>>)> {
    let mut attrs = HashMap::new();
    let mut subnodes = Vec::new();

    loop {
      // break early if at brace
      if self.token == token::RBRACE {
        break;
      }

      // we're here
      // |
      // v
      // ATTR = VAL ;
      // NAME @ PATH
      // PATH { ... }
      // PATH ;
      //      ^-- peeking here
      if self.reader.peek().tok == token::EQ {
        // we're here
        // |
        // v
        // ATTR = VAL ;
        let name_span = self.span;
        let some_name = match self.expect_ident() {
          Some(name) => name,
          None => return None,
        };

        if attrs.contains_key(&some_name) {
          self.error(format!("key `{}` is already defined", some_name));
          return None;
        }

        self.bump(); // bump token::EQ

        // we're here
        //        |
        //        v
        // ATTR = VAL ;
        let attr_value_span = self.span;
        let attr_value = match self.parse_attribute_value() {
          Some(value) => value,
          None => return None,
        };

        //   we're here
        //            |
        //            v
        // ATTR = VAL ;
        if !self.expect(&token::SEMI) {
          return None;
        }

        attrs.insert(some_name, node::Attribute::new(
            attr_value, name_span, attr_value_span));
      } else {
        // this should be a subnode
        let oldsp = self.span;
        let oldtok = self.token.clone();
        let node = match self.parse_node() {
          Some(node) => node,
          None => {
            self.span = oldsp;
            self.error(format!("expected `=` or node but found `{}`",
                token::to_str(&oldtok)));
            return None;
          },
        };

        subnodes.push(box(GC) node);
      }
    }

    Some((attrs, subnodes))
  }

  fn parse_attribute_value(&mut self) -> Option<node::AttributeValue> {
    match self.token {
      token::LIT_STR(string_val) => {
        self.bump();
        let string = token::get_ident(string_val).get().to_str();
        Some(node::StrValue(string))
      },
      token::LIT_INT_UNSUFFIXED(intval) => {
        self.bump();
        Some(node::UIntValue(intval as uint))
      },
      token::BINOP(token::AND) => {
        self.bump();
        let name = match self.expect_ident() {
          Some(name) => name,
          None => return None,
        };
        Some(node::RefValue(name))
      },
      ref other => {
        self.error(format!("expected string but found `{}`",
            token::to_str(other)));
        None
      }
    }
  }

  fn error(&self, m: String) {
    self.sess.span_diagnostic.span_err(self.span, m.as_slice());
  }

  /// Bumps a token.
  ///
  /// This moves current token to last token, pops a new token from backlog or
  /// reader and returns the last token (i.e. the 'current' token at the time of
  /// method call).
  fn bump(&mut self) -> token::Token {
    let tok = self.token.clone();
    self.last_span = self.span;
    self.last_token = Some(box tok.clone());

    let next = self.reader.next_token();

    self.span = next.sp;
    self.token = next.tok;

    tok
  }

  /// Expects that the current token is t. Bumps on success.
  fn expect(&mut self, t: &token::Token) -> bool {
    if self.token == *t {
      self.bump();
      true
    } else {
      let token_str = token::to_str(t);
      let this_token_str = token::to_str(&self.token);
      self.error(format!("expected `{}` but found `{}`", token_str,
          this_token_str));
      false
    }
  }

  /// Expects that the current token is IDENT, returns its string value. Bumps
  /// on success.
  fn expect_ident(&mut self) -> Option<String> {
    let tok_str = token::to_str(&self.token);
    match self.token {
      token::IDENT(_, _) => {
        self.bump();
        Some(tok_str)
      },
      _ => {
        self.error(format!("expected identifier but found `{}`", tok_str));
        None
      },
    }
  }
}
<|endoftext|>


<commit_before>//! Common types for the [push notifications module][push]
//!
//! [push]: https://matrix.org/docs/spec/client_server/r0.6.1#id89

use serde::{Deserialize, Serialize};

mod action;
mod any_push_rule;
mod condition;

pub use self::{
    action::{Action, Tweak},
    any_push_rule::{AnyPushRule, MissingConditionsError, MissingPatternError},
    condition::{ComparisonOperator, PushCondition, RoomMemberCountIs},
};

/// A push ruleset scopes a set of rules according to some criteria.
///
/// For example, some rules may only be applied for messages from a particular sender, a particular
/// room, or by default. The push ruleset contains the entire set of scopes and rules.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Ruleset {
    /// These rules configure behavior for (unencrypted) messages that match certain patterns.
    pub content: Vec<PatternedPushRule>,

    /// These user-configured rules are given the highest priority.
    ///
    /// This field is named `override_` instead of `override` because the latter is a reserved
    /// keyword in Rust.
    #[serde(rename = "override")]
    pub override_: Vec<ConditionalPushRule>,

    /// These rules change the behavior of all messages for a given room.
    pub room: Vec<PushRule>,

    /// These rules configure notification behavior for messages from a specific Matrix user ID.
    pub sender: Vec<PushRule>,

    /// These rules are identical to override rules, but have a lower priority than `content`,
    /// `room` and `sender` rules.
    pub underride: Vec<ConditionalPushRule>,
}

impl Ruleset {
    /// Creates an empty `Ruleset`.
    pub fn new() -> Self {
        Default::default()
    }
}

/// A push rule is a single rule that states under what conditions an event should be passed onto a
/// push gateway and how the notification should be presented.
///
/// These rules are stored on the user's homeserver. They are manually configured by the user, who
/// can create and view them via the Client/Server API.
///
/// To create an instance of this type, first create a `PushRuleInit` and convert it via
/// `PushRule::from` / `.into()`.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct PushRule {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,
}

/// Initial set of fields of `PushRule`.
///
/// This struct will not be updated even if additional fields are added to `PushRule` in a new
/// (non-breaking) release of the Matrix specification.
#[derive(Debug)]
pub struct PushRuleInit {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,
}

impl From<PushRuleInit> for PushRule {
    fn from(init: PushRuleInit) -> Self {
        let PushRuleInit { actions, default, enabled, rule_id } = init;
        Self { actions, default, enabled, rule_id }
    }
}

/// Like `PushRule`, but with an additional `conditions` field.
///
/// Only applicable to underride and override rules.
///
/// To create an instance of this type, first create a `ConditionalPushRuleInit` and convert it via
/// `ConditionalPushRule::from` / `.into()`.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct ConditionalPushRule {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,

    /// The conditions that must hold true for an event in order for a rule to be applied to an
    /// event.
    ///
    /// A rule with no conditions always matches.
    pub conditions: Vec<PushCondition>,
}

/// Initial set of fields of `ConditionalPushRule`.
///
/// This struct will not be updated even if additional fields are added to `ConditionalPushRule` in
/// a new (non-breaking) release of the Matrix specification.
#[derive(Debug)]
pub struct ConditionalPushRuleInit {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,

    /// The conditions that must hold true for an event in order for a rule to be applied to an
    /// event.
    ///
    /// A rule with no conditions always matches.
    pub conditions: Vec<PushCondition>,
}

impl From<ConditionalPushRuleInit> for ConditionalPushRule {
    fn from(init: ConditionalPushRuleInit) -> Self {
        let ConditionalPushRuleInit { actions, default, enabled, rule_id, conditions } = init;
        Self { actions, default, enabled, rule_id, conditions }
    }
}

/// Like `PushRule`, but with an additional `pattern` field.
///
/// Only applicable to content rules.
///
/// To create an instance of this type, first create a `PatternedPushRuleInit` and convert it via
/// `PatternedPushRule::from` / `.into()`.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct PatternedPushRule {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,

    /// The glob-style pattern to match against.
    pub pattern: String,
}

/// Initial set of fields of `PatterenedPushRule`.
///
/// This struct will not be updated even if additional fields are added to `PatterenedPushRule` in a
/// new (non-breaking) release of the Matrix specification.
#[derive(Debug)]
pub struct PatternedPushRuleInit {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,

    /// The glob-style pattern to match against.
    pub pattern: String,
}

impl From<PatternedPushRuleInit> for PatternedPushRule {
    fn from(init: PatternedPushRuleInit) -> Self {
        let PatternedPushRuleInit { actions, default, enabled, rule_id, pattern } = init;
        Self { actions, default, enabled, rule_id, pattern }
    }
}

/// Information for the pusher implementation itself.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PusherData {
    /// Required if the pusher's kind is http. The URL to use to send notifications to.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub url: Option<String>,

    /// The format to use when sending notifications to the Push Gateway.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub format: Option<PushFormat>,
}

/// A special format that the homeserver should use when sending notifications to a Push Gateway.
/// Currently, only "event_id_only" is supported as of [Push Gateway API r0.1.1][spec].
///
/// [spec]: https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PushFormat {
    /// Require the homeserver to only send a reduced set of fields in the push.
    EventIdOnly,
}
<commit_msg>common: Make recently-moved types non-exhaustive<commit_after>//! Common types for the [push notifications module][push]
//!
//! [push]: https://matrix.org/docs/spec/client_server/r0.6.1#id89

use serde::{Deserialize, Serialize};

mod action;
mod any_push_rule;
mod condition;

pub use self::{
    action::{Action, Tweak},
    any_push_rule::{AnyPushRule, MissingConditionsError, MissingPatternError},
    condition::{ComparisonOperator, PushCondition, RoomMemberCountIs},
};

/// A push ruleset scopes a set of rules according to some criteria.
///
/// For example, some rules may only be applied for messages from a particular sender, a particular
/// room, or by default. The push ruleset contains the entire set of scopes and rules.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Ruleset {
    /// These rules configure behavior for (unencrypted) messages that match certain patterns.
    pub content: Vec<PatternedPushRule>,

    /// These user-configured rules are given the highest priority.
    ///
    /// This field is named `override_` instead of `override` because the latter is a reserved
    /// keyword in Rust.
    #[serde(rename = "override")]
    pub override_: Vec<ConditionalPushRule>,

    /// These rules change the behavior of all messages for a given room.
    pub room: Vec<PushRule>,

    /// These rules configure notification behavior for messages from a specific Matrix user ID.
    pub sender: Vec<PushRule>,

    /// These rules are identical to override rules, but have a lower priority than `content`,
    /// `room` and `sender` rules.
    pub underride: Vec<ConditionalPushRule>,
}

impl Ruleset {
    /// Creates an empty `Ruleset`.
    pub fn new() -> Self {
        Default::default()
    }
}

/// A push rule is a single rule that states under what conditions an event should be passed onto a
/// push gateway and how the notification should be presented.
///
/// These rules are stored on the user's homeserver. They are manually configured by the user, who
/// can create and view them via the Client/Server API.
///
/// To create an instance of this type, first create a `PushRuleInit` and convert it via
/// `PushRule::from` / `.into()`.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct PushRule {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,
}

/// Initial set of fields of `PushRule`.
///
/// This struct will not be updated even if additional fields are added to `PushRule` in a new
/// (non-breaking) release of the Matrix specification.
#[derive(Debug)]
pub struct PushRuleInit {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,
}

impl From<PushRuleInit> for PushRule {
    fn from(init: PushRuleInit) -> Self {
        let PushRuleInit { actions, default, enabled, rule_id } = init;
        Self { actions, default, enabled, rule_id }
    }
}

/// Like `PushRule`, but with an additional `conditions` field.
///
/// Only applicable to underride and override rules.
///
/// To create an instance of this type, first create a `ConditionalPushRuleInit` and convert it via
/// `ConditionalPushRule::from` / `.into()`.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct ConditionalPushRule {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,

    /// The conditions that must hold true for an event in order for a rule to be applied to an
    /// event.
    ///
    /// A rule with no conditions always matches.
    pub conditions: Vec<PushCondition>,
}

/// Initial set of fields of `ConditionalPushRule`.
///
/// This struct will not be updated even if additional fields are added to `ConditionalPushRule` in
/// a new (non-breaking) release of the Matrix specification.
#[derive(Debug)]
pub struct ConditionalPushRuleInit {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,

    /// The conditions that must hold true for an event in order for a rule to be applied to an
    /// event.
    ///
    /// A rule with no conditions always matches.
    pub conditions: Vec<PushCondition>,
}

impl From<ConditionalPushRuleInit> for ConditionalPushRule {
    fn from(init: ConditionalPushRuleInit) -> Self {
        let ConditionalPushRuleInit { actions, default, enabled, rule_id, conditions } = init;
        Self { actions, default, enabled, rule_id, conditions }
    }
}

/// Like `PushRule`, but with an additional `pattern` field.
///
/// Only applicable to content rules.
///
/// To create an instance of this type, first create a `PatternedPushRuleInit` and convert it via
/// `PatternedPushRule::from` / `.into()`.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct PatternedPushRule {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,

    /// The glob-style pattern to match against.
    pub pattern: String,
}

/// Initial set of fields of `PatterenedPushRule`.
///
/// This struct will not be updated even if additional fields are added to `PatterenedPushRule` in a
/// new (non-breaking) release of the Matrix specification.
#[derive(Debug)]
pub struct PatternedPushRuleInit {
    /// Actions to determine if and how a notification is delivered for events matching this rule.
    pub actions: Vec<Action>,

    /// Whether this is a default rule, or has been set explicitly.
    pub default: bool,

    /// Whether the push rule is enabled or not.
    pub enabled: bool,

    /// The ID of this rule.
    pub rule_id: String,

    /// The glob-style pattern to match against.
    pub pattern: String,
}

impl From<PatternedPushRuleInit> for PatternedPushRule {
    fn from(init: PatternedPushRuleInit) -> Self {
        let PatternedPushRuleInit { actions, default, enabled, rule_id, pattern } = init;
        Self { actions, default, enabled, rule_id, pattern }
    }
}

/// Information for the pusher implementation itself.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct PusherData {
    /// Required if the pusher's kind is http. The URL to use to send notifications to.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub url: Option<String>,

    /// The format to use when sending notifications to the Push Gateway.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub format: Option<PushFormat>,
}

impl PusherData {
    /// Creates an empty `PusherData`.
    pub fn new() -> Self {
        Default::default()
    }
}

/// A special format that the homeserver should use when sending notifications to a Push Gateway.
/// Currently, only "event_id_only" is supported as of [Push Gateway API r0.1.1][spec].
///
/// [spec]: https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[serde(rename_all = "snake_case")]
pub enum PushFormat {
    /// Require the homeserver to only send a reduced set of fields in the push.
    EventIdOnly,
}
<|endoftext|>


<commit_before>extern crate cmake;
extern crate bindgen;

use std::env;
use std::path::PathBuf;
use cmake::Config;

fn main() {
    let target = env::var("TARGET").unwrap();
    let is_debug = env::var("DEBUG").unwrap() == "true";
    let bindings = bindgen::Builder::default()
        .clang_arg("-Ivendor/enet/include/")
        .header("wrapper.h")
        .derive_debug(false)
        .generate()
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");

    let dst = Config::new("vendor/enet")
                .build_target("enet")
                .build();

    eprintln!("LUL: {}", dst.display());

    if target.contains("windows") {
        if is_debug {
            println!("cargo:rustc-link-search=native={}/build/Debug", dst.display());
        } else {
            println!("cargo:rustc-link-search=native={}/build/Release", dst.display());
        }
    } else {
        println!("cargo:rustc-link-search=native={}", dst.display());
    }
    println!("cargo:rustc-link-lib=static=enet");
}
<commit_msg>Link to dylib winmm on Windows<commit_after>extern crate cmake;
extern crate bindgen;

use std::env;
use std::path::PathBuf;
use cmake::Config;

fn main() {
    let target = env::var("TARGET").unwrap();
    let is_debug = env::var("DEBUG").unwrap() == "true";
    let bindings = bindgen::Builder::default()
        .clang_arg("-Ivendor/enet/include/")
        .header("wrapper.h")
        .derive_debug(false)
        .generate()
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");

    let dst = Config::new("vendor/enet")
                .build_target("enet")
                .build();

    eprintln!("LUL: {}", dst.display());

    if target.contains("windows") {
        if is_debug {
            println!("cargo:rustc-link-search=native={}/build/Debug", dst.display());
        } else {
            println!("cargo:rustc-link-search=native={}/build/Release", dst.display());
        }
        println!("cargo:rustc-link-lib=dylib=winmm");
    } else {
        println!("cargo:rustc-link-search=native={}", dst.display());
    }
    println!("cargo:rustc-link-lib=static=enet");
}
<|endoftext|>


<commit_before>use std::env;
use std::path::Path;

use ctl10n;

fn main() {
    println!("cargo:rerun-if-changed=locales/*.toml");
    if let Err(err) = ctl10n::convert_strings_file(
        format!(
            "locales/{}.toml",
            &env::var("LOCALE").unwrap_or("zh".to_string())
        ),
        Path::new(&env::var("OUT_DIR").unwrap()).join("ctl10n_macros.rs"),
    ) {
        panic!("{}", err);
    }
}
<commit_msg>`rerun-if-changed` doesn't support wildcard<commit_after>use std::env;
use std::path::Path;

use ctl10n;

const LOCALES: &[&str] = &["zh", "en"];

fn main() {
    for locale in LOCALES {
        println!("cargo:rerun-if-changed=locales/{}.toml", locale);
    }
    if let Err(err) = ctl10n::convert_strings_file(
        format!(
            "locales/{}.toml",
            &env::var("LOCALE").unwrap_or("zh".to_string())
        ),
        Path::new(&env::var("OUT_DIR").unwrap()).join("ctl10n_macros.rs"),
    ) {
        panic!("{}", err);
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::process::Command;
use std::path::*;

fn main() {
    Command::new("sh")
        .arg("build_lib.sh")
        .output()
        .unwrap_or_else(|e| panic!("failed to execute process: {}", e));
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let path = Path::new(&manifest_dir).join("DOtherSide").join("build").join("lib");

    println!("cargo:rustc-link-search=native={}", path.display());
    println!("cargo:rerun-if-changed={}", path.display());
    println!("cargo:rustc-link-lib=static=DOtherSideStatic");
    println!("cargo:rustc-link-lib=dylib=stdc++");

    let target = env::var("TARGET").expect("Environment variable TARGET not set");

    let osx_framework = if target.contains("darwin") { "=framework" }
                        else  { "" };
    // On Linux, libraries are name "Qt5Core", not "QtCore" as on OSX
    let linux_qt_lib_ver = if target.contains("linux") { "5" }
                           else  { "" };

    println!("cargo:rustc-link-lib{}=Qt{}Core", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Gui", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Qml", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Quick", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Widgets", osx_framework, linux_qt_lib_ver);
}
<commit_msg>Refactored building of a library<commit_after>use std::env;
use std::process::Command;
use std::path::*;

fn main() {
    Command::new("sh")
        .arg("build_lib.sh")
        .output()
        .unwrap_or_else(|e| panic!("failed to execute process: {}", e));
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let path = Path::new(&manifest_dir).join("DOtherSide").join("build").join("lib");

    println!("cargo:rustc-link-search=native={}", path.display());
    println!("cargo:rerun-if-changed={}", path.display());
    println!("cargo:rustc-link-lib=static=DOtherSideStatic");
    println!("cargo:rustc-link-lib=dylib=stdc++");

    let target = env::var("TARGET").expect("Environment variable TARGET not set");

    let osx_framework = if target.contains("darwin") { "=framework" }
                        else  { "" };
    // On Linux, libraries are named "Qt5Core", not "QtCore" as on OSX
    let linux_qt_lib_ver = if target.contains("linux") { "5" }
                           else  { "" };

    const QT_PLUGINS: [&'static str; 5] = ["Core", "Gui", "Qml", "Quick", "Widgets"];
    for plugin in &QT_PLUGINS {
        println!("cargo:rustc-link-lib{}=Qt{}{}", osx_framework, linux_qt_lib_ver, plugin);
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn main() {
    let feature_prefix = "CARGO_FEATURE_";
    let out_dir = env::var("OUT_DIR").unwrap();

    let mut crates = Vec::new();
    for (key, val) in env::vars() {
        if val == "1" && key.starts_with(feature_prefix) {
            let krate = key[feature_prefix.len()..].to_lowercase();
            match krate.as_ref() {
            "default" => continue,
            "all" => continue,
            _ => {},
            }
            crates.push(krate.to_string());
        }
    }
    crates.sort();
    let mut cf = File::create(Path::new(&out_dir).join("uutils_crates.rs")).unwrap();
    let mut mf = File::create(Path::new(&out_dir).join("uutils_map.rs")).unwrap();
    mf.write_all("
    type UtilityMap = HashMap<&'static str, fn(Vec<String>) -> i32>;

    fn util_map() -> UtilityMap {
    let mut map: UtilityMap = HashMap::new();\n".as_bytes()).unwrap();
    for krate in crates {
        match krate.as_ref() {
            "false" | "true" | "test" => {},
            _ => cf.write_all(format!("extern crate {krate} as uu{krate};\n", krate=krate).as_bytes()).unwrap(),
        }

        match krate.as_ref() {
            "hashsum" => {
                mf.write_all("map.insert(\"hashsum\", uuhashsum::uumain);
                              map.insert(\"md5sum\", uuhashsum::uumain);
                              map.insert(\"sha1sum\", uuhashsum::uumain);
                              map.insert(\"sha224sum\", uuhashsum::uumain);
                              map.insert(\"sha256sum\", uuhashsum::uumain);
                              map.insert(\"sha384sum\", uuhashsum::uumain);
                              map.insert(\"sha512sum\", uuhashsum::uumain);\n".as_bytes()).unwrap();
            },
            "false" | "true" | "test" => {
                mf.write_all(format!("fn uu{}", krate).as_bytes()).unwrap();
                mf.write_all("(_: Vec<String>) -> i32 { 1 }\n".as_bytes()).unwrap();
                mf.write_all(format!("map.insert(\"{krate}\", uu{krate} as fn(Vec<String>) -> i32);\n", krate=krate).as_bytes()).unwrap();
            },
            _ =>
                mf.write_all(format!("map.insert(\"{krate}\", uu{krate}::uumain as fn(Vec<String>) -> i32);\n", krate= krate).as_bytes()).unwrap(),
        }
    }
    mf.write_all("map
    }\n".as_bytes()).unwrap();
    cf.flush().unwrap();
    mf.flush().unwrap();
}
<commit_msg>Fix multicall true<commit_after>use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn main() {
    let feature_prefix = "CARGO_FEATURE_";
    let out_dir = env::var("OUT_DIR").unwrap();

    let mut crates = Vec::new();
    for (key, val) in env::vars() {
        if val == "1" && key.starts_with(feature_prefix) {
            let krate = key[feature_prefix.len()..].to_lowercase();
            match krate.as_ref() {
            "default" => continue,
            "all" => continue,
            _ => {},
            }
            crates.push(krate.to_string());
        }
    }
    crates.sort();
    let mut cf = File::create(Path::new(&out_dir).join("uutils_crates.rs")).unwrap();
    let mut mf = File::create(Path::new(&out_dir).join("uutils_map.rs")).unwrap();
    mf.write_all("
    type UtilityMap = HashMap<&'static str, fn(Vec<String>) -> i32>;

    fn util_map() -> UtilityMap {
    let mut map: UtilityMap = HashMap::new();\n".as_bytes()).unwrap();
    for krate in crates {
        match krate.as_ref() {
            "false" | "true" | "test" => {},
            _ => cf.write_all(format!("extern crate {krate} as uu{krate};\n", krate=krate).as_bytes()).unwrap(),
        }

        match krate.as_ref() {
            "hashsum" => {
                mf.write_all("map.insert(\"hashsum\", uuhashsum::uumain);
                              map.insert(\"md5sum\", uuhashsum::uumain);
                              map.insert(\"sha1sum\", uuhashsum::uumain);
                              map.insert(\"sha224sum\", uuhashsum::uumain);
                              map.insert(\"sha256sum\", uuhashsum::uumain);
                              map.insert(\"sha384sum\", uuhashsum::uumain);
                              map.insert(\"sha512sum\", uuhashsum::uumain);\n".as_bytes()).unwrap();
            },
            "true" => {
                mf.write_all(format!("fn uu{}", krate).as_bytes()).unwrap();
                mf.write_all("(_: Vec<String>) -> i32 { 0 }\n".as_bytes()).unwrap();
                mf.write_all(format!("map.insert(\"{krate}\", uu{krate} as fn(Vec<String>) -> i32);\n", krate=krate).as_bytes()).unwrap();
            }
            "false" | "test" => {
                mf.write_all(format!("fn uu{}", krate).as_bytes()).unwrap();
                mf.write_all("(_: Vec<String>) -> i32 { 1 }\n".as_bytes()).unwrap();
                mf.write_all(format!("map.insert(\"{krate}\", uu{krate} as fn(Vec<String>) -> i32);\n", krate=krate).as_bytes()).unwrap();
            },
            _ =>
                mf.write_all(format!("map.insert(\"{krate}\", uu{krate}::uumain as fn(Vec<String>) -> i32);\n", krate= krate).as_bytes()).unwrap(),
        }
    }
    mf.write_all("map
    }\n".as_bytes()).unwrap();
    cf.flush().unwrap();
    mf.flush().unwrap();
}
<|endoftext|>


<commit_before>fn main() {
    if cfg!(target_os = "macos") {
        // if we're on Mac OS X we'll kindly add DYLD_LIBRARY_PATH to rustc's
        // linker search path
        if let Some(dyld_paths) = option_env!("DYLD_LIBRARY_PATH") {
            print_paths(dyld_paths);
        }
        // if we're on Mac OS X we'll kindly add DYLD_FALLBACK_LIBRARY_PATH to rustc's
        // linker search path
        if let Some(dyld_fallback_paths) = option_env!("DYLD_FALLBACK_LIBRARY_PATH") {
            print_paths(dyld_fallback_paths);
        }
    }
}

fn print_paths(paths: &str) {
    for path in paths.split(':').filter(|x| x.is_empty()) {
        println!("cargo:rustc-link-search=native={}", path)
    }
}

<commit_msg>add missing ! in condition to filter empty paths<commit_after>fn main() {
    if cfg!(target_os = "macos") {
        // if we're on Mac OS X we'll kindly add DYLD_LIBRARY_PATH to rustc's
        // linker search path
        if let Some(dyld_paths) = option_env!("DYLD_LIBRARY_PATH") {
            print_paths(dyld_paths);
        }
        // if we're on Mac OS X we'll kindly add DYLD_FALLBACK_LIBRARY_PATH to rustc's
        // linker search path
        if let Some(dyld_fallback_paths) = option_env!("DYLD_FALLBACK_LIBRARY_PATH") {
            print_paths(dyld_fallback_paths);
        }
    }
}

fn print_paths(paths: &str) {
    for path in paths.split(':').filter(|x| !x.is_empty()) {
        println!("cargo:rustc-link-search=native={}", path)
    }
}

<|endoftext|>


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

extern crate cc;

use std::env;
use std::path::PathBuf;

fn main() {
    let mut build = cc::Build::new();
    let outdir = env::var("DEP_MOZJS_OUTDIR").unwrap();
    let include_path: PathBuf = [&outdir, "dist", "include"].iter().collect();

    build.cpp(true)
        .file("src/jsglue.cpp")
        .flag("-DSTATIC_JS_API")
        .include(include_path);
    if env::var("CARGO_FEATURE_DEBUGMOZJS").is_ok() {
        build.define("DEBUG", "");

        if cfg!(target_os = "windows") {
            build.flag("-Od");
        } else {
            build.flag("-g");
            build.flag("-O0");
        }
    }

    if env::var("CARGO_FEATURE_PROFILEMOZJS").is_ok() {
        build.flag_if_supported("-fno-omit-frame-pointer");
    }

    build.flag_if_supported("-Wno-c++0x-extensions");
    build.flag_if_supported("-Wno-return-type-c-linkage");
    build.flag_if_supported("-Wno-invalid-offsetof");
    build.flag_if_supported("-Wno-unused-parameter");

    let confdefs_path: PathBuf = [&outdir, "js", "src", "js-confdefs.h"].iter().collect();
    if cfg!(target_os = "windows") {
        build.flag(&format!("-FI{}", confdefs_path.to_string_lossy()));
        build.define("WIN32", "");
        build.flag("-Zi");
        build.flag("-GR-");
        build.flag("-std:c++17");
    } else {
        build.flag("-fPIC");
        build.flag("-fno-rtti");
        build.flag("-std=c++17");
        build.define("JS_NO_JSVAL_JSID_STRUCT_TYPES", "");
        build.flag("-include");
        build.flag(&confdefs_path.to_string_lossy());
    }

    build.compile("jsglue");
    println!("cargo:rerun-if-changed=src/jsglue.cpp");
}
<commit_msg>Auto merge of #533 - glandium:msvc, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate cc;

use std::env;
use std::path::PathBuf;

fn main() {
    let mut build = cc::Build::new();
    let outdir = env::var("DEP_MOZJS_OUTDIR").unwrap();
    let include_path: PathBuf = [&outdir, "dist", "include"].iter().collect();

    build.cpp(true)
        .file("src/jsglue.cpp")
        .flag("-DSTATIC_JS_API")
        .include(include_path);
    if env::var("CARGO_FEATURE_DEBUGMOZJS").is_ok() {
        build.define("DEBUG", "");

        if cfg!(target_os = "windows") {
            build.flag("-Od");
        } else {
            build.flag("-g");
            build.flag("-O0");
        }
    }

    if env::var("CARGO_FEATURE_PROFILEMOZJS").is_ok() {
        build.flag_if_supported("-fno-omit-frame-pointer");
    }

    build.flag_if_supported("-Wno-c++0x-extensions");
    build.flag_if_supported("-Wno-return-type-c-linkage");
    build.flag_if_supported("-Wno-invalid-offsetof");
    build.flag_if_supported("-Wno-unused-parameter");

    let confdefs_path: PathBuf = [&outdir, "js", "src", "js-confdefs.h"].iter().collect();
    if build.get_compiler().is_like_msvc() {
        build.flag(&format!("-FI{}", confdefs_path.to_string_lossy()));
        build.define("WIN32", "");
        build.flag("-Zi");
        build.flag("-GR-");
        build.flag("-std:c++17");
    } else {
        build.flag("-fPIC");
        build.flag("-fno-rtti");
        build.flag("-std=c++17");
        build.define("JS_NO_JSVAL_JSID_STRUCT_TYPES", "");
        build.flag("-include");
        build.flag(&confdefs_path.to_string_lossy());
    }

    build.compile("jsglue");
    println!("cargo:rerun-if-changed=src/jsglue.cpp");
}
<|endoftext|>


<commit_before>/* build.rs */

extern crate pkg_config;

fn main() {
/*
   If not existing in the standard library search path, create a symbolic link there, named libopensc.so
   (Windows: opensc.lib), targeting the relevant object: With Linux, that's (depending on OpenSC version)
   something like libopensc.so.5 or libopensc.so.6 or ...
 */

/* pkg_config-based-adaption to installed OpenSC release version
   with file /usr/lib/x86_64-linux-gnu/pkgconfig/opensc.pc in place:
   This will print to stdout (for Kubuntu):
   cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu
   cargo:rustc-link-lib=opensc
   cargo:rustc-cfg=v0_19_0   <= or whatever version the installed OpenSC package is

   Whenever the installed OpenSC package changes, be reminded of these actions required:
   1. Check that a file or symbolic link libopensc.so/opensc.lib exists in OS library search path (and points to the correct library)
   2. Adapt Version: in /usr/lib/x86_64-linux-gnu/pkgconfig/opensc.pc
   3. Delete file Cargo.lock and delete directory target (/path/to/opensc-sys/target)
   4. Rebuild the driver by first deleting Cargo.lock and target (/path/to/acos5_64/target); this forces the changed OpenSC package version for opensc-sys
   5. Rebuild (if used) acos5_64_pkcs15init and sm by first deleting Cargo.lock and target
   6. Run cargo build -v -v and check that for both e.g. driver and opensc-sys, the changed OpenSC package version was used
   7. If that failed, remove directory target, deactivate the following match pkg_config... {...} code block and activate the required lines println!("cargo:rustc-...=... manually in all build.rs.
*//*
    match pkg_config::Config::new().atleast_version("0.15.0").probe("opensc") {
        Ok(lib) => {
            match lib.version.as_str() {
                "0.15.0" => println!("cargo:rustc-cfg=v0_15_0"),
                "0.16.0" => println!("cargo:rustc-cfg=v0_16_0"),
                "0.17.0" => println!("cargo:rustc-cfg=v0_17_0"),
                "0.18.0" => println!("cargo:rustc-cfg=v0_18_0"),
                "0.19.0" => println!("cargo:rustc-cfg=v0_19_0"),
                _ => ()
            }
        }
        Err(_e) => panic!("No pkg-config found for opensc library") // "{}", e.description()
    };*/
/* in case of non-availability of pkg-config or failure of above: */
    println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu");
    println!("cargo:rustc-link-lib=opensc");
    println!("cargo:rustc-cfg=v0_15_0");//   <= or whatever version the installed OpenSC package is
/**/

    /* other conditionaĺ compilation settings */
    println!("cargo:rustc-cfg=log"); // enables acos5_64 log output to file debug_file, set in opensc.conf (e.g. debug_file = "/tmp/opensc-debug.log";). Otherwise the driver will be almost quiet referring that
//    println!("cargo:rustc-cfg=impl_default"); // enables impl Default      for some struct s
//    println!("cargo:rustc-cfg=impl_display"); // enables impl fmt::Display for some struct s
//    println!("cargo:rustc-cfg=gui"); // unused currently: enables compile additional functionality, that is required only by acos5_64_gui; see repo carblue/acos5_64_gui
}
<commit_msg>fix cfg(v0_15_0) 2<commit_after>/* build.rs */

extern crate pkg_config;

fn main() {
/*
   If not existing in the standard library search path, create a symbolic link there, named libopensc.so
   (Windows: opensc.lib), targeting the relevant object: With Linux, that's (depending on OpenSC version)
   something like libopensc.so.5 or libopensc.so.6 or ...
 */

/* pkg_config-based-adaption to installed OpenSC release version
   with file /usr/lib/x86_64-linux-gnu/pkgconfig/opensc.pc in place:
   This will print to stdout (for Kubuntu):
   cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu
   cargo:rustc-link-lib=opensc
   cargo:rustc-cfg=v0_19_0   <= or whatever version the installed OpenSC package is

   Whenever the installed OpenSC package changes, be reminded of these actions required:
   1. Check that a file or symbolic link libopensc.so/opensc.lib exists in OS library search path (and points to the correct library)
   2. Adapt Version: in /usr/lib/x86_64-linux-gnu/pkgconfig/opensc.pc
   3. Delete file Cargo.lock and delete directory target (/path/to/opensc-sys/target)
   4. Rebuild the driver by first deleting Cargo.lock and target (/path/to/acos5_64/target); this forces the changed OpenSC package version for opensc-sys
   5. Rebuild (if used) acos5_64_pkcs15init and sm by first deleting Cargo.lock and target
   6. Run cargo build -v -v and check that for both e.g. driver and opensc-sys, the changed OpenSC package version was used
   7. If that failed, remove directory target, deactivate the following match pkg_config... {...} code block and activate the required lines println!("cargo:rustc-...=... manually in all build.rs.
*/
    match pkg_config::Config::new().atleast_version("0.15.0").probe("opensc") {
        Ok(lib) => {
            match lib.version.as_str() {
                "0.15.0" => println!("cargo:rustc-cfg=v0_15_0"),
                "0.16.0" => println!("cargo:rustc-cfg=v0_16_0"),
                "0.17.0" => println!("cargo:rustc-cfg=v0_17_0"),
                "0.18.0" => println!("cargo:rustc-cfg=v0_18_0"),
                "0.19.0" => println!("cargo:rustc-cfg=v0_19_0"),
                _ => ()
            }
        }
        Err(_e) => panic!("No pkg-config found for opensc library") // "{}", e.description()
    };
/* in case of non-availability of pkg-config or failure of above:
    println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu");
    println!("cargo:rustc-link-lib=opensc");
    println!("cargo:rustc-cfg=v0_19_0");   <= or whatever version the installed OpenSC package is
*/

    /* other conditionaĺ compilation settings */
    println!("cargo:rustc-cfg=log"); // enables acos5_64 log output to file debug_file, set in opensc.conf (e.g. debug_file = "/tmp/opensc-debug.log";). Otherwise the driver will be almost quiet referring that
//    println!("cargo:rustc-cfg=impl_default"); // enables impl Default      for some struct s
//    println!("cargo:rustc-cfg=impl_display"); // enables impl fmt::Display for some struct s
//    println!("cargo:rustc-cfg=gui"); // unused currently: enables compile additional functionality, that is required only by acos5_64_gui; see repo carblue/acos5_64_gui
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Added first example to work with futures<commit_after>extern crate futures;
extern crate futures_cpupool;

use std::io;
use futures::Future;
use futures_cpupool::CpuPool;

fn check_prime_boxed(n: u64) -> Box<Future<Item = bool, Error = io::Error>> {
    for i in 2..n {
        if n % i == 0 {
            return Box::new(futures::future::ok(false));
        }
    }
    Box::new(futures::future::ok(true))
}
fn check_prime_impl_trait(n: u64) -> impl Future<Item = bool, Error = io::Error> {
    for i in 2..n {
        if n % i == 0 {
            return futures::future::ok(false);
        }
    }
    futures::future::ok(true)
}

fn check_prime(n: u64) -> bool {
    for i in 2..n {
        if n % i == 0 { return false}
    }
    true
}

fn main() {
    let input: u64 = 58466453;
    println!("Right before first call");
    let res_one = check_prime_boxed(input);

    println!("Called check_prime_boxed");
    let res_two = check_prime_impl_trait(input);

    println!("Called check_prime_impl_trait");
    println!("Results are {} and {}", res_one.wait().unwrap(),
    res_two.wait().unwrap());

    let thread_pool = CpuPool::new(4);
    let res_three = thread_pool.spawn_fn(
            move || {
                let temp = check_prime(input);
                let result: Result<bool, ()> = Ok(temp);
                result
            });
     println!("Called check_prime in another thread");
     println!("Result from the last call: {}", res_three.wait().unwrap());

}
<|endoftext|>


<commit_before>use crate::{foreign::Source, Error};
use std::fs;
use std::io;
use std::os::unix::fs::OpenOptionsExt;
use std::path::Path;
use tar::Archive;

pub fn unpack_tarfile(source: Source, dest_dir: &str) -> Result<(), Error> {
    let dest_dir = Path::new(dest_dir);

    let mut tar = Archive::new(source);

    for file in tar.entries()? {
        let mut file = file?;

        let dest_file = dest_dir.join(file.path()?);

        fs::create_dir_all(dest_file.parent().unwrap())?;

        match file.header().entry_type() {
            tar::EntryType::Directory => {
                fs::create_dir(dest_file)?;
            }
            tar::EntryType::Regular => {
                let mode = if file.header().mode()? & libc::S_IXUSR == 0 {
                    0o666
                } else {
                    0o777
                };
                let mut f = fs::OpenOptions::new()
                    .create(true)
                    .write(true)
                    .mode(mode)
                    .open(dest_file)?;
                io::copy(&mut file, &mut f)?;
            }
            tar::EntryType::Symlink => {
                std::os::unix::fs::symlink(file.header().link_name()?.unwrap(), dest_file)?;
            }
            t => return Err(Error::Misc(format!("unsupported tar entry type '{:?}'", t))),
        }
    }

    Ok(())
}
<commit_msg>Ignore tar header entries<commit_after>use crate::{foreign::Source, Error};
use std::fs;
use std::io;
use std::os::unix::fs::OpenOptionsExt;
use std::path::Path;
use tar::Archive;

pub fn unpack_tarfile(source: Source, dest_dir: &str) -> Result<(), Error> {
    let dest_dir = Path::new(dest_dir);

    let mut tar = Archive::new(source);

    for file in tar.entries()? {
        let mut file = file?;

        let dest_file = dest_dir.join(file.path()?);

        fs::create_dir_all(dest_file.parent().unwrap())?;

        match file.header().entry_type() {
            tar::EntryType::Directory => {
                fs::create_dir(dest_file)?;
            }
            tar::EntryType::Regular => {
                let mode = if file.header().mode()? & libc::S_IXUSR == 0 {
                    0o666
                } else {
                    0o777
                };
                let mut f = fs::OpenOptions::new()
                    .create(true)
                    .write(true)
                    .mode(mode)
                    .open(dest_file)?;
                io::copy(&mut file, &mut f)?;
            }
            tar::EntryType::Symlink => {
                std::os::unix::fs::symlink(file.header().link_name()?.unwrap(), dest_file)?;
            }
            tar::EntryType::XGlobalHeader | tar::EntryType::XHeader => {}
            t => return Err(Error::Misc(format!("unsupported tar entry type '{:?}'", t))),
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>#![ warn( rust_2018_idioms ) ]
#![ warn( missing_debug_implementations ) ]
#![ warn( missing_docs ) ]

// #![ feature( type_name_of_val ) ]
// #![ feature( trace_macros ) ]

/* qqq : for Dima : wrong header */ /* aaa : Dmytro : used valid header in modules */

//!
//! wTools - Collection of general purpose tools for solving problems. Fundamentally extend the language without spoiling, so may be used solely or in conjunction with another module of such kind.
//!

#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/Readme.md" ) ) ]

/* zzz : register error_tools */
/* zzz : alias werror -> error_tools  */
/* zzz : register text_tools as alias for wstring */

/* zzz : implement module::mod_at */
/* zzz : implement and publish mod_expose */

/* zzz : use skeptic? */
/* zzz : rename dt -> adt */

/* zzz : make sure CD run test on both stable and nightly channels */
/* zzz : make sure CD run debug tests and release tests */
/* zzz : introduce tag to run fewer tests */

// /// Iter tools.
// #[ cfg( feature = "iter_tools" ) ]
// pub mod iter;
// #[ cfg( feature = "iter_tools" ) ]
// #[ doc( inline ) ]
// pub use iter::exposed::*;
//
// /// Meta tools.
// #[ cfg( feature = "meta_tools" ) ]
// pub mod meta;
// #[ cfg( feature = "meta_tools" ) ]
// #[ doc( inline ) ]
// pub use meta::*;
//
// /// Type checking tools.
// #[ cfg( feature = "typing_tools" ) ]
// pub mod typing;
// #[ cfg( feature = "typing_tools" ) ]
// #[ doc( inline ) ]
// pub use typing::*;
//
// /// Collection of primal data types
// #[ cfg( any( feature = "dt", feature = "data_type" ) ) ]
// pub mod dt;
//
// ///
// /// Collection of general purpose time tools.
// ///
//
// #[ cfg( feature = "time_tools" ) ]
// pub mod time;

/// Dependencies.
pub mod dependencies
{
  #[ cfg( feature = "former" ) ]
  pub use ::former;
  #[ cfg( feature = "woptions" ) ]
  pub use ::woptions;

  #[ cfg( feature = "meta_tools" ) ]
  pub use ::meta_tools;
  #[ cfg( feature = "impls_index" ) ]
  pub use ::impls_index;
  #[ cfg( feature = "mod_interface" ) ]
  pub use ::mod_interface;

  #[ cfg( feature = "typing_tools" ) ]
  pub use ::typing_tools;
  #[ cfg( feature = "time_tools" ) ]
  pub use ::time_tools;
  #[ cfg( feature = "wstring_tools" ) ]
  pub use ::wstring_tools;
  #[ cfg( feature = "werror" ) ]
  pub use ::werror;
  #[ cfg( feature = "winterval" ) ]
  pub use ::winterval;
  #[ cfg( feature = "derive_tools" ) ]
  pub use ::derive_tools;
  #[ cfg( feature = "diagnostics" ) ]
  pub use ::diagnostics_tools;

  // #[ cfg( debug_assertions ) ]
  // pub use ::wtest_basic;

}

/// Own namespace of the module.
pub mod protected
{
  pub use super::orphan::*;
  // pub use ::mod_interface::orphan::*;

  #[ cfg( feature = "iter_tools" ) ]
  pub use ::iter_tools as iter;
  #[ cfg( feature = "meta_tools" ) ]
  pub use ::meta_tools as meta;
  #[ cfg( feature = "typing_tools" ) ]
  pub use ::typing_tools as typing;
  #[ cfg( feature = "diagnostics" ) ]
  pub use ::diagnostics_tools as diagnostics;
  #[ cfg( any( feature = "dt", feature = "data_type" ) ) ]
  pub use ::data_type as dt;
  #[ cfg( feature = "time_tools" ) ]
  pub use ::time_tools as time;
  #[ cfg( feature = "werror" ) ]
  pub use ::werror as error;
  #[ cfg( feature = "former" ) ]
  pub use ::former as former;
  #[ cfg( feature = "woptions" ) ]
  pub use ::woptions as options;
  #[ cfg( feature = "winterval" ) ]
  pub use ::winterval as interval;
  #[ cfg( feature = "wstring_tools" ) ]
  pub use ::wstring_tools as string;
  #[ cfg( feature = "derive_tools" ) ]
  pub use ::derive_tools as derive;

  // #[ cfg( feature = "iter_tools" ) ]
  // pub use super::iter;
  // #[ cfg( feature = "iter_tools" ) ]
  // pub use iter::exposed::*;
  //
  // #[ cfg( feature = "meta_tools" ) ]
  // pub use super::meta;
  // #[ cfg( feature = "meta_tools" ) ]
  // pub use meta::*;
  //
  // #[ cfg( feature = "typing_tools" ) ]
  // pub use super::typing;
  // #[ cfg( feature = "typing_tools" ) ]
  // pub use typing::*;
  //
  // #[ cfg( any( feature = "dt", feature = "data_type" ) ) ]
  // pub use super::dt;
}

pub use protected::*;

/// Orphan namespace of the module.
pub mod orphan
{
  pub use super::exposed::*;
}

/// Exposed namespace of the module.
pub mod exposed
{
  pub use super::prelude::*;
  pub use super::iter::exposed::*;
  pub use super::meta::exposed::*;
  pub use super::typing::exposed::*;
  #[ cfg( feature = "diagnostics" ) ]
  pub use super::diagnostics::exposed::*;
  pub use super::dt::exposed::*;
  pub use super::time::exposed::*;
  pub use super::time::exposed::*;
  pub use super::error::exposed::*;
  pub use super::former::exposed::*;
  pub use super::options::exposed::*;
  pub use super::interval::exposed::*;
  pub use super::string::exposed::*;
  pub use super::derive::exposed::*;
}

/// Prelude to use essentials: `use my_module::prelude::*`.
pub mod prelude
{
  pub use super::iter::prelude::*;
  #[ cfg( feature = "meta_tools" ) ]
  pub use super::meta::prelude::*;
  pub use super::typing::prelude::*;
  #[ cfg( feature = "diagnostics" ) ]
  pub use super::diagnostics::prelude::*;
  pub use super::dt::prelude::*;
  pub use super::time::prelude::*;
  pub use super::time::prelude::*;
  pub use super::error::prelude::*;
  pub use super::former::prelude::*;
  pub use super::options::prelude::*;
  pub use super::interval::prelude::*;
  pub use super::string::prelude::*;
  pub use super::derive::prelude::*;
}
<commit_msg>cleaning<commit_after>#![ warn( rust_2018_idioms ) ]
#![ warn( missing_debug_implementations ) ]
#![ warn( missing_docs ) ]

// #![ feature( type_name_of_val ) ]
// #![ feature( trace_macros ) ]

/* qqq : for Dima : wrong header */ /* aaa : Dmytro : used valid header in modules */

//!
//! wTools - Collection of general purpose tools for solving problems. Fundamentally extend the language without spoiling, so may be used solely or in conjunction with another module of such kind.
//!

#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/Readme.md" ) ) ]

/* zzz : register error_tools */
/* zzz : alias werror -> error_tools  */
/* zzz : register text_tools as alias for wstring */

/* zzz : implement module::mod_at */
/* zzz : implement and publish mod_expose */

/* zzz : use skeptic? */
/* zzz : rename dt -> adt */

/* zzz : make sure CD run test on both stable and nightly channels */
/* zzz : make sure CD run debug tests and release tests */
/* zzz : introduce tag to run fewer tests */

/// Dependencies.
pub mod dependencies
{
  #[ cfg( feature = "former" ) ]
  pub use ::former;
  #[ cfg( feature = "woptions" ) ]
  pub use ::woptions;
  #[ cfg( feature = "meta_tools" ) ]
  pub use ::meta_tools;
  #[ cfg( feature = "impls_index" ) ]
  pub use ::impls_index;
  #[ cfg( feature = "mod_interface" ) ]
  pub use ::mod_interface;
  #[ cfg( feature = "typing_tools" ) ]
  pub use ::typing_tools;
  #[ cfg( feature = "time_tools" ) ]
  pub use ::time_tools;
  #[ cfg( feature = "wstring_tools" ) ]
  pub use ::wstring_tools;
  #[ cfg( feature = "werror" ) ]
  pub use ::werror;
  #[ cfg( feature = "winterval" ) ]
  pub use ::winterval;
  #[ cfg( feature = "derive_tools" ) ]
  pub use ::derive_tools;
  #[ cfg( feature = "diagnostics" ) ]
  pub use ::diagnostics_tools;

}

/// Own namespace of the module.
pub mod protected
{
  pub use super::orphan::*;

  #[ cfg( feature = "iter_tools" ) ]
  pub use ::iter_tools as iter;
  #[ cfg( feature = "meta_tools" ) ]
  pub use ::meta_tools as meta;
  #[ cfg( feature = "typing_tools" ) ]
  pub use ::typing_tools as typing;
  #[ cfg( feature = "diagnostics" ) ]
  pub use ::diagnostics_tools as diagnostics;
  #[ cfg( any( feature = "dt", feature = "data_type" ) ) ]
  pub use ::data_type as dt;
  #[ cfg( feature = "time_tools" ) ]
  pub use ::time_tools as time;
  #[ cfg( feature = "werror" ) ]
  pub use ::werror as error;
  #[ cfg( feature = "former" ) ]
  pub use ::former as former;
  #[ cfg( feature = "woptions" ) ]
  pub use ::woptions as options;
  #[ cfg( feature = "winterval" ) ]
  pub use ::winterval as interval;
  #[ cfg( feature = "wstring_tools" ) ]
  pub use ::wstring_tools as string;
  #[ cfg( feature = "derive_tools" ) ]
  pub use ::derive_tools as derive;

}

pub use protected::*;

/// Orphan namespace of the module.
pub mod orphan
{
  pub use super::exposed::*;
}

/// Exposed namespace of the module.
pub mod exposed
{
  pub use super::prelude::*;
  pub use super::iter::exposed::*;
  #[ cfg( feature = "meta_tools" ) ]
  pub use super::meta::exposed::*;
  pub use super::typing::exposed::*;
  #[ cfg( feature = "diagnostics" ) ]
  pub use super::diagnostics::exposed::*;
  pub use super::dt::exposed::*;
  pub use super::time::exposed::*;
  pub use super::time::exposed::*;
  pub use super::error::exposed::*;
  pub use super::former::exposed::*;
  pub use super::options::exposed::*;
  pub use super::interval::exposed::*;
  pub use super::string::exposed::*;
  pub use super::derive::exposed::*;
}

/// Prelude to use essentials: `use my_module::prelude::*`.
pub mod prelude
{
  pub use super::iter::prelude::*;
  #[ cfg( feature = "meta_tools" ) ]
  pub use super::meta::prelude::*;
  pub use super::typing::prelude::*;
  #[ cfg( feature = "diagnostics" ) ]
  pub use super::diagnostics::prelude::*;
  pub use super::dt::prelude::*;
  pub use super::time::prelude::*;
  pub use super::time::prelude::*;
  pub use super::error::prelude::*;
  pub use super::former::prelude::*;
  pub use super::options::prelude::*;
  pub use super::interval::prelude::*;
  pub use super::string::prelude::*;
  pub use super::derive::prelude::*;
}
<|endoftext|>


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

//! Different static asserts that ensure the build does what it's expected to.
//!
//! TODO: maybe cfg(test) this?

#![allow(unused_imports)]

use std::mem;

macro_rules! check_enum_value {
    ($a:expr, $b:expr) => {
        unsafe {
            mem::transmute::<[u32; $a as usize],
                             [u32; $b as usize]>([0; $a as usize]);
        }
    }
}

// NB: It's a shame we can't do this statically with bitflags, but no
// const-fn and no other way to access the numerical value :-(
macro_rules! check_enum_value_non_static {
    ($a:expr, $b:expr) => {
        assert_eq!($a as usize, $b as usize);
    }
}

#[test]
fn assert_restyle_hints_match() {
    use style::restyle_hints::*; // For flags
    use gecko_bindings::structs::nsRestyleHint;

    check_enum_value_non_static!(nsRestyleHint::eRestyle_Self, RESTYLE_SELF.bits());
    // XXX This for Servo actually means something like an hypothetical
    // Restyle_AllDescendants (but without running selector matching on the
    // element). ServoRestyleManager interprets it like that, but in practice we
    // should align the behavior with Gecko adding a new restyle hint, maybe?
    //
    // See https://bugzilla.mozilla.org/show_bug.cgi?id=1291786
    check_enum_value_non_static!(nsRestyleHint::eRestyle_SomeDescendants, RESTYLE_DESCENDANTS.bits());
    check_enum_value_non_static!(nsRestyleHint::eRestyle_LaterSiblings, RESTYLE_LATER_SIBLINGS.bits());
}

// Note that we can't call each_pseudo_element, parse_pseudo_element, or
// similar, because we'd need the foreign atom symbols to link.
#[test]
fn assert_basic_pseudo_elements() {
    let mut saw_before = false;
    let mut saw_after = false;

    macro_rules! pseudo_element {
        (":before", $atom:expr, false) => {
            saw_before = true;
        };
        (":after", $atom:expr, false) => {
            saw_after = true;
        };
        ($pseudo_str_with_colon:expr, $atom:expr, $is_anon_box:expr) => {
            // Do nothing
        };
    }

    include!("../../../components/style/generated/gecko_pseudo_element_helper.rs");

    assert!(saw_before);
    assert!(saw_after);
}
<commit_msg>Use correct path for test-stylo (fixes #13563)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Different static asserts that ensure the build does what it's expected to.
//!
//! TODO: maybe cfg(test) this?

#![allow(unused_imports)]

use std::mem;

macro_rules! check_enum_value {
    ($a:expr, $b:expr) => {
        unsafe {
            mem::transmute::<[u32; $a as usize],
                             [u32; $b as usize]>([0; $a as usize]);
        }
    }
}

// NB: It's a shame we can't do this statically with bitflags, but no
// const-fn and no other way to access the numerical value :-(
macro_rules! check_enum_value_non_static {
    ($a:expr, $b:expr) => {
        assert_eq!($a as usize, $b as usize);
    }
}

#[test]
fn assert_restyle_hints_match() {
    use style::restyle_hints::*; // For flags
    use style::gecko_bindings::structs::nsRestyleHint;

    check_enum_value_non_static!(nsRestyleHint::eRestyle_Self, RESTYLE_SELF.bits());
    // XXX This for Servo actually means something like an hypothetical
    // Restyle_AllDescendants (but without running selector matching on the
    // element). ServoRestyleManager interprets it like that, but in practice we
    // should align the behavior with Gecko adding a new restyle hint, maybe?
    //
    // See https://bugzilla.mozilla.org/show_bug.cgi?id=1291786
    check_enum_value_non_static!(nsRestyleHint::eRestyle_SomeDescendants, RESTYLE_DESCENDANTS.bits());
    check_enum_value_non_static!(nsRestyleHint::eRestyle_LaterSiblings, RESTYLE_LATER_SIBLINGS.bits());
}

// Note that we can't call each_pseudo_element, parse_pseudo_element, or
// similar, because we'd need the foreign atom symbols to link.
#[test]
fn assert_basic_pseudo_elements() {
    let mut saw_before = false;
    let mut saw_after = false;

    macro_rules! pseudo_element {
        (":before", $atom:expr, false) => {
            saw_before = true;
        };
        (":after", $atom:expr, false) => {
            saw_after = true;
        };
        ($pseudo_str_with_colon:expr, $atom:expr, $is_anon_box:expr) => {
            // Do nothing
        };
    }

    include!("../../../components/style/gecko/generated/gecko_pseudo_element_helper.rs");

    assert!(saw_before);
    assert!(saw_after);
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(clippy)]

#![allow(unused)]
#![deny(clippy, clippy_pedantic)]

use std::collections::BTreeMap;
use std::collections::HashMap;
use std::ops::Mul;

struct T;

impl T {
    fn add(self, other: T) -> T { self } //~ERROR defining a method called `add`
    fn drop(&mut self) { } //~ERROR defining a method called `drop`

    fn sub(&self, other: T) -> &T { self } // no error, self is a ref
    fn div(self) -> T { self } // no error, different #arguments
    fn rem(self, other: T) { } // no error, wrong return type

    fn into_u32(self) -> u32 { 0 } // fine
    fn into_u16(&self) -> u16 { 0 } //~ERROR methods called `into_*` usually take self by value

    fn to_something(self) -> u32 { 0 } //~ERROR methods called `to_*` usually take self by reference
}

#[derive(Clone,Copy)]
struct U;

impl U {
    fn to_something(self) -> u32 { 0 } // ok because U is Copy
}

impl Mul<T> for T {
    type Output = T;
    fn mul(self, other: T) -> T { self } // no error, obviously
}

/// Utility macro to test linting behavior in `option_methods()`
/// The lints included in `option_methods()` should not lint if the call to map is partially
/// within a macro
macro_rules! opt_map {
    ($opt:expr, $map:expr) => {($opt).map($map)};
}

/// Checks implementation of the following lints:
/// OPTION_MAP_UNWRAP_OR
/// OPTION_MAP_UNWRAP_OR_ELSE
fn option_methods() {
    let opt = Some(1);

    // Check OPTION_MAP_UNWRAP_OR
    // single line case
    let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or(a)`
                               //~| NOTE replace `map(|x| x + 1).unwrap_or(0)`
               .unwrap_or(0); // should lint even though this call is on a separate line
    // multi line cases
    let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or(a)`
                        x + 1
                    }
              ).unwrap_or(0);
    let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or(a)`
               .unwrap_or({
                    0
                });
    // macro case
    let _ = opt_map!(opt, |x| x + 1).unwrap_or(0); // should not lint

    // Check OPTION_MAP_UNWRAP_OR_ELSE
    // single line case
    let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or_else(g)`
                               //~| NOTE replace `map(|x| x + 1).unwrap_or_else(|| 0)`
               .unwrap_or_else(|| 0); // should lint even though this call is on a separate line
    // multi line cases
    let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or_else(g)`
                        x + 1
                    }
              ).unwrap_or_else(|| 0);
    let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or_else(g)`
               .unwrap_or_else(||
                    0
                );
    // macro case
    let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0); // should not lint

}

/// Struct to generate false positive for Iterator-based lints
#[derive(Copy, Clone)]
struct IteratorFalsePositives {
    foo: u32,
}

impl IteratorFalsePositives {
    fn filter(self) -> IteratorFalsePositives {
        self
    }

    fn next(self) -> IteratorFalsePositives {
        self
    }

    fn find(self) -> Option<u32> {
        Some(self.foo)
    }

    fn position(self) -> Option<u32> {
        Some(self.foo)
    }

    fn rposition(self) -> Option<u32> {
        Some(self.foo)
    }
}

/// Checks implementation of FILTER_NEXT lint
fn filter_next() {
    let v = vec![3, 2, 1, 0, -1, -2, -3];

    // check single-line case
    let _ = v.iter().filter(|&x| *x < 0).next();
    //~^ ERROR called `filter(p).next()` on an Iterator.
    //~| NOTE replace `filter(|&x| *x < 0).next()`

    // check multi-line case
    let _ = v.iter().filter(|&x| { //~ERROR called `filter(p).next()` on an Iterator.
                                *x < 0
                            }
                   ).next();

    // check that we don't lint if the caller is not an Iterator
    let foo = IteratorFalsePositives { foo: 0 };
    let _ = foo.filter().next();
}

/// Checks implementation of SEARCH_IS_SOME lint
fn search_is_some() {
    let v = vec![3, 2, 1, 0, -1, -2, -3];

    // check `find().is_some()`, single-line
    let _ = v.iter().find(|&x| *x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `find(|&x| *x < 0).is_some()`

    // check `find().is_some()`, multi-line
    let _ = v.iter().find(|&x| { //~ERROR called `is_some()` after searching
                              *x < 0
                          }
                   ).is_some();

    // check `position().is_some()`, single-line
    let _ = v.iter().position(|&x| x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `position(|&x| x < 0).is_some()`

    // check `position().is_some()`, multi-line
    let _ = v.iter().position(|&x| { //~ERROR called `is_some()` after searching
                                  x < 0
                              }
                   ).is_some();

    // check `rposition().is_some()`, single-line
    let _ = v.iter().rposition(|&x| x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `rposition(|&x| x < 0).is_some()`

    // check `rposition().is_some()`, multi-line
    let _ = v.iter().rposition(|&x| { //~ERROR called `is_some()` after searching
                                   x < 0
                               }
                   ).is_some();

    // check that we don't lint if the caller is not an Iterator
    let foo = IteratorFalsePositives { foo: 0 };
    let _ = foo.find().is_some();
    let _ = foo.position().is_some();
    let _ = foo.rposition().is_some();
}

/// Checks implementation of the OR_FUN_CALL lint
fn or_fun_call() {
    struct Foo;

    impl Foo {
        fn new() -> Foo { Foo }
    }

    fn make<T>() -> T { unimplemented!(); }

    let with_constructor = Some(vec![1]);
    with_constructor.unwrap_or(make());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_constructor.unwrap_or_else(make)

    let with_new = Some(vec![1]);
    with_new.unwrap_or(Vec::new());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_new.unwrap_or_default();

    let with_const_args = Some(vec![1]);
    with_const_args.unwrap_or(Vec::with_capacity(12));
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_const_args.unwrap_or_else(|| Vec::with_capacity(12));

    let with_err : Result<_, ()> = Ok(vec![1]);
    with_err.unwrap_or(make());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_err.unwrap_or_else(|_| make());

    let with_err_args : Result<_, ()> = Ok(vec![1]);
    with_err_args.unwrap_or(Vec::with_capacity(12));
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_err_args.unwrap_or_else(|_| Vec::with_capacity(12));

    let with_default_trait = Some(1);
    with_default_trait.unwrap_or(Default::default());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_default_trait.unwrap_or_default();

    let with_default_type = Some(1);
    with_default_type.unwrap_or(u64::default());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_default_type.unwrap_or_default();

    let with_vec = Some(vec![1]);
    with_vec.unwrap_or(vec![]);
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_vec.unwrap_or_else(|| vec![]);

    let without_default = Some(Foo);
    without_default.unwrap_or(Foo::new());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION without_default.unwrap_or_else(Foo::new);

    let mut map = HashMap::<u64, String>::new();
    map.entry(42).or_insert(String::new());
    //~^ERROR use of `or_insert` followed by a function call
    //~|HELP try this
    //~|SUGGESTION map.entry(42).or_insert_with(String::new);

    let mut btree = BTreeMap::<u64, String>::new();
    btree.entry(42).or_insert(String::new());
    //~^ERROR use of `or_insert` followed by a function call
    //~|HELP try this
    //~|SUGGESTION btree.entry(42).or_insert_with(String::new);
}

fn main() {
    use std::io;

    let opt = Some(0);
    let _ = opt.unwrap();  //~ERROR used unwrap() on an Option

    let res: Result<i32, ()> = Ok(0);
    let _ = res.unwrap();  //~ERROR used unwrap() on a Result

    let _ = "str".to_string();  //~ERROR `"str".to_owned()` is faster

    let v = &"str";
    let string = v.to_string();  //~ERROR `(*v).to_owned()` is faster
    let _again = string.to_string();  //~ERROR `String.to_string()` is a no-op

    res.ok().expect("disaster!"); //~ERROR called `ok().expect()`
    // the following should not warn, since `expect` isn't implemented unless
    // the error type implements `Debug`
    let res2: Result<i32, MyError> = Ok(0);
    res2.ok().expect("oh noes!");
    // we currently don't warn if the error type has a type parameter
    // (but it would be nice if we did)
    let res3: Result<u32, MyErrorWithParam<u8>>= Ok(0);
    res3.ok().expect("whoof");
    let res4: Result<u32, io::Error> = Ok(0);
    res4.ok().expect("argh"); //~ERROR called `ok().expect()`
    let res5: io::Result<u32> = Ok(0);
    res5.ok().expect("oops"); //~ERROR called `ok().expect()`
    let res6: Result<u32, &str> = Ok(0);
    res6.ok().expect("meh"); //~ERROR called `ok().expect()`
}

struct MyError(()); // doesn't implement Debug

#[derive(Debug)]
struct MyErrorWithParam<T> {
    x: T
}

fn starts_with() {
    "".chars().next() == Some(' ');
    //~^ ERROR starts_with
    //~| HELP like this
    //~| SUGGESTION "".starts_with(' ')

    Some(' ') != "".chars().next();
    //~^ ERROR starts_with
    //~| HELP like this
    //~| SUGGESTION !"".starts_with(' ')
}

fn use_extend_from_slice() {
    let mut v : Vec<&'static str> = vec![];
    v.extend(&["Hello", "World"]); //~ERROR use of `extend`
    v.extend(&vec!["Some", "more"]); //~ERROR use of `extend`
    v.extend(vec!["And", "even", "more"].iter()); //~ERROR use of `extend`
    let o : Option<&'static str> = None;
    v.extend(o);
    v.extend(Some("Bye"));
    v.extend(vec!["Not", "like", "this"]);
    v.extend(["Nor", "this"].iter());
}
<commit_msg>fixed and extended tests<commit_after>#![feature(plugin)]
#![plugin(clippy)]

#![allow(unused)]
#![deny(clippy, clippy_pedantic)]

use std::collections::BTreeMap;
use std::collections::HashMap;
use std::ops::Mul;

struct T;

impl T {
    fn add(self, other: T) -> T { self } //~ERROR defining a method called `add`
    fn drop(&mut self) { } //~ERROR defining a method called `drop`

    fn sub(&self, other: T) -> &T { self } // no error, self is a ref
    fn div(self) -> T { self } // no error, different #arguments
    fn rem(self, other: T) { } // no error, wrong return type

    fn into_u32(self) -> u32 { 0 } // fine
    fn into_u16(&self) -> u16 { 0 } //~ERROR methods called `into_*` usually take self by value

    fn to_something(self) -> u32 { 0 } //~ERROR methods called `to_*` usually take self by reference
}

#[derive(Clone,Copy)]
struct U;

impl U {
    fn to_something(self) -> u32 { 0 } // ok because U is Copy
}

impl Mul<T> for T {
    type Output = T;
    fn mul(self, other: T) -> T { self } // no error, obviously
}

/// Utility macro to test linting behavior in `option_methods()`
/// The lints included in `option_methods()` should not lint if the call to map is partially
/// within a macro
macro_rules! opt_map {
    ($opt:expr, $map:expr) => {($opt).map($map)};
}

/// Checks implementation of the following lints:
/// OPTION_MAP_UNWRAP_OR
/// OPTION_MAP_UNWRAP_OR_ELSE
fn option_methods() {
    let opt = Some(1);

    // Check OPTION_MAP_UNWRAP_OR
    // single line case
    let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or(a)`
                               //~| NOTE replace `map(|x| x + 1).unwrap_or(0)`
               .unwrap_or(0); // should lint even though this call is on a separate line
    // multi line cases
    let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or(a)`
                        x + 1
                    }
              ).unwrap_or(0);
    let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or(a)`
               .unwrap_or({
                    0
                });
    // macro case
    let _ = opt_map!(opt, |x| x + 1).unwrap_or(0); // should not lint

    // Check OPTION_MAP_UNWRAP_OR_ELSE
    // single line case
    let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or_else(g)`
                               //~| NOTE replace `map(|x| x + 1).unwrap_or_else(|| 0)`
               .unwrap_or_else(|| 0); // should lint even though this call is on a separate line
    // multi line cases
    let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or_else(g)`
                        x + 1
                    }
              ).unwrap_or_else(|| 0);
    let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or_else(g)`
               .unwrap_or_else(||
                    0
                );
    // macro case
    let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0); // should not lint

}

/// Struct to generate false positive for Iterator-based lints
#[derive(Copy, Clone)]
struct IteratorFalsePositives {
    foo: u32,
}

impl IteratorFalsePositives {
    fn filter(self) -> IteratorFalsePositives {
        self
    }

    fn next(self) -> IteratorFalsePositives {
        self
    }

    fn find(self) -> Option<u32> {
        Some(self.foo)
    }

    fn position(self) -> Option<u32> {
        Some(self.foo)
    }

    fn rposition(self) -> Option<u32> {
        Some(self.foo)
    }
}

/// Checks implementation of FILTER_NEXT lint
fn filter_next() {
    let v = vec![3, 2, 1, 0, -1, -2, -3];

    // check single-line case
    let _ = v.iter().filter(|&x| *x < 0).next();
    //~^ ERROR called `filter(p).next()` on an Iterator.
    //~| NOTE replace `filter(|&x| *x < 0).next()`

    // check multi-line case
    let _ = v.iter().filter(|&x| { //~ERROR called `filter(p).next()` on an Iterator.
                                *x < 0
                            }
                   ).next();

    // check that we don't lint if the caller is not an Iterator
    let foo = IteratorFalsePositives { foo: 0 };
    let _ = foo.filter().next();
}

/// Checks implementation of SEARCH_IS_SOME lint
fn search_is_some() {
    let v = vec![3, 2, 1, 0, -1, -2, -3];

    // check `find().is_some()`, single-line
    let _ = v.iter().find(|&x| *x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `find(|&x| *x < 0).is_some()`

    // check `find().is_some()`, multi-line
    let _ = v.iter().find(|&x| { //~ERROR called `is_some()` after searching
                              *x < 0
                          }
                   ).is_some();

    // check `position().is_some()`, single-line
    let _ = v.iter().position(|&x| x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `position(|&x| x < 0).is_some()`

    // check `position().is_some()`, multi-line
    let _ = v.iter().position(|&x| { //~ERROR called `is_some()` after searching
                                  x < 0
                              }
                   ).is_some();

    // check `rposition().is_some()`, single-line
    let _ = v.iter().rposition(|&x| x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `rposition(|&x| x < 0).is_some()`

    // check `rposition().is_some()`, multi-line
    let _ = v.iter().rposition(|&x| { //~ERROR called `is_some()` after searching
                                   x < 0
                               }
                   ).is_some();

    // check that we don't lint if the caller is not an Iterator
    let foo = IteratorFalsePositives { foo: 0 };
    let _ = foo.find().is_some();
    let _ = foo.position().is_some();
    let _ = foo.rposition().is_some();
}

/// Checks implementation of the OR_FUN_CALL lint
fn or_fun_call() {
    struct Foo;

    impl Foo {
        fn new() -> Foo { Foo }
    }

    fn make<T>() -> T { unimplemented!(); }

    let with_constructor = Some(vec![1]);
    with_constructor.unwrap_or(make());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_constructor.unwrap_or_else(make)

    let with_new = Some(vec![1]);
    with_new.unwrap_or(Vec::new());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_new.unwrap_or_default();

    let with_const_args = Some(vec![1]);
    with_const_args.unwrap_or(Vec::with_capacity(12));
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_const_args.unwrap_or_else(|| Vec::with_capacity(12));

    let with_err : Result<_, ()> = Ok(vec![1]);
    with_err.unwrap_or(make());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_err.unwrap_or_else(|_| make());

    let with_err_args : Result<_, ()> = Ok(vec![1]);
    with_err_args.unwrap_or(Vec::with_capacity(12));
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_err_args.unwrap_or_else(|_| Vec::with_capacity(12));

    let with_default_trait = Some(1);
    with_default_trait.unwrap_or(Default::default());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_default_trait.unwrap_or_default();

    let with_default_type = Some(1);
    with_default_type.unwrap_or(u64::default());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_default_type.unwrap_or_default();

    let with_vec = Some(vec![1]);
    with_vec.unwrap_or(vec![]);
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_vec.unwrap_or_else(|| vec![]);

    let without_default = Some(Foo);
    without_default.unwrap_or(Foo::new());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION without_default.unwrap_or_else(Foo::new);

    let mut map = HashMap::<u64, String>::new();
    map.entry(42).or_insert(String::new());
    //~^ERROR use of `or_insert` followed by a function call
    //~|HELP try this
    //~|SUGGESTION map.entry(42).or_insert_with(String::new);

    let mut btree = BTreeMap::<u64, String>::new();
    btree.entry(42).or_insert(String::new());
    //~^ERROR use of `or_insert` followed by a function call
    //~|HELP try this
    //~|SUGGESTION btree.entry(42).or_insert_with(String::new);
}

fn main() {
    use std::io;

    let opt = Some(0);
    let _ = opt.unwrap();  //~ERROR used unwrap() on an Option

    let res: Result<i32, ()> = Ok(0);
    let _ = res.unwrap();  //~ERROR used unwrap() on a Result

    let _ = "str".to_string();  //~ERROR `"str".to_owned()` is faster

    let v = &"str";
    let string = v.to_string();  //~ERROR `(*v).to_owned()` is faster
    let _again = string.to_string();  //~ERROR `String.to_string()` is a no-op

    res.ok().expect("disaster!"); //~ERROR called `ok().expect()`
    // the following should not warn, since `expect` isn't implemented unless
    // the error type implements `Debug`
    let res2: Result<i32, MyError> = Ok(0);
    res2.ok().expect("oh noes!");
    // we currently don't warn if the error type has a type parameter
    // (but it would be nice if we did)
    let res3: Result<u32, MyErrorWithParam<u8>>= Ok(0);
    res3.ok().expect("whoof");
    let res4: Result<u32, io::Error> = Ok(0);
    res4.ok().expect("argh"); //~ERROR called `ok().expect()`
    let res5: io::Result<u32> = Ok(0);
    res5.ok().expect("oops"); //~ERROR called `ok().expect()`
    let res6: Result<u32, &str> = Ok(0);
    res6.ok().expect("meh"); //~ERROR called `ok().expect()`
}

struct MyError(()); // doesn't implement Debug

#[derive(Debug)]
struct MyErrorWithParam<T> {
    x: T
}

fn starts_with() {
    "".chars().next() == Some(' ');
    //~^ ERROR starts_with
    //~| HELP like this
    //~| SUGGESTION "".starts_with(' ')

    Some(' ') != "".chars().next();
    //~^ ERROR starts_with
    //~| HELP like this
    //~| SUGGESTION !"".starts_with(' ')
}

fn use_extend_from_slice() {
    let mut v : Vec<&'static str> = vec![];
    v.extend(&["Hello", "World"]); //~ERROR use of `extend`
    v.extend(&vec!["Some", "more"]);
    //~^ERROR use of `extend`
    //~| HELP try this
    //~| SUGGESTION v.extend_from_slice(&vec!["Some", "more"]);

    v.extend(vec!["And", "even", "more"].iter()); //~ERROR use of `extend`
    let o : Option<&'static str> = None;
    v.extend(o);
    v.extend(Some("Bye"));
    v.extend(vec!["Not", "like", "this"]);
    v.extend(["But", "this"].iter());
    //~^ERROR use of `extend
    //~| HELP try this
    //~| SUGGESTION v.extend_from_slice(&["But", "this"]);
}
<|endoftext|>