<commit_before>use std::collections::{HashMap, LinkedList};

use parser::{parse, Node};
use errors::{Result};

/// This is the parsed equivalent of a template file
/// Not mean to be used directly unless you want a one-off template rendering
#[derive(Debug, Clone)]
pub struct Template {
    /// filename
    pub name: String,
    /// Parsed ast
    pub ast: Node,
    /// macros defined in that file
    pub macros: HashMap<String, Node>,
    /// (filename, namespace) for the macros imported in that file
    pub imported_macro_files: Vec<(String, String)>,
    /// Only used during initial parsing. Rendering will use `self.parents`
    pub parent: Option<String>,
    /// only used during initial parsing. Rendering will use `self.blocks_definitions`
    pub blocks: HashMap<String, Node>,

    /// Filled when all templates have been parsed: contains the full list of parent templates
    /// as opposed to Tera::Template which only contains the optional parent
    pub parents: Vec<String>,
    /// Filled when all templates have been parsed: contains the definition of all the blocks for
    /// the current template and the definition of parent templates if there is. Needed for super()
    /// to work without having to find them each time.
    /// The value is a Vec of all the definitions in order, with the tpl name from where it comes from
    /// Order is from highest in hierarchy to current template
    /// The tpl name is needed in order to load its macros
    pub blocks_definitions: HashMap<String, Vec<(String, Node)>>,
}

impl Template {
    /// Parse the template string given
    pub fn new(tpl_name: &str, input: &str) -> Result<Template> {
        let ast = parse(input)?;

        let mut blocks = HashMap::new();
        // We find all those blocks at first so we don't need to do it for each render
        // Recursive because we can have blocks inside blocks
        fn find_blocks(tpl_name: &str, ast: LinkedList<Node>, blocks: &mut HashMap<String, Node>) -> Result<()> {
            for node in ast {
                match node {
                    Node::Block { ref name, ref body } => {
                        if blocks.contains_key(name) {
                            bail!("Block `{}` is duplicated", name);
                        }
                        blocks.insert(name.to_string(), node.clone());
                        find_blocks(tpl_name, body.get_children(), blocks)?;
                    },
                    _ => continue,
                };
            }

            Ok(())
        }
        find_blocks(tpl_name, ast.get_children(), &mut blocks)?;

        // We also find all macros defined/imported in the template file
        let mut macros = HashMap::new();
        let mut imported_macro_files = vec![];
        let mut parent = None;
        for node in ast.get_children() {
            match node {
                Node::Extends(ref name) => {
                    parent = Some(name.to_string());
                },
                Node::Macro { ref name, .. } => {
                    if macros.contains_key(name) {
                        bail!("Macro `{}` is duplicated", name);
                    }
                    macros.insert(name.to_string(), node.clone());
                },
                Node::ImportMacro { tpl_name, name } => {
                    imported_macro_files.push((tpl_name.to_string(), name.to_string()));
                }
                _ => continue,
            };
        }

        Ok(Template {
            name: tpl_name.to_string(),
            ast: ast,
            parent: parent,
            blocks: blocks,
            macros: macros,
            imported_macro_files: imported_macro_files,

            parents: vec![],
            blocks_definitions: HashMap::new(),
        })
    }
}

#[cfg(test)]
mod tests {
    use super::Template;

    #[test]
    fn test_can_parse_ok_template() {
        Template::new("hello", "Hello {{ world }}.").unwrap();
    }

    #[test]
    fn test_can_find_parent_template() {
        let tpl = Template::new("hello", "{% extends \"base.html\" %}").unwrap();

        assert_eq!(tpl.parent.unwrap(), "base.html".to_string());
    }

    #[test]
    fn test_can_find_blocks() {
        let tpl = Template::new(
            "hello",
            "{% extends \"base.html\" %}{% block hey %}{% endblock hey %}"
        ).unwrap();

        assert_eq!(tpl.parent.unwrap(), "base.html".to_string());
        assert_eq!(tpl.blocks.contains_key("hey"), true);
    }

    #[test]
    fn test_can_find_nested_blocks() {
        let tpl = Template::new(
            "hello",
            "{% extends \"base.html\" %}{% block hey %}{% block extrahey %}{% endblock extrahey %}{% endblock hey %}"
        ).unwrap();

        assert_eq!(tpl.parent.unwrap(), "base.html".to_string());
        assert_eq!(tpl.blocks.contains_key("hey"), true);
        assert_eq!(tpl.blocks.contains_key("extrahey"), true);
    }

    #[test]
    fn test_can_find_macros() {
        let tpl = Template::new("hello", "{% macro hey() %}{% endmacro hey %}").unwrap();
        assert_eq!(tpl.macros.contains_key("hey"), true);
    }

    #[test]
    fn test_can_find_imported_macros() {
        let tpl = Template::new("hello", "{% import \"macros.html\" as macros %}").unwrap();
        assert_eq!(tpl.imported_macro_files, vec![("macros.html".to_string(), "macros".to_string())]);
    }
}
<commit_msg>Remove unused tpl_name in template<commit_after>use std::collections::{HashMap, LinkedList};

use parser::{parse, Node};
use errors::{Result};

/// This is the parsed equivalent of a template file
/// Not mean to be used directly unless you want a one-off template rendering
#[derive(Debug, Clone)]
pub struct Template {
    /// filename
    pub name: String,
    /// Parsed ast
    pub ast: Node,
    /// macros defined in that file
    pub macros: HashMap<String, Node>,
    /// (filename, namespace) for the macros imported in that file
    pub imported_macro_files: Vec<(String, String)>,
    /// Only used during initial parsing. Rendering will use `self.parents`
    pub parent: Option<String>,
    /// only used during initial parsing. Rendering will use `self.blocks_definitions`
    pub blocks: HashMap<String, Node>,

    /// Filled when all templates have been parsed: contains the full list of parent templates
    /// as opposed to Tera::Template which only contains the optional parent
    pub parents: Vec<String>,
    /// Filled when all templates have been parsed: contains the definition of all the blocks for
    /// the current template and the definition of parent templates if there is. Needed for super()
    /// to work without having to find them each time.
    /// The value is a Vec of all the definitions in order, with the tpl name from where it comes from
    /// Order is from highest in hierarchy to current template
    /// The tpl name is needed in order to load its macros
    pub blocks_definitions: HashMap<String, Vec<(String, Node)>>,
}

impl Template {
    /// Parse the template string given
    pub fn new(tpl_name: &str, input: &str) -> Result<Template> {
        let ast = parse(input)?;

        let mut blocks = HashMap::new();
        // We find all those blocks at first so we don't need to do it for each render
        // Recursive because we can have blocks inside blocks
        fn find_blocks(ast: LinkedList<Node>, blocks: &mut HashMap<String, Node>) -> Result<()> {
            for node in ast {
                match node {
                    Node::Block { ref name, ref body } => {
                        if blocks.contains_key(name) {
                            bail!("Block `{}` is duplicated", name);
                        }
                        blocks.insert(name.to_string(), node.clone());
                        find_blocks(body.get_children(), blocks)?;
                    },
                    _ => continue,
                };
            }

            Ok(())
        }
        find_blocks(ast.get_children(), &mut blocks)?;

        // We also find all macros defined/imported in the template file
        let mut macros = HashMap::new();
        let mut imported_macro_files = vec![];
        let mut parent = None;
        for node in ast.get_children() {
            match node {
                Node::Extends(ref name) => {
                    parent = Some(name.to_string());
                },
                Node::Macro { ref name, .. } => {
                    if macros.contains_key(name) {
                        bail!("Macro `{}` is duplicated", name);
                    }
                    macros.insert(name.to_string(), node.clone());
                },
                Node::ImportMacro { tpl_name, name } => {
                    imported_macro_files.push((tpl_name.to_string(), name.to_string()));
                }
                _ => continue,
            };
        }

        Ok(Template {
            name: tpl_name.to_string(),
            ast: ast,
            parent: parent,
            blocks: blocks,
            macros: macros,
            imported_macro_files: imported_macro_files,

            parents: vec![],
            blocks_definitions: HashMap::new(),
        })
    }
}

#[cfg(test)]
mod tests {
    use super::Template;

    #[test]
    fn test_can_parse_ok_template() {
        Template::new("hello", "Hello {{ world }}.").unwrap();
    }

    #[test]
    fn test_can_find_parent_template() {
        let tpl = Template::new("hello", "{% extends \"base.html\" %}").unwrap();

        assert_eq!(tpl.parent.unwrap(), "base.html".to_string());
    }

    #[test]
    fn test_can_find_blocks() {
        let tpl = Template::new(
            "hello",
            "{% extends \"base.html\" %}{% block hey %}{% endblock hey %}"
        ).unwrap();

        assert_eq!(tpl.parent.unwrap(), "base.html".to_string());
        assert_eq!(tpl.blocks.contains_key("hey"), true);
    }

    #[test]
    fn test_can_find_nested_blocks() {
        let tpl = Template::new(
            "hello",
            "{% extends \"base.html\" %}{% block hey %}{% block extrahey %}{% endblock extrahey %}{% endblock hey %}"
        ).unwrap();

        assert_eq!(tpl.parent.unwrap(), "base.html".to_string());
        assert_eq!(tpl.blocks.contains_key("hey"), true);
        assert_eq!(tpl.blocks.contains_key("extrahey"), true);
    }

    #[test]
    fn test_can_find_macros() {
        let tpl = Template::new("hello", "{% macro hey() %}{% endmacro hey %}").unwrap();
        assert_eq!(tpl.macros.contains_key("hey"), true);
    }

    #[test]
    fn test_can_find_imported_macros() {
        let tpl = Template::new("hello", "{% import \"macros.html\" as macros %}").unwrap();
        assert_eq!(tpl.imported_macro_files, vec![("macros.html".to_string(), "macros".to_string())]);
    }
}
<|endoftext|>


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

//! Character conversions.

use convert::TryFrom;
use fmt;
use mem::transmute;
use str::FromStr;
use super::MAX;

/// Converts a `u32` to a `char`.
///
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
/// [`as`]:
///
/// ```
/// let c = '💯';
/// let i = c as u32;
///
/// assert_eq!(128175, i);
/// ```
///
/// However, the reverse is not true: not all valid [`u32`]s are valid
/// [`char`]s. `from_u32()` will return `None` if the input is not a valid value
/// for a [`char`].
///
/// [`char`]: ../../std/primitive.char.html
/// [`u32`]: ../../std/primitive.u32.html
/// [`as`]: ../../book/first-edition/casting-between-types.html#as
///
/// For an unsafe version of this function which ignores these checks, see
/// [`from_u32_unchecked`].
///
/// [`from_u32_unchecked`]: fn.from_u32_unchecked.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = char::from_u32(0x2764);
///
/// assert_eq!(Some('❤'), c);
/// ```
///
/// Returning `None` when the input is not a valid [`char`]:
///
/// ```
/// use std::char;
///
/// let c = char::from_u32(0x110000);
///
/// assert_eq!(None, c);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_u32(i: u32) -> Option<char> {
    char::try_from(i).ok()
}

/// Converts a `u32` to a `char`, ignoring validity.
///
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
/// [`as`]:
///
/// ```
/// let c = '💯';
/// let i = c as u32;
///
/// assert_eq!(128175, i);
/// ```
///
/// However, the reverse is not true: not all valid [`u32`]s are valid
/// [`char`]s. `from_u32_unchecked()` will ignore this, and blindly cast to
/// [`char`], possibly creating an invalid one.
///
/// [`char`]: ../../std/primitive.char.html
/// [`u32`]: ../../std/primitive.u32.html
/// [`as`]: ../../book/first-edition/casting-between-types.html#as
///
/// # Safety
///
/// This function is unsafe, as it may construct invalid `char` values.
///
/// For a safe version of this function, see the [`from_u32`] function.
///
/// [`from_u32`]: fn.from_u32.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = unsafe { char::from_u32_unchecked(0x2764) };
///
/// assert_eq!('❤', c);
/// ```
#[inline]
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
pub unsafe fn from_u32_unchecked(i: u32) -> char {
    transmute(i)
}

#[stable(feature = "char_convert", since = "1.13.0")]
impl From<char> for u32 {
    /// Converts a [`char`] into a [`u32`].
    ///
    /// [`char`]: primitive.char.html
    /// [`u32`]: primitive.u32.html
    #[inline]
    fn from(c: char) -> Self {
        c as u32
    }
}

/// Maps a byte in 0x00...0xFF to a `char` whose code point has the same value, in U+0000 to U+00FF.
///
/// Unicode is designed such that this effectively decodes bytes
/// with the character encoding that IANA calls ISO-8859-1.
/// This encoding is compatible with ASCII.
///
/// Note that this is different from ISO/IEC 8859-1 a.k.a. ISO 8859-1 (with one less hyphen),
/// which leaves some "blanks", byte values that are not assigned to any character.
/// ISO-8859-1 (the IANA one) assigns them to the C0 and C1 control codes.
///
/// Note that this is *also* different from Windows-1252 a.k.a. code page 1252,
/// which is a superset ISO/IEC 8859-1 that assigns some (not all!) blanks
/// to punctuation and various Latin characters.
///
/// To confuse things further, [on the Web](https://encoding.spec.whatwg.org/)
/// `ascii`, `iso-8859-1`, and `windows-1252` are all aliases
/// for a superset of Windows-1252 that fills the remaining blanks with corresponding
/// C0 and C1 control codes.
#[stable(feature = "char_convert", since = "1.13.0")]
impl From<u8> for char {
    /// Converts a [`u8`] into a [`char`].
    ///
    /// [`u8`]: primitive.u8.html
    /// [`char`]: primitive.char.html
    #[inline]
    fn from(i: u8) -> Self {
        i as char
    }
}

/// An error which can be returned when parsing a char.
#[stable(feature = "char_from_str", since = "1.20.0")]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseCharError {
    kind: CharErrorKind,
}

impl ParseCharError {
    #[unstable(feature = "char_error_internals",
               reason = "this method should not be available publicly",
               issue = "0")]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        match self.kind {
            CharErrorKind::EmptyString => {
                "cannot parse char from empty string"
            },
            CharErrorKind::TooManyChars => "too many characters in string"
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum CharErrorKind {
    EmptyString,
    TooManyChars,
}

#[stable(feature = "char_from_str", since = "1.20.0")]
impl fmt::Display for ParseCharError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.__description().fmt(f)
    }
}

#[stable(feature = "char_from_str", since = "1.20.0")]
impl FromStr for char {
    type Err = ParseCharError;

    #[inline]
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut chars = s.chars();
        match (chars.next(), chars.next()) {
            (None, _) => {
                Err(ParseCharError { kind: CharErrorKind::EmptyString })
            },
            (Some(c), None) => Ok(c),
            _ => {
                Err(ParseCharError { kind: CharErrorKind::TooManyChars })
            }
        }
    }
}

#[unstable(feature = "try_from", issue = "33417")]
impl TryFrom<u32> for char {
    type Error = CharTryFromError;

    #[inline]
    fn try_from(i: u32) -> Result<Self, Self::Error> {
        if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
            Err(CharTryFromError(()))
        } else {
            Ok(unsafe { from_u32_unchecked(i) })
        }
    }
}

/// The error type returned when a conversion from u32 to char fails.
#[unstable(feature = "try_from", issue = "33417")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct CharTryFromError(());

#[unstable(feature = "try_from", issue = "33417")]
impl fmt::Display for CharTryFromError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "converted integer out of range for `char`".fmt(f)
    }
}

/// Converts a digit in the given radix to a `char`.
///
/// A 'radix' here is sometimes also called a 'base'. A radix of two
/// indicates a binary number, a radix of ten, decimal, and a radix of
/// sixteen, hexadecimal, to give some common values. Arbitrary
/// radices are supported.
///
/// `from_digit()` will return `None` if the input is not a digit in
/// the given radix.
///
/// # Panics
///
/// Panics if given a radix larger than 36.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = char::from_digit(4, 10);
///
/// assert_eq!(Some('4'), c);
///
/// // Decimal 11 is a single digit in base 16
/// let c = char::from_digit(11, 16);
///
/// assert_eq!(Some('b'), c);
/// ```
///
/// Returning `None` when the input is not a digit:
///
/// ```
/// use std::char;
///
/// let c = char::from_digit(20, 10);
///
/// assert_eq!(None, c);
/// ```
///
/// Passing a large radix, causing a panic:
///
/// ```
/// use std::thread;
/// use std::char;
///
/// let result = thread::spawn(|| {
///     // this panics
///     let c = char::from_digit(1, 37);
/// }).join();
///
/// assert!(result.is_err());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_digit(num: u32, radix: u32) -> Option<char> {
    if radix > 36 {
        panic!("from_digit: radix is too high (maximum 36)");
    }
    if num < radix {
        let num = num as u8;
        if num < 10 {
            Some((b'0' + num) as char)
        } else {
            Some((b'a' + num - 10) as char)
        }
    } else {
        None
    }
}

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

//! Character conversions.

use convert::TryFrom;
use fmt;
use mem::transmute;
use str::FromStr;
use super::MAX;

/// Converts a `u32` to a `char`.
///
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
/// [`as`]:
///
/// ```
/// let c = '💯';
/// let i = c as u32;
///
/// assert_eq!(128175, i);
/// ```
///
/// However, the reverse is not true: not all valid [`u32`]s are valid
/// [`char`]s. `from_u32()` will return `None` if the input is not a valid value
/// for a [`char`].
///
/// [`char`]: ../../std/primitive.char.html
/// [`u32`]: ../../std/primitive.u32.html
/// [`as`]: ../../book/first-edition/casting-between-types.html#as
///
/// For an unsafe version of this function which ignores these checks, see
/// [`from_u32_unchecked`].
///
/// [`from_u32_unchecked`]: fn.from_u32_unchecked.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = char::from_u32(0x2764);
///
/// assert_eq!(Some('❤'), c);
/// ```
///
/// Returning `None` when the input is not a valid [`char`]:
///
/// ```
/// use std::char;
///
/// let c = char::from_u32(0x110000);
///
/// assert_eq!(None, c);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_u32(i: u32) -> Option<char> {
    char::try_from(i).ok()
}

/// Converts a `u32` to a `char`, ignoring validity.
///
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
/// [`as`]:
///
/// ```
/// let c = '💯';
/// let i = c as u32;
///
/// assert_eq!(128175, i);
/// ```
///
/// However, the reverse is not true: not all valid [`u32`]s are valid
/// [`char`]s. `from_u32_unchecked()` will ignore this, and blindly cast to
/// [`char`], possibly creating an invalid one.
///
/// [`char`]: ../../std/primitive.char.html
/// [`u32`]: ../../std/primitive.u32.html
/// [`as`]: ../../book/first-edition/casting-between-types.html#as
///
/// # Safety
///
/// This function is unsafe, as it may construct invalid `char` values.
///
/// For a safe version of this function, see the [`from_u32`] function.
///
/// [`from_u32`]: fn.from_u32.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = unsafe { char::from_u32_unchecked(0x2764) };
///
/// assert_eq!('❤', c);
/// ```
#[inline]
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
pub unsafe fn from_u32_unchecked(i: u32) -> char {
    transmute(i)
}

#[stable(feature = "char_convert", since = "1.13.0")]
impl From<char> for u32 {
    /// Converts a [`char`] into a [`u32`].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::mem;
    ///
    /// fn main() {
    ///     let c = 'c';
    ///     let u = u32::from(c);
    ///     assert!(4 == mem::size_of_val(&u))
    /// }
    /// ```
    #[inline]
    fn from(c: char) -> Self {
        c as u32
    }
}

/// Maps a byte in 0x00...0xFF to a `char` whose code point has the same value, in U+0000 to U+00FF.
///
/// Unicode is designed such that this effectively decodes bytes
/// with the character encoding that IANA calls ISO-8859-1.
/// This encoding is compatible with ASCII.
///
/// Note that this is different from ISO/IEC 8859-1 a.k.a. ISO 8859-1 (with one less hyphen),
/// which leaves some "blanks", byte values that are not assigned to any character.
/// ISO-8859-1 (the IANA one) assigns them to the C0 and C1 control codes.
///
/// Note that this is *also* different from Windows-1252 a.k.a. code page 1252,
/// which is a superset ISO/IEC 8859-1 that assigns some (not all!) blanks
/// to punctuation and various Latin characters.
///
/// To confuse things further, [on the Web](https://encoding.spec.whatwg.org/)
/// `ascii`, `iso-8859-1`, and `windows-1252` are all aliases
/// for a superset of Windows-1252 that fills the remaining blanks with corresponding
/// C0 and C1 control codes.
#[stable(feature = "char_convert", since = "1.13.0")]
impl From<u8> for char {
    /// Converts a [`u8`] into a [`char`].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::mem;
    ///
    /// fn main() {
    ///     let u = 32 as u8;
    ///     let c = char::from(u);
    ///     assert!(4 == mem::size_of_val(&c))
    /// }
    /// ```
    #[inline]
    fn from(i: u8) -> Self {
        i as char
    }
}

/// An error which can be returned when parsing a char.
#[stable(feature = "char_from_str", since = "1.20.0")]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseCharError {
    kind: CharErrorKind,
}

impl ParseCharError {
    #[unstable(feature = "char_error_internals",
               reason = "this method should not be available publicly",
               issue = "0")]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        match self.kind {
            CharErrorKind::EmptyString => {
                "cannot parse char from empty string"
            },
            CharErrorKind::TooManyChars => "too many characters in string"
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum CharErrorKind {
    EmptyString,
    TooManyChars,
}

#[stable(feature = "char_from_str", since = "1.20.0")]
impl fmt::Display for ParseCharError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.__description().fmt(f)
    }
}

#[stable(feature = "char_from_str", since = "1.20.0")]
impl FromStr for char {
    type Err = ParseCharError;

    #[inline]
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut chars = s.chars();
        match (chars.next(), chars.next()) {
            (None, _) => {
                Err(ParseCharError { kind: CharErrorKind::EmptyString })
            },
            (Some(c), None) => Ok(c),
            _ => {
                Err(ParseCharError { kind: CharErrorKind::TooManyChars })
            }
        }
    }
}

#[unstable(feature = "try_from", issue = "33417")]
impl TryFrom<u32> for char {
    type Error = CharTryFromError;

    #[inline]
    fn try_from(i: u32) -> Result<Self, Self::Error> {
        if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
            Err(CharTryFromError(()))
        } else {
            Ok(unsafe { from_u32_unchecked(i) })
        }
    }
}

/// The error type returned when a conversion from u32 to char fails.
#[unstable(feature = "try_from", issue = "33417")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct CharTryFromError(());

#[unstable(feature = "try_from", issue = "33417")]
impl fmt::Display for CharTryFromError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "converted integer out of range for `char`".fmt(f)
    }
}

/// Converts a digit in the given radix to a `char`.
///
/// A 'radix' here is sometimes also called a 'base'. A radix of two
/// indicates a binary number, a radix of ten, decimal, and a radix of
/// sixteen, hexadecimal, to give some common values. Arbitrary
/// radices are supported.
///
/// `from_digit()` will return `None` if the input is not a digit in
/// the given radix.
///
/// # Panics
///
/// Panics if given a radix larger than 36.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = char::from_digit(4, 10);
///
/// assert_eq!(Some('4'), c);
///
/// // Decimal 11 is a single digit in base 16
/// let c = char::from_digit(11, 16);
///
/// assert_eq!(Some('b'), c);
/// ```
///
/// Returning `None` when the input is not a digit:
///
/// ```
/// use std::char;
///
/// let c = char::from_digit(20, 10);
///
/// assert_eq!(None, c);
/// ```
///
/// Passing a large radix, causing a panic:
///
/// ```
/// use std::thread;
/// use std::char;
///
/// let result = thread::spawn(|| {
///     // this panics
///     let c = char::from_digit(1, 37);
/// }).join();
///
/// assert!(result.is_err());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_digit(num: u32, radix: u32) -> Option<char> {
    if radix > 36 {
        panic!("from_digit: radix is too high (maximum 36)");
    }
    if num < radix {
        let num = num as u8;
        if num < 10 {
            Some((b'0' + num) as char)
        } else {
            Some((b'a' + num - 10) as char)
        }
    } else {
        None
    }
}

<|endoftext|>


<commit_before>mod fakes;

use crate::web::Server;
use failure::Error;
use once_cell::unsync::OnceCell;
use postgres::Connection;
use reqwest::{Client, Method, RequestBuilder};
use std::sync::{Arc, Mutex, MutexGuard};

pub(crate) fn wrapper(f: impl FnOnce(&TestEnvironment) -> Result<(), Error>) {
    let env = TestEnvironment::new();
    let result = f(&env);
    env.cleanup();

    if let Err(err) = result {
        eprintln!("the test failed: {}", err);
        for cause in err.iter_causes() {
            eprintln!("  caused by: {}", cause);
        }

        eprintln!("{}", err.backtrace());

        panic!("the test failed");
    }
}

pub(crate) struct TestEnvironment {
    db: OnceCell<TestDatabase>,
    frontend: OnceCell<TestFrontend>,
}

impl TestEnvironment {
    fn new() -> Self {
        Self {
            db: OnceCell::new(),
            frontend: OnceCell::new(),
        }
    }

    fn cleanup(self) {
        if let Some(frontend) = self.frontend.into_inner() {
            frontend.server.leak();
        }
    }

    pub(crate) fn db(&self) -> &TestDatabase {
        self.db
            .get_or_init(|| TestDatabase::new().expect("failed to initialize the db"))
    }

    pub(crate) fn frontend(&self) -> &TestFrontend {
        self.frontend.get_or_init(|| TestFrontend::new(self.db()))
    }
}

pub(crate) struct TestDatabase {
    conn: Arc<Mutex<Connection>>,
}

impl TestDatabase {
    fn new() -> Result<Self, Error> {
        // The temporary migration uses CREATE TEMPORARY TABLE instead of CREATE TABLE, creating
        // fresh temporary copies of the database on top of the real one. The temporary tables are
        // only visible to this connection, and will be deleted when it exits.
        let conn = crate::db::connect_db()?;
        crate::db::migrate_temporary(None, &conn)?;

        Ok(TestDatabase {
            conn: Arc::new(Mutex::new(conn)),
        })
    }

    pub(crate) fn conn(&self) -> MutexGuard<Connection> {
        self.conn.lock().expect("failed to lock the connection")
    }

    pub(crate) fn fake_release(&self) -> fakes::FakeRelease {
        fakes::FakeRelease::new(self)
    }
}

pub(crate) struct TestFrontend {
    server: Server,
    client: Client,
}

impl TestFrontend {
    fn new(db: &TestDatabase) -> Self {
        Self {
            server: Server::start_test(db.conn.clone()),
            client: Client::new(),
        }
    }

    fn build_request(&self, method: Method, url: &str) -> RequestBuilder {
        self.client
            .request(method, &format!("http://{}{}", self.server.addr(), url))
    }

    pub(crate) fn get(&self, url: &str) -> RequestBuilder {
        self.build_request(Method::GET, url)
    }
}
<commit_msg>don't hang forever on test panics<commit_after>mod fakes;

use crate::web::Server;
use failure::Error;
use once_cell::unsync::OnceCell;
use postgres::Connection;
use reqwest::{Client, Method, RequestBuilder};
use std::sync::{Arc, Mutex, MutexGuard};

pub(crate) fn wrapper(f: impl FnOnce(&TestEnvironment) -> Result<(), Error>) {
    use std::panic;
    let env = TestEnvironment::new();
    // if we didn't catch the panic, the server would hang forever
    let maybe_panic = panic::catch_unwind(panic::AssertUnwindSafe(|| f(&env)));
    env.cleanup();
    let result = match maybe_panic {
        Ok(r) => r,
        Err(payload) => panic::resume_unwind(payload),
    };

    if let Err(err) = result {
        eprintln!("the test failed: {}", err);
        for cause in err.iter_causes() {
            eprintln!("  caused by: {}", cause);
        }

        eprintln!("{}", err.backtrace());

        panic!("the test failed");
    }
}

pub(crate) struct TestEnvironment {
    db: OnceCell<TestDatabase>,
    frontend: OnceCell<TestFrontend>,
}

impl TestEnvironment {
    fn new() -> Self {
        Self {
            db: OnceCell::new(),
            frontend: OnceCell::new(),
        }
    }

    fn cleanup(self) {
        if let Some(frontend) = self.frontend.into_inner() {
            frontend.server.leak();
        }
    }

    pub(crate) fn db(&self) -> &TestDatabase {
        self.db
            .get_or_init(|| TestDatabase::new().expect("failed to initialize the db"))
    }

    pub(crate) fn frontend(&self) -> &TestFrontend {
        self.frontend.get_or_init(|| TestFrontend::new(self.db()))
    }
}

pub(crate) struct TestDatabase {
    conn: Arc<Mutex<Connection>>,
}

impl TestDatabase {
    fn new() -> Result<Self, Error> {
        // The temporary migration uses CREATE TEMPORARY TABLE instead of CREATE TABLE, creating
        // fresh temporary copies of the database on top of the real one. The temporary tables are
        // only visible to this connection, and will be deleted when it exits.
        let conn = crate::db::connect_db()?;
        crate::db::migrate_temporary(None, &conn)?;

        Ok(TestDatabase {
            conn: Arc::new(Mutex::new(conn)),
        })
    }

    pub(crate) fn conn(&self) -> MutexGuard<Connection> {
        self.conn.lock().expect("failed to lock the connection")
    }

    pub(crate) fn fake_release(&self) -> fakes::FakeRelease {
        fakes::FakeRelease::new(self)
    }
}

pub(crate) struct TestFrontend {
    server: Server,
    client: Client,
}

impl TestFrontend {
    fn new(db: &TestDatabase) -> Self {
        Self {
            server: Server::start_test(db.conn.clone()),
            client: Client::new(),
        }
    }

    fn build_request(&self, method: Method, url: &str) -> RequestBuilder {
        self.client
            .request(method, &format!("http://{}{}", self.server.addr(), url))
    }

    pub(crate) fn get(&self, url: &str) -> RequestBuilder {
        self.build_request(Method::GET, url)
    }
}
<|endoftext|>


<commit_before>use crate::cmp::Ordering;
use crate::time::Duration;

use core::hash::{Hash, Hasher};

pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
use crate::convert::TryInto;

const NSEC_PER_SEC: u64 = 1_000_000_000;

#[derive(Copy, Clone)]
struct Timespec {
    t: libc::timespec,
}

impl Timespec {
    const fn zero() -> Timespec {
        Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } }
    }

    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
        if self >= other {
            Ok(if self.t.tv_nsec >= other.t.tv_nsec {
                Duration::new(
                    (self.t.tv_sec - other.t.tv_sec) as u64,
                    (self.t.tv_nsec - other.t.tv_nsec) as u32,
                )
            } else {
                Duration::new(
                    (self.t.tv_sec - 1 - other.t.tv_sec) as u64,
                    self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
                )
            })
        } else {
            match other.sub_timespec(self) {
                Ok(d) => Err(d),
                Err(d) => Ok(d),
            }
        }
    }

    fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
        let mut secs = other
            .as_secs()
            .try_into() // <- target type would be `libc::time_t`
            .ok()
            .and_then(|secs| self.t.tv_sec.checked_add(secs))?;

        // Nano calculations can't overflow because nanos are <1B which fit
        // in a u32.
        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
        if nsec >= NSEC_PER_SEC as u32 {
            nsec -= NSEC_PER_SEC as u32;
            secs = secs.checked_add(1)?;
        }
        Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
    }

    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
        let mut secs = other
            .as_secs()
            .try_into() // <- target type would be `libc::time_t`
            .ok()
            .and_then(|secs| self.t.tv_sec.checked_sub(secs))?;

        // Similar to above, nanos can't overflow.
        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
        if nsec < 0 {
            nsec += NSEC_PER_SEC as i32;
            secs = secs.checked_sub(1)?;
        }
        Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
    }
}

impl PartialEq for Timespec {
    fn eq(&self, other: &Timespec) -> bool {
        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
    }
}

impl Eq for Timespec {}

impl PartialOrd for Timespec {
    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Timespec {
    fn cmp(&self, other: &Timespec) -> Ordering {
        let me = (self.t.tv_sec, self.t.tv_nsec);
        let other = (other.t.tv_sec, other.t.tv_nsec);
        me.cmp(&other)
    }
}

impl Hash for Timespec {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.t.tv_sec.hash(state);
        self.t.tv_nsec.hash(state);
    }
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod inner {
    use crate::fmt;
    use crate::mem;
    use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
    use crate::sys::cvt;
    use crate::sys_common::mul_div_u64;
    use crate::time::Duration;

    use super::Timespec;
    use super::NSEC_PER_SEC;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
    pub struct Instant {
        t: u64,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };

    #[repr(C)]
    #[derive(Copy, Clone)]
    struct mach_timebase_info {
        numer: u32,
        denom: u32,
    }
    type mach_timebase_info_t = *mut mach_timebase_info;
    type kern_return_t = libc::c_int;

    impl Instant {
        pub fn now() -> Instant {
            extern "C" {
                fn mach_absolute_time() -> u64;
            }
            Instant { t: unsafe { mach_absolute_time() } }
        }

        pub const fn zero() -> Instant {
            Instant { t: 0 }
        }

        pub fn actually_monotonic() -> bool {
            true
        }

        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
            let diff = self.t.checked_sub(other.t)?;
            let info = info();
            let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
            Some(Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32))
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_add(checked_dur2intervals(other)?)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            use crate::ptr;

            let mut s = libc::timeval { tv_sec: 0, tv_usec: 0 };
            cvt(unsafe { libc::gettimeofday(&mut s, ptr::null_mut()) }).unwrap();
            return SystemTime::from(s);
        }

        pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl From<libc::timeval> for SystemTime {
        fn from(t: libc::timeval) -> SystemTime {
            SystemTime::from(libc::timespec {
                tv_sec: t.tv_sec,
                tv_nsec: (t.tv_usec * 1000) as libc::c_long,
            })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("SystemTime")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    fn checked_dur2intervals(dur: &Duration) -> Option<u64> {
        let nanos =
            dur.as_secs().checked_mul(NSEC_PER_SEC)?.checked_add(dur.subsec_nanos() as u64)?;
        let info = info();
        Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64))
    }

    fn info() -> mach_timebase_info {
        static mut INFO: mach_timebase_info = mach_timebase_info { numer: 0, denom: 0 };
        static STATE: AtomicUsize = AtomicUsize::new(0);

        unsafe {
            // If a previous thread has filled in this global state, use that.
            if STATE.load(SeqCst) == 2 {
                return INFO;
            }

            // ... otherwise learn for ourselves ...
            let mut info = mem::zeroed();
            extern "C" {
                fn mach_timebase_info(info: mach_timebase_info_t) -> kern_return_t;
            }

            mach_timebase_info(&mut info);

            // ... and attempt to be the one thread that stores it globally for
            // all other threads
            if STATE.compare_exchange(0, 1, SeqCst, SeqCst).is_ok() {
                INFO = info;
                STATE.store(2, SeqCst);
            }
            return info;
        }
    }
}

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
mod inner {
    use crate::fmt;
    use crate::sys::cvt;
    use crate::time::Duration;

    use super::Timespec;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct Instant {
        t: Timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: now(libc::CLOCK_MONOTONIC) }
        }

        pub const fn zero() -> Instant {
            Instant { t: Timespec::zero() }
        }

        pub fn actually_monotonic() -> bool {
            (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64"))
                || (cfg!(target_os = "linux") && cfg!(target_arch = "x86"))
                || cfg!(target_os = "fuchsia")
                || false // last clause, used so `||` is always trailing above
        }

        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
            self.t.sub_timespec(&other.t).ok()
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl fmt::Debug for Instant {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("Instant")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            SystemTime { t: now(libc::CLOCK_REALTIME) }
        }

        pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("SystemTime")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    #[cfg(not(target_os = "dragonfly"))]
    pub type clock_t = libc::c_int;
    #[cfg(target_os = "dragonfly")]
    pub type clock_t = libc::c_ulong;

    fn now(clock: clock_t) -> Timespec {
        let mut t = Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } };
        cvt(unsafe { libc::clock_gettime(clock, &mut t.t) }).unwrap();
        t
    }
}
<commit_msg>Rollup merge of #68762 - ForNeVeR:patch-1, r=alexcrichton<commit_after>use crate::cmp::Ordering;
use crate::time::Duration;

use core::hash::{Hash, Hasher};

pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
use crate::convert::TryInto;

const NSEC_PER_SEC: u64 = 1_000_000_000;

#[derive(Copy, Clone)]
struct Timespec {
    t: libc::timespec,
}

impl Timespec {
    const fn zero() -> Timespec {
        Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } }
    }

    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
        if self >= other {
            Ok(if self.t.tv_nsec >= other.t.tv_nsec {
                Duration::new(
                    (self.t.tv_sec - other.t.tv_sec) as u64,
                    (self.t.tv_nsec - other.t.tv_nsec) as u32,
                )
            } else {
                Duration::new(
                    (self.t.tv_sec - 1 - other.t.tv_sec) as u64,
                    self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
                )
            })
        } else {
            match other.sub_timespec(self) {
                Ok(d) => Err(d),
                Err(d) => Ok(d),
            }
        }
    }

    fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
        let mut secs = other
            .as_secs()
            .try_into() // <- target type would be `libc::time_t`
            .ok()
            .and_then(|secs| self.t.tv_sec.checked_add(secs))?;

        // Nano calculations can't overflow because nanos are <1B which fit
        // in a u32.
        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
        if nsec >= NSEC_PER_SEC as u32 {
            nsec -= NSEC_PER_SEC as u32;
            secs = secs.checked_add(1)?;
        }
        Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
    }

    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
        let mut secs = other
            .as_secs()
            .try_into() // <- target type would be `libc::time_t`
            .ok()
            .and_then(|secs| self.t.tv_sec.checked_sub(secs))?;

        // Similar to above, nanos can't overflow.
        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
        if nsec < 0 {
            nsec += NSEC_PER_SEC as i32;
            secs = secs.checked_sub(1)?;
        }
        Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
    }
}

impl PartialEq for Timespec {
    fn eq(&self, other: &Timespec) -> bool {
        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
    }
}

impl Eq for Timespec {}

impl PartialOrd for Timespec {
    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Timespec {
    fn cmp(&self, other: &Timespec) -> Ordering {
        let me = (self.t.tv_sec, self.t.tv_nsec);
        let other = (other.t.tv_sec, other.t.tv_nsec);
        me.cmp(&other)
    }
}

impl Hash for Timespec {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.t.tv_sec.hash(state);
        self.t.tv_nsec.hash(state);
    }
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod inner {
    use crate::fmt;
    use crate::mem;
    use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
    use crate::sys::cvt;
    use crate::sys_common::mul_div_u64;
    use crate::time::Duration;

    use super::Timespec;
    use super::NSEC_PER_SEC;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
    pub struct Instant {
        t: u64,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };

    #[repr(C)]
    #[derive(Copy, Clone)]
    struct mach_timebase_info {
        numer: u32,
        denom: u32,
    }
    type mach_timebase_info_t = *mut mach_timebase_info;
    type kern_return_t = libc::c_int;

    impl Instant {
        pub fn now() -> Instant {
            extern "C" {
                fn mach_absolute_time() -> u64;
            }
            Instant { t: unsafe { mach_absolute_time() } }
        }

        pub const fn zero() -> Instant {
            Instant { t: 0 }
        }

        pub fn actually_monotonic() -> bool {
            true
        }

        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
            let diff = self.t.checked_sub(other.t)?;
            let info = info();
            let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
            Some(Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32))
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_add(checked_dur2intervals(other)?)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            use crate::ptr;

            let mut s = libc::timeval { tv_sec: 0, tv_usec: 0 };
            cvt(unsafe { libc::gettimeofday(&mut s, ptr::null_mut()) }).unwrap();
            return SystemTime::from(s);
        }

        pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl From<libc::timeval> for SystemTime {
        fn from(t: libc::timeval) -> SystemTime {
            SystemTime::from(libc::timespec {
                tv_sec: t.tv_sec,
                tv_nsec: (t.tv_usec * 1000) as libc::c_long,
            })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("SystemTime")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    fn checked_dur2intervals(dur: &Duration) -> Option<u64> {
        let nanos =
            dur.as_secs().checked_mul(NSEC_PER_SEC)?.checked_add(dur.subsec_nanos() as u64)?;
        let info = info();
        Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64))
    }

    fn info() -> mach_timebase_info {
        static mut INFO: mach_timebase_info = mach_timebase_info { numer: 0, denom: 0 };
        static STATE: AtomicUsize = AtomicUsize::new(0);

        unsafe {
            // If a previous thread has filled in this global state, use that.
            if STATE.load(SeqCst) == 2 {
                return INFO;
            }

            // ... otherwise learn for ourselves ...
            let mut info = mem::zeroed();
            extern "C" {
                fn mach_timebase_info(info: mach_timebase_info_t) -> kern_return_t;
            }

            mach_timebase_info(&mut info);

            // ... and attempt to be the one thread that stores it globally for
            // all other threads
            if STATE.compare_exchange(0, 1, SeqCst, SeqCst).is_ok() {
                INFO = info;
                STATE.store(2, SeqCst);
            }
            return info;
        }
    }
}

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
mod inner {
    use crate::fmt;
    use crate::sys::cvt;
    use crate::time::Duration;

    use super::Timespec;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct Instant {
        t: Timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: now(libc::CLOCK_MONOTONIC) }
        }

        pub const fn zero() -> Instant {
            Instant { t: Timespec::zero() }
        }

        pub fn actually_monotonic() -> bool {
            (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64"))
                || (cfg!(target_os = "linux") && cfg!(target_arch = "x86"))
                || cfg!(target_os = "fuchsia")
        }

        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
            self.t.sub_timespec(&other.t).ok()
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl fmt::Debug for Instant {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("Instant")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            SystemTime { t: now(libc::CLOCK_REALTIME) }
        }

        pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("SystemTime")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    #[cfg(not(target_os = "dragonfly"))]
    pub type clock_t = libc::c_int;
    #[cfg(target_os = "dragonfly")]
    pub type clock_t = libc::c_ulong;

    fn now(clock: clock_t) -> Timespec {
        let mut t = Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } };
        cvt(unsafe { libc::clock_gettime(clock, &mut t.t) }).unwrap();
        t
    }
}
<|endoftext|>


<commit_before>use quote::ToTokens;
use quote::Tokens;
use std::collections::HashMap;
use syn::{Data, DataEnum, DeriveInput, Fields};
use utils::{field_idents, named_to_vec, numbered_vars, unnamed_to_vec};

/// Provides the hook to expand `#[derive(TryInto)]` into an implementation of `TryInto`
pub fn expand(input: &DeriveInput, _: &str) -> Tokens {
    match input.data {
        Data::Enum(ref data_enum) => enum_try_into(input, data_enum),
        _ => panic!("Only enums can derive TryInto"),
    }
}

fn enum_try_into(input: &DeriveInput, data_enum: &DataEnum) -> Tokens {
    let mut variants_per_types = HashMap::new();
    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
    let input_type = &input.ident;

    for variant in &data_enum.variants {
        let original_types = match variant.fields {
            Fields::Unnamed(ref fields) => unnamed_to_vec(fields).iter().map(|f| &f.ty).collect(),
            Fields::Named(ref fields) => named_to_vec(fields).iter().map(|f| &f.ty).collect(),
            Fields::Unit => vec![],
        };
        variants_per_types
            .entry(original_types)
            .or_insert(vec![])
            .push(variant);
    }

    let mut tokens = Tokens::new();

    for (ref original_types, ref variants) in variants_per_types {
        let mut matchers = vec![];
        let vars = &numbered_vars(original_types.len(), "");
        for variant in variants.iter() {
            let subtype = &variant.ident;
            let subtype = quote!(#input_type::#subtype);
            matchers.push(match variant.fields {
                Fields::Unnamed(_) => quote!(#subtype(#(#vars),*)),
                Fields::Named(ref fields) => {
                    let field_vec = &named_to_vec(fields);
                    let field_names = &field_idents(field_vec);
                    quote!(#subtype{#(#field_names: #vars),*})
                }
                Fields::Unit => quote!(#subtype),
            });
        }

        let vars = if vars.len() == 1 {
            quote!(#(#vars)*)
        } else {
            quote!((#(#vars),*))
        };

        let output_type = if original_types.len() == 1 {
            format!("{}", quote!(#(#original_types)*))
        } else {
            let types = original_types
                .iter()
                .map(|t| format!("{}", quote!(#t)))
                .collect::<Vec<_>>();
            format!("({})", types.join(", "))
        };
        let variants = variants
            .iter()
            .map(|v| format!("{}", v.ident))
            .collect::<Vec<_>>()
            .join(", ");
        let message = format!("Only {} can be converted to {}", variants, output_type);

        let try_from = quote!{
            impl#impl_generics ::std::convert::TryFrom<#input_type#ty_generics> for
                (#(#original_types),*) #where_clause {
                type Error = &'static str;

                #[allow(unused_variables)]
                #[inline]
                fn try_from(value: #input_type#ty_generics) -> Result<Self, Self::Error> {
                    match value {
                        #(#matchers)|* => Ok(#vars),
                        _ => Err(#message),
                    }
                }
            }
        };
        try_from.to_tokens(&mut tokens)
    }
    tokens
}
<commit_msg>Clippy fix<commit_after>use quote::ToTokens;
use quote::Tokens;
use std::collections::HashMap;
use syn::{Data, DataEnum, DeriveInput, Fields};
use utils::{field_idents, named_to_vec, numbered_vars, unnamed_to_vec};

/// Provides the hook to expand `#[derive(TryInto)]` into an implementation of `TryInto`
pub fn expand(input: &DeriveInput, _: &str) -> Tokens {
    match input.data {
        Data::Enum(ref data_enum) => enum_try_into(input, data_enum),
        _ => panic!("Only enums can derive TryInto"),
    }
}

fn enum_try_into(input: &DeriveInput, data_enum: &DataEnum) -> Tokens {
    let mut variants_per_types = HashMap::new();
    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
    let input_type = &input.ident;

    for variant in &data_enum.variants {
        let original_types = match variant.fields {
            Fields::Unnamed(ref fields) => unnamed_to_vec(fields).iter().map(|f| &f.ty).collect(),
            Fields::Named(ref fields) => named_to_vec(fields).iter().map(|f| &f.ty).collect(),
            Fields::Unit => vec![],
        };
        variants_per_types
            .entry(original_types)
            .or_insert_with(Vec::new)
            .push(variant);
    }

    let mut tokens = Tokens::new();

    for (ref original_types, ref variants) in variants_per_types {
        let mut matchers = vec![];
        let vars = &numbered_vars(original_types.len(), "");
        for variant in variants.iter() {
            let subtype = &variant.ident;
            let subtype = quote!(#input_type::#subtype);
            matchers.push(match variant.fields {
                Fields::Unnamed(_) => quote!(#subtype(#(#vars),*)),
                Fields::Named(ref fields) => {
                    let field_vec = &named_to_vec(fields);
                    let field_names = &field_idents(field_vec);
                    quote!(#subtype{#(#field_names: #vars),*})
                }
                Fields::Unit => quote!(#subtype),
            });
        }

        let vars = if vars.len() == 1 {
            quote!(#(#vars)*)
        } else {
            quote!((#(#vars),*))
        };

        let output_type = if original_types.len() == 1 {
            format!("{}", quote!(#(#original_types)*))
        } else {
            let types = original_types
                .iter()
                .map(|t| format!("{}", quote!(#t)))
                .collect::<Vec<_>>();
            format!("({})", types.join(", "))
        };
        let variants = variants
            .iter()
            .map(|v| format!("{}", v.ident))
            .collect::<Vec<_>>()
            .join(", ");
        let message = format!("Only {} can be converted to {}", variants, output_type);

        let try_from = quote!{
            impl#impl_generics ::std::convert::TryFrom<#input_type#ty_generics> for
                (#(#original_types),*) #where_clause {
                type Error = &'static str;

                #[allow(unused_variables)]
                #[inline]
                fn try_from(value: #input_type#ty_generics) -> Result<Self, Self::Error> {
                    match value {
                        #(#matchers)|* => Ok(#vars),
                        _ => Err(#message),
                    }
                }
            }
        };
        try_from.to_tokens(&mut tokens)
    }
    tokens
}
<|endoftext|>


<commit_before>use std::ops::{Mul, Add, Div, Sub, Index};
use libnum::{One, Zero, Float};
use std::cmp::PartialEq;
use math::linalg::Metric;
use math::utils::dot;

pub struct Vector<T> {
	pub size: usize,
	pub data: Vec<T>
}

impl<T: Zero + One + Copy> Vector<T> {
    pub fn new(data: Vec<T>) -> Vector<T> {

    	let size = data.len();

        Vector {
            size: size,
            data: data
        }
    }

    pub fn zeros(size: usize) -> Vector<T> {
    	Vector {
            size: size,
            data: vec![T::zero(); size]
        }
    }

    pub fn ones(size: usize) -> Vector<T> {
    	Vector {
            size: size,
            data: vec![T::one(); size]
        }
    }
}

impl<T: Copy + One + Zero + Mul<T, Output=T> + Add<T, Output=T>> Vector<T> {
	pub fn dot(&self, v: &Vector<T>) -> T {
    	dot(&self.data, &v.data)
    }
}

impl<T: Copy + One + Zero + Mul<T, Output=T>> Mul<T> for Vector<T> {
    type Output = Vector<T>;

    fn mul(self, f: T) -> Vector<T> {
        let new_data = self.data.into_iter().map(|v| v * f).collect();

        Vector {
            size: self.size,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + PartialEq + Div<T, Output=T>> Div<T> for Vector<T> {
    type Output = Vector<T>;

    fn div(self, f: T) -> Vector<T> {
    	assert!(f != T::zero());

        let new_data = self.data.into_iter().map(|v| v / f).collect();

        Vector {
            size: self.size,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T>> Add<T> for Vector<T> {
	type Output = Vector<T>;

	fn add(self, f: T) -> Vector<T> {
		let new_data = self.data.into_iter().map(|v| v + f).collect();

        Vector {
            size: self.size,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T>> Add<Vector<T>> for Vector<T> {
	type Output = Vector<T>;

	fn add(self, v: Vector<T>) -> Vector<T> {
		assert!(self.size == v.size);

		let new_data = self.data.into_iter().enumerate().map(|(i,s)| s + v.data[i]).collect();

        Vector {
            size: self.size,
            data: new_data
        }
	}
}

impl<T: Copy + One + Zero + Sub<T, Output=T>> Sub<T> for Vector<T> {
	type Output = Vector<T>;

	fn sub(self, f: T) -> Vector<T> {
		let new_data = self.data.into_iter().map(|v| v - f).collect();

        Vector {
            size: self.size,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Sub<T, Output=T>> Sub<Vector<T>> for Vector<T> {
	type Output = Vector<T>;

	fn sub(self, v: Vector<T>) -> Vector<T> {
		assert!(self.size == v.size);

		let new_data = self.data.into_iter().enumerate().map(|(i,s)| s - v.data[i]).collect();

        Vector {
            size: self.size,
            data: new_data
        }
	}
}

impl<T> Index<usize> for Vector<T> {
	type Output = T;

	fn index(&self, idx : usize) -> &T {
		assert!(idx < self.size);

		&self.data[idx]
	}
}

impl<T: Float> Metric<T> for Vector<T> {
    fn norm(&self) -> T {
        let mut s = T::zero();

        for u in &self.data {
            s = s + (*u) * (*u);
        }

        s.sqrt()
    }
}<commit_msg>Updating vector to use general borrow states.<commit_after>use std::ops::{Mul, Add, Div, Sub, Index};
use libnum::{One, Zero, Float};
use std::cmp::PartialEq;
use math::linalg::Metric;
use math::utils::dot;

pub struct Vector<T> {
	pub size: usize,
	pub data: Vec<T>
}

impl<T: Zero + One + Copy> Vector<T> {
    pub fn new(data: Vec<T>) -> Vector<T> {

    	let size = data.len();

        Vector {
            size: size,
            data: data
        }
    }

    pub fn zeros(size: usize) -> Vector<T> {
    	Vector {
            size: size,
            data: vec![T::zero(); size]
        }
    }

    pub fn ones(size: usize) -> Vector<T> {
    	Vector {
            size: size,
            data: vec![T::one(); size]
        }
    }
}

impl<T: Copy + One + Zero + Mul<T, Output=T> + Add<T, Output=T>> Vector<T> {
	pub fn dot(&self, v: &Vector<T>) -> T {
    	dot(&self.data, &v.data)
    }
}

impl<T: Copy + One + Zero + Mul<T, Output=T>> Mul<T> for Vector<T> {
    type Output = Vector<T>;

    fn mul(self, f: T) -> Vector<T> {
        (&self) * (&f)
    }
}

impl<'a, T: Copy + One + Zero + Mul<T, Output=T>> Mul<T> for &'a Vector<T> {
    type Output = Vector<T>;

    fn mul(self, f: T) -> Vector<T> {
        self * (&f)
    }
}

impl<'a, T: Copy + One + Zero + Mul<T, Output=T>> Mul<&'a T> for Vector<T> {
    type Output = Vector<T>;

    fn mul(self, f: &T) -> Vector<T> {
        (&self) * f
    }
}

impl<'a, 'b, T: Copy + One + Zero + Mul<T, Output=T>> Mul<&'b T> for &'a Vector<T> {
    type Output = Vector<T>;

    fn mul(self, f: &T) -> Vector<T> {
        let new_data = self.data.iter().map(|v| (*v) * (*f)).collect();

        Vector {
            size: self.size,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + PartialEq + Div<T, Output=T>> Div<T> for Vector<T> {
    type Output = Vector<T>;

    fn div(self, f: T) -> Vector<T> {
        (&self) * (&f)
    }
}

impl<'a, T: Copy + One + Zero + PartialEq + Div<T, Output=T>> Div<T> for &'a Vector<T> {
    type Output = Vector<T>;

    fn div(self, f: T) -> Vector<T> {
        self * (&f)
    }
}

impl<'a, T: Copy + One + Zero + PartialEq + Div<T, Output=T>> Div<&'a T> for Vector<T> {
    type Output = Vector<T>;

    fn div(self, f: &T) -> Vector<T> {
        (&self) * f
    }
}

impl<'a, 'b, T: Copy + One + Zero + PartialEq + Div<T, Output=T>> Div<&'b T> for &'a Vector<T> {
    type Output = Vector<T>;

    fn div(self, f: &T) -> Vector<T> {
    	assert!(*f != T::zero());

        let new_data = self.data.iter().map(|v| *v / *f).collect();

        Vector {
            size: self.size,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T>> Add<T> for Vector<T> {
    type Output = Vector<T>;

    fn add(self, f: T) -> Vector<T> {
        (&self) * (&f)
    }
}

impl<'a, T: Copy + One + Zero + Add<T, Output=T>> Add<T> for &'a Vector<T> {
    type Output = Vector<T>;

    fn add(self, f: T) -> Vector<T> {
        self * (&f)
    }
}

impl<'a, T: Copy + One + Zero + Add<T, Output=T>> Add<&'a T> for Vector<T> {
    type Output = Vector<T>;

    fn add(self, f: &T) -> Vector<T> {
        (&self) * f
    }
}

impl<'a, 'b, T: Copy + One + Zero + Add<T, Output=T>> Add<&'b T> for &'a Vector<T> {
	type Output = Vector<T>;

	fn add(self, f: &T) -> Vector<T> {
		let new_data = self.data.iter().map(|v| *v + *f).collect();

        Vector {
            size: self.size,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T>> Add<Vector<T>> for Vector<T> {
    type Output = Vector<T>;

    fn add(self, v: Vector<T>) -> Vector<T> {
        (&self) + (&v)
    }
}

impl<'a, T: Copy + One + Zero + Add<T, Output=T>> Add<Vector<T>> for &'a Vector<T> {
    type Output = Vector<T>;

    fn add(self, v: Vector<T>) -> Vector<T> {
        self + (&v)
    }
}

impl<'a, T: Copy + One + Zero + Add<T, Output=T>> Add<&'a Vector<T>> for Vector<T> {
    type Output = Vector<T>;

    fn add(self, v: &Vector<T>) -> Vector<T> {
        (&self) + v
    }
}

impl<'a, 'b, T: Copy + One + Zero + Add<T, Output=T>> Add<&'b Vector<T>> for &'a Vector<T> {
	type Output = Vector<T>;

	fn add(self, v: &Vector<T>) -> Vector<T> {
		assert!(self.size == v.size);

		let new_data = self.data.iter().enumerate().map(|(i,s)| *s + v.data[i]).collect();

        Vector {
            size: self.size,
            data: new_data
        }
	}
}

impl<T: Copy + One + Zero + Sub<T, Output=T>> Sub<T> for Vector<T> {
    type Output = Vector<T>;

    fn sub(self, f: T) -> Vector<T> {
        (&self) - (&f)
    }
}

impl<'a, T: Copy + One + Zero + Sub<T, Output=T>> Sub<T> for &'a Vector<T> {
    type Output = Vector<T>;

    fn sub(self, f: T) -> Vector<T> {
        self - (&f)
    }
}

impl<'a, T: Copy + One + Zero + Sub<T, Output=T>> Sub<&'a T> for Vector<T> {
    type Output = Vector<T>;

    fn sub(self, f: &T) -> Vector<T> {
            (&self) - f
        }
    }

impl<'a, 'b, T: Copy + One + Zero + Sub<T, Output=T>> Sub<&'b T> for &'a Vector<T> {
	type Output = Vector<T>;

	fn sub(self, f: &T) -> Vector<T> {
		let new_data = self.data.iter().map(|v| *v - *f).collect();

        Vector {
            size: self.size,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Sub<T, Output=T>> Sub<Vector<T>> for Vector<T> {
    type Output = Vector<T>;

    fn sub(self, v: Vector<T>) -> Vector<T> {
        (&self) - (&v)
    }
}

impl<'a, T: Copy + One + Zero + Sub<T, Output=T>> Sub<Vector<T>> for &'a Vector<T> {
    type Output = Vector<T>;

    fn sub(self, v: Vector<T>) -> Vector<T> {
        (&self) - v
    }
}

impl<'a, T: Copy + One + Zero + Sub<T, Output=T>> Sub<&'a Vector<T>> for Vector<T> {
    type Output = Vector<T>;

    fn sub(self, v: &Vector<T>) -> Vector<T> {
        (&self) - v
    }
}

impl<'a, 'b, T: Copy + One + Zero + Sub<T, Output=T>> Sub<&'b Vector<T>> for &'a Vector<T> {
	type Output = Vector<T>;

	fn sub(self, v: &Vector<T>) -> Vector<T> {
		assert!(self.size == v.size);

		let new_data = self.data.iter().enumerate().map(|(i,s)| *s - v.data[i]).collect();

        Vector {
            size: self.size,
            data: new_data
        }
	}
}

impl<T> Index<usize> for Vector<T> {
	type Output = T;

	fn index(&self, idx : usize) -> &T {
		assert!(idx < self.size);

		&self.data[idx]
	}
}

impl<T: Float> Metric<T> for Vector<T> {
    fn norm(&self) -> T {
        let mut s = T::zero();

        for u in &self.data {
            s = s + (*u) * (*u);
        }

        s.sqrt()
    }
}<|endoftext|>


<commit_before>use super::size_hint;

/// See [`multizip`](../fn.multizip.html) for more information.
#[derive(Clone)]
pub struct Zip<T> {
    t: T,
}

impl<T> Zip<T> {
    /// Deprecated: renamed to multizip
    #[deprecated(note = "Renamed to multizip")]
    pub fn new<U>(t: U) -> Zip<T>
        where Zip<T>: From<U>,
              Zip<T>: Iterator,
    {
        multizip(t)
    }
}

/// An iterator that generalizes *.zip()* and allows running multiple iterators in lockstep.
///
/// The iterator `Zip<(I, J, ..., M)>` is formed from a tuple of iterators (or values that
/// implement `IntoIterator`) and yields elements
/// until any of the subiterators yields `None`.
///
/// The iterator element type is a tuple like like `(A, B, ..., E)` where `A` to `E` are the
/// element types of the subiterator.
///
/// **Note:** The result of this macro is a value of a named type (`Zip<(I, J,
/// ..)>` of each component iterator `I, J, ...`) if each component iterator is
/// nameable.
///
/// Prefer [`izip!()`] over `multizip` for the performance benefits of using the
/// standard library `.zip()`. Prefer `multizip` if a nameable type is needed.
///
/// [`izip!()`]: macro.izip.html
///
/// ```
/// use itertools::multizip;
///
/// // iterate over three sequences side-by-side
/// let mut results = [0, 0, 0, 0];
/// let inputs = [3, 7, 9, 6];
///
/// for (r, index, input) in multizip((&mut results, 0..10, &inputs)) {
///     *r = index * 10 + input;
/// }
///
/// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
/// ```
pub fn multizip<T, U>(t: U) -> Zip<T>
    where Zip<T>: From<U>,
          Zip<T>: Iterator,
{
    Zip::from(t)
}

macro_rules! impl_zip_iter {
    ($($B:ident),*) => (
        #[allow(non_snake_case)]
        impl<$($B: IntoIterator),*> From<($($B,)*)> for Zip<($($B::IntoIter,)*)> {
            fn from(t: ($($B,)*)) -> Self {
                let ($($B,)*) = t;
                Zip { t: ($($B.into_iter(),)*) }
            }
        }

        #[allow(non_snake_case)]
        #[allow(unused_assignments)]
        impl<$($B),*> Iterator for Zip<($($B,)*)>
            where
            $(
                $B: Iterator,
            )*
        {
            type Item = ($($B::Item,)*);

            fn next(&mut self) -> Option<Self::Item>
            {
                let ($(ref mut $B,)*) = self.t;

                // NOTE: Just like iter::Zip, we check the iterators
                // for None in order. We may finish unevenly (some
                // iterators gave n + 1 elements, some only n).
                $(
                    let $B = match $B.next() {
                        None => return None,
                        Some(elt) => elt
                    };
                )*
                Some(($($B,)*))
            }

            fn size_hint(&self) -> (usize, Option<usize>)
            {
                let sh = (::std::usize::MAX, None);
                let ($(ref $B,)*) = self.t;
                $(
                    let sh = size_hint::min($B.size_hint(), sh);
                )*
                sh
            }
        }

        #[allow(non_snake_case)]
        impl<$($B),*> ExactSizeIterator for Zip<($($B,)*)> where
            $(
                $B: ExactSizeIterator,
            )*
        { }
    );
}

impl_zip_iter!(A);
impl_zip_iter!(A, B);
impl_zip_iter!(A, B, C);
impl_zip_iter!(A, B, C, D);
impl_zip_iter!(A, B, C, D, E);
impl_zip_iter!(A, B, C, D, E, F);
impl_zip_iter!(A, B, C, D, E, F, G);
impl_zip_iter!(A, B, C, D, E, F, G, H);
<commit_msg>MAINT: Remove deprecated constructor Zip::new (use izip or multizip)<commit_after>use super::size_hint;

/// See [`multizip`](../fn.multizip.html) for more information.
#[derive(Clone)]
pub struct Zip<T> {
    t: T,
}

/// An iterator that generalizes *.zip()* and allows running multiple iterators in lockstep.
///
/// The iterator `Zip<(I, J, ..., M)>` is formed from a tuple of iterators (or values that
/// implement `IntoIterator`) and yields elements
/// until any of the subiterators yields `None`.
///
/// The iterator element type is a tuple like like `(A, B, ..., E)` where `A` to `E` are the
/// element types of the subiterator.
///
/// **Note:** The result of this macro is a value of a named type (`Zip<(I, J,
/// ..)>` of each component iterator `I, J, ...`) if each component iterator is
/// nameable.
///
/// Prefer [`izip!()`] over `multizip` for the performance benefits of using the
/// standard library `.zip()`. Prefer `multizip` if a nameable type is needed.
///
/// [`izip!()`]: macro.izip.html
///
/// ```
/// use itertools::multizip;
///
/// // iterate over three sequences side-by-side
/// let mut results = [0, 0, 0, 0];
/// let inputs = [3, 7, 9, 6];
///
/// for (r, index, input) in multizip((&mut results, 0..10, &inputs)) {
///     *r = index * 10 + input;
/// }
///
/// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
/// ```
pub fn multizip<T, U>(t: U) -> Zip<T>
    where Zip<T>: From<U>,
          Zip<T>: Iterator,
{
    Zip::from(t)
}

macro_rules! impl_zip_iter {
    ($($B:ident),*) => (
        #[allow(non_snake_case)]
        impl<$($B: IntoIterator),*> From<($($B,)*)> for Zip<($($B::IntoIter,)*)> {
            fn from(t: ($($B,)*)) -> Self {
                let ($($B,)*) = t;
                Zip { t: ($($B.into_iter(),)*) }
            }
        }

        #[allow(non_snake_case)]
        #[allow(unused_assignments)]
        impl<$($B),*> Iterator for Zip<($($B,)*)>
            where
            $(
                $B: Iterator,
            )*
        {
            type Item = ($($B::Item,)*);

            fn next(&mut self) -> Option<Self::Item>
            {
                let ($(ref mut $B,)*) = self.t;

                // NOTE: Just like iter::Zip, we check the iterators
                // for None in order. We may finish unevenly (some
                // iterators gave n + 1 elements, some only n).
                $(
                    let $B = match $B.next() {
                        None => return None,
                        Some(elt) => elt
                    };
                )*
                Some(($($B,)*))
            }

            fn size_hint(&self) -> (usize, Option<usize>)
            {
                let sh = (::std::usize::MAX, None);
                let ($(ref $B,)*) = self.t;
                $(
                    let sh = size_hint::min($B.size_hint(), sh);
                )*
                sh
            }
        }

        #[allow(non_snake_case)]
        impl<$($B),*> ExactSizeIterator for Zip<($($B,)*)> where
            $(
                $B: ExactSizeIterator,
            )*
        { }
    );
}

impl_zip_iter!(A);
impl_zip_iter!(A, B);
impl_zip_iter!(A, B, C);
impl_zip_iter!(A, B, C, D);
impl_zip_iter!(A, B, C, D, E);
impl_zip_iter!(A, B, C, D, E, F);
impl_zip_iter!(A, B, C, D, E, F, G);
impl_zip_iter!(A, B, C, D, E, F, G, H);
<|endoftext|>


<commit_before><commit_msg>add received messages iterator to AsyncClient<commit_after><|endoftext|>


<commit_before><commit_msg>Revert "Work around RA's RUSTC_WRAPPER poisoning all subsequent command-line builds"<commit_after><|endoftext|>


<commit_before>use crate::syntax::atom::Atom::{self, *};
use crate::syntax::{error, ident, Api, ExternFn, Ref, Ty1, Type, Types, Var};
use proc_macro2::Ident;
use syn::{Error, Result};

pub(crate) fn typecheck(apis: &[Api], types: &Types) -> Result<()> {
    let mut errors = Vec::new();

    for ty in types {
        match ty {
            Type::Ident(ident) => {
                if Atom::from(ident).is_none()
                    && !types.structs.contains_key(ident)
                    && !types.cxx.contains(ident)
                    && !types.rust.contains(ident)
                {
                    errors.push(unsupported_type(ident));
                }
            }
            Type::RustBox(ptr) => {
                if let Type::Ident(ident) = &ptr.inner {
                    if types.cxx.contains(ident) {
                        errors.push(unsupported_cxx_type_in_box(ptr));
                    }
                    if Atom::from(ident).is_none() {
                        continue;
                    }
                }
                errors.push(unsupported_box_target(ptr));
            }
            Type::UniquePtr(ptr) => {
                if let Type::Ident(ident) = &ptr.inner {
                    if types.rust.contains(ident) {
                        errors.push(unsupported_rust_type_in_unique_ptr(ptr));
                    }
                    match Atom::from(ident) {
                        None | Some(CxxString) => continue,
                        _ => {}
                    }
                }
                errors.push(unsupported_unique_ptr_target(ptr));
            }
            Type::Ref(ty) => {
                if let Type::Void(_) = ty.inner {
                    errors.push(unsupported_reference_type(ty));
                }
            }
            _ => {}
        }
    }

    for api in apis {
        match api {
            Api::Struct(strct) => {
                for field in &strct.fields {
                    if is_unsized(&field.ty, types) {
                        errors.push(field_by_value(field, types));
                    }
                }
            }
            Api::CxxFunction(efn) | Api::RustFunction(efn) => {
                for arg in &efn.args {
                    if is_unsized(&arg.ty, types) {
                        errors.push(argument_by_value(arg, types));
                    }
                }
                if let Some(ty) = &efn.ret {
                    if is_unsized(ty, types) {
                        errors.push(return_by_value(ty, types));
                    }
                }
                if efn.throws {
                    errors.push(Error::new_spanned(
                        efn,
                        "fallible functions are not implemented yet",
                    ));
                }
            }
            _ => {}
        }
    }

    for api in apis {
        if let Api::CxxFunction(efn) = api {
            errors.extend(check_mut_return_restriction(efn).err());
        }
        if let Api::CxxFunction(efn) | Api::RustFunction(efn) = api {
            errors.extend(check_multiple_arg_lifetimes(efn).err());
        }
    }

    ident::check_all(apis, &mut errors);

    let mut iter = errors.into_iter();
    let mut all_errors = match iter.next() {
        Some(err) => err,
        None => return Ok(()),
    };
    for err in iter {
        all_errors.combine(err);
    }
    Err(all_errors)
}

fn is_unsized(ty: &Type, types: &Types) -> bool {
    let ident = match ty {
        Type::Ident(ident) => ident,
        Type::Void(_) => return true,
        _ => return false,
    };
    ident == CxxString || types.cxx.contains(ident) || types.rust.contains(ident)
}

fn check_mut_return_restriction(efn: &ExternFn) -> Result<()> {
    match &efn.ret {
        Some(Type::Ref(ty)) if ty.mutability.is_some() => {}
        _ => return Ok(()),
    }

    for arg in &efn.args {
        if let Type::Ref(ty) = &arg.ty {
            if ty.mutability.is_some() {
                return Ok(());
            }
        }
    }

    Err(Error::new_spanned(
        efn,
        "&mut return type is not allowed unless there is a &mut argument",
    ))
}

fn check_multiple_arg_lifetimes(efn: &ExternFn) -> Result<()> {
    match &efn.ret {
        Some(Type::Ref(_)) => {}
        _ => return Ok(()),
    }

    let mut reference_args = 0;
    for arg in &efn.args {
        if let Type::Ref(_) = &arg.ty {
            reference_args += 1;
        }
    }

    if reference_args == 1 {
        Ok(())
    } else {
        Err(Error::new_spanned(
            efn,
            "functions that return a reference must take exactly one input reference",
        ))
    }
}

fn describe(ty: &Type, types: &Types) -> String {
    match ty {
        Type::Ident(ident) => {
            if types.structs.contains_key(ident) {
                "struct".to_owned()
            } else if types.cxx.contains(ident) {
                "C++ type".to_owned()
            } else if types.rust.contains(ident) {
                "opaque Rust type".to_owned()
            } else if Atom::from(ident) == Some(CxxString) {
                "C++ string".to_owned()
            } else {
                ident.to_string()
            }
        }
        Type::RustBox(_) => "Box".to_owned(),
        Type::UniquePtr(_) => "unique_ptr".to_owned(),
        Type::Ref(_) => "reference".to_owned(),
        Type::Str(_) => "&str".to_owned(),
        Type::Void(_) => "()".to_owned(),
    }
}

fn unsupported_type(ident: &Ident) -> Error {
    Error::new(ident.span(), "unsupported type")
}

fn unsupported_reference_type(ty: &Ref) -> Error {
    Error::new_spanned(ty, "unsupported reference type")
}

fn unsupported_cxx_type_in_box(unique_ptr: &Ty1) -> Error {
    Error::new_spanned(unique_ptr, error::BOX_CXX_TYPE.msg)
}

fn unsupported_box_target(unique_ptr: &Ty1) -> Error {
    Error::new_spanned(unique_ptr, "unsupported target type of Box")
}

fn unsupported_rust_type_in_unique_ptr(unique_ptr: &Ty1) -> Error {
    Error::new_spanned(unique_ptr, "unique_ptr of a Rust type is not supported yet")
}

fn unsupported_unique_ptr_target(unique_ptr: &Ty1) -> Error {
    Error::new_spanned(unique_ptr, "unsupported unique_ptr target type")
}

fn field_by_value(field: &Var, types: &Types) -> Error {
    let desc = describe(&field.ty, types);
    let message = format!("using {} by value is not supported", desc);
    Error::new_spanned(field, message)
}

fn argument_by_value(arg: &Var, types: &Types) -> Error {
    let desc = describe(&arg.ty, types);
    let message = format!("passing {} by value is not supported", desc);
    Error::new_spanned(arg, message)
}

fn return_by_value(ty: &Type, types: &Types) -> Error {
    let desc = describe(ty, types);
    let message = format!("returning {} by value is not supported", desc);
    Error::new_spanned(ty, message)
}
<commit_msg>Split the fallible function error message<commit_after>use crate::syntax::atom::Atom::{self, *};
use crate::syntax::{error, ident, Api, ExternFn, Lang::*, Ref, Ty1, Type, Types, Var};
use proc_macro2::Ident;
use syn::{Error, Result};

pub(crate) fn typecheck(apis: &[Api], types: &Types) -> Result<()> {
    let mut errors = Vec::new();

    for ty in types {
        match ty {
            Type::Ident(ident) => {
                if Atom::from(ident).is_none()
                    && !types.structs.contains_key(ident)
                    && !types.cxx.contains(ident)
                    && !types.rust.contains(ident)
                {
                    errors.push(unsupported_type(ident));
                }
            }
            Type::RustBox(ptr) => {
                if let Type::Ident(ident) = &ptr.inner {
                    if types.cxx.contains(ident) {
                        errors.push(unsupported_cxx_type_in_box(ptr));
                    }
                    if Atom::from(ident).is_none() {
                        continue;
                    }
                }
                errors.push(unsupported_box_target(ptr));
            }
            Type::UniquePtr(ptr) => {
                if let Type::Ident(ident) = &ptr.inner {
                    if types.rust.contains(ident) {
                        errors.push(unsupported_rust_type_in_unique_ptr(ptr));
                    }
                    match Atom::from(ident) {
                        None | Some(CxxString) => continue,
                        _ => {}
                    }
                }
                errors.push(unsupported_unique_ptr_target(ptr));
            }
            Type::Ref(ty) => {
                if let Type::Void(_) = ty.inner {
                    errors.push(unsupported_reference_type(ty));
                }
            }
            _ => {}
        }
    }

    for api in apis {
        match api {
            Api::Struct(strct) => {
                for field in &strct.fields {
                    if is_unsized(&field.ty, types) {
                        errors.push(field_by_value(field, types));
                    }
                }
            }
            Api::CxxFunction(efn) | Api::RustFunction(efn) => {
                for arg in &efn.args {
                    if is_unsized(&arg.ty, types) {
                        errors.push(argument_by_value(arg, types));
                    }
                }
                if let Some(ty) = &efn.ret {
                    if is_unsized(ty, types) {
                        errors.push(return_by_value(ty, types));
                    }
                }
                if efn.throws && efn.lang == Cxx {
                    errors.push(Error::new_spanned(
                        efn,
                        "fallible C++ functions are not implemented yet",
                    ));
                }
                if efn.throws && efn.lang == Rust {
                    errors.push(Error::new_spanned(
                        efn,
                        "fallible Rust functions are not implemented yet",
                    ));
                }
            }
            _ => {}
        }
    }

    for api in apis {
        if let Api::CxxFunction(efn) = api {
            errors.extend(check_mut_return_restriction(efn).err());
        }
        if let Api::CxxFunction(efn) | Api::RustFunction(efn) = api {
            errors.extend(check_multiple_arg_lifetimes(efn).err());
        }
    }

    ident::check_all(apis, &mut errors);

    let mut iter = errors.into_iter();
    let mut all_errors = match iter.next() {
        Some(err) => err,
        None => return Ok(()),
    };
    for err in iter {
        all_errors.combine(err);
    }
    Err(all_errors)
}

fn is_unsized(ty: &Type, types: &Types) -> bool {
    let ident = match ty {
        Type::Ident(ident) => ident,
        Type::Void(_) => return true,
        _ => return false,
    };
    ident == CxxString || types.cxx.contains(ident) || types.rust.contains(ident)
}

fn check_mut_return_restriction(efn: &ExternFn) -> Result<()> {
    match &efn.ret {
        Some(Type::Ref(ty)) if ty.mutability.is_some() => {}
        _ => return Ok(()),
    }

    for arg in &efn.args {
        if let Type::Ref(ty) = &arg.ty {
            if ty.mutability.is_some() {
                return Ok(());
            }
        }
    }

    Err(Error::new_spanned(
        efn,
        "&mut return type is not allowed unless there is a &mut argument",
    ))
}

fn check_multiple_arg_lifetimes(efn: &ExternFn) -> Result<()> {
    match &efn.ret {
        Some(Type::Ref(_)) => {}
        _ => return Ok(()),
    }

    let mut reference_args = 0;
    for arg in &efn.args {
        if let Type::Ref(_) = &arg.ty {
            reference_args += 1;
        }
    }

    if reference_args == 1 {
        Ok(())
    } else {
        Err(Error::new_spanned(
            efn,
            "functions that return a reference must take exactly one input reference",
        ))
    }
}

fn describe(ty: &Type, types: &Types) -> String {
    match ty {
        Type::Ident(ident) => {
            if types.structs.contains_key(ident) {
                "struct".to_owned()
            } else if types.cxx.contains(ident) {
                "C++ type".to_owned()
            } else if types.rust.contains(ident) {
                "opaque Rust type".to_owned()
            } else if Atom::from(ident) == Some(CxxString) {
                "C++ string".to_owned()
            } else {
                ident.to_string()
            }
        }
        Type::RustBox(_) => "Box".to_owned(),
        Type::UniquePtr(_) => "unique_ptr".to_owned(),
        Type::Ref(_) => "reference".to_owned(),
        Type::Str(_) => "&str".to_owned(),
        Type::Void(_) => "()".to_owned(),
    }
}

fn unsupported_type(ident: &Ident) -> Error {
    Error::new(ident.span(), "unsupported type")
}

fn unsupported_reference_type(ty: &Ref) -> Error {
    Error::new_spanned(ty, "unsupported reference type")
}

fn unsupported_cxx_type_in_box(unique_ptr: &Ty1) -> Error {
    Error::new_spanned(unique_ptr, error::BOX_CXX_TYPE.msg)
}

fn unsupported_box_target(unique_ptr: &Ty1) -> Error {
    Error::new_spanned(unique_ptr, "unsupported target type of Box")
}

fn unsupported_rust_type_in_unique_ptr(unique_ptr: &Ty1) -> Error {
    Error::new_spanned(unique_ptr, "unique_ptr of a Rust type is not supported yet")
}

fn unsupported_unique_ptr_target(unique_ptr: &Ty1) -> Error {
    Error::new_spanned(unique_ptr, "unsupported unique_ptr target type")
}

fn field_by_value(field: &Var, types: &Types) -> Error {
    let desc = describe(&field.ty, types);
    let message = format!("using {} by value is not supported", desc);
    Error::new_spanned(field, message)
}

fn argument_by_value(arg: &Var, types: &Types) -> Error {
    let desc = describe(&arg.ty, types);
    let message = format!("passing {} by value is not supported", desc);
    Error::new_spanned(arg, message)
}

fn return_by_value(ty: &Type, types: &Types) -> Error {
    let desc = describe(ty, types);
    let message = format!("returning {} by value is not supported", desc);
    Error::new_spanned(ty, message)
}
<|endoftext|>


<commit_before>use crate::syntax::check::Check;
use crate::syntax::namespace::Namespace;
use crate::syntax::{error, Api};
use proc_macro2::Ident;

fn check(cx: &mut Check, ident: &Ident) {
    let s = ident.to_string();
    if s.starts_with("cxxbridge") {
        cx.error(ident, error::CXXBRIDGE_RESERVED.msg);
    }
    if s.contains("__") {
        cx.error(ident, error::DOUBLE_UNDERSCORE.msg);
    }
}

pub(crate) fn check_all(cx: &mut Check, namespace: &Namespace, apis: &[Api]) {
    for segment in namespace {
        check(cx, segment);
    }

    for api in apis {
        match api {
            Api::Include(_) => {}
            Api::Struct(strct) => {
                check(cx, &strct.ident);
                for field in &strct.fields {
                    check(cx, &field.ident);
                }
            }
            Api::Enum(enm) => {
                check(cx, &enm.ident);
                for variant in &enm.variants {
                    check(cx, &variant.ident);
                }
            }
            Api::CxxType(ety) | Api::RustType(ety) => {
                check(cx, &ety.ident);
            }
            Api::CxxFunction(efn) | Api::RustFunction(efn) => {
                check(cx, &efn.ident);
                for arg in &efn.args {
                    check(cx, &arg.ident);
                }
            }
            Api::TypeAlias(_alias) => unimplemented!(),
        }
    }
}
<commit_msg>Type alias ident checking<commit_after>use crate::syntax::check::Check;
use crate::syntax::namespace::Namespace;
use crate::syntax::{error, Api};
use proc_macro2::Ident;

fn check(cx: &mut Check, ident: &Ident) {
    let s = ident.to_string();
    if s.starts_with("cxxbridge") {
        cx.error(ident, error::CXXBRIDGE_RESERVED.msg);
    }
    if s.contains("__") {
        cx.error(ident, error::DOUBLE_UNDERSCORE.msg);
    }
}

pub(crate) fn check_all(cx: &mut Check, namespace: &Namespace, apis: &[Api]) {
    for segment in namespace {
        check(cx, segment);
    }

    for api in apis {
        match api {
            Api::Include(_) => {}
            Api::Struct(strct) => {
                check(cx, &strct.ident);
                for field in &strct.fields {
                    check(cx, &field.ident);
                }
            }
            Api::Enum(enm) => {
                check(cx, &enm.ident);
                for variant in &enm.variants {
                    check(cx, &variant.ident);
                }
            }
            Api::CxxType(ety) | Api::RustType(ety) => {
                check(cx, &ety.ident);
            }
            Api::CxxFunction(efn) | Api::RustFunction(efn) => {
                check(cx, &efn.ident);
                for arg in &efn.args {
                    check(cx, &arg.ident);
                }
            }
            Api::TypeAlias(alias) => {
                check(cx, &alias.ident);
            }
        }
    }
}
<|endoftext|>